Skip to content

Fix/graph and issues#26

Merged
mvoutov merged 4 commits intomainfrom
fix/graph-and-issues
Mar 23, 2026
Merged

Fix/graph and issues#26
mvoutov merged 4 commits intomainfrom
fix/graph-and-issues

Conversation

@mvoutov
Copy link
Copy Markdown
Contributor

@mvoutov mvoutov commented Mar 23, 2026

What

Why

Closes #

How I tested

  • npm test passes
  • Tested against a real repo:
  • --dry-run output looks correct (if applicable)

Checklist

  • Changes are focused on a single feature or fix
  • Tests added or updated for any logic changes
  • No new dependencies added (or justified in the PR description)

Summary by CodeRabbit

  • New Features

    • Targeted documentation generation via a --domains option and domain-only mode
  • Bug Fixes

    • Show warnings when graph context generation fails
    • Safer handling of missing graph/data fields
  • Documentation

    • Minimum Node.js requirement raised to 20
    • Added Dev docs and Code review guidance
  • Chores

    • Added timeout protections and improved output path messaging for generated docs
    • Updated test fixture path resolution

mvoutov added 3 commits March 23, 2026 14:42
  Node's spawn() can't locate .cmd wrappers without shell: true.
  Scoped to win32 only.

  Closes #25
  Allows regenerating specific domains without touching the base skill or
  CLAUDE.md. Skips discovery and shows actionable retry hint when domains fail.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 23, 2026

Walkthrough

Refines docs and Node requirement, hardens optional-chaining and graph handling, adds domain-filtered chunked generation with discovery-skipping, improves error logging and Windows process handling, and adds timeouts/robustness to hook scripts and tests.

Changes

Cohort / File(s) Summary
Docs & Requirements
CLAUDE.md
Added "Dev docs" and "Code review" sections; raised runtime requirement from Node ≥18 to Node ≥20.
Chunked generation & CLI flow
src/commands/doc-init.js
Added isBaseOnly/isDomainsOnly flags; domain-filtering for --mode chunked --domains; skip discovery/interactive prompts when appropriate; generateChunked() gains domainsOnly param to skip base generation & CLAUDE.md; improved retry messaging; hardened graph/dependency access with optional chaining and defaults.
Graph commands & output
src/commands/doc-graph.js, src/commands/doc-sync.js
Safer optional-chaining for cluster stats; updated artifact path text; log warnings when graph build fails instead of silent swallow.
Runner & process handling
src/lib/runner.js
Enable spawn shell only on Windows; use Windows taskkill for timeout termination, retain SIGTERM elsewhere.
Hook scripts & prompt module
src/templates/hooks/graph-context-prompt.sh, src/templates/hooks/graph-context-prompt.mjs
Make symlink-resolving function return on cd failure; add 5s startup timeout and clear it when main completes.
Tests
tests/graph-persistence.test.js
Replace import.meta.dirname with dirname(fileURLToPath(import.meta.url)) for fixture path resolution.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI as CLI (doc-init)
participant FS as Filesystem (.claude / repo)
participant Graph as Graph Builder
participant Claude as Claude (AI)
CLI->>FS: read repo + existing base skill (if domains-only)
CLI->>Graph: build repo graph (optional)
Graph-->>CLI: graph or error (warning logged)
CLI->>Claude: invoke generation (skip base when domainsOnly)
Claude-->>CLI: generated skill artifacts
CLI->>FS: write .claude artifacts and code-map

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely empty placeholder text with no concrete details about changes, rationale, testing approach, or issue linkage. Complete all sections: describe the specific changes (graph hardening, Windows process handling, Node 20 upgrade), explain why they're needed, document how testing was performed, and link any related issues.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Fix/graph and issues' is vague and does not clearly convey the main purpose of the changes; it lacks specificity about what graph issues are being fixed. Use a more descriptive title like 'Fix graph context and error handling' or 'Improve graph resilience and Windows compatibility' to better reflect the actual changes.

✏️ 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 fix/graph-and-issues

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/doc-init.js`:
- Around line 874-875: The retry hints currently print commands that default to
the current working directory; update the two console.log lines that reference
skippedDomains so they include the actual target repository path used by the
command invocation (the variable in this file that holds the target repo, e.g.
targetPath/targetDir/repoDir) instead of assuming cwd; modify both occurrences
that build the strings for "aspens doc init --mode chunked --domains
\"${skippedDomains.join(',')}\"" and "aspens doc init --mode chunked --timeout
600" to interpolate the repository path variable (the same variable used earlier
in this module when resolving the target repo) so the suggested retry commands
point to the original target.
- Around line 127-128: The code conflates two different modes by using
skipDiscovery for both base-only and retry/domains flows, causing the
base-generation path and existing-docs prompt to be skipped; split this into two
explicit booleans (e.g., isBaseOnly = options.mode === 'base-only' and
isDomainsOnly = options.mode === 'chunked' && extraDomains &&
extraDomains.length > 0 or isRetryOnly) and update all uses: replace
skipDiscovery in the repoGraph check and the later domainsOnly logic with the
appropriate boolean (use isBaseOnly where you want the base-only behavior and
isDomainsOnly/isRetryOnly where you want to skip discovery/retry-only behavior)
so that base-only runs still generate base files and trigger the existing-docs
strategy prompt.

In `@src/lib/runner.js`:
- Around line 53-56: The timeout cleanup currently calls child.kill('SIGTERM')
but on Windows (where spawn is created with shell: process.platform === 'win32')
that only terminates the shell (cmd.exe) and leaves the Claude process tree
orphaned; modify the timeout handler that references the spawned child (the
variable child from spawn(...)) to run platform-specific cleanup: if
process.platform === 'win32' invoke a child process to run `taskkill /pid
<child.pid> /t /f` to kill the entire process tree, otherwise call
child.kill('SIGTERM') as before; ensure you handle errors from taskkill and only
attempt taskkill when child.pid exists.

In `@src/templates/hooks/graph-context-prompt.sh`:
- Around line 53-54: Remove the external GNU `timeout 5s` call from the shell
hook and implement an internal, portable timeout inside
graph-context-prompt.mjs: in graph-context-prompt.mjs set a Node.js timer
(setTimeout) that sends SIGTERM to process after the desired timeout, clear the
timer (clearTimeout) on normal completion or error, and ensure the module reads
from stdin and exits with appropriate codes; keep the hook invocation as a
simple NODE_NO_WARNINGS=1 node graph-context-prompt.mjs >"$STDOUT_FILE"
2>"$STDERR_FILE" so macOS works without coreutils.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8e44f30f-b450-4560-920d-036be65947a5

📥 Commits

Reviewing files that changed from the base of the PR and between 9a17328 and 1782971.

📒 Files selected for processing (7)
  • CLAUDE.md
  • src/commands/doc-graph.js
  • src/commands/doc-init.js
  • src/commands/doc-sync.js
  • src/lib/runner.js
  • src/templates/hooks/graph-context-prompt.sh
  • tests/graph-persistence.test.js

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/doc-init.js`:
- Around line 875-876: The printed retry commands in src/commands/doc-init.js
use the variable repoPath unquoted which will break when the path contains
spaces; update the two console.log calls that use pc.dim (the lines referencing
skippedDomains.join(',') and the timeout variant) to wrap repoPath in quotes
(use "${repoPath}") so the generated shell commands are robust for paths with
spaces; keep the rest of the string intact and ensure you preserve the existing
interpolation for skippedDomains.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d5dd338d-1fde-46e0-bb22-c624285c4a79

📥 Commits

Reviewing files that changed from the base of the PR and between 1782971 and 31938b5.

📒 Files selected for processing (4)
  • src/commands/doc-init.js
  • src/lib/runner.js
  • src/templates/hooks/graph-context-prompt.mjs
  • src/templates/hooks/graph-context-prompt.sh
✅ Files skipped from review due to trivial changes (1)
  • src/templates/hooks/graph-context-prompt.sh

Comment on lines +875 to +876
console.log(pc.dim(` Retry just these: aspens doc init --mode chunked --domains "${skippedDomains.join(',')}" ${repoPath}`));
console.log(pc.dim(` Or retry all: aspens doc init --mode chunked --timeout 600 ${repoPath}`));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Quote the repo path to handle spaces.

If repoPath contains spaces, these commands will fail. Wrap it in quotes for robustness.

Proposed fix
-    console.log(pc.dim(`  Retry just these: aspens doc init --mode chunked --domains "${skippedDomains.join(',')}" ${repoPath}`));
-    console.log(pc.dim(`  Or retry all: aspens doc init --mode chunked --timeout 600 ${repoPath}`));
+    console.log(pc.dim(`  Retry just these: aspens doc init --mode chunked --domains "${skippedDomains.join(',')}" "${repoPath}"`));
+    console.log(pc.dim(`  Or retry all: aspens doc init --mode chunked --timeout 600 "${repoPath}"`));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(pc.dim(` Retry just these: aspens doc init --mode chunked --domains "${skippedDomains.join(',')}" ${repoPath}`));
console.log(pc.dim(` Or retry all: aspens doc init --mode chunked --timeout 600 ${repoPath}`));
console.log(pc.dim(` Retry just these: aspens doc init --mode chunked --domains "${skippedDomains.join(',')}" "${repoPath}"`));
console.log(pc.dim(` Or retry all: aspens doc init --mode chunked --timeout 600 "${repoPath}"`));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/doc-init.js` around lines 875 - 876, The printed retry commands
in src/commands/doc-init.js use the variable repoPath unquoted which will break
when the path contains spaces; update the two console.log calls that use pc.dim
(the lines referencing skippedDomains.join(',') and the timeout variant) to wrap
repoPath in quotes (use "${repoPath}") so the generated shell commands are
robust for paths with spaces; keep the rest of the string intact and ensure you
preserve the existing interpolation for skippedDomains.

@mvoutov mvoutov merged commit 30220d0 into main Mar 23, 2026
3 checks passed
@mvoutov mvoutov deleted the fix/graph-and-issues branch March 23, 2026 22:29
@coderabbitai coderabbitai bot mentioned this pull request Mar 28, 2026
6 tasks
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