zettelkasten.outlines¶
zettelkasten.outlines ¶
Backward-compatible shim: outlines was renamed to outline_registry.
The multi-outline registry now lives in :mod:zettelkasten.outline_registry.
This module re-exports its full surface so existing importers
(from zettelkasten import outlines) keep working unchanged.
validate_id ¶
Validate that value is safe to interpolate into a filesystem path.
By default this is a containment check, not a format check. It rejects
empty values, path separators, .. sequences, absolute paths, control
characters, and over-long strings -- but otherwise permits any characters
(letters, digits, -, _, ., : for namespaced IDs, etc.) so
existing IDs keep working.
When for_filename=True the check is stricter: it additionally rejects
Windows-illegal filename characters (including :, which would otherwise
create an NTFS alternate data stream), trailing dots/spaces (silently
stripped by Windows), and reserved device names. Use this mode at sites that
turn the value directly into a filename.
Returns the value unchanged when valid; raises :class:ValueError otherwise.
Source code in memory/safety.py
atomic_write_text ¶
Write text to path crash-safely (temp file + fsync + rename).
The temp file is created in the SAME directory as path so the final
os.replace is an atomic rename on the same filesystem. The file's
contents are flushed and os.fsync'd before the rename, and the PARENT
DIRECTORY is fsync'd after, so a crash can never leave a half-written
manifest/note nor lose the directory entry of a newly-created file. The temp
file is cleaned up on failure. Mirrors the temp+rename precedent in
config.write_config and embeddings.save_cache, adding the fsyncs for
durability.
Source code in zettelkasten/graph_io.py
load_review ¶
Load a single literature-review manifest from _reviews/
Returns {} for a missing file (no exception), mirroring
:func:load_project. _reviews/ lives beside _projects/ at
<repo>/.zettelkasten/.
A corrupt manifest (invalid YAML, non-UTF-8 bytes, unreadable inode) is
NOT silently swallowed: unlike the missing case it would mask real data
loss, so it is re-raised as a clear, catchable ValueError that the route
layer can map to a clean status instead of a raw 500 traceback.
Source code in zettelkasten/graph_io.py
write_yaml_atomic ¶
Dump data to YAML and write it atomically via :func:atomic_write_text.
Uses default_flow_style=False, sort_keys=False to match the existing
manifest/meta YAML style in this package.
Source code in zettelkasten/graph_io.py
split_overlay ¶
Split a manifest overlay into (review_wide, outline_overlay).
Both halves are normalized to the full per-key shape, so a partial / None
overlay still yields complete sub-dicts.
Source code in zettelkasten/outline_registry.py
merge_overlay ¶
Recombine a shared review-wide half + one outline's per-outline half.
Returns the full overlay shape :func:review.apply_overlay expects.
Source code in zettelkasten/outline_registry.py
draft_path ¶
The markdown artifact path for an outline.
The default outline keeps the legacy _reviews/<name>.md path; additional
outlines namespace their markdown by id.
Source code in zettelkasten/outline_registry.py
ensure_outlines ¶
ensure_outlines(name: str, *, graphs_dir: 'Path | None' = None, manifest: dict[str, Any] | None = None) -> dict[str, Any]
Return the outlines store {"outlines": {id: record}} for a review.
The default outline (derived from the manifest) is always present when the
review exists; additional outlines come from the sidecar. Pass manifest to
avoid a redundant load.
Source code in zettelkasten/outline_registry.py
get_outline ¶
get_outline(name: str, outline_id: str, *, graphs_dir: 'Path | None' = None, manifest: dict[str, Any] | None = None) -> dict[str, Any] | None
A single outline record, or None if it does not exist.
Source code in zettelkasten/outline_registry.py
merged_overlay ¶
merged_overlay(name: str, outline_id: str, *, graphs_dir: 'Path | None' = None, manifest: dict[str, Any] | None = None) -> dict[str, Any] | None
The full overlay for an outline: shared review-wide + that outline's structure.
Returns None when there is nothing to honor — no manifest (the default
outline's review does not exist), or an unknown additional outline id — so
callers fall back to the graph-derived ordering exactly as before.
Source code in zettelkasten/outline_registry.py
get_question ¶
get_question(name: str, outline_id: str, *, graphs_dir: 'Path | None' = None, manifest: dict[str, Any] | None = None) -> str
An outline's research question (default → the review's own question).
Source code in zettelkasten/outline_registry.py
read_draft_cache ¶
read_draft_cache(name: str, outline_id: str, *, graphs_dir: 'Path | None' = None, manifest: dict[str, Any] | None = None) -> dict[str, Any] | None
The stored scaffold cache block for an outline (or None).
Source code in zettelkasten/outline_registry.py
write_draft_cache ¶
write_draft_cache(name: str, outline_id: str, scaffold: dict[str, Any], *, graphs_dir: 'Path | None' = None) -> None
Persist an ADDITIONAL outline's scaffold cache into the sidecar.
The default outline's cache lives in the manifest and is written by
:func:zettelkasten.outline._persist_draft — never here.
Source code in zettelkasten/outline_registry.py
list_outlines ¶
Summaries of every outline (default first, then additional).
Source code in zettelkasten/outline_registry.py
create_outline ¶
create_outline(name: str, *, title: str = '', question: str = '', outline_id: str | None = None, spine: str | None = None, spine_mode: str | None = None, project: str = '', graph: str = '', graphs_dir: 'Path | None' = None, get_graph: Any = None) -> dict[str, Any]
Create a new ADDITIONAL outline (never the default) under a review.
A fresh structure starts PRISTINE — an empty overlay with no seeded
ordering, exactly like :func:zettelkasten.review.create_review. Its
structure then reports as unbuilt so the dashboard shows the blank "build a
structure" state (and the Structure wizard) instead of the raw
auto-projection. (get_graph/project/graph are accepted for
call-site compatibility but no longer used at creation.)
Source code in zettelkasten/outline_registry.py
rename_outline ¶
Patch an outline's display title (default → the review title). True if it existed.
Source code in zettelkasten/outline_registry.py
set_outline_question ¶
set_outline_question(name: str, outline_id: str, question: str, *, graphs_dir: 'Path | None' = None) -> bool
Set an outline's research question (default → the review's question).
Source code in zettelkasten/outline_registry.py
set_outline_spine ¶
set_outline_spine(name: str, outline_id: str, spine: str | None, *, spine_mode: str | None = None, graphs_dir: 'Path | None' = None) -> bool
Set an outline's spine org id (default → the review manifest).
Any blank/empty value clears the spine (stored as None). spine_mode is
the section-partition mode for an overarching selection; it is stored
normalized alongside the spine, and is always cleared to None when the
spine itself is cleared (a mode with no spine is meaningless). Returns True if
the outline existed.
Source code in zettelkasten/outline_registry.py
delete_outline ¶
Remove an ADDITIONAL outline. The default outline cannot be deleted.
Returns True if removed; False for an unknown id or the default.