Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/hooks/update-graph.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ BUILD_OK=0
if command -v codegraph &>/dev/null; then
codegraph build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true
else
node "${CLAUDE_PROJECT_DIR:-$PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true
node "${CLAUDE_PROJECT_DIR:-$PROJECT_DIR}/dist/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true

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.

P2 Fallback Requires Built Dist

When this hook runs in a checkout where codegraph is not on PATH and dist/cli.js has not been built yet, the fallback still exits through the silent failure path because dist/ is ignored and only created after the build step. That leaves BUILD_OK at 0, so the graph rebuild is skipped without any visible error.

Fix in Claude Code

fi

# Update marker only if we did a full rebuild AND it succeeded
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/hook-fallback-build-path.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Regression guard for issue #1836: .claude/hooks/update-graph.sh's
* fallback build path (used when the `codegraph` binary isn't on PATH)
* invoked `node <project>/src/cli.js`, a file that has never existed —
* the CLI entry point is TypeScript at src/cli.ts, compiled to dist/cli.js
* (see package.json's `bin.codegraph`). That branch silently failed
* (stderr redirected to /dev/null), so BUILD_OK stayed 0 and the graph
* never rebuilt for contributors without a global codegraph install.
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = path.resolve(__dirname, '..', '..');
const HOOK_PATH = path.join(REPO_ROOT, '.claude', 'hooks', 'update-graph.sh');

describe('update-graph.sh hook fallback build path', () => {
const script = fs.readFileSync(HOOK_PATH, 'utf8');
const packageJson = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'package.json'), 'utf8'));
const cliEntry = packageJson.bin.codegraph.replace(/^\.\//, '');

it('never references a nonexistent src/cli.js', () => {
expect(script).not.toMatch(/\bsrc\/cli\.js\b/);
});

it("invokes package.json's bin.codegraph entry point in the fallback branch", () => {
expect(script).toContain(`/${cliEntry}" build`);
});
});
Loading