chore(release): v2.4.0 by carlos-alm · Pull Request #103 · optave/ops-codegraph-tool · GitHub
Skip to content

chore(release): v2.4.0#103

Merged
carlos-alm merged 3 commits into
mainfrom
feat/update-notification
Feb 26, 2026
Merged

chore(release): v2.4.0#103
carlos-alm merged 3 commits into
mainfrom
feat/update-notification

Conversation

@carlos-alm

@carlos-alm carlos-alm commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bump version to 2.4.0 in package.json and package-lock.json
  • Add CHANGELOG.md entry for v2.4.0 covering all changes since v2.3.0
  • Add update notification after CLI commands — checks npm for newer versions and displays an upgrade hint

Highlights (v2.4.0)

  • Git co-change analysis — surfaces files that frequently change together using Jaccard similarity
  • Node role classification — labels nodes as entry/core/utility/adapter/dead/leaf based on graph topology
  • tree-sitter Query API — replaces manual AST walk for faster JS/TS/TSX extraction
  • Enhanced Mermaid export — subgraphs, edge labels, node shapes, and styling
  • CLI improvements--json for search, --file glob filter, --exclude for prune
  • Update notification — checks npm for newer versions after commands
  • 14 bug fixes including ONNX memory leak, incremental build structure preservation, embed config respect

Test plan

  • Verify node src/cli.js --version outputs 2.4.0
  • Verify CHANGELOG.md renders correctly on GitHub
  • Run npm test to confirm no regressions

Check the npm registry for newer versions (cached 24h) and print a
non-intrusive notification box to stderr. Zero new dependencies — uses
Node built-in https module and a minimal inline semver compare.

Suppressed in CI, non-TTY, --json output, and when NO_UPDATE_CHECK=1
is set. Skipped for long-running commands (mcp, watch).

Impact: 6 functions changed, 2 affected
@claude

claude Bot commented Feb 25, 2026

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a non-intrusive update notification system that checks for new versions after CLI commands complete. The implementation uses a 24-hour cache to minimize network requests and gracefully suppresses checks in CI environments, non-TTY contexts, and long-running commands.

Key implementation details:

  • Zero new dependencies — uses Node built-in https module
  • Atomic cache writes using temp file + rename pattern (update-check.js:50-56)
  • Minimal inline semver comparison limited to numeric x.y.z versions
  • 3-second timeout on npm registry requests with proper error handling
  • Comprehensive test coverage (20 tests) including edge cases

No issues found — code is well-structured, defensive, and thoroughly tested.

Confidence Score: 5/5

  • This PR is safe to merge with no concerns
  • Clean implementation with zero dependencies, comprehensive test coverage (20 tests), proper error handling throughout, atomic file operations, and defensive coding practices. The feature is well-isolated and cannot break existing functionality due to the top-level try-catch in the hook.
  • No files require special attention

Important Files Changed

Filename Overview
src/cli.js Added postAction hook that calls update check after commands, excluding long-running commands (mcp, watch) and --json output
src/update-check.js New module implementing update notification with semver comparison, 24h cache, npm registry fetch, and atomic file writes
tests/unit/update-check.test.js Comprehensive test suite with 20 tests covering semver logic, cache behavior, network failures, TTY detection, and environment suppression

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[CLI Command Executes] --> B{postAction Hook}
    B --> C{Is command mcp/watch?}
    C -->|Yes| D[Skip update check]
    C -->|No| E{Is --json flag set?}
    E -->|Yes| D
    E -->|No| F[checkForUpdates]
    
    F --> G{CI env set?}
    G -->|Yes| H[Return null]
    G -->|No| I{NO_UPDATE_CHECK set?}
    I -->|Yes| H
    I -->|No| J{stderr.isTTY?}
    J -->|No| H
    J -->|Yes| K[Load Cache]
    
    K --> L{Cache exists & fresh?}
    L -->|Yes| M{Current < Cached Latest?}
    L -->|No| N[Fetch from npm registry]
    
    N --> O{Fetch success?}
    O -->|No| H
    O -->|Yes| P[Save to cache]
    P --> Q{Current < Latest?}
    
    M -->|Yes| R[Return update info]
    M -->|No| H
    Q -->|Yes| R
    Q -->|No| H
    
    R --> S[printUpdateNotification]
    S --> T[Display box on stderr]
    
    D --> U[Continue]
    H --> U
    T --> U
Loading

Last reviewed commit: eb3ccdf

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@carlos-alm carlos-alm changed the title feat(cli): add update notification after commands chore(release): v2.4.0 Feb 25, 2026
The CI environment variable caused checkForUpdates to bail out at the
guard clause before reaching fetch/cache logic, making 5 tests fail
in GitHub Actions.
@claude

claude Bot commented Feb 26, 2026

Copy link
Copy Markdown

@carlos-alm carlos-alm merged commit 851bcb0 into main Feb 26, 2026
16 checks passed
@carlos-alm carlos-alm deleted the feat/update-notification branch February 26, 2026 03:49
carlos-alm added a commit that referenced this pull request Mar 21, 2026
…552)

The probabilistic Leiden refinement changes community assignments and
introduces non-determinism — both qualify as breaking per the column
definition. Added a note about using a deterministic seed for CI
reproducibility.
carlos-alm added a commit that referenced this pull request Mar 21, 2026
…552)

* docs: add true Leiden refinement phase to backlog (ID 103)

Current vendored implementation uses greedy refinement, which is
functionally Louvain with an extra pass. The paper's randomized
refinement (Algorithm 3) is what guarantees well-connected
communities — the defining contribution of Leiden over Louvain.

* fix: mark backlog item #103 as breaking, add deterministic seed note (#552)

The probabilistic Leiden refinement changes community assignments and
introduces non-determinism — both qualify as breaking per the column
definition. Added a note about using a deterministic seed for CI
reproducibility.

* feat: implement true Leiden probabilistic refinement (Algorithm 3)

Replace greedy best-gain selection in refinement phase with Boltzmann
sampling p(v, C) ∝ exp(ΔH/θ) per Traag et al. 2019, Algorithm 3.
This is the defining contribution of Leiden over Louvain — guarantees
γ-connected communities instead of bridge-connected subcommunities.

Deterministic via seeded PRNG (mulberry32) — same seed always produces
identical community assignments. New refinementTheta option (default
0.01) controls temperature: lower → more greedy, higher → exploratory.

Breaking: community assignments will differ from prior greedy refinement
for any graph where multiple candidates have positive quality gain
during the refinement phase.

Impact: 2 functions changed, 4 affected

* docs: remove backlog #103 — ships in this PR, not a breaking change

* fix: align Leiden refinement with Algorithm 3 (Traag et al. 2019)

Three corrections to match the paper:

1. Singleton guard — only nodes still in singleton communities are
   candidates for merging. Once merged, a node is locked for the
   remainder of the pass. Essential for γ-connectedness guarantee.

2. Single pass — one randomized sweep, not an iterative while-loop.
   Iterating until convergence is Louvain behavior, not Leiden.

3. Stay option — the "remain as singleton" choice (ΔH=0) is included
   in the Boltzmann distribution, so a node may probabilistically
   stay alone even when positive-gain merges exist.

Impact: 1 functions changed, 1 affected

* test: add Algorithm 3 conformance tests for Leiden refinement

Three new tests that would catch deviations from the paper:

- Stay option: high theta preserves singletons because ΔH=0 competes
  in the Boltzmann distribution. Without it, all positive-gain nodes
  would be forced to merge.
- Singleton guard: ring of triangles stays granular across seeds.
  Without the guard, iterative passes would collapse adjacent triangles.
- Single pass: refine=true preserves at least as many communities as
  refine=false on a uniform weak-link graph. Iterative convergence
  would over-merge.

* feat: post-refinement connectivity split and fix default theta

Three improvements to complete the robust Leiden implementation:

1. Default refinementTheta changed from 0.01 to 1.0. The old default
   made exp(ΔH/0.01) extremely peaked, effectively disabling the
   probabilistic behavior. θ=1.0 matches the paper's exp(ΔH).

2. Post-refinement split step: after probabilistic refinement, BFS
   each community's induced subgraph. If a community has disconnected
   components, split them into separate community IDs. O(V+E) total.
   This replaces the expensive per-candidate γ-connectedness check
   with a cheap post-step using codegraph's existing graph primitives.

3. New connectivity validation test: across multiple seeds, verify
   every community is internally connected via BFS on the subgraph.
   This directly tests the core Leiden guarantee.

Adds resizeCommunities() to partition API for the split step.

Impact: 6 functions changed, 5 affected
carlos-alm added a commit that referenced this pull request Mar 21, 2026
* docs: add true Leiden refinement phase to backlog (ID 103)

Current vendored implementation uses greedy refinement, which is
functionally Louvain with an extra pass. The paper's randomized
refinement (Algorithm 3) is what guarantees well-connected
communities — the defining contribution of Leiden over Louvain.

* fix: mark backlog item #103 as breaking, add deterministic seed note (#552)

The probabilistic Leiden refinement changes community assignments and
introduces non-determinism — both qualify as breaking per the column
definition. Added a note about using a deterministic seed for CI
reproducibility.

* feat: implement true Leiden probabilistic refinement (Algorithm 3)

Replace greedy best-gain selection in refinement phase with Boltzmann
sampling p(v, C) ∝ exp(ΔH/θ) per Traag et al. 2019, Algorithm 3.
This is the defining contribution of Leiden over Louvain — guarantees
γ-connected communities instead of bridge-connected subcommunities.

Deterministic via seeded PRNG (mulberry32) — same seed always produces
identical community assignments. New refinementTheta option (default
0.01) controls temperature: lower → more greedy, higher → exploratory.

Breaking: community assignments will differ from prior greedy refinement
for any graph where multiple candidates have positive quality gain
during the refinement phase.

Impact: 2 functions changed, 4 affected

* docs: remove backlog #103 — ships in this PR, not a breaking change

* fix: align Leiden refinement with Algorithm 3 (Traag et al. 2019)

Three corrections to match the paper:

1. Singleton guard — only nodes still in singleton communities are
   candidates for merging. Once merged, a node is locked for the
   remainder of the pass. Essential for γ-connectedness guarantee.

2. Single pass — one randomized sweep, not an iterative while-loop.
   Iterating until convergence is Louvain behavior, not Leiden.

3. Stay option — the "remain as singleton" choice (ΔH=0) is included
   in the Boltzmann distribution, so a node may probabilistically
   stay alone even when positive-gain merges exist.

Impact: 1 functions changed, 1 affected

* test: add Algorithm 3 conformance tests for Leiden refinement

Three new tests that would catch deviations from the paper:

- Stay option: high theta preserves singletons because ΔH=0 competes
  in the Boltzmann distribution. Without it, all positive-gain nodes
  would be forced to merge.
- Singleton guard: ring of triangles stays granular across seeds.
  Without the guard, iterative passes would collapse adjacent triangles.
- Single pass: refine=true preserves at least as many communities as
  refine=false on a uniform weak-link graph. Iterative convergence
  would over-merge.

* feat: post-refinement connectivity split and fix default theta

Three improvements to complete the robust Leiden implementation:

1. Default refinementTheta changed from 0.01 to 1.0. The old default
   made exp(ΔH/0.01) extremely peaked, effectively disabling the
   probabilistic behavior. θ=1.0 matches the paper's exp(ΔH).

2. Post-refinement split step: after probabilistic refinement, BFS
   each community's induced subgraph. If a community has disconnected
   components, split them into separate community IDs. O(V+E) total.
   This replaces the expensive per-candidate γ-connectedness check
   with a cheap post-step using codegraph's existing graph primitives.

3. New connectivity validation test: across multiple seeds, verify
   every community is internally connected via BFS on the subgraph.
   This directly tests the core Leiden guarantee.

Adds resizeCommunities() to partition API for the split step.

Impact: 6 functions changed, 5 affected

* docs: replace language support prose with checkmark compatibility matrix

Replaces the "Symbols Extracted" prose column with a scannable
checkmark grid covering Imports, Exports, Call Sites, Heritage,
Type Inference, and Dataflow per language.

* docs: use ✓ instead of ✅ in language compatibility matrix

* docs: restructure roadmap phases and expand language support to 34

- Move 5.7-5.9 (supply-chain, CI quality, kill list) out of TypeScript
  Migration into new Phase 9 (Quality, Security & Technical Debt)
- Move Expanded Language Support from Phase 10 to Phase 7, right after
  Native Analysis Acceleration
- Expand language roadmap from 8 planned additions to 23 (34 total),
  covering all major tree-sitter grammars with both WASM and Rust support
- Renumber all subsequent phases (7→8 through 12→13)
- Update all internal cross-references

* fix: address Greptile review feedback on Leiden refinement

- Guard against theta <= 0 with RangeError in refineWithinCoarseCommunities
- Fix termination check to also consider effectivePartition community count
  when refine is enabled (coarse graph is built from effectivePartition)
- Add refinementTheta to DEFAULTS.community and wire through communities.js
- Replace per-node candidates array allocation with pre-allocated flat
  typed arrays (Int32Array/Float64Array) to reduce GC pressure in hot loop
- Traverse both outEdges and inEdges in splitDisconnectedCommunities for
  weak connectivity on directed graphs

Impact: 4 functions changed, 15 affected

* fix: address Greptile review feedback on Leiden refinement

- Guard against theta <= 0 with RangeError in refineWithinCoarseCommunities
- Fix termination check to also consider effectivePartition community count
  when refine is enabled (coarse graph is built from effectivePartition)
- Add refinementTheta to DEFAULTS.community and wire through communities.js
- Replace per-node candidates array allocation with pre-allocated flat
  typed arrays (Int32Array/Float64Array) to reduce GC pressure in hot loop
- Traverse both outEdges and inEdges in splitDisconnectedCommunities for
  weak connectivity on directed graphs

Impact: 4 functions changed, 15 affected

* fix: update config test to include refinementTheta default

* ci: trigger CI rerun

* fix: retrigger CI after test fix

* style: format community defaults test assertion
carlos-alm added a commit that referenced this pull request Apr 16, 2026
#103 — Recursively foldable graph viewer (Tier 1g)
#104 — Architecture-as-code validation gate (Tier 1j)
carlos-alm added a commit that referenced this pull request Apr 16, 2026
* docs(backlog): add Weft-inspired items #103 and #104

#103 — Recursively foldable graph viewer (Tier 1g)
#104 — Architecture-as-code validation gate (Tier 1j)

* fix(backlog): correct stale .js file references to .ts in item #103
Zeeeepa pushed a commit to Zeeeepa/codegraph that referenced this pull request Jun 22, 2026
Zeeeepa pushed a commit to Zeeeepa/codegraph that referenced this pull request Jun 22, 2026
) (optave#552)

* docs: add true Leiden refinement phase to backlog (ID 103)

Current vendored implementation uses greedy refinement, which is
functionally Louvain with an extra pass. The paper's randomized
refinement (Algorithm 3) is what guarantees well-connected
communities — the defining contribution of Leiden over Louvain.

* fix: mark backlog item optave#103 as breaking, add deterministic seed note (optave#552)

The probabilistic Leiden refinement changes community assignments and
introduces non-determinism — both qualify as breaking per the column
definition. Added a note about using a deterministic seed for CI
reproducibility.

* feat: implement true Leiden probabilistic refinement (Algorithm 3)

Replace greedy best-gain selection in refinement phase with Boltzmann
sampling p(v, C) ∝ exp(ΔH/θ) per Traag et al. 2019, Algorithm 3.
This is the defining contribution of Leiden over Louvain — guarantees
γ-connected communities instead of bridge-connected subcommunities.

Deterministic via seeded PRNG (mulberry32) — same seed always produces
identical community assignments. New refinementTheta option (default
0.01) controls temperature: lower → more greedy, higher → exploratory.

Breaking: community assignments will differ from prior greedy refinement
for any graph where multiple candidates have positive quality gain
during the refinement phase.

Impact: 2 functions changed, 4 affected

* docs: remove backlog optave#103 — ships in this PR, not a breaking change

* fix: align Leiden refinement with Algorithm 3 (Traag et al. 2019)

Three corrections to match the paper:

1. Singleton guard — only nodes still in singleton communities are
   candidates for merging. Once merged, a node is locked for the
   remainder of the pass. Essential for γ-connectedness guarantee.

2. Single pass — one randomized sweep, not an iterative while-loop.
   Iterating until convergence is Louvain behavior, not Leiden.

3. Stay option — the "remain as singleton" choice (ΔH=0) is included
   in the Boltzmann distribution, so a node may probabilistically
   stay alone even when positive-gain merges exist.

Impact: 1 functions changed, 1 affected

* test: add Algorithm 3 conformance tests for Leiden refinement

Three new tests that would catch deviations from the paper:

- Stay option: high theta preserves singletons because ΔH=0 competes
  in the Boltzmann distribution. Without it, all positive-gain nodes
  would be forced to merge.
- Singleton guard: ring of triangles stays granular across seeds.
  Without the guard, iterative passes would collapse adjacent triangles.
- Single pass: refine=true preserves at least as many communities as
  refine=false on a uniform weak-link graph. Iterative convergence
  would over-merge.

* feat: post-refinement connectivity split and fix default theta

Three improvements to complete the robust Leiden implementation:

1. Default refinementTheta changed from 0.01 to 1.0. The old default
   made exp(ΔH/0.01) extremely peaked, effectively disabling the
   probabilistic behavior. θ=1.0 matches the paper's exp(ΔH).

2. Post-refinement split step: after probabilistic refinement, BFS
   each community's induced subgraph. If a community has disconnected
   components, split them into separate community IDs. O(V+E) total.
   This replaces the expensive per-candidate γ-connectedness check
   with a cheap post-step using codegraph's existing graph primitives.

3. New connectivity validation test: across multiple seeds, verify
   every community is internally connected via BFS on the subgraph.
   This directly tests the core Leiden guarantee.

Adds resizeCommunities() to partition API for the split step.

Impact: 6 functions changed, 5 affected
Zeeeepa pushed a commit to Zeeeepa/codegraph that referenced this pull request Jun 22, 2026
* docs: add true Leiden refinement phase to backlog (ID 103)

Current vendored implementation uses greedy refinement, which is
functionally Louvain with an extra pass. The paper's randomized
refinement (Algorithm 3) is what guarantees well-connected
communities — the defining contribution of Leiden over Louvain.

* fix: mark backlog item optave#103 as breaking, add deterministic seed note (optave#552)

The probabilistic Leiden refinement changes community assignments and
introduces non-determinism — both qualify as breaking per the column
definition. Added a note about using a deterministic seed for CI
reproducibility.

* feat: implement true Leiden probabilistic refinement (Algorithm 3)

Replace greedy best-gain selection in refinement phase with Boltzmann
sampling p(v, C) ∝ exp(ΔH/θ) per Traag et al. 2019, Algorithm 3.
This is the defining contribution of Leiden over Louvain — guarantees
γ-connected communities instead of bridge-connected subcommunities.

Deterministic via seeded PRNG (mulberry32) — same seed always produces
identical community assignments. New refinementTheta option (default
0.01) controls temperature: lower → more greedy, higher → exploratory.

Breaking: community assignments will differ from prior greedy refinement
for any graph where multiple candidates have positive quality gain
during the refinement phase.

Impact: 2 functions changed, 4 affected

* docs: remove backlog optave#103 — ships in this PR, not a breaking change

* fix: align Leiden refinement with Algorithm 3 (Traag et al. 2019)

Three corrections to match the paper:

1. Singleton guard — only nodes still in singleton communities are
   candidates for merging. Once merged, a node is locked for the
   remainder of the pass. Essential for γ-connectedness guarantee.

2. Single pass — one randomized sweep, not an iterative while-loop.
   Iterating until convergence is Louvain behavior, not Leiden.

3. Stay option — the "remain as singleton" choice (ΔH=0) is included
   in the Boltzmann distribution, so a node may probabilistically
   stay alone even when positive-gain merges exist.

Impact: 1 functions changed, 1 affected

* test: add Algorithm 3 conformance tests for Leiden refinement

Three new tests that would catch deviations from the paper:

- Stay option: high theta preserves singletons because ΔH=0 competes
  in the Boltzmann distribution. Without it, all positive-gain nodes
  would be forced to merge.
- Singleton guard: ring of triangles stays granular across seeds.
  Without the guard, iterative passes would collapse adjacent triangles.
- Single pass: refine=true preserves at least as many communities as
  refine=false on a uniform weak-link graph. Iterative convergence
  would over-merge.

* feat: post-refinement connectivity split and fix default theta

Three improvements to complete the robust Leiden implementation:

1. Default refinementTheta changed from 0.01 to 1.0. The old default
   made exp(ΔH/0.01) extremely peaked, effectively disabling the
   probabilistic behavior. θ=1.0 matches the paper's exp(ΔH).

2. Post-refinement split step: after probabilistic refinement, BFS
   each community's induced subgraph. If a community has disconnected
   components, split them into separate community IDs. O(V+E) total.
   This replaces the expensive per-candidate γ-connectedness check
   with a cheap post-step using codegraph's existing graph primitives.

3. New connectivity validation test: across multiple seeds, verify
   every community is internally connected via BFS on the subgraph.
   This directly tests the core Leiden guarantee.

Adds resizeCommunities() to partition API for the split step.

Impact: 6 functions changed, 5 affected

* docs: replace language support prose with checkmark compatibility matrix

Replaces the "Symbols Extracted" prose column with a scannable
checkmark grid covering Imports, Exports, Call Sites, Heritage,
Type Inference, and Dataflow per language.

* docs: use ✓ instead of ✅ in language compatibility matrix

* docs: restructure roadmap phases and expand language support to 34

- Move 5.7-5.9 (supply-chain, CI quality, kill list) out of TypeScript
  Migration into new Phase 9 (Quality, Security & Technical Debt)
- Move Expanded Language Support from Phase 10 to Phase 7, right after
  Native Analysis Acceleration
- Expand language roadmap from 8 planned additions to 23 (34 total),
  covering all major tree-sitter grammars with both WASM and Rust support
- Renumber all subsequent phases (7→8 through 12→13)
- Update all internal cross-references

* fix: address Greptile review feedback on Leiden refinement

- Guard against theta <= 0 with RangeError in refineWithinCoarseCommunities
- Fix termination check to also consider effectivePartition community count
  when refine is enabled (coarse graph is built from effectivePartition)
- Add refinementTheta to DEFAULTS.community and wire through communities.js
- Replace per-node candidates array allocation with pre-allocated flat
  typed arrays (Int32Array/Float64Array) to reduce GC pressure in hot loop
- Traverse both outEdges and inEdges in splitDisconnectedCommunities for
  weak connectivity on directed graphs

Impact: 4 functions changed, 15 affected

* fix: address Greptile review feedback on Leiden refinement

- Guard against theta <= 0 with RangeError in refineWithinCoarseCommunities
- Fix termination check to also consider effectivePartition community count
  when refine is enabled (coarse graph is built from effectivePartition)
- Add refinementTheta to DEFAULTS.community and wire through communities.js
- Replace per-node candidates array allocation with pre-allocated flat
  typed arrays (Int32Array/Float64Array) to reduce GC pressure in hot loop
- Traverse both outEdges and inEdges in splitDisconnectedCommunities for
  weak connectivity on directed graphs

Impact: 4 functions changed, 15 affected

* fix: update config test to include refinementTheta default

* ci: trigger CI rerun

* fix: retrigger CI after test fix

* style: format community defaults test assertion
Zeeeepa pushed a commit to Zeeeepa/codegraph that referenced this pull request Jun 22, 2026
…ave#945)

* docs(backlog): add Weft-inspired items optave#103 and optave#104

optave#103 — Recursively foldable graph viewer (Tier 1g)
optave#104 — Architecture-as-code validation gate (Tier 1j)

* fix(backlog): correct stale .js file references to .ts in item optave#103
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