Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
983 commits
Select commit Hold shift + click to select a range
813db19
Merge pull request #1295 from sirphilliptubell/perf/fix5
safishamsi Jun 13, 2026
b830862
fix: four production bugs — Windows crashes, ghost-merge collision, v…
safishamsi Jun 13, 2026
10655b9
changelog: document four bug fixes (#1257, #1288, #1298, #1299)
safishamsi Jun 13, 2026
9bed831
Merge pull request #1209 from nucleusjay/ci-run-security-scanners
safishamsi Jun 13, 2026
591cc93
Merge pull request #1166 from leonaburime-ucla/docs/node-summaries-rfc
safishamsi Jun 13, 2026
b61c985
changelog: document #1209 security CI and #1166 node-summaries RFC
safishamsi Jun 13, 2026
85de47e
fix: community names blank in query/MCP after cluster-only; --graph f…
safishamsi Jun 13, 2026
a4f3e86
changelog: document community name fix and --graph alias (#1304, #1305)
safishamsi Jun 13, 2026
fd470fa
docs: add --graph flag example to graphify-mcp usage (#1304)
safishamsi Jun 13, 2026
61836ce
feat: custom endpoints via OPENAI_BASE_URL/OPENAI_MODEL and ANTHROPIC…
slydlake Jun 16, 2026
09da529
feat: extract JS/TS this.X=, exports.X=, prototype, class arrow field…
siddarthc Jun 16, 2026
adb52a1
Index .psm1, anchor Swift import targets, dedupe no-cluster edges
safishamsi Jun 16, 2026
fd152ad
Release 0.8.40
safishamsi Jun 16, 2026
4fbb333
Collapse Swift module imports to one shared node
safishamsi Jun 16, 2026
2100b3d
Resolve cross-file Java type references by import package
safishamsi Jun 16, 2026
be3dcfc
Unify query skill: ship expansion + inline fallback to every platform
safishamsi Jun 16, 2026
d885833
fix node label lookup normalization (#1353)
balloon72 Jun 17, 2026
9a7dbfb
fix js workspace import resolution (#1352)
balloon72 Jun 17, 2026
a16b3e1
fix incremental no-cluster graph updates (#1350)
pkudinov Jun 17, 2026
f117aac
feat: PowerShell .psd1 manifest parsing & Import-Module / dot-source …
geektan123 Jun 17, 2026
fd463de
fix(build_merge): replace re-extracted files instead of accumulating …
RelywOo Jun 17, 2026
d8fa70e
Harden HTML output against U+2028 XSS + two crash-on-adversarial-inpu…
mistic96 Jun 17, 2026
2e01f37
Resolve cross-file Swift class relationships from member calls and co…
safishamsi Jun 17, 2026
2c662c7
Pass root to build_merge in the update runbook so stale nodes get pru…
safishamsi Jun 17, 2026
9c8bd4d
Populate Obsidian canvas when no community data is present (#1324)
safishamsi Jun 17, 2026
8437ef4
Backfill edge source_file from endpoint nodes (#1279)
safishamsi Jun 17, 2026
5b98897
fix(skill): pin extraction source_file + root the full build, prune d…
RelywOo Jun 17, 2026
e9f8dde
Stop fuzzy dedup over-merging numbered siblings, cross-file boilerpla…
safishamsi Jun 17, 2026
5b0c154
Honour configured output-token cap for OpenAI-compatible backends (#1…
safishamsi Jun 17, 2026
c9f2ef5
Document this session's fixes in changelog and add JSON-truncation tr…
safishamsi Jun 17, 2026
9e0b876
Release 0.8.41
safishamsi Jun 17, 2026
b2a1722
Merge .graphifyignore with .gitignore instead of replacing it (#1363)
safishamsi Jun 18, 2026
895a60f
Model Java records as type nodes and extract constructor calls (#1373)
safishamsi Jun 18, 2026
897483f
Merge #1366: prune deleted-only and root the full build so --update s…
safishamsi Jun 18, 2026
4f539e7
Slice oversized text documents so the whole file is extracted (#1369)
safishamsi Jun 18, 2026
d12eb28
Note intra-file slicing in the JSON-truncation troubleshooting entry …
safishamsi Jun 18, 2026
baf2410
Release 0.8.42
safishamsi Jun 18, 2026
9e8fa2a
Bump vulnerable dependencies to patched versions (#1375)
safishamsi Jun 18, 2026
ab1e0ec
Adaptive split-and-retry for community labeling on parse failure (#12…
safishamsi Jun 18, 2026
8883991
Unify node-ID normalization into a single source of truth (#1378)
safishamsi Jun 18, 2026
5038129
Accept str paths in the semantic extract entry points (#1386)
safishamsi Jun 19, 2026
e6eaad3
Emit edges for markdown links so hub docs connect (#1376)
safishamsi Jun 19, 2026
a789564
Reject Windows-style git hooks paths instead of creating a junk dir (…
safishamsi Jun 19, 2026
8e6ba9d
Parse package manifests into canonical package nodes + depends_on edg…
safishamsi Jun 19, 2026
435da06
Release 0.8.43
safishamsi Jun 19, 2026
7d07a24
Don't Path()-coerce FileSlice units in the extract entry points (#139…
safishamsi Jun 19, 2026
30fe8ba
Fix crash/data-loss bugs in the generated skill runbooks (#1392)
safishamsi Jun 19, 2026
382b669
Fix remaining #1392 skill bugs: --directed propagation, content-only …
safishamsi Jun 19, 2026
dce54a0
Release 0.8.44
safishamsi Jun 19, 2026
5d05372
Apply the #1392 runbook fixes to the Aider and Devin monolith skills
safishamsi Jun 19, 2026
d168de9
Relativize hyperedge source_file and honour GRAPHIFY_OUT everywhere (…
safishamsi Jun 22, 2026
1f42a2d
Write a portable manifest.json from the skill runbooks (#1417)
safishamsi Jun 22, 2026
6954a28
Show the scan root in the GRAPH_REPORT.md header instead of '.' (#1419)
safishamsi Jun 22, 2026
b8dc31f
Honour GRAPHIFY_OUT end-to-end, not just in the path guards (#1423)
safishamsi Jun 22, 2026
aad3b47
Request hyperedges in the native-backend extraction prompt (#1418 fol…
safishamsi Jun 22, 2026
5862bce
Release 0.8.45
safishamsi Jun 22, 2026
aa06e10
fix: catch OSError when Cargo.toml is missing during --cargo introspe…
DhruvTilva Jun 22, 2026
2323ce1
fix(opencode): strip backticks from plugin reminder to prevent silent…
WSHAPER Jun 21, 2026
dbce453
Add CUDA (.cu/.cuh) support via the C++ extractor
raylei50653 Jun 21, 2026
0b96b61
fix: resolve F821 undefined name 'nx' in prs.py
DhruvTilva Jun 22, 2026
30cc4c0
fix(export): never emit punctuation-only Obsidian filenames (e.g. @.md)
Jun 20, 2026
739230e
Add regression tests for punctuation-only Obsidian/Canvas filenames (…
safishamsi Jun 22, 2026
0aeda15
Resolve cross-file type-annotation refs to a single node, not phantom…
safishamsi Jun 22, 2026
a4d09ae
Install the hermes skill to %LOCALAPPDATA% on Windows (#1403)
safishamsi Jun 22, 2026
53edd27
perf(serve): trigram candidate prefilter to cut O(N) query latency
papinto Jun 22, 2026
e7ba16b
skill: add Step 4.5 graph-health gate + anchor caches on the scan root
bahcgscateringsa-design Jun 23, 2026
87fe887
Changelog for the #1431 query prefilter and #1437 health-gate/cache-a…
safishamsi Jun 23, 2026
29fd98f
Release 0.8.46
safishamsi Jun 23, 2026
ad6cb75
feat(install): add cross-framework `agents` platform (+ `skills` alias)
TPAteeq Jun 23, 2026
2c7cbb6
Fix: validate_extraction crashes on non-hashable node id / edge endpoint
dschwartzi Jun 24, 2026
c390456
fix: resolve Python ClassName.method() qualified calls to class-metho…
safishamsi Jun 24, 2026
b448c16
docs(changelog): add #1447 entry (non-hashable id/endpoint crash fix)
safishamsi Jun 24, 2026
533859d
fix(update): file-aware shrink-guard so removed symbols prune without…
safishamsi Jun 24, 2026
89dd00f
feat: self-improving work-memory — save-result outcomes + graphify re…
safishamsi Jun 24, 2026
6d9617a
feat: zero-config work-memory adoption via skill + git hooks (#1441)
safishamsi Jun 24, 2026
f87011b
Release 0.8.47
safishamsi Jun 24, 2026
c06db05
fix(skill): agent self-refreshes LESSONS.md so work-memory works with…
safishamsi Jun 24, 2026
d193b62
feat(reflect): --if-stale to skip redundant runs; agent uses it at se…
safishamsi Jun 24, 2026
1a14e94
fix(reflect): dedupe dead-ends and corrections by question
safishamsi Jun 24, 2026
22a58ff
feat: parallel community labeling via --max-concurrency / --batch-siz…
safishamsi Jun 24, 2026
b3ab221
refactor(extract): begin per-language extractor split (#1212)
TheFedaikin Jun 24, 2026
a95a833
chore(extract): drop now-dead `from .ids import make_id` import
safishamsi Jun 24, 2026
ec6b397
security: floor starlette >=1.3.1 (CVE-2026-48818, CVE-2026-54283)
safishamsi Jun 24, 2026
f9ded63
fix(serve): show community name in get_community MCP output (#1448)
rmart1308 Jun 24, 2026
bc362cb
Release 0.8.48
safishamsi Jun 25, 2026
6d3c959
Release 0.8.49 — fix wheel packaging for graphify.extractors
safishamsi Jun 25, 2026
e4ff54f
docs(changelog): present 0.8.49 changes directly (drop internal packa…
safishamsi Jun 25, 2026
5d63aad
fix(export): case-fold filename dedup so case-only labels don't overw…
TPAteeq Jun 25, 2026
7278e24
fix(export): lay out canvas node cards in the box's sqrt(n)-column gr…
TPAteeq Jun 25, 2026
68dba89
feat(llm): honor *_BASE_URL for kimi/gemini/deepseek backends (#1458)
jc2shile Jun 25, 2026
7dc5d96
feat(extract): WPF/XAML structural extraction with code-behind bridge…
MikeKatsoulakis Jun 25, 2026
1e3270a
fix(skill): state up front that no API key is required, with a non-su…
safishamsi Jun 25, 2026
9b583a0
fix(hooks): match the real file extension in the Read|Glob hook (#1463)
marketechniks Jun 25, 2026
75a5e6d
fix(reflect): include analysis/labels sidecars in --if-stale freshnes…
oleksii-tumanov Jun 26, 2026
349465b
fix(extract): parse .vue SFC <script> with the right grammar (#1468)
papinto Jun 26, 2026
905e0a7
feat(extract): link XAML views to ViewModels and extract binding refe…
MikeKatsoulakis Jun 26, 2026
8994b55
fix(extract): recover dropped Objective-C relationships (#1475)
safishamsi Jun 26, 2026
31b3752
fix(extract): emit references for Java field types (#1485)
oleksii-tumanov Jun 27, 2026
9b49bfd
fix(extract): emit references for Java type annotations (#1487)
oleksii-tumanov Jun 27, 2026
ff47316
fix(llm): force non-streaming on OpenAI-compatible calls (#1223)
jiangyq9 Jun 27, 2026
7a94f72
fix(wiki): portable relative markdown links so navigation works outsi…
TPAteeq Jun 27, 2026
652ba42
feat(extract): index Metal (.metal) shader files (#1480)
jiangyq9 Jun 27, 2026
a16b5bd
feat(label): add --missing-only flag for incremental community naming…
jiangyq9 Jun 27, 2026
b17e88c
release: 0.8.50
safishamsi Jun 27, 2026
36b76ce
fix(extract): Go cross-file type refs emit sourceless stubs (#1500)
TPAteeq Jun 27, 2026
76b6eab
feat(extract): resolve C# cross-file type references + enum/struct/re…
TheFedaikin Jun 27, 2026
6509d0c
fix(extract): disambiguate imported type stubs across files without b…
jiangyq9 Jun 27, 2026
6a45263
chore: sync uv.lock to 0.8.50
safishamsi Jun 27, 2026
1225677
docs: fix `graphify global add` example (#1489)
MikeKatsoulakis Jun 27, 2026
11dc819
docs(install): uv tool PATH setup + uvx --from graphifyy for macOS (#…
TPAteeq Jun 27, 2026
1b99496
fix: resolve explain/affected when a source-file path matches multipl…
behavio1 Jun 27, 2026
940cb53
fix(extract): emit Java enum and annotation declarations as type node…
oleksii-tumanov Jun 28, 2026
1f3f1c1
fix(extract): emit Java generic parent relationships (#1510)
oleksii-tumanov Jun 28, 2026
0e8d92c
fix(llm): tolerate non-UTF8 claude-cli output on Windows GBK systems …
nuthalapativarun Jun 28, 2026
8b177cb
fix(export): don't overwrite user notes or .obsidian config in an exi…
safishamsi Jun 28, 2026
8e98b91
release: 0.8.51
safishamsi Jun 28, 2026
7592244
docs: document --obsidian-dir and its existing-vault safety (#1506)
safishamsi Jun 28, 2026
f7f89d7
feat(cli): --timing flag for per-stage timings on extract and cluster…
safishamsi Jun 28, 2026
21a9f1f
chore: sync uv.lock to 0.8.51
safishamsi Jun 28, 2026
b46634e
fix(ids): node IDs include the full repo-relative path (#1504, #1509)
safishamsi Jun 28, 2026
388d1b6
docs(changelog): clarify --force is needed to recover previously-coll…
safishamsi Jun 28, 2026
3999dbc
feat(ids): warn on legacy-id graphs + harden re-key source_file contr…
safishamsi Jun 28, 2026
73710d3
fix(ids): legacy-id detector only inspects file-level nodes (no Go fa…
safishamsi Jun 28, 2026
92e682f
release: 0.9.0
safishamsi Jun 28, 2026
94e5baf
docs: document the --timing flag in the extract examples (#1490)
safishamsi Jun 28, 2026
afa4ade
fix(extract): drop internal origin_file so it stops leaking into grap…
TPAteeq Jun 28, 2026
d177f04
fix(extract): add origin_file to cross-file stubs in the six dedicate…
TPAteeq Jun 28, 2026
8b9a998
fix(extract): skip Java type-parameter references (#1518)
oleksii-tumanov Jun 28, 2026
67d8c53
docs(changelog): add #1515 and #1518 entries to Unreleased
safishamsi Jun 28, 2026
faa9218
chore: sync uv.lock to 0.9.0
safishamsi Jun 28, 2026
0080d8a
fix(update): prune edges owned by a re-extracted file (#1521)
safishamsi Jun 28, 2026
35fb437
fix(ids): salt residual separator-collision node IDs injectively (#1522)
safishamsi Jun 28, 2026
981e2b9
fix(extract): emit Java record component references (#1519)
oleksii-tumanov Jun 28, 2026
22a5afb
docs(changelog): add #1521, #1522, #1519 entries
safishamsi Jun 28, 2026
64c1f21
fix(llm): retry rate-limited (429) requests instead of dropping the c…
safishamsi Jun 28, 2026
0ca73bd
docs: document GRAPHIFY_MAX_RETRIES env var (#1523)
safishamsi Jun 28, 2026
b7e256f
release: 0.9.1
safishamsi Jun 28, 2026
1990612
docs: add Discord badge to README
safishamsi Jun 28, 2026
12193a8
chore: untrack committed .DS_Store files
safishamsi Jun 29, 2026
86ecb76
feat(ruby): type-aware member-call resolution via a resolver framewor…
vamsipavanmahesh Jun 29, 2026
4e4935a
fix(llm): enforce API timeout in the secondary LLM dispatch path (#1442)
DhruvTilva Jun 29, 2026
407a7f1
fix(export,cli): GraphML null-attr coercion + save-result --answer-fi…
antonioscarinci Jun 29, 2026
e3e4198
fix(skillgen): host-generic /graphify install guidance (#1530)
ari-mitophane Jun 29, 2026
738c9ce
chore(deps): bump msgpack 1.2.1 and pydantic-settings 2.14.2 (Dependa…
safishamsi Jun 29, 2026
36b5e5c
chore(deps): drop unused `safety` dev dep (removes unfixable nltk HIGH)
safishamsi Jun 29, 2026
2133539
fix(js): resolve alias/workspace import edges + honor tsconfig paths …
safishamsi Jun 29, 2026
7a9cda2
fix(cache): prune orphan semantic-cache entries at end of extract (#1…
safishamsi Jun 29, 2026
e8dabad
feat(imports): resolve workspace subpath exports via package.json exp…
guyoron1 Jun 29, 2026
1652dad
fix(objc): NS_ASSUME_NONNULL parse failure, dangling .m imports, allo…
safishamsi Jun 29, 2026
51fc00a
fix(swift): type-qualified static calls resolve as EXTRACTED, not INF…
safishamsi Jun 29, 2026
1d8d278
docs: add Unreleased changelog section for today's fixes
safishamsi Jun 29, 2026
544f95e
release: 0.9.2
safishamsi Jun 29, 2026
5746964
feat(js): resolve TypeScript wildcard path aliases (#1544)
oleksii-tumanov Jun 30, 2026
c8c604d
feat(js): resolve namespace re-export bindings (export * as ns from) …
oleksii-tumanov Jun 30, 2026
1801da0
feat(ts): resolve this.field.method() calls via constructor-injection…
guyoron1 Jun 30, 2026
0792b41
feat(objc): dot-syntax property accesses and @selector() call edges (…
guyoron1 Jun 30, 2026
5779767
feat(reflect): work-memory overlay — surface learned verdicts as a gr…
safishamsi Jun 30, 2026
00e00a0
fix(reflect): work-memory staleness false-positive on relative source…
safishamsi Jun 30, 2026
2cdc212
docs: README work-memory overlay note + Unreleased changelog
safishamsi Jun 30, 2026
c865a3c
fix(reflect): layout-ordered source resolution for overlay staleness …
safishamsi Jun 30, 2026
bd885cc
fix(hyperedge): accept members/node_ids alias keys for the member lis…
safishamsi Jun 30, 2026
bee3849
fix(resolve): test mocks no longer erase the real cross-file call gra…
safishamsi Jun 30, 2026
3bc3fee
fix(extract): merge header/impl class fragmentation + C++/ObjC header…
safishamsi Jun 30, 2026
49252d3
feat(extract): cross-file member-call resolution for C++ and ObjC (#1…
safishamsi Jun 30, 2026
b9d8067
feat(csharp): namespace-aware cross-file type resolution (#1562)
TheFedaikin Jun 30, 2026
0c551ac
release: 0.9.3
safishamsi Jun 30, 2026
19e7a31
feat(extract): capture indirect dispatch as indirect_call edges (#1565)
sheik-hiiobd Jun 30, 2026
cf747ab
feat(extract): resolve cross-file indirect dispatch as indirect_call
safishamsi Jun 30, 2026
8288829
feat(extract): capture dispatch tables as indirect_call edges (#1566)
safishamsi Jun 30, 2026
6dc1cb0
feat(extract): capture indirect dispatch for JS/TS (#1566 slice 5)
safishamsi Jun 30, 2026
47033c8
fix(cli): make skill-version warning direction-aware (#1568)
safishamsi Jun 30, 2026
311e63a
feat(extract): capture assignment/return indirect_call edges (#1566 s…
sheik-hiiobd Jun 30, 2026
69b3997
docs(changelog): note assignment/return indirect_call (#1569)
safishamsi Jun 30, 2026
4f40967
fix(build): preserve hyperedges + harden prune root in build_merge (#…
safishamsi Jul 1, 2026
8fdbf50
feat(extract): capture getattr(obj, "name") indirect_call edges (#156…
sheik-hiiobd Jul 1, 2026
1aab291
feat(cluster): deterministic hub community labels (readable without a…
sheik-hiiobd Jul 1, 2026
20547c4
docs(changelog): note getattr slice 3 (#1575) and hub labels (#1576)
safishamsi Jul 1, 2026
93e8e44
docs(build): correct deduplicate_by_label docstring — dormant, not au…
TPAteeq Jun 28, 2026
4a8d6ba
fix: harden graph JSON loading against corruption (#1536)
guyoron1 Jun 29, 2026
5320aa8
fix(dedup): warn on cross-chunk node ID collision to surface silent d…
nuthalapativarun Jun 28, 2026
879c058
fix(hooks): limit Windows hook rebuild workers
matiasduartee Jun 30, 2026
a19b9e9
fix(ruby): emit inherits edge for class superclass
hibin-m Jun 29, 2026
64a6093
fix(groovy): emit inherits/implements edges for extends/implements
hibin-m Jun 29, 2026
6eb7c01
test(build): add regression tests for corrupt graph.json (#1537)
safishamsi Jul 1, 2026
de7d362
fix(build): relativize source_file across a symlinked root (#1571 fol…
safishamsi Jul 1, 2026
b7f88af
release: 0.9.4
safishamsi Jul 1, 2026
e34e27c
fix(extract): cross-file indirect_call survives id relativization (0.…
safishamsi Jul 1, 2026
8127ff9
fix(cluster): detect stale community labels on cluster-only re-cluster
safishamsi Jul 1, 2026
f2ea6a6
fix(elixir): expand multi-alias brace form into per-module imports edges
Synvoya Jul 1, 2026
b8f41c7
fix(fortran): emit calls edges for function invocations
Synvoya Jul 1, 2026
674184d
fix(rust): emit references edges for enum variant field types
Synvoya Jul 1, 2026
7e24c3b
docs(changelog): note elixir/fortran/rust extractor fixes (#1577, #15…
safishamsi Jul 1, 2026
984a6a8
fix(julia): emit imports for qualified, relative, and scoped-selected…
Synvoya Jul 1, 2026
7eb847b
fix(rust): emit field type references for tuple structs
Synvoya Jul 1, 2026
297075c
fix(systemverilog): emit field references for qualified class properties
Synvoya Jul 1, 2026
532a20e
docs(changelog): note julia/rust-tuple-struct/systemverilog fixes (#1…
safishamsi Jul 1, 2026
784e9c8
fix(extract): case-sensitive cross-file resolution in case-sensitive …
safishamsi Jul 1, 2026
67b4525
fix(scala): emit field type references for var declarations
Synvoya Jul 1, 2026
a129ff2
fix(powershell): emit inherits/implements edges for class base types
Synvoya Jul 1, 2026
cd3a376
fix(objc): emit implements edge for protocol-to-protocol adoption
Synvoya Jul 1, 2026
51f805e
fix(php): emit type references for promoted constructor properties
Synvoya Jul 1, 2026
bb5e519
fix(csharp): emit type references for properties
Synvoya Jul 1, 2026
21bcb43
fix(cpp): emit generic_arg references for base-class template arguments
Synvoya Jul 1, 2026
ad70152
fix(swift): emit references for enum associated-value types
Synvoya Jul 1, 2026
f4a7994
docs(changelog): note 7-language type-reference/inheritance fixes (#1…
safishamsi Jul 1, 2026
5190a4e
docs: point LinkedIn badge to Graphify Labs company page
safishamsi Jul 1, 2026
b70a6d7
fix: allow python@ shebang in skill detection (#1586) + merge-graphs …
safishamsi Jul 2, 2026
44c0a5e
fix(swift): resolve calls on a singleton cached into a local var (#1604)
safishamsi Jul 2, 2026
1256d65
perf(hooks): eliminate multi-second foreground stalls before the deta…
TNRealtorApp Jul 1, 2026
6e97088
fix(serve): drop question/filler stopwords from query terms
Edge4711 Jul 1, 2026
9e7fbcb
feat(serve): optional project_path for multi-project MCP serving
joanfgarcia Jul 1, 2026
d89ec68
release: 0.9.5
safishamsi Jul 2, 2026
62f49ba
fix: persist cluster-only analysis sidecar
sanmaxdev Jul 2, 2026
32ff6d6
fix(claude-cli): deliver extraction instructions in the user turn
javargasm Jul 2, 2026
1226c34
Treat .mts/.cts (TypeScript module extensions) as TypeScript
ashmitg Jul 2, 2026
9811def
fix(extract): capture the TS import-equals form (import x = require(.…
papinto Jul 2, 2026
009a98b
Contain symlinked extraction inputs
Tok6Flow0 Jul 2, 2026
09aeb97
fix(extract): extract TS/JS generator functions as nodes
papinto Jun 26, 2026
869aaf7
fix(extract): emit a node for TS namespace / module containers
papinto Jun 26, 2026
3540416
fix(extract): emit reference edges for TS/JS decorators
papinto Jul 2, 2026
41ce87e
docs(changelog): note the #1617/#1607/#1615/#1613 fixes
safishamsi Jul 2, 2026
eebc406
feat(extract): C# receiver-typed member-call resolution (#1609)
safishamsi Jul 2, 2026
cf4b4ef
fix(build): don't crash when a node's source_file is the scan root (#…
safishamsi Jul 2, 2026
d56ee83
fix: guarantee per-term BFS seed diversity in query (fixes #1445)
nokternol Jul 1, 2026
412a29d
docs(changelog): note per-term BFS seed diversity (#1596)
safishamsi Jul 3, 2026
8d8d2b8
fix(update): reconcile removed and renamed sources
oleksii-tumanov Jul 2, 2026
53638d4
docs(changelog): note stale-source reconciliation on update (#1623)
safishamsi Jul 3, 2026
21294f0
fix(skill): utf-8 encoding in query reference snippets (#1619 A2)
safishamsi Jul 3, 2026
4744dfe
feat(extract): TS/JS member calls on local new-binding + typed-param …
safishamsi Jul 3, 2026
2ba07e8
fix(export): guard to_canvas against dangling community members (#123…
safishamsi Jul 3, 2026
e2ef4ef
fix: harden semantic extraction and kill phantom import edges (#1631,…
safishamsi Jul 4, 2026
53c769d
fix(apex): emit extends edges for interface multiple inheritance
Synvoya Jul 4, 2026
9b04022
fix(kotlin): emit implements edge for interface delegation (`by`)
Synvoya Jul 4, 2026
5737388
docs: changelog credit for #1645 (apex extends) and #1644 (kotlin by …
safishamsi Jul 4, 2026
13e2bdd
fix(ruby): extract module/Struct/Class.new containers and resolve con…
safishamsi Jul 4, 2026
29b3f91
release: 0.9.6
safishamsi Jul 4, 2026
983da3c
docs(readme): sync code-extension list with detect.py
safishamsi Jul 4, 2026
62b8eb1
fix(extract): gate JS/TS cross-file calls on import evidence to kill …
safishamsi Jul 4, 2026
f917494
fix(detect): incremental correctness for Office sources + long paths,…
safishamsi Jul 4, 2026
54825b6
fix: windows skill name, opencode plugin separator, doc-corpus report…
safishamsi Jul 4, 2026
9fea1a4
docs: add BENCHMARKS.md and link it from the README
safishamsi Jul 4, 2026
3140b2e
docs(readme): move star-history chart from top to bottom
safishamsi Jul 4, 2026
1288a55
fix(extract): don't cache zero-node results; warn on empty source fil…
safishamsi Jul 5, 2026
5ffa921
Fix invalid virtual postgres source_file URI backslashes on Windows (…
raman118 Jul 4, 2026
94392de
fix(extract): don't report deferred import() as a file cycle (#1241)
Synvoya Jul 5, 2026
aa1bbda
Fix case-sensitive file suffix filtering silently skipping capitalize…
raman118 Jul 4, 2026
d9f97b9
docs: changelog credit for #1671, #1672, #1241
safishamsi Jul 5, 2026
6631af7
feat(ruby/affected): mixes_in edges for include/extend/prepend + meth…
safishamsi Jul 5, 2026
21b52e1
docs(readme): new Graphify logo (cropped icon + wordmark)
safishamsi Jul 5, 2026
94239d6
fix(extract): route extensionless shebang scripts to their AST extractor
Stashub Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.git
.github
.venv
venv
__pycache__
*.pyc
.pytest_cache
.ruff_cache
.mypy_cache
dist
build
*.egg-info
graphify-out
graphify-benchmark
graphify_eval
graphify_test
worked
llm-stack-corpus
llm-stack-demo
product-site
ebook
tests
docs
*.md
!README.md
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Tell GitHub Linguist to ignore generated/example HTML files when calculating
# the repo's primary language. Without this, large graph.html artifacts in
# worked/ dominate the byte count and the repo shows as HTML instead of Python.
worked/**/*.html linguist-vendored=true
graphify-out/**/*.html linguist-vendored=true
*.html linguist-detectable=false
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: safishamsi
106 changes: 106 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: CI

on:
push:
branches: ["v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "main"]
pull_request:
branches: ["v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "main"]
workflow_dispatch:

jobs:
skillgen-check:
# Fast lint-style guard: the skill files under graphify/ are generated from
# the fragments in tools/skillgen/. This fails if someone hand-edited a
# generated file or forgot to re-run the generator and bless expected/, and it
# runs the build-time validators that guard per-host coverage, the file_type
# enum, the monolith round-trips, and the always-on round-trips.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
# The audit-coverage, monolith-roundtrip, and always-on-roundtrip
# validators read blobs from origin/v8. A shallow checkout omits that
# ref, so fetch the full history here and the validators run for real
# (rather than skipping). The other jobs stay shallow.
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: "3.12"

# --frozen keeps uv from re-resolving and rewriting uv.lock as a side
# effect of `uv run`; the lock is committed and must not churn in CI.
- name: Check generated skill artifacts are up to date
run: uv run --frozen python -m tools.skillgen --check

- name: Audit per-host v8 coverage
run: uv run --frozen python -m tools.skillgen --audit-coverage

- name: Check the file_type enum is a singleton
run: uv run --frozen python -m tools.skillgen --schema-singleton

- name: Round-trip the monoliths against v8
run: uv run --frozen python -m tools.skillgen --monolith-roundtrip

- name: Round-trip the always-on blocks against v8
run: uv run --frozen python -m tools.skillgen --always-on-roundtrip

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.12"]

steps:
- uses: actions/checkout@v6
with:
# test_skillgen.py reads pre-split skill bodies from the immutable
# baseline commit via `git show`; a shallow checkout omits that history
# and the baseline tests fail. Full history mirrors the skillgen-check job.
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: ${{ matrix.python-version }}

# --frozen installs straight from the committed uv.lock without re-resolving
# or rewriting it, so CI never churns the lock.
- name: Install dependencies
run: uv sync --all-extras --frozen

- name: Run tests
run: uv run --frozen pytest tests/ -q --tb=short

- name: Verify install works end-to-end
run: |
uv run --frozen graphify --help
uv run --frozen graphify install

security-scan:
# The dev deps include bandit and pip-audit. Run them in CI so a new
# HIGH-severity finding or vulnerable dependency is caught on the PR that
# introduces it, rather than at the next manual audit.
# Non-blocking for now (continue-on-error) to avoid breaking CI on
# pre-existing findings; remove continue-on-error after the initial
# cleanup pass.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: "3.12"

- name: Install dependencies
run: uv sync --frozen

- name: bandit (static security analysis)
continue-on-error: true
run: uv run --frozen bandit -r graphify -ll

- name: pip-audit (dependency vulnerabilities)
continue-on-error: true
run: uv run --frozen pip-audit --strict
64 changes: 64 additions & 0 deletions .github/workflows/release-graph.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Release graph asset

on:
release:
types: [published]
workflow_dispatch:

jobs:
build-graph:
runs-on: ubuntu-latest
permissions:
contents: write # needed to upload release assets

steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
python-version: "3.12"

- name: Install graphify
run: uv sync --frozen

- name: Build graph of graphify source (AST-only, no API cost)
# graphify/skills/ contains 126+ .md files that trigger the LLM pass.
# Temporarily ignore all .md files so extraction stays pure AST (no API key needed).
run: |
echo "*.md" >> .graphifyignore
echo "*.txt" >> .graphifyignore
uv run --frozen graphify extract graphify/ --out .
git checkout .graphifyignore 2>/dev/null || rm -f .graphifyignore

- name: Cluster, label communities and generate GRAPH_REPORT.md
# cluster-only writes GRAPH_REPORT.md and names communities (no LLM needed
# for basic numeric labels; --no-label skips LLM labeling entirely).
run: uv run --frozen graphify cluster-only . --no-label

- name: Generate HTML viewer
run: uv run --frozen graphify export html --graph graphify-out/graph.json

- name: Bundle release asset
run: |
mkdir -p dist-graph
cp graphify-out/graph.json dist-graph/
cp graphify-out/graph.html dist-graph/
[ -f graphify-out/GRAPH_REPORT.md ] && cp graphify-out/GRAPH_REPORT.md dist-graph/ || true
tar -czf graphify-self-graph.tar.gz -C dist-graph .
echo "Asset contents:"
tar -tzf graphify-self-graph.tar.gz

- name: Upload to GitHub release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: graphify-self-graph.tar.gz

- name: Upload as workflow artifact (for workflow_dispatch runs)
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
with:
name: graphify-self-graph
path: graphify-self-graph.tar.gz
retention-days: 7
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,30 @@ build/
*.so
*.egg
.graphify/
graphify-out/
.graphify_*.json
.graphify_python
.claude/
skills/
# The packaged skill bundles under graphify/skills/ are generated, committed
# artifacts (rendered by tools/skillgen). Keep them tracked even though the
# broad skills/ rule above ignores install-target skill dirs elsewhere.
!graphify/skills/
!graphify/skills/**
# The skillgen core fragments are the human-edited source of the lean SKILL.md.
# A global "core" ignore (for core dumps) would otherwise drop them.
!tools/skillgen/fragments/core/
!tools/skillgen/fragments/core/**
docs/superpowers/
.vscode/
.kilo
openspec/
# Local benchmark scripts — never commit
scripts/run_k2_*.py
scripts/llm.py
scripts/benchmark_kimi*.json
scripts/benchmark_kimi*.py
paper/

# macOS Finder metadata
.DS_Store
22 changes: 22 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Run with: uv run pre-commit install (pre-commit is already a dev dependency)
# One-off across the tree: uv run pre-commit run --all-files
#
# The skillgen hook is the local anti-drift guard. The skill files under
# graphify/ are generated from the fragments in tools/skillgen/; a hand-edit to
# a generated file fails this check the same way CI does. Run
# `python -m tools.skillgen` then `--bless` to regenerate after a fragment edit.
repos:
- repo: local
hooks:
- id: skillgen-check
name: skillgen --check (generated skill artifacts are up to date)
entry: python -m tools.skillgen --check
language: system
pass_filenames: false
always_run: true

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.14
hooks:
- id: ruff
args: ["--config", "pyproject.toml"]
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## graphify

This project has a graphify knowledge graph at graphify-out/.

Rules:
- Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost)
85 changes: 85 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Architecture

graphify is a Claude Code skill backed by a Python library. The skill orchestrates the library; the library can be used standalone.

## Pipeline

```
detect() → extract() → build_graph() → cluster() → analyze() → report() → export()
```

Each stage is a single function in its own module. They communicate through plain Python dicts and NetworkX graphs - no shared state, no side effects outside `graphify-out/`.

## Module responsibilities

| Module | Function | Input → Output |
|--------|----------|----------------|
| `detect.py` | `collect_files(root)` | directory → `[Path]` filtered list |
| `extract.py` | `extract(path)` | file path → `{nodes, edges}` dict |
| `build.py` | `build_graph(extractions)` | list of extraction dicts → `nx.Graph` |
| `cluster.py` | `cluster(G)` | graph → graph with `community` attr on each node |
| `analyze.py` | `analyze(G)` | graph → analysis dict (god nodes, surprises, questions) |
| `report.py` | `render_report(G, analysis)` | graph + analysis → GRAPH_REPORT.md string |
| `export.py` | `export(G, out_dir, ...)` | graph → Obsidian vault, graph.json, graph.html, graph.svg |
| `callflow_html.py` | `write_callflow_html(...)` | graphify-out files → Mermaid architecture/call-flow HTML |
| `ingest.py` | `ingest(url, ...)` | URL → file saved to corpus dir |
| `cache.py` | `check_semantic_cache / save_semantic_cache` | files → (cached, uncached) split |
| `security.py` | validation helpers | URL / path / label → validated or raises |
| `validate.py` | `validate_extraction(data)` | extraction dict → raises on schema errors |
| `serve.py` | `start_server(graph_path)` | graph file path → MCP stdio server |
| `watch.py` | `watch(root, flag_path)` | directory → writes flag file on change |
| `benchmark.py` | `run_benchmark(graph_path)` | graph file → corpus vs subgraph token comparison |

## Extraction output schema

Every extractor returns:

```json
{
"nodes": [
{"id": "unique_string", "label": "human name", "source_file": "path", "source_location": "L42"}
],
"edges": [
{"source": "id_a", "target": "id_b", "relation": "calls|imports|uses|...", "confidence": "EXTRACTED|INFERRED|AMBIGUOUS"}
]
}
```

`validate.py` enforces this schema before `build_graph()` consumes it.

## Confidence labels

| Label | Meaning |
|-------|---------|
| `EXTRACTED` | Relationship is explicitly stated in the source (e.g., an import statement, a direct call) |
| `INFERRED` | Relationship is a reasonable deduction (e.g., call-graph second pass, co-occurrence in context) |
| `AMBIGUOUS` | Relationship is uncertain; flagged for human review in GRAPH_REPORT.md |

## Adding a new language extractor

1. Add a `extract_<lang>(path: Path) -> dict` function in `extract.py` following the existing pattern (tree-sitter parse → walk nodes → collect `nodes` and `edges` → call-graph second pass for INFERRED `calls` edges).
2. Register the file suffix in `extract()` dispatch and `collect_files()`.
3. Add the suffix to `CODE_EXTENSIONS` in `detect.py` and `_WATCHED_EXTENSIONS` in `watch.py`.
4. Add the tree-sitter package to `pyproject.toml` dependencies.
5. Add a fixture file to `tests/fixtures/` and tests to `tests/test_languages.py`.

## Security

All external input passes through `graphify/security.py` before use:

- URLs → `validate_url()` (http/https only) + `_NoFileRedirectHandler` (blocks file:// redirects)
- Fetched content → `safe_fetch()` / `safe_fetch_text()` (size cap, timeout)
- Graph file paths → `validate_graph_path()` (must resolve inside `graphify-out/`)
- Node labels → `sanitize_label()` (strips control chars, caps 256 chars, HTML-escapes)

See `SECURITY.md` for the full threat model.

## Testing

One test file per module under `tests/`. Run with:

```bash
pytest tests/ -q
```

All tests are pure unit tests - no network calls, no file system side effects outside `tmp_path`.
Loading