feat(export): per-community subfolders + path-aware filenames for to_obsidian#844
feat(export): per-community subfolders + path-aware filenames for to_obsidian#844fitliferepo wants to merge 1 commit into
Conversation
…obsidian Restructure to_obsidian and to_canvas output to address three long-standing issues with the Obsidian vault layout: 1. Filename collisions. The old logic produced files like `__init__()_1.md`, `__init__()_2.md` when multiple nodes shared a label. New logic slugs the last 3 source-path segments + the label, so two `__init__()` nodes in different modules get distinct, source-traceable filenames like `app-routers-pipeline-py--init` and `app-models-py--init`. 2. Flat vault layout. All node notes used to land in one directory. Now each node is written into a per-community subfolder, and each folder gets a `_OVERVIEW.md` (replacing top-level `_COMMUNITY_*.md`). A new `_INDEX.md` at vault root lists every community sorted by size. 3. Dangling cross-community links. The old "Connections to other communities" section emitted `[[_COMMUNITY_X]]` wikilinks; with the new layout these now resolve to `[[<folder>/_OVERVIEW|<community name>]]`. Edge cases handled: - Community labels that slug to the same string (e.g. three communities all labelled "main") now get unique folder names `main/`, `main-2/`, `main-3/`, each with its own _OVERVIEW. - Nodes with empty label or empty source_file fall back to `node.md`. to_canvas updated to match: canvas file refs now point at `<community-folder>/<filename>.md` so the canvas resolves against the new vault structure. Adds 4 new tests covering subfolder layout, path-disambiguated filenames, unique-folder behaviour under colliding community labels, and a vault-wide no-dangling-wikilinks invariant. Updates the existing canvas test to assert that every canvas file ref maps to a file actually written by to_obsidian.
|
Thanks for this — per-community subfolders is a great UX improvement and the test coverage is solid. Two issues to fix before we merge: 1. Duplicated helper code (must fix) 2. Cross-folder wikilink collisions (must fix) Minor
Once these are fixed and the PR is rebased onto current |
Why
When
to_obsidianis run on a real codebase, the current output has three issues that get in the way of using the vault:__init__()_1.md,__init__()_2.md(no way to tell which file)app-routers-pipeline-py--init.md,app-models-py--init.md(path-traceable)_OVERVIEW.mdinside[[_COMMUNITY_X]](dangle once you rename overviews)[[folder/_OVERVIEW|name]](always resolves)Tested on a ~1,700-node codebase: 0 dangling wikilinks, 0 lost files, 64 navigable subfolders instead of 1,700+ files at root.
What
graphify/export.py:to_obsidian: pre-computes a unique folder name per community id (handles label collisions), routes each node note into its community folder, replaces_COMMUNITY_*.mdwith per-folder_OVERVIEW.md, emits a top-level_INDEX.mdwith communities sorted by size.to_canvas: uses the same path-aware naming and emits canvas file refs as<folder>/<filename>.mdso the canvas resolves against the new layout.<last-3-source-path-segments-slug>--<label-slug>. Falls back to plain label slug ifsource_fileis missing, then tonodeif both are empty.Tests
4 new tests + 1 updated:
test_to_obsidian_writes_per_community_subfolders— subfolder + overview + index emittest_to_obsidian_filenames_disambiguate_by_source_path— no_1suffixes for same-label nodestest_to_obsidian_unique_folders_when_community_labels_collide— three communities labelled "main" →main/,main-2/,main-3/test_to_obsidian_has_no_dangling_wikilinks— vault-wide invarianttest_to_canvas_file_paths_relative_to_vault— updated to assert canvas refs resolve to real files on diskAll 19 tests in
test_export.pypass. Full suite (test_export.py test_cli_export.py test_build.py test_cluster.py test_analyze.py): 84 passed. Pre-existing failures intest_multilang.py(SQL) andtest_ollama.pyare unrelated and reproduce on stockv7.Compatibility
to_obsidianandto_canvaskeep the same signatures and return types.[[bare-name]]links across subfolders automatically._COMMUNITY_*.mdat the vault root, they'll need to switch to reading<folder>/_OVERVIEW.md.