Commit Graph
771 Commits
Author SHA1 Message Date
SafiandClaude Opus 4.8 895a60f4e3 Model Java records as type nodes and extract constructor calls (#1373)
Add record_declaration to the Java class types so a record becomes a first-class
type node instead of an isolated file node, and add object_creation_expression
to call types with a dedicated branch that reads the callee from the `type`
field (new Foo() has no `name` field), so `new Foo(...)` emits a calls edge to
the constructed type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 01:18:48 +01:00
SafiandClaude Opus 4.8 b2a1722903 Merge .graphifyignore with .gitignore instead of replacing it (#1363)
A .graphifyignore made graphify skip that directory's .gitignore entirely, so a
file excluded only by .gitignore (including neutrally-named secrets the
sensitive-file heuristic misses) got indexed into the graph and could leak into
committed graph artifacts. Read .gitignore first and .graphifyignore last so
their patterns merge and graphifyignore negations still win.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 01:15:24 +01:00
SafiandClaude Opus 4.8 9e0b8766f4 Release 0.8.41
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v0.8.41
2026-06-17 19:09:43 +01:00
SafiandClaude Opus 4.8 c9f2ef5e48 Document this session's fixes in changelog and add JSON-truncation troubleshooting
Add changelog entries for the Swift cross-file (#1356), update prune (#1361),
obsidian canvas (#1324), and edge source_file backfill (#1279) fixes that
shipped without changelog notes, and a README troubleshooting entry for the
LLM JSON-truncation warnings and how to reduce them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:43:08 +01:00
SafiandClaude Opus 4.8 5b0c154828 Honour configured output-token cap for OpenAI-compatible backends (#1365)
ollama/openai/deepseek/kimi set max_tokens in their backend config, but the
openai-compat dispatch read only max_completion_tokens (which only gemini
defines), so their output silently capped at the 8192 fallback and truncated
deep-mode JSON. Read either key and give the openai config an explicit cap;
GRAPHIFY_MAX_OUTPUT_TOKENS still overrides.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:35:58 +01:00
e9f8dde7af Stop fuzzy dedup over-merging numbered siblings, cross-file boilerplate, and prefix-divergent labels (#1284, #1243)
Three pass-2 guards (mirrored in the --dedup-llm pair collection): block merges
when labels' embedded numbers differ as zero-padding-insensitive multisets;
block cross-file merges of file-anchored rationale/document nodes (same-file
still merges); and score cross-file long labels on plain Jaro instead of
Jaro-Winkler so the prefix bonus can't fabricate merges of shared-prefix but
token-divergent entities (jest-native vs react-native), while genuine cross-file
duplicates still clear Jaro and same-file near-duplicates keep Jaro-Winkler.

Co-Authored-By: van4oza <van4oza@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:21:19 +01:00
SafiandClaude Opus 4.8 8437ef465e Backfill edge source_file from endpoint nodes (#1279)
Semantic/LLM edges occasionally omit source_file, which build only normalized
when already present, so the field reached graph.json empty and downstream
validation flagged it. Backfill from the source (then target) node in
build_from_json and in the --no-cluster raw-write path, which bypasses it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:49:31 +01:00
SafiandClaude Opus 4.8 9c8bd4d47c Populate Obsidian canvas when no community data is present (#1324)
to_canvas built cards solely by iterating communities, so a graph with no
community data (--no-cluster builds, or a missing analysis sidecar) wrote the
empty 32-byte {"nodes":[],"edges":[]} shell while notes rendered fine. Fall back
to one synthetic community covering every node so the canvas reflects the graph.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:49:31 +01:00
SafiandClaude Opus 4.8 2c662c7917 Pass root to build_merge in the update runbook so stale nodes get pruned (#1361)
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>
2026-06-17 13:30:02 +01:00
SafiandClaude Opus 4.8 2e01f37c81 Resolve cross-file Swift class relationships from member calls and constructors (#1356)
Capture property/field initializer constructor calls, build a per-file Swift
type table from property/parameter declarations, and add a member-call
resolution pass that types the receiver and emits an edge only when the type
name resolves to exactly one definition. Additive and INFERRED-only; the
is_member_call drop and the #543/#1219 god-node guards stay intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 12:08:59 +01:00
mistic96 d8fa70e17b Harden HTML output against U+2028 XSS + two crash-on-adversarial-input fixes (#1357)
Harden HTML export against U+2028/U+2029 script-breakout XSS + two crash-on-adversarial-input fixes (non-dict LLM JSON, _extract_parallel IndexError). Validated: full suite 2107 passed, HTML export smoke clean. Thanks @mistic96.
2026-06-17 10:46:19 +01:00
RelywOo fd463deb03 fix(build_merge): replace re-extracted files instead of accumulating stale edges (#1344)
build_merge: prune a re-extracted file's stale nodes/edges before merge instead of accumulating (fixes #1283, #1285). Validated: full suite 2107 passed. Thanks @RelywOo.
2026-06-17 10:46:15 +01:00
geektan123 f117aaccc6 feat: PowerShell .psd1 manifest parsing & Import-Module / dot-source edge emission (#1331) (#1341)
Index PowerShell .psd1 manifests + emit Import-Module/dot-source edges (closes #1331). Builds on the shipped .psm1 support. Validated: full suite 2107 passed, 18 new tests. Thanks @geektan123.
2026-06-17 10:46:12 +01:00
Pavel Kudinov a16b3e1b45 fix incremental no-cluster graph updates (#1350)
Harden incremental no-cluster updates: fixes empty-write graph wipeout on no-op update --no-cluster (#1347) and git-hook subdir path resolution (#1348). Complementary to #1317. Validated: full suite 2107 passed, no-op re-run no longer wipes graph. Thanks @pkudinov.
2026-06-17 10:46:08 +01:00
balloon72 9a7dbfbb84 fix js workspace import resolution (#1352)
Fixes #1334: detect npm/yarn package.json workspaces (array + yarn object form), pnpm precedence preserved. Reviewed: full suite 2087 passed, no regressions. Thanks @balloon72.
2026-06-17 10:29:47 +01:00
balloon72 d885833112 fix node label lookup normalization (#1353)
Fixes #1338 (Unicode NFD/NFC): serve._find_node now matches tokenized labels; affected.resolve_seed NFC-normalizes + casefolds. Reviewed: full suite 2087 passed, CLI smoke clean, no regressions. Thanks @balloon72.
2026-06-17 10:29:43 +01:00
SafiandClaude Opus 4.8 be3dcfca08 Unify query skill: ship expansion + inline fallback to every platform
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>
2026-06-16 03:33:23 +01:00
SafiandClaude Opus 4.8 2100b3d05b Resolve cross-file Java type references by import package
Same-named types in different packages left implements/inherits edges stuck on
bare shadow stubs, isolating the real interface (_rewire_unique_stub_nodes only
fixes the globally-unique case). New _resolve_java_type_references pass uses each
referencing file's import statements (+ package decl) to build an FQN->def index,
re-points dangling implements/inherits/imports edges to the exact definition, and
drops the orphaned stub. External/stdlib imports stay unresolved (correct). Runs
after id-disambiguation so target ids are final. Java-scoped; other _extract_generic
languages share the same bare-name fallback and remain a follow-up.

Adds tests/test_java_type_resolution.py (simple, ambiguous-by-import, build-survival).
Refs #1318.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 03:16:08 +01:00
SafiandClaude Opus 4.8 4fbb33301c Collapse Swift module imports to one shared node
Adopts the approach from #1330 (thanks @duncan-daydream) on top of the v0.8.40
Swift import fix: _import_swift returns (id,label) module pairs, the extractor
materializes a type=module anchor node per import, and _disambiguate_colliding_node_ids
exempts type=module nodes so the same module imported from N files collapses to
one shared node (enables reverse traversal "what imports CoreKit"). The --no-cluster
writer now dedupes nodes by id and edges to match the clustered build_from_json path.

Replaces the interim _import_label/synthesize_import_module_nodes mechanism.
Adds tests/test_swift_import_resolution.py (cross-file collapse, build survival)
and dedupe_nodes coverage. Refs #1327, #1330.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 03:06:43 +01:00
SafiandClaude Opus 4.8 fd152add64 Release 0.8.40
Bump version to 0.8.40; document this release in CHANGELOG (PowerShell .psm1
indexing, Swift import survival, no-cluster edge dedup, custom OpenAI/Anthropic
endpoints, JS/TS assignment-form extraction, community-name + --graph fixes,
four production bug fixes, perf, security CI); add .psm1 to the README
supported-extensions table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v0.8.40
2026-06-16 02:38:28 +01:00
SafiandClaude Opus 4.8 adb52a1ea0 Index .psm1, anchor Swift import targets, dedupe no-cluster edges
- #1315: add .psm1 to CODE_EXTENSIONS + _DISPATCH so PowerShell modules are indexed
- #1327: synthesize a module node for Swift import targets (new LanguageConfig
  flag synthesize_import_module_nodes) so imports edges survive build.py pruning;
  strengthen the Swift dangling-edge test to also assert edge targets
- #1317: dedupe parallel edges by (source,target,relation) in the --no-cluster
  and incremental update write paths so edge counts are deterministic and
  `update` is idempotent

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 02:28:16 +01:00
Siddarth Chintamani 09da5294e4 feat: extract JS/TS this.X=, exports.X=, prototype, class arrow fields, function expressions (#1323)
Extract JS/TS this.X=, exports.X=, prototype, class arrow fields, and function expressions (closes #1322). Validated locally against v8: full suite 2069 passed.
2026-06-16 02:14:31 +01:00
Timon 61836ce0e8 feat: custom endpoints via OPENAI_BASE_URL/OPENAI_MODEL and ANTHROPIC_BASE_URL/ANTHROPIC_MODEL (#1273)
Custom OPENAI/ANTHROPIC base-url + model env vars for self-hosted and proxy endpoints. CI green (3.10/3.12).
2026-06-16 01:41:15 +01:00
Safi fd470faeee docs: add --graph flag example to graphify-mcp usage (#1304) 2026-06-13 19:44:36 +01:00
Safi a4f3e862b2 changelog: document community name fix and --graph alias (#1304, #1305) 2026-06-13 19:36:12 +01:00
SafiandClaude Sonnet 4.6 85de47e121 fix: community names blank in query/MCP after cluster-only; --graph for graphify-mcp
export.py: to_json now accepts community_labels and writes community_name onto
each node. Previously cluster-only wrote labels only to GRAPH_REPORT.md,
graph.html, and .graphify_labels.json — graph.json stored only the numeric cid,
so query/MCP showed blank or numeric community values (#1305).

__main__.py: pass community_labels=labels to to_json in cluster-only path.
explain command now prefers community_name over raw numeric community field.

serve.py: query and get_node read paths prefer community_name over community,
with fallback so old graphs without the field still work. Adds --graph flag as
an alias for the positional argument in graphify-mcp/_main(), fixing
"unrecognized arguments: --graph" for users following the documented pattern
shared by every other graphify subcommand (#1304).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 19:34:18 +01:00
Safi b61c985c12 changelog: document #1209 security CI and #1166 node-summaries RFC 2026-06-13 16:03:58 +01:00
Safi 591cc934a7 Merge pull request #1166 from leonaburime-ucla/docs/node-summaries-rfc
docs: add RFC for file-level node summaries
2026-06-13 15:56:42 +01:00
Safi 9bed8318c6 Merge pull request #1209 from nucleusjay/ci-run-security-scanners
Wire bandit and pip-audit into CI
2026-06-13 15:56:39 +01:00
Safi 10655b92eb changelog: document four bug fixes (#1257, #1288, #1298, #1299) 2026-06-13 15:16:17 +01:00
SafiandClaude Sonnet 4.6 b83086297f fix: four production bugs — Windows crashes, ghost-merge collision, version probe
extract.py: clamp ProcessPoolExecutor max_workers to 61 on Windows (issue #1298).
Python's ProcessPoolExecutor hard-caps at 61 on Windows via WaitForMultipleObjects;
>61-core machines crashed on AST extraction. Clamp applied after all input paths
(auto-compute, GRAPHIFY_MAX_WORKERS, --max-workers) to cover all three.

build.py: skip ghost-merge when two AST nodes share (basename, label) key (issue #1257).
When same-named symbols appear in same-named files across directories (e.g. two
render() in two index.ts), last-writer-wins produced an arbitrary canonical node
and mis-pointed all edges. Now tracked in _loc_collisions; ambiguous keys are
skipped in Pass 2, leaving the ghost intact rather than merging into the wrong node.

__main__.py: ignore OSError on unreadable .graphify_version probes (issue #1299).
On restricted-permission installs or network mounts, .exists()/.read_text() raised
PermissionError and crashed every graphify query/explain/path call at startup.
All three FS probes now wrapped in try/except OSError: return.

prs.py: resolve claude.cmd on Windows in prs.py claude-cli backend (issue #1288).
The _call_llm and _call_claude_cli paths were already fixed; prs.py had the same
bare ["claude", ...] call that fails on Windows npm installs with WinError 2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 15:13:23 +01:00
Safi 813db19252 Merge pull request #1295 from sirphilliptubell/perf/fix5
perf: parallelize save_manifest file hashing with ThreadPoolExecutor
2026-06-13 11:28:43 +01:00
Safi dbbf0a45a1 Merge pull request #1294 from sirphilliptubell/perf/fix4
perf: convert _walk_js_tree from recursive generator to iterative
2026-06-13 11:28:40 +01:00
Sir Phillip Tubell 0f6d46f822 perf: parallelize save_manifest file hashing with ThreadPoolExecutor
stat+MD5 across all files now fans out over a thread pool instead of running sequentially — I/O-bound work releases the GIL so this scales with available disk concurrency.
2026-06-12 16:07:51 -04:00
Safi c4689a2f47 bump version to 0.8.39 v0.8.39 2026-06-12 20:36:47 +01:00
Sir Phillip Tubell a7c69808ac perf: convert _walk_js_tree from recursive generator to iterative
Eliminates O(depth) generator-frame chain overhead. Each leaf's value previously propagated through 26+ yield-from frames; now a single stack loop handles the full traversal.
2026-06-12 15:19:44 -04:00
Safi 3929eca450 changelog: add unreleased entries for #1289, #1207, #1208, #1176 2026-06-12 20:18:17 +01:00
Safi 70a1ad7278 Merge pull request #1176 from galshubeli/falkordb-backend
feat: add FalkorDB export backend (#1175)
2026-06-12 20:15:30 +01:00
Safi 70380b8ea0 Merge pull request #1208 from nucleusjay/pin-tree-sitter-deps
Pin tree-sitter dependency version ranges
2026-06-12 20:15:27 +01:00
Safi 3e8cd7da6d Merge pull request #1207 from nucleusjay/fix-merge-chunks-and-manifest-bugs
Fix two latent bugs: merge-chunks output and manifest data loss
2026-06-12 20:15:23 +01:00
Safi 418fab8e23 Merge pull request #1289 from sirphilliptubell/perf/fix1
perf: fix O(n^2) -> O(n) LSH neighbor lookup in dedup
2026-06-12 20:15:20 +01:00
Safi 6c2f273742 changelog: add unreleased entries for #1280, #1276, #1282, #1281 2026-06-12 19:58:49 +01:00
Safi 5a21685bf1 Merge pull request #1281 from BemoBit/docs/fa-readme
docs: add Persian (فارسی) translation and language selector link
2026-06-12 19:54:47 +01:00
Safi fb1908cc55 Merge pull request #1282 from balloon72/codex/community-label-model
feat: add --model to community labeling commands
2026-06-12 19:54:44 +01:00
Safi 90decbc4ed Merge pull request #1276 from papinto/fix/graphifyignore-negation-pruning
fix: a single negation (!) in .graphifyignore no longer disables all directory pruning
2026-06-12 19:54:41 +01:00
Safi 0ff84d8bf3 Merge pull request #1280 from s22hyun/fix/affected-edges-key
fix(affected): handle "edges"-keyed graph.json in load_graph (KeyError: 'links')
2026-06-12 19:54:38 +01:00
Sir Phillip Tubell c4d6b412ca perf: fix O(n^2) -> O(n) LSH neighbor lookup in dedup
Replaced O(n) linear scan `next((n for n in candidates if n["id"] == neighbor_id))` with O(1) dict lookup via pre-built `candidates_by_id`. Also pre-caches `_norm()` results in `norm_cache` to avoid recomputing per inner iteration.

For a 36k-file codebase (~100k high-entropy candidates) this reduces the pass-2 loop from O(n^2*B) (~30–100B iterations) to O(n*B), eliminating the multi-minute CPU hang after AST extraction completes.
2026-06-12 10:31:01 -04:00
hanmo1 b304331d24 feat: add model override for community labeling 2026-06-12 17:57:19 +08:00
Behnam Moradi 0e74c0401e docs: add Persian (فارسی) translation and language selector link
Adds complete Persian translation (README.fa-IR.md) with RTL formatting and updates main README language selector to include Persian between Arabic and Italian.
2026-06-12 11:15:32 +03:30
s22hyun 2ab2302112 fix(affected): handle "edges"-keyed graph.json in load_graph (KeyError: 'links') 2026-06-12 15:33:33 +09:00