Skip to content

Resync Rust port to graphify-py v0.8.19 (d9debdf)#10

Merged
rblaine95 merged 8 commits into
masterfrom
resync/graphify-py/d9debdf
May 26, 2026
Merged

Resync Rust port to graphify-py v0.8.19 (d9debdf)#10
rblaine95 merged 8 commits into
masterfrom
resync/graphify-py/d9debdf

Conversation

@rblaine95

@rblaine95 rblaine95 commented May 26, 2026

Copy link
Copy Markdown
Member

Summary

Resyncs the Rust workspace with graphify-py v0.8.19, picking up everything between submodule 3efae38..d9debdf.

  • .NET project-file extractors — new extract_sln, extract_csproj, and extract_razor in a dotnet.rs extractor module, plus .sln/.csproj/.fsproj/.vbproj/.razor/.cshtml added to CODE_EXTENSIONS. Captures NuGet refs, project-to-project deps, target frameworks, @using/@inject/@inherits/@model, Blazor components, and @code methods.
  • Devin CLI — new graphify devin install/uninstall (and --project) writing to ~/.config/devin/skills/... plus .windsurf/rules/graphify.md. Devin reads .windsurf/rules/*.md the same way Windsurf IDE does.
  • TS 5.0 extends array fixread_tsconfig_aliases now accepts a string OR an array of paths, processing parents in order and skipping scoped npm configs per entry. Closes the silent alias-drop on TS 5 repos.
  • Nested worktrees/ skipis_noise_dir takes an optional parent and treats .claude/worktrees/, .git/worktrees/, etc. as noise.
  • Chinese query segmentationquery_terms bigram-segments CJK-Unified-Ideograph runs (no jieba dep; Python's _jieba is None fallback path is the active one in Rust).
  • Wiki null source_file regression — the Rust Value::String(_) pattern match already handles this; added a parity test to lock it in.

Submodule pointer advanced separately on the first commit so the resync is bisectable. Workspace version bumped to 0.8.19. Cargo.lock updated. cargo upgrade --incompatible is a no-op — every workspace dep is already at the latest major.

Documentation updates

The README/USAGE graphify-out/ listing claimed only three files; updated to show the full set (canonical outputs + sidecars + opt-in artefacts like wiki/, GRAPH_TREE.html, cypher.txt). Language list mentions .NET; installer list mentions Devin.

Test plan

  • cargo nextest run --workspace — 1416 tests pass (2 skipped, both net-prefixed)
  • cargo clippy --all-targets --all-features --workspace — clean
  • cargo fmt — clean
  • hk check — clean
  • CodeRabbit review (3 passes) — all findings addressed or documented as parity-preserving false positives in commit history

Summary by CodeRabbit

  • New Features

    • .NET project support (.sln/.csproj/.fsproj/.vbproj) and Razor component extraction
    • Devin CLI platform installer/uninstaller
    • TypeScript config handling for array-based extends
    • Improved CJK-aware search tokenization
  • Bug Fixes

    • Skip nested worktrees under dotted parent directories
    • More robust Razor code-block and method discovery
    • Null-safe wiki generation
  • Documentation

    • Expanded output directory and usage docs; added Devin install instructions

Review Change Stack

rblaine95 added 5 commits May 26, 2026 17:20
Ports:
- `.NET` project-file extractors: `.sln`, `.csproj` / `.fsproj` /
  `.vbproj`, `.razor` / `.cshtml`. New `dotnet.rs` extractor module
  in `graphify-extract`, wired into the dispatch table; `.sln` /
  `.csproj` / `.fsproj` / `.vbproj` / `.razor` / `.cshtml` added to
  `CODE_EXTENSIONS` in `graphify-detect`.
- Devin CLI install/uninstall: new platform module in
  `graphify-hooks` with both user-scope (`~/.config/devin/...`) and
  project-scope (`.devin/...` + `.windsurf/rules/graphify.md`)
  variants, plus `graphify devin install/uninstall` subcommand.
- tsconfig `extends` array (TypeScript 5.0): `read_tsconfig_aliases`
  now accepts a string OR an array of paths, processes parents in
  order, and skips scoped npm configs per entry. Fixes silent
  alias-resolution failure on TS 5 repos.
- Nested `worktrees/` skip-dir: `is_noise_dir` takes an optional
  parent name and treats `worktrees` nested inside a dotted dir
  (`.claude/worktrees/`, `.git/worktrees/`) as noise.
- Chinese query segmentation in `graphify-serve`: `query_terms` now
  bigram-segments terms containing CJK Unified Ideographs and keeps
  the original term alongside the bigrams. Hiragana / Katakana /
  Hangul fall through as single terms.
- Wiki null `source_file` regression test (#1016): Rust's pattern
  match already handled `Value::Null`; added a parity test to lock
  the behavior in.

Workspace version bumped to 0.8.19. `Cargo.lock` updated.
README.md and USAGE.md updated to reflect actual `graphify-out/`
contents (the previous "3 files" listing missed every sidecar) and
to mention the new .NET formats and Devin platform.

Ave Deus Mechanicus
Applies the trivial findings from CodeRabbit's review of the resync
commit:

- Wiki regression test now asserts the community article file
  ("Parsing_Layer.md") was emitted, not just the index, tightening
  the #1016 guard against silent rendering failures.
- `CSPROJ_MAX_BYTES` is documented as a parity-locked literal that
  matches `graphify-py`'s 2 MiB limit. Lowering or raising it
  belongs in a coordinated parity bump, so it stays a constant.
- `labels` and `relations` helpers in the .NET parity-language
  tests get `#[must_use]` so a forgotten assertion would surface as
  a warning.

Two CodeRabbit findings flagged as critical (`remove_skill` errors
dropped in `devin_uninstall` / `devin_project_uninstall`) are false
positives: `remove_skill` is declared as `fn(&Path)` and swallows
errors internally by design, matching the existing `pi_uninstall`
pattern. There is no `Result` to propagate.

Glory to the Omnissiah
A trivial follow-up from CodeRabbit's second review pass — annotating
the `is_searchable` predicate in `graphify-serve` with `#[must_use]`
so an accidentally-discarded boolean result would surface as a
warning. Matches the workspace convention for pure predicates.

By the will of the Machine God
CodeRabbit flagged the brace-counting loop in `extract_razor`'s
`@code { ... }` body finder for not handling braces inside strings,
char literals, or comments. The graphify-py reference
(`extract_razor` in `extract.py`) uses the identical brace-only
algorithm, so adding lexer state would diverge from byte-identical
parity, which the resync explicitly preserves.

Documented the decision inline so future readers see the parity
constraint and don't repeat the request. The behavioural impact is
bounded: a pathological string like `"}{";` inside a method body
could shrink `block_end`, but the downstream method-name regex
only fires on declaration-shaped lines, so any false truncation
silently drops methods rather than producing spurious nodes.

A line from the Adeptus Mechanicus Prayerbook:
"The Machine remembers, even when we forget."
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 810fda09-35f4-4c42-8b76-1f925a67246a

📥 Commits

Reviewing files that changed from the base of the PR and between 98d9538 and d26171a.

📒 Files selected for processing (5)
  • crates/graphify-extract/src/extractors/dotnet.rs
  • crates/graphify-extract/tests/parity_languages.rs
  • crates/graphify-hooks/src/platform/devin.rs
  • crates/graphify-serve/src/graph.rs
  • crates/graphify-serve/tests/parity.rs

📝 Walkthrough

Walkthrough

This PR increments the workspace version to 0.8.19, adds .NET (.sln/.csproj/.razor) extractors and tests, integrates Devin CLI installers (user & project) with project rules, supports TS extends arrays, adds CJK bigram query segmentation, refines noise pruning with parent context, and updates docs and the submodule pointer.

Changes

Release 0.8.19: .NET Support and Devin Integration

Layer / File(s) Summary
File type detection & docs
crates/graphify-detect/src/extensions.rs, README.md, USAGE.md
Extend CODE_EXTENSIONS with .NET and Razor-related extensions; expand README/USAGE descriptions of graphify-out/ sidecars and document graphify devin install (including --project).
Noise detection refinement
crates/graphify-detect/src/sensitive.rs, crates/graphify-detect/src/walk.rs, crates/graphify-detect/tests/parity_detect.rs
is_noise_dir now accepts parent_name: Option<&str> and treats worktrees under dotted parents as noise; walkers pass parent info and a parity test verifies exclusion.
.NET extractors implementation
crates/graphify-extract/Cargo.toml, crates/graphify-extract/src/extractors/dotnet.rs
Add quick-xml dep; implement extract_sln, extract_csproj (XML parsing, package/project refs, frameworks/SDK), and extract_razor (directives, components, @code brace-aware method discovery).
Extractor wiring & dispatch
crates/graphify-extract/src/extractors/mod.rs, crates/graphify-extract/src/extractors/multi.rs, crates/graphify-extract/src/lib.rs
Register dotnet module, re-export extract_sln, extract_csproj, extract_razor, update multi-extractor dispatch and crate re-exports.
.NET fixtures & tests
crates/graphify-extract/tests/fixtures/*, crates/graphify-extract/tests/parity_languages.rs, crates/graphify-extract/tests/parity.rs
Add sample.csproj, sample.razor, sample.sln fixtures and extensive parity tests for .NET extraction, Razor behavior, and tsconfig-array extends alias resolution.
TypeScript 5+ extends support
crates/graphify-extract/src/tsconfig.rs, crates/graphify-extract/tests/parity.rs
read_tsconfig_aliases supports extends as string or array and merges parent alias maps; parity test verifies alias resolution.
Devin platform hooks
crates/graphify-hooks/src/platform/devin.rs
Add devin_install, devin_uninstall, devin_project_install, devin_project_uninstall, embedded .windsurf/rules content, and path helpers.
Devin registration & installer mapping
crates/graphify-hooks/src/platform/mod.rs, crates/graphify-hooks/src/platform/common/install_skill.rs
Register devin module and re-export its hooks; extend skill_for() mapping to install to .config/devin/skills/graphify/SKILL.md.
CLI wiring for Devin
src/cli/args.rs, src/cli/dispatch.rs, src/cli/install.rs
Add Command::Devin variant, dispatch routing, and special-case project vs user install/uninstall to call Devin-specific hooks.
Devin parity tests
crates/graphify-hooks/tests/parity.rs
Add tests covering user/project install/uninstall, idempotency ("already configured"), no-op uninstall, and generic installer integration.
CJK-aware query preprocessing
crates/graphify-serve/src/graph.rs, crates/graphify-serve/tests/parity.rs
Add Chinese character detection, bigram segmentation fallback, and ASCII-length filtering in query_terms; add parity tests for mixed CJK/ASCII and non-CJK scripts.
Wiki null source_file regression
crates/graphify-wiki/tests/parity.rs
Add regression test ensuring to_wiki handles nodes with source_file = Null.
Version bump & misc
Cargo.toml, graphify-py, CLI docs
Bump workspace version to 0.8.19, update graphify-py submodule commit, and add CLI docs for Devin installer flags.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

A rabbit hops through dotted paths,
Counting cs and razor drafts,
Devin plants a skillful seed,
Chinese bigrams help the read,
Version bumped — the files sing fast! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective: resyncing the Rust port to match graphify-py v0.8.19, which is the primary theme of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch resync/graphify-py/d9debdf

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]

This comment was marked as resolved.

rblaine95 added 3 commits May 26, 2026 18:19
Decode XML entities in attr_ci. quick-xml's normalized_value applies
XML 1.0 attribute-value normalization including entity unescaping, so
a `PackageReference Include="A&amp;B"` becomes a literal `A&B` node
label — matching ElementTree's behaviour in graphify-py.

Tighten .NET parity tests with `r.error.is_none()` guards on the
success paths of `sln_contains_edges`, `sln_project_dependency`, and
the `csproj_*` / `razor_*` tests that previously inspected nodes or
edges without first checking for an extractor error.

Replace the OS-specific `/nonexistent/file.razor` path in
`razor_missing_file` with a child of a `tempfile::tempdir()` that is
never created — works on Windows where `/nonexistent/...` would
otherwise resolve against the current drive.

Update `devin_uninstall` / `devin_project_uninstall` docs to match
the actual error contract: skill removal is best-effort because the
shared `remove_skill` helper swallows filesystem errors by design.
`devin_project_uninstall` still propagates errors from removing
`.windsurf/rules/graphify.md`.

The bigram-segmentation finding (cross-script bigrams) is left as-is:
graphify-py's `_segment_chinese` fallback uses the identical
`text[i:i+2]` algorithm across raw characters with no script
boundary, and parity is the goal of this resync.

By the will of the Machine God
Two long-standing defects in `graphify-py` were ported verbatim
during the v0.8.19 resync and disputed earlier on parity grounds.
Per the project rule that bugs in the Python reference are NOT
requirements, both are fixed here with regression tests and the
divergences documented inline.

Chinese bigram segmentation (`graphify-serve`):
- `segment_chinese_bigram` now walks contiguous runs of CJK
  Unified Ideographs and emits bigrams only **within** each run.
  Cross-script tokens like "a前b" no longer produce noisy "a前"
  and "前b" pairs; the unsegmented original is still preserved
  for exact-substring matches.
- Python's `_segment_chinese` fallback walked raw character pairs
  with no script awareness; the noise was invisible there only
  because jieba (when installed) sidestepped the path entirely.

@code brace counter in `extract_razor` (`graphify-extract`):
- New `find_csharp_block_end` state machine tracks line comments,
  block comments, regular strings (with `\` escape), verbatim
  strings (with `""` escape), interpolated strings, and char
  literals. Braces inside any of those don't count toward depth.
- The previous Python-style brace-only counter truncated
  `block_end` early on bodies containing `"}{"` or `}` in a
  comment, silently dropping every method declared below that
  point.

New regression tests:
- `query_terms_chinese_mixed_script_does_not_bigram_across_scripts`
- `razor_code_block_brace_counter_ignores_strings_and_comments`

Full workspace gate: 1418 tests pass (was 1416, +2).

A line from the Adeptus Mechanicus Prayerbook:
"To break is to mend; the Machine learns through its scars."
CodeRabbit flagged that the new .NET extension list (`.fsproj`,
`.vbproj`, `.cshtml`) is wired into the dispatch table but never
exercised — the existing parity tests cover `.csproj` and `.razor`
only. Add three smoke tests that build tiny tempdir fixtures and
assert `extract_csproj` / `extract_razor` succeed and emit nodes
for each new extension.

These complement the dispatch-table check in `parity.rs::test_dispatch_table`
(which only verifies `_get_extractor` returns Some for each ext) by
running the real extractor end-to-end.

Glory to the Omnissiah
@rblaine95 rblaine95 force-pushed the resync/graphify-py/d9debdf branch from d84c9a6 to d26171a Compare May 26, 2026 17:29
@rblaine95 rblaine95 merged commit 1a99a35 into master May 26, 2026
12 checks passed
@rblaine95 rblaine95 deleted the resync/graphify-py/d9debdf branch May 26, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant