Don’t trust your memory — write it down.
pj(...) for portable paths and a serialization family for consistent read/write across JSON, YAML, text, JSONL, jstr, binary, and related formats.
1. Why a Unified File System Utility
Without a unified file system utility, every script and demo re-implements path joining, alias resolution, encoding handling, and serialization. The results are inconsistent: one module usesos.path.join(...) with hardcoded relative paths, another uses pathlib.Path with expanduser(), and a third hardcodes / separators that break on Windows. Serialization diverges the same way — one caller writes JSON with indent=2, another uses default=str, and a third hard-codes utf-8 encoding.
pj(...) is the single path vocabulary: it expands ~, resolves environment variables, normalizes separators, optionally returns absolute paths, and resolves caller-provided aliases. The serialization family uses config-driven defaults (CM_HVNB at heavenbase.serialize.encoding and heavenbase.serialize.indent) so every caller gets consistent output without repeating those parameters.
pj(...), then read or write through the matching serialization helper without re-specifying encoding, indentation, or platform details.
2. Two Core Ideas
File System utilities split cleanly into path vocabulary and serialization I/O. Everything else on this page — touching folders, listing files, copying artifacts, folder diagrams — supports those two flows.2.1. pj(...) — Portable Paths
pj(...) is the canonical path join helper. It joins path parts, expands ~ and environment variables, normalizes separators, optionally returns an absolute path, and can resolve caller-provided aliases.
Think of it as a small path vocabulary. . means the current working location, ~ expands to the user home, environment variables expand through the operating system, and aliases such as % or & can point to a package data folder or resource folder when the caller or config manager provides that alias map.
Utility
pj(...) handles normal paths and caller aliases. CM_HVNB.pj(...) handles HeavenBase package aliases: %/ for package-local data and &/ for package resources.2.2. Serialization Family — Config-Driven I/O
The serialization helpers wrap common read/write for the same reason configuration wraps hyperparameters: callers should not pass encoding, indentation, and platform path details through every function. Each format exposes the same naming pattern:
Text encodings default to
heavenbase.serialize.encoding, which is utf-8 in the default config. JSON and YAML indentation default to heavenbase.serialize.indent, which is 4. Missing files return empty defaults ("", {}, [], or b"") unless you pass strict=True. This shows the benefit of the config-driven approach: you can change the default encoding or indentation without changing every caller.
JSON helpers use HbJsonEncoder and HbJsonDecoder, which preserve common HeavenBase values such as datetimes, decimals, tuples, sets, and callable references — so artifacts round-trip without ad-hoc default=str handlers.
3. Build a Path
Usepj(...) for ordinary local paths:
4. Prepare Files and Folders
Usetouch_dir(...) and touch_file(...) before writing artifacts. Both create missing parents and return an absolute path.
clear=True only when the folder or file should start empty:
5. Read and Write Data
Serialization is the second pillar of this page. Pick a format, call the matching helper, and letCM_HVNB supply encoding and indentation defaults. Combine with pj(...) and touch_dir(...) for a complete artifact workflow.
5.1. JSON
Use JSON for structured machine-readable artifacts — configs, run metadata, workspace snapshots, and interchange with other tools.sort_keys=True when deterministic key order matters (for example, before hashing). Pass compact=True or indent=None for one-line output.
5.2. YAML
Use YAML for human-editable structured files such as config templates and small manifests.heavenbase.serialize.indent.
5.3. Text
Use text helpers for logs, Markdown notes, plain reports, and any human-readable line-oriented output.load_txt returns "" for a missing file unless strict=True. append_txt adds a trailing newline after each write.
5.4. JSONL
Use JSONL when a workflow appends one event or record at a time — run logs, streaming exports, and incremental audit trails.append_jsonl for incremental writes and dump_jsonl when you have the full iterable in memory. Use iter_jsonl to stream large files without loading every line at once.
5.5. jstr — Python-Facing Text
jstr means “JSON when the top-level value is a container, otherwise string.” Usedumps_jstr, loads_jstr, dump_jstr, load_jstr, and save_jstr at text boundaries such as Tool results, memstate rows, and MCP payloads where structured values should stay machine-readable while scalars and other values stay human-readable through str(...).
Rules:
- Top-level
dictorlistvalues (including nested containers) serialize as compact JSON through the same encoder asdumps_json. - All other values, including
int,float,bool,None, tuples, sets, and custom objects, usestr(obj). loads_jstrparses text that looks like a JSON object or array; invalid JSON in that shape, and all other text, is returned unchanged as a string.
serializer=None and resolves to the shared jstr_serializer Capsule at execution time, so toolkit.run_to_str(...) and FastMCP serving route successful tool outputs through dumps_jstr. Local Python callers can still use toolkit.run(...) for raw objects.
5.6. Binary
Use binary helpers for raw byte payloads — model weights, compressed blobs, image bytes, and other non-text artifacts.load_bin returns b"" for a missing file unless strict=True.
5.7. Hex and Base64
Use hex and Base64 helpers when byte payloads need a text-safe representation in files or logs.dump_hex and dump_b64 decode a hex or Base64 string and write the resulting bytes. load_hex and load_b64 read a binary file and return a hex or Base64 text representation. Use dumps_b64 / loads_b64 for in-memory encoding without touching the filesystem.
5.8. Pickle
Use pickle only for trusted local artifacts produced by your own environment. Pickle can execute arbitrary code during load and must never cross a trust boundary.6. List, Copy, and Delete Artifacts
list_files(...) reads direct children. enum_files(...) walks recursively. Both return stable, case-insensitive order.
replace, skip, and strict; directories also support merge.
7. Show a Folder Diagram
Usefolder_diagram(...) for compact diagnostics in logs, reports, and docs snippets.

