The Usage block's bare `/graphify` comment read "full pipeline on current
directory -> Obsidian vault", contradicting Step 6 (HTML viz always; Obsidian
vault only when --obsidian is explicitly given). The comment predated the
opt-in change and told agents a bare /graphify produces a vault. It now reads
"full pipeline on current directory (HTML viz; add --obsidian for a vault)".
Fixed at the skillgen source (fragments/core/core.md + the aider monolith
override), added a sanctioned-diff predicate so the monolith round-trip guard
allows the change, and re-blessed the expected/ snapshots. Every generated
skill-*.md now carries the corrected comment; the only content change across
all rendered files is this one line.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#1635: the windows skill variant declared `name: graphify-windows`, but
`graphify install --platform windows` writes it to ~/.claude/skills/graphify/
SKILL.md and Claude Code requires the folder name to equal the frontmatter
`name` — the suffix broke discovery. platforms.toml now sets name = "graphify"
(regenerated + re-blessed).
#1646: the OpenCode (and Kilo) plugin prepended its reminder with `&&`, which
Windows PowerShell 5.1 rejects as a statement separator, breaking the first
bash command of every session. Switched to `;` (valid in PowerShell 5.1, Bash,
POSIX).
#1657: the GRAPH_REPORT.md "Import Cycles" section printed "None detected" on
documents-only corpora where imports don't exist — now gated on code nodes /
import edges being present. The other two items in that issue (mojibake in
manifest/report, stdout encoding) are already handled on current v8: both files
are written UTF-8 and main() reconfigures stdout/stderr to UTF-8.
Full suite: 2909 passed, 3 skipped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The query reference doc's inline vocab-harvest / fallback-search snippets used
bare Path(...).read_text()/write_text(), which on Windows (default cp1252)
crash with UnicodeEncodeError on the cross-language corpora the doc itself
demonstrates (Cyrillic labels like обработчик). Add encoding="utf-8" to all
five sites in the skillgen source fragment and regenerate; blessed expected/,
skillgen --check + --monolith-roundtrip green.
Scoped to the concrete reproduced crash; the larger #1619 findings (the
Windows .exe interpreter-guard rewrite, INPUT_PATH backslash guidance, BOM
handling) are a separate skill-template pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#1586: the skill's interpreter-detection allowlist rejected any shebath path
with a char outside [a-zA-Z0-9/_.-], so Homebrew's versioned python@3.13 path
was skipped and detection fell through to a bare python3 without graphify.
Allow @ in the skillgen source fragments (core/devin/aider/posix), regenerate
all skill artifacts, and register the change as a sanctioned monolith diff.
Injection chars (; $ ( etc.) are still rejected.
#1606: graphify merge-graphs crashed with an unhandled NetworkXError when
inputs disagreed on directed/multigraph. _to_simple only converted MultiGraph,
leaving a DiGraph to fail compose. Normalize every input to a plain undirected
Graph (the merged cross-repo view is undirected anyway).
Also confirmed on v8: `graphify kilo install` (#1605) works (reporter was on an
older version), and `pip3 install graphifyy` failing on macOS (#1585) is a
broken Homebrew Python 3.14 / pyexpat env, not a graphify issue — pip crashes
in its own vendored distlib before graphify is touched.
skillgen --check / --monolith-roundtrip / --schema-singleton all green; shell
smoke accepts python@3.13 and still rejects `; rm -rf /` and `$(evil)`. Full
suite 2789.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generated install/skill guidance told agents to invoke a literal `skill`
tool with `skill: "graphify"`, which is host-specific and not valid in
every environment. The always-on AGENTS fragment, packaged artifact,
expected snapshot, and _skill_registration() output now use host-generic
wording: "use the installed graphify skill or instructions". Also decodes
skillgen git blob reads as UTF-8 for Windows and replaces stale English
code-block examples in the translated READMEs.
The always-on roundtrip guard deliberately freezes the v8 baseline, so an
intentional wording change would otherwise fail it. Rather than only
patching the pytest mirror (which left the blocking CLI guard
--always-on-roundtrip red, as the original PR did), this adds an explicit,
reviewable ALWAYS_ON_SANCTIONED_EDITS registry: the guard applies the
approved old->new substitution to the baseline before the byte-for-byte
compare, so this exact sentence is allowed while any other drift still
fails. CLI guard and pytest test now agree and CI passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These were committed before .gitignore included the .DS_Store rule, so
gitignore never removed them from tracking. Untrack them (they remain
on local disk, just leave git) — the existing .gitignore rule keeps
them out going forward.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BREAKING node-ID format change. The stem that prefixes every node id was the
immediate parent dir + filename, so same-named files in different directories
collided into one last-writer-wins node and silently dropped graph content
(docs/v1/api/README.md and docs/v2/api/README.md both -> api_readme). The stem is
now the full repo-relative path (docs_v1_api_readme vs docs_v2_api_readme);
top-level files are unchanged (setup.py -> setup).
- extractors/base.py::_file_stem -> full path (as_posix; make_id collapses
separators). The two hand-copied stems (symbol_resolution, mcp_ingest) now
import the canonical one, so they can't drift again.
- llm.py system prompt + extraction-spec fragments aligned to the same rule,
fixing the #1509 AST<->LLM divergence (prompt used zero parent dirs -> ghosts).
Regenerated + blessed the per-host specs.
- build_from_json deterministically re-keys every non-AST node id from its
source_file via the new stem (and registers old-stem aliases), so a cached or
pre-migration semantic fragment carrying an old short id reconciles with the
AST node instead of spawning a ghost. The semantic cache is unversioned, so
this code-side re-key (not LLM prose) is what makes it survive the format change
with no re-bill. AST nodes are already canonical and skipped.
- Migration: existing graphs migrate automatically on the next build/update (the
re-key runs in build_from_json, including the whole graph fed back through
build_merge); `graphify extract --force` for a clean rebuild. Neo4j persisted
stores need a re-import; GraphML layouts go stale.
Full suite green (2505 passed); #1504 collision fixed and old-id fragments
re-keyed verified by smoke. Lands on v9 for review before a 0.9.0 release.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hermes and the other AGENTS.md hosts (Codex, Aider, OpenClaw, Droid, Trae, ...)
run the graphify CLI directly and do not dispatch subagents. The Step 3 extraction
guidance only described the no-API-key path as "fall straight through to subagent
dispatch", so on `/graphify .` those agents had no path they could take, fixated on
the GEMINI/ANTHROPIC key language, and looped for minutes insisting on a missing key
before eventually proceeding (a pure-code corpus is AST-only and needs no key at all).
Step 3 now opens with a hoisted, host-agnostic statement -- graphify needs no API
key, never prompt for one, never block on one; code is AST-only; a code-only corpus
skips semantic extraction entirely -- and the no-key fallback now spells out a
terminal-only path (write the empty semantic file and continue, or extract content
inline) instead of assuming subagent dispatch.
Applied in the shared core fragment and in the aider/devin core variants, so all 16
skill bodies carry it; the aider/devin change is registered as a sanctioned
monolith-roundtrip diff. Regression test (test_extraction_states_no_api_key_required_
for_every_host) renders every host and pins the wording, ordering, and the
non-subagent fallback so this can't silently regress.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both the agent (session start) and the post-commit hook can run reflect; the runs
are deterministic and idempotent, but back-to-back ones are wasted work. Add
`graphify reflect --if-stale`, which no-ops when LESSONS.md is already at least as
new as every input (the memory docs and the graph). The skill's session-start
guidance now uses `--if-stale`, so when the hook just refreshed the file the
agent's run costs almost nothing, while a skill-only install still refreshes
on demand.
New lessons_fresh() helper + 5 tests (mtime freshness in each direction, and the
CLI skip/run behavior). Regenerated per-host references + re-blessed expected/;
all five skillgen guards pass; full suite 2388 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A skill-only install (no `graphify hook install`) recorded outcomes via
save-result but never ran reflect, so LESSONS.md was never generated or
refreshed and the lessons never surfaced. The query reference now instructs the
agent to run `graphify reflect` itself at the start of graph work (cheap,
deterministic, no-op with no saved outcomes) before reading LESSONS.md. The
post-commit hook stays as a between-session freshness optimization, not a
requirement. Regenerated per-host references/query.md + re-blessed expected/;
all five skillgen guards pass; full suite 2383 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the self-improving loop "just work" once graphify is installed:
- Skill: the query reference now tells the agent to read
graphify-out/reflections/LESSONS.md at the start of graph work (start from
preferred sources, skip known dead ends, see prior corrections) and to record
--outcome useful|dead_end|corrected (+ --correction) on save-result.
- Hooks: the post-commit and post-checkout rebuild bodies now auto-run reflect
after _rebuild_code — best-effort, only when graphify-out/memory/ holds saved
outcomes, and never fails the hook — so LESSONS.md refreshes on every rebuild
without a manual `graphify reflect`.
Regenerated the per-host references/query.md and re-blessed expected/; all five
skillgen guards pass (check, audit-coverage, schema-singleton, monolith-roundtrip,
always-on-roundtrip). Verified end-to-end: install hook, save-result --outcome,
commit a code change -> hook rebuilds and writes LESSONS.md with the outcome.
Full suite 2383 passed; ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`graphify install --platform agents` installs the skill to the generic
Agent-Skills locations: the spec's user-global ~/.agents/skills (global) and
./.agents/skills (--project) — the directories `npx skills` and spec-compliant
frameworks read. `--platform skills` is an alias. Previously that user-global
location was only reachable as an accidental side effect of the gemini-on-Windows
branch. Bare `graphify install` is unchanged (still single-platform claude/windows).
The platform is registered in tools/skillgen/platforms.toml (split, mirroring
amp's agents-md body) and rendered through the skillgen drift/coverage guards.
Since it is a post-v8 platform with no own v8 body, its --audit-coverage baseline
is amp's v8 body (the body it re-homes). The rendered skill body is byte-identical
to amp's; only the on-demand hooks reference differs (its own `graphify agents
install` wording).
The `graphify agents install` / `graphify skills install` subcommand is the
amp-twin: it also wires an AGENTS.md always-on section, keeping it honest with the
hooks reference it points at. The `--platform agents` path stays skill-only,
exactly as amp's `--platform amp` does.
Also: `skill-agents.md` added to package-data, and the wheel-packaging guard now
covers every platform's skill body (not just references/always-on), so a missing
skill body fails CI instead of only breaking install for real users.
Closes#1405. Implements #1432.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two integrity improvements to the core skill runbook (rendered via skillgen):
1. Graph-health gate (new Step 4.5): runs diagnostics.diagnose_extraction
read-only after build, before labeling, and surfaces dangling/missing/
self-loop and same-endpoint-collapsed edges — the silent-corruption modes of
incremental updates and AST/LLM id mismatches. Never aborts.
2. Anchor the AST and semantic caches on the scan root (root/cache_root=
'INPUT_PATH') instead of the cwd, matching the CLI extract path
(ast cache_root=out_root, check/save_semantic_cache(root=out_root)) and
build_from_json/save_manifest (#1361 parity). Without this, running from a
cwd != scan root cold-misses the cache and can split AST vs semantic caches.
Source edited in tools/skillgen/fragments/core/core.md; artifacts + expected/
regenerated via 'python -m tools.skillgen' (+ --bless). Full suite green
(2229 passed); skillgen + cache suites green (80 passed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The split-skill runbook passed '.' as report.generate's root argument in
Steps 4 and 5, so `/graphify /some/path` produced a report titled
"# Graph Report - ." regardless of the scanned directory. It now passes
'INPUT_PATH' (the Aider/Devin monoliths were already correct). Display-only:
no path written to graph.json or manifest.json was affected. Regenerated +
blessed the split-skill artifacts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The skill runbooks called save_manifest(...) with no root=, so manifest keys
were stored as absolute paths (e.g. /Users/.../main.go). Cloning or moving the
repo then broke `graphify --update`: detect_incremental matched none of the
cached keys, so the entire corpus re-extracted (and the report showed ghost
nodes). The native `graphify extract`/`update` CLI already passed root=target;
the agent-executed runbooks did not.
All four runbook call sites now pass root='INPUT_PATH', relativizing manifest
keys to the scan root (portable forward-slash form, per save_manifest's #777
support): the lean-core skill.md Step 9, the shared --update reference, and the
Aider/Devin monoliths.
The monolith edit is registered as a new sanctioned change-class
(_is_manifest_root_fix_line) in the round-trip guard, mirroring how the #1392
runbook fixes were sanctioned. Regenerated + blessed all artifacts; added a
regression test asserting every shipped runbook threads root= into save_manifest.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The monoliths are hand-maintained single files frozen against a pinned pristine-v8 blob by the round-trip guard, so they were excluded from the 0.8.44 #1392 batch. Evolve the guard from a positional zip (line-count-exact, single-line-class allowlist) to a multiset diff that classifies every added/removed line against documented sanctioned change-classes, so the multi-line fixes can land while any unsanctioned drift still fails. Add predicates for the four fix classes and broaden the enum/chunk-cleanup predicates to match both the v8 and rewritten forms.
Both monoliths now: thread directed=IS_DIRECTED through every build_from_json call (a --directed run no longer collapses reciprocal edges), scope semantic extraction to document/paper/image, unlink a stale .graphify_cached.json on a cache miss, and run Step 4's zero-node guard before any write with the report/analysis gated on to_json persisting the graph (#1392).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes the non-crash tier of #1392 in the Claude-path skill fragments:
- #6/#7: build_from_json/build_merge now take directed=IS_DIRECTED in Step 4, Step 5 rebuild, and the --update merge/diff, with prose telling the agent to substitute IS_DIRECTED like INPUT_PATH (a --directed run no longer silently rebuilds undirected and collapses reciprocal edges)
- #10: semantic extraction only flattens document/paper/image, not code (AST already covers code) so subagents stop re-reading every source file
- #12: .graphify_cached.json is deleted on a cache miss so Part C never merges a stale cache from a prior run
- #11: --update now transcribes changed video files and moves transcripts to documents before the semantic pipeline
- #4/#5/#23: transcribe writes via write_text (no shell redirect), uses GRAPHIFY_WHISPER_MODEL/PROMPT env, status to stderr
- #2/#3: add-watch and exports use $(cat graphify-out/.graphify_python) explicitly; MCP Desktop config documents the absolute interpreter path
- #21: extraction-spec example id namespaced (auth_session_validatetoken)
- #22: query term split keeps tokens >= 3 chars
aider/devin monoliths are pinned by the roundtrip invariant and excluded; their own Step 1 already instructs replacing python3 with the resolved interpreter.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Five fixes in the skillgen fragments (re-rendered): chunk paths now derive from
cwd to match where Part C globs (a non-cwd scan produced "no nodes"); the
code-only fast path writes an empty .graphify_semantic.json so Part C doesn't
FileNotFoundError; --cluster-only relies on the self-contained CLI instead of
re-running Steps 5-9 against deleted intermediate files; and Step 4 runs the
zero-node guard before any write and only writes GRAPH_REPORT.md / analysis when
to_json actually persisted the graph (honoring the #479 shrink-guard).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
After #1361 added root= to the --update build_merge call, build_merge's prune
(which runs after the merge) began matching freshly re-extracted changed-file
nodes and deleting them — a regression in 0.8.41 where --update on a changed
file wiped its nodes. This drops `changed` from prune_sources (replace-on-
re-extract from #1344 already reconciles changed files), passes root= to the
full build's build_from_json so its node-key base matches the update side, and
pins the extraction-spec source_file to the verbatim path so the two runs never
drift. Re-blessed skillgen expected/ snapshots.
Co-Authored-By: RelywOo <RelywOo@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the source_file convention fix begun in #1344 (build_merge
replace-on-re-extract) and #1361 (pass root= to build_merge in the --update
runbook). Two gaps still let the full build and incremental --update emit
different source_file bases for the same file, so the source_file-keyed replace
missed and duplicates accumulated:
1. extraction-spec(.md/-compact.md): the subagent's source_file slot was an
unpinned "relative/path", so it invented a base per run (and the node id,
derived from the same path, drifted too). Pin it to the verbatim FILE_LIST
path so _norm_source_file(root) canonicalizes every run identically.
2. core.md: the full build called build_from_json WITHOUT root=, so #1361's
update-side root= had no matching base on the full-build side. Pass
root='INPUT_PATH' at both sites (Step 4 export, Step 5 report) so the full
build and --update relativize to the same base.
update.md prune_sources = deleted only. Changed files are replaced by build_merge
(#1344); once root= aligns the bases, leaving `changed` in prune_sources would
delete the freshly re-extracted nodes.
Engine (build.py) unchanged. Regenerated all skill artifacts via
tools/skillgen/gen.py. Adds test_build_merge_root_collapses_convention_drift.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /graphify --update runbook called build_merge with absolute prune_sources
but no root=, so _norm_source_file never relativized them to match the graph's
relative source_file values. Nothing was pruned and changed/deleted files left
ghost nodes that compounded on every incremental update. Fix the shared skillgen
fragment to pass root='INPUT_PATH' and re-render all platform artifacts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The query skill was split across two fragments so no platform got both
capabilities: Claude had the vocab/IDF query-expansion step but no fallback if
the CLI was unavailable; every other platform had the inline NetworkX fallback
but the weaker raw-question matcher. Merge into one unified query reference +
stub (Step 0 expansion -> CLI traversal -> inline NetworkX fallback, plus
path/explain inline) shipped to all hosts. Remove the query_variant enum, its
toml field, and the _CLI_ONLY_QUERY_HEADINGS coverage-audit exemption. Re-render
all skill artifacts and re-bless expected/. skillgen check/audit-coverage/
monolith-roundtrip/schema-singleton all pass. Refs #1325.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The no-push 'graphify export falkordb' path advertised
'redis-cli -x GRAPH.QUERY graphify < cypher.txt', but FalkorDB rejects that
with 'query with more than one statement is not supported' - cypher.txt is a
multi-statement Neo4j script. The individual statements ARE valid OpenCypher
(verified by loading them one at a time), only bulk script import is unsupported.
Message + skill docs now say so and point to --push (the verified load path).
Makes the FalkorDB option a first-class sibling of Neo4j in the agent skill,
not just the export CLI:
- --falkordb / --falkordb-push shorthands documented in core.md + the shared
exports.md reference, so they render into all modular platform skills and
read exactly like --neo4j / --neo4j-push. (The aider/devin monoliths are
diff-frozen vs v8 by skillgen's roundtrip guard, so they are left untouched.)
- README command reference switched to the /graphify ./raw --falkordb-push form.
- Documented URI scheme is now falkordb://localhost:6379; the scheme is only
informational (host/port are parsed out), so redis:// or a bare host:port
remain equivalent. Regenerated skill artifacts + expected/ snapshots.
The Agent Skills spec only defines name, description, license,
compatibility, metadata, and allowed-tools as valid frontmatter fields.
The trigger: /graphify line was non-spec, silently ignored by spec-
following hosts, and flagged by agentskills validate CI checks.
- gen.py: removed trigger emission from _render_frontmatter; added
_is_trigger_line() helper for roundtrip allow-list
- fragments/core/aider.md: removed hardcoded trigger: /graphify
- platforms.toml: removed trigger doc comment and trigger="" entries
- test_skillgen.py: replaced trigger-assertion tests with a single
test asserting no host has trigger: in frontmatter
- Regenerated all 125 skill artifacts
Routing intent is preserved: the description field already contains
"treated as a graphify query first" and "graphify-out/ exists".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three-part fix:
dedup.py: Pass 1 exact-merge now skips nodes with an empty source_file.
Previously all no-source_file nodes with the same label landed in one
bucket and were merged, destroying distinct symbols (third-party deps,
standalone functions) that happened to share a short name.
update.md (skillgen + all 13 host variants): the --update merge now
passes both deleted AND changed files to prune_sources, mirroring what
watch._rebuild_code already does correctly. Old nodes for re-extracted
files are pruned before fresh AST is inserted — no fuzzy reconciliation
needed, no cross-file collapse possible.
export.py: anti-shrink guard message now names fuzzy dedup as a
possible cause (not only "missing chunk files"), and advises a full
rebuild as the safe recovery path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
#1174: affected.py load_graph now forces directed=True before
node_link_graph, matching the identical fix in serve.py and __main__.py.
Undirected graphs (directed:false in graph.json) were causing in_edges
to fall back to a direction-blind scan, missing true callers and
reporting false positives. Regression test added.
#1173: post-commit and post-checkout hook bodies now read
graphify-out/.graphify_root before calling _rebuild_code, falling back
to Path('.') if absent. A scoped build (graphify src/) no longer gets
silently expanded to the full repo on the next commit. Tests added.
#1172: Step 9 cleanup split into rm -f for fixed files and
find -maxdepth 1 -delete for the chunk glob. Under fish/zsh an
unmatched glob aborts the entire rm -f line, leaving temp files on disk.
Fixed in the three skillgen source fragments and regenerated.
#1163: detect_incremental type guard on stored mtime — if the manifest
contains a dict-valued mtime (schema drift from older versions), coerce
to None rather than propagating a non-numeric into comparisons.
Regression test added.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gen.py imported tomllib unconditionally, but that is 3.11+ stdlib only and
graphify supports (and CI tests) 3.10 - so importing tools.skillgen.gen, and
thus collecting test_skillgen.py, crashed the 3.10 test job with
ModuleNotFoundError. Fall back to the tomli backport on <3.11 and add tomli to
the dev group under that marker. Verified the fallback loads and parses with
tomllib forced absent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
R1: the 6 always-on blocks were read into module-level constants at import,
so a missing/corrupt always_on/*.md crashed `import graphify.__main__` and
bricked every CLI command, not just install. Make _always_on lazy + lru_cached,
raising a clear "reinstall" error only on the install path that needs the block;
a module __getattr__ keeps the legacy constant names importable for the tests.
Verified: deleting a block no longer crashes `graphify --version`.
skillgen baselines: the self-check guards pinned to the moving `origin/v8` ref,
which stops pointing at the pre-split state once the split lands on v8 (the
always-on-roundtrip guard then fails in CI and monolith-roundtrip goes vacuous).
Pin _v8_baseline_ref, ALWAYS_ON_BASELINE_REF, and the two monolith roundtrip_refs
to the immutable pre-split commit SHA, matching the stated "does not track HEAD"
intent; update the 4 tests that asserted the old ref string.
R2: add tests/test_wheel_packaging.py - build the wheel and assert every
references bundle and always-on block ships in it, so a package-data glob miss
can't pass the repo-tree guards yet hard-exit `graphify install` for real users.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All-platform progressive-disclosure skill split + generator (addresses #1106).
Splits each platform's skill into a lean core (~615 lines, full default pipeline inline) + on-demand references/, generated from a single source via tools/skillgen with a CI/pre-commit drift gate. 13 hosts split, aider/devin stay monoliths. Also fixes the stale bare-path bugs across the previously hand-maintained variants and moves the always-on blocks into packaged markdown.
Verified: all 5 generator guards pass, byte-verbatim load-bearing slices, lean cores self-sufficient on the default path across all 13 split hosts, references gated to non-default branches, description preserves the graphify-out-query-first clause. Supersedes #1119 (Claude-first subset).
Known follow-up applied on top: harden _always_on() against a missing packaged file so a partial install can't brick the CLI.