feat: add repo map codebase intelligence - #1867
Conversation
…tural summaries
Adds a new module that builds a structural map of the repository by parsing
source files with tree-sitter, building a cross-file reference graph weighted
by IDF, ranking files with PageRank, and rendering a token-budgeted summary
of the most important files and their signatures.
Surface:
- RepoMap tool the model can call on-demand, with focus_files / focus_symbols
- /repomap slash command with --tokens, --focus, --stats, --invalidate
- Auto-injection into session system context, gated by REPO_MAP=1 env var
(compile-time feature('REPO_MAP') flag stays off in scripts/build.ts)
How it works:
git ls-files → tree-sitter WASM parse → extract defs/refs →
IDF-weighted directed graph → PageRank → render top files until token budget
Files imported by many others rank highest. Common symbol names (get, set,
map, value) are down-weighted via IDF. Results cached to disk keyed by
(path, mtime, size) — only changed files are re-parsed.
Supported languages: TypeScript, JavaScript, Python.
Tree-sitter tag queries are inlined as string constants in queries.ts so
they ship inside dist/cli.mjs and work after npm install — the .scm source
files are kept for readability/Aider attribution but are not required at
runtime. A drift-guard test (queries.test.ts) asserts byte-equality between
the inlined strings and the .scm source files.
Dependencies added: web-tree-sitter, tree-sitter-wasms, graphology,
graphology-pagerank, graphology-operators, js-tiktoken.
- computeMapHash now folds per-file mtime+size into the cache key so a source edit (without changing the file list) no longer returns the prior rendered map. Adds a regression test that edits a file and confirms the second build reflects the new symbol without manual invalidateCache(). - queries.test.ts byte-for-byte drift guard normalizes CRLF -> LF when reading the .scm source so Windows checkouts pass. .gitattributes also pins *.scm to LF on future checkouts. - Externals: declare web-tree-sitter, tree-sitter-wasms, graphology*, and js-tiktoken in scripts/externals.ts so build validation passes.
📝 WalkthroughWalkthroughAdds repo-map generation, caching, and context injection, then wires the new ChangesRepo Map Feature
Async cwd overrides
Estimated code review effort: 4 (Complex) | ~75 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 7✅ Passed checks (7 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 29
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/commands/repomap/repomap.test.ts (1)
1-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNo coverage for
call()output paths.Only
parseArgsis tested;call()'s stats/invalidate/default branches (formatting,getCwd/buildRepoMapwiring) are untested here. As per path instructions, tests should provide "meaningful coverage of the changed behavior" for command handlers, not just their argument parser.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands/repomap/repomap.test.ts` around lines 1 - 57, Add tests for the repomap command handler itself, not just parseArgs: cover the call() branches for default, --stats, and --invalidate so the formatting and getCwd/buildRepoMap wiring are exercised. Use the existing parseArgs and call symbols in repomap.ts to locate the command entrypoint, and assert the expected output/side effects for each mode.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/repo-map.md`:
- Line 35: The repo map documentation is out of sync with the actual default
token budget used by the repomap command. Update the token budget mention in the
docs to match the behavior implemented in repomap handling (the default in the
repomap command and its test is 2048), and make sure any other nearby references
in the same doc stay consistent with the current `repomap` behavior.
- Around line 45-52: The fenced command examples in the repo map docs are
missing a language specifier, which triggers markdownlint MD040. Update the
opening fence for the repomap examples to use a text language tag, keeping the
existing content unchanged, so the markdown block is explicitly labeled and the
lint warning is resolved.
In `@package.json`:
- Around line 108-116: The new dependency entries in package.json are using
caret ranges while the surrounding manifest mostly pins exact versions. Update
the package entries for graphology, graphology-operators, graphology-pagerank,
and js-tiktoken to use fixed versions, matching the existing versioning
convention used by nearby dependencies.
- Around line 134-139: Update the dependency entries in package.json so
web-tree-sitter and tree-sitter-wasms use exact pinned versions instead of caret
ranges. These two packages are ABI-coupled, so lock them to a known-compatible
pair in the dependency list to prevent bun install from pulling mismatched
core/grammar versions and breaking parsing. Keep the change limited to the
package.json dependency declarations for web-tree-sitter and tree-sitter-wasms.
In `@README.md`:
- Line 251: The repo map documentation currently claims a default auto-injected
budget that does not match the implementation, so update the README entry to
reflect the actual default used by the repomap command. Verify the default value
in the repomap logic, especially `src/commands/repomap/repomap.ts` and the
related `REPO_MAP`/`/repomap` docs, then revise the prose so the documented
default matches the code behavior exactly.
In `@src/commands/repomap/repomap.test.ts`:
- Around line 5-11: The test case in repomap.test.ts has a stale title that no
longer matches the assertion in parseArgs. Update the description of the test
around the parseArgs default-token check so it reflects the actual default of
2048 tokens, keeping the rest of the expectations unchanged.
In `@src/commands/repomap/repomap.ts`:
- Line 12: The default token budget is inconsistent between `repomap` and the
documentation. Check the `tokens` default in `src/commands/repomap/repomap.ts`
and align it with the intended value across the README, `docs/repo-map.md`, and
the related test expectation. If 2048 is correct, update the docs/tests to
match; otherwise change the code default to 1024 so all references stay
consistent.
- Around line 38-93: The repomap command in call() can throw uncaught errors
when buildRepoMap() or its upstream initParser/file enumeration fails, so wrap
the build path in a try/catch. Use the existing call() flow around the
invalidate and normal build branches to catch exceptions and return a friendly
text error instead of letting a raw stack trace escape. Include a clear fallback
message for both the invalidateCache(root) rebuild path and the standard
buildRepoMap({ root, maxTokens, focusFiles }) path.
In `@src/context.repoMap.test.ts`:
- Around line 10-21: The tests are asserting the wrong thing:
`getRepoMapContext` is never called in the “flag off” case, and
`getSystemContext` is never exercised in the repoMap omission case. Update
`src/context.repoMap.test.ts` to invoke `getRepoMapContext` and
`getSystemContext` directly, and assert the real gating behavior
(`getRepoMapContext` returns null when
`feature('REPO_MAP')`/`process.env.REPO_MAP` is off, and `getSystemContext`
omits the `repoMap` key). If needed, mock the feature flag or extract the gating
logic from `context.ts` into a small testable helper so the named behaviors are
actually covered.
- Around line 78-84: The repo map default assertion is using a brittle raw text
search in the test; update the check in context.repoMap.test.ts to verify the
parsed build config value instead of matching the literal string in
scripts/build.ts. Prefer importing or evaluating the build config object used by
the build setup and assert that the REPO_MAP flag is false via the relevant
config symbol rather than relying on file text contents.
In `@src/context.ts`:
- Around line 162-164: The repo map work in context.ts is still awaited
sequentially even though the comment says it runs in parallel; update the
context-building flow around getRepoMapContext and gitStatus to start both
promises before awaiting them. Use the existing Promise.all pattern already used
elsewhere in the file to run gitStatus and getRepoMapContext concurrently, then
destructure the results where they are consumed.
- Around line 114-144: getRepoMapContext currently awaits buildRepoMap() with no
deadline, so a slow or cold repo-map build can block context assembly. Add a
short timeout around the async repo map generation inside getRepoMapContext, and
have it fall back to null when the timeout wins. Keep the existing logging
behavior in the try/catch path and ensure the timeout is applied before
returning the repo map string from buildRepoMap().
In `@src/context/repoMap/cache.ts`:
- Around line 16-19: The cache key fingerprint in getCacheFilePath still uses
SHA1, which is what the security scan flags. Update the hash algorithm in
getCacheFilePath to SHA256, and apply the same digest change anywhere else in
the repoMap cache flow that derives cache filenames or fingerprints (including
the related cache read/write logic in the referenced block) so the entire cache
path generation stays consistent.
- Around line 53-71: `getCachedTags`, `setCachedTags`, and `computeMapHash` are
each calling `statSync` on the same files during a single `buildRepoMap` run,
causing redundant filesystem work. Refactor the repo map flow to collect each
file’s stat data once and thread it through both the hash computation and cache
validation paths, so `computeMapHash` and the cache helpers reuse the same
metadata instead of re-statting. Use the existing
`buildRepoMap`/`getCachedTags`/`setCachedTags` symbols to locate the shared
file-processing path and pass cached stat info through it.
In `@src/context/repoMap/graph.ts`:
- Around line 41-49: The fan-out work in graph.ts is still unbounded for
ambiguous symbols because idf() only lowers weight and the buildGraph path still
iterates every defFiles entry for each reference. Update the
buildGraph/reference-to-definition matching logic to skip or cap symbols whose
defIndex.get(symbolName)?.size exceeds a reasonable threshold, and apply that
safeguard consistently wherever those matches are expanded so COMMON_NAMES no
longer just discounts but also limits iteration cost.
In `@src/context/repoMap/index.ts`:
- Around line 44-64: The rendered map caching logic is abusing the per-file
Tag/CacheEntry shape by storing the full map in Tag.signature and metadata in
Tag.name inside cache.entries. Refactor repoMap caching to use a dedicated
renderedEntries field on CacheData (or equivalent) keyed by mapHash, and update
the read/write paths in repoMap/index.ts to store and retrieve { map, fileCount,
tokenCount } directly instead of special-casing __rendered__ entries in entries.
- Around line 41-46: The cache in repoMap is never pruned, so stale per-file
entries and old `__rendered__*` snapshots accumulate across runs. Update
`loadCache`/`saveCache` usage in `src/context/repoMap/index.ts` around
`computeMapHash`, `loadCache`, and `renderedCacheKey` to remove entries for
files no longer present in the current `files` list and to evict or expire old
rendered cache entries (for example by keeping only the most recent N or using a
TTL). Make sure the cleanup happens before persisting the cache so
`cache.entries` does not grow without bound.
In `@src/context/repoMap/pagerank.ts`:
- Around line 35-42: Update the docstring for runPageRank so it does not claim
focusFiles receive a “100x boost in the personalization vector,” since the
implementation does not use PageRank personalization. Reword it to describe the
actual behavior in pagerank.ts: PageRank runs normally, then focusFiles are
boosted afterward via post-processing in the scoring logic, so readers do not
mistake it for a personalized PageRank run.
- Around line 1-2: The Pagerank helper currently imports the deprecated
unmaintained `graphology-pagerank` package, so update the `pagerank` import in
`src/context/repoMap/pagerank.ts` to the maintained Graphology replacement and
keep the same `alpha`, `maxIterations`, `tolerance`, and `getEdgeWeight` usage.
Verify the `pagerank` function call sites still work with the new package and
adjust any wrapper code in `pagerank.ts` if the export shape differs, using the
existing `Graph` and `pagerank` symbols to locate the integration.
In `@src/context/repoMap/parser.ts`:
- Around line 10-14: The project-root fallback in parser.ts is tied to NODE_ENV
instead of how the module is being executed, so the root path can be computed
incorrectly when running from source. Update the __projectRoot resolution logic
in the parser module to detect the runtime location from import.meta.url or the
current file path (for example, distinguish src execution from the bundled
dist/cli.mjs) rather than relying on NODE_ENV, and keep the existing
__filename-based setup intact.
- Around line 69-87: `initParser` can race when called concurrently because it
only checks `initialized` after entering the async setup, so multiple callers
may run the `import('web-tree-sitter')` and `ParserClass!.init` path at the same
time. Make the initialization re-entrant safe by guarding the in-flight setup in
`initParser` itself, using a shared promise or equivalent lock so concurrent
callers await the same initialization work. Keep the existing `initialized`,
`ParserClass`, and `LanguageLoader` handling, but ensure only one successful
initialization sequence runs before those symbols are used by `loadLanguage` and
`createParser`.
In `@src/context/repoMap/renderer.ts`:
- Around line 27-50: The packing loop in renderer.ts stops too early when a
ranked file would exceed the token budget. In the file iteration that builds
sections from rankedFiles, change the over-budget branch in the render flow so
it skips the current file and keeps evaluating later files instead of
terminating the loop. Keep the existing no-partial-file behavior, but preserve
packing in renderFileSection/countTokens by allowing smaller lower-ranked files
to be added when they fit.
In `@src/context/repoMap/repoMap.test.ts`:
- Around line 202-222: The timing assertion in the repo map cache test is flaky
because it compares wall-clock build durations. In repoMap.test.ts inside the
“second build of unchanged fixture uses the cache” test, remove the buildTimeMs
comparison and keep the cacheHit and map equality checks, which already verify
the behavior through buildRepoMap and its returned result fields.
- Around line 224-265: The current test in repoMap.test.ts is invalidating the
entire cache before the second build, so it never באמת verifies per-file mtime
invalidation. Remove the pre-second-build invalidateCache(tempDir) call in the
modifying-a-file test, then assert behavior in buildRepoMap/getCacheStats that
specifically shows fileE.ts was recomputed while untouched files reused their
per-file cache entries. Keep the existing test setup around FIXTURE_FILES,
buildRepoMap, and invalidateCache only for cleanup so the test matches its name
and inline expectation.
In `@src/context/repoMap/symbolExtractor.ts`:
- Around line 37-108: The symbolExtractor flow is leaking web-tree-sitter
resources because only parser.delete() is called, while the Tree and Query
objects created in symbolExtractor() are never explicitly freed. Update the
try/catch flow to move cleanup into a finally block, ensure the parsed tree is
deleted on both success and error paths, and delete the Query after use as well.
Also cache the compiled Query by language (around the loadLanguage/query
construction path) so it is not rebuilt for every file.
In `@src/tools/RepoMapTool/RepoMapTool.test.ts`:
- Around line 60-144: The RepoMapTool tests currently bypass the public tool API
by calling buildRepoMap directly, so call() behavior is not covered. Update the
RepoMapTool.call-related tests to invoke RepoMapTool.call end-to-end, ideally by
mocking getCwd so the focus_symbols path can be exercised without relying on
complex cwd patching. Make sure the test also covers the surrounding call()
flow, including checkPermissions and mapToolResultToToolResultBlockParam, rather
than only validating buildRepoMap output.
In `@src/tools/RepoMapTool/RepoMapTool.ts`:
- Around line 94-101: RepoMapTool currently has no stable path, so
checkReadPermissionForTool falls back to ask on every request instead of reusing
permission grants. Add a getPath implementation on RepoMapTool that returns a
stable repository path, likely getCwd(), and make sure checkPermissions
continues to use checkReadPermissionForTool with that path so working-directory
and allow-rule decisions can persist.
- Around line 129-157: The focus-symbol resolution in RepoMapTool is doing a
separate repo-wide extractTags pass before buildRepoMap(), which duplicates work
and can re-parse every file. Update the focus_symbols lookup in RepoMapTool.ts
to reuse the existing cached tag flow via getCachedTags/setCachedTags, or
otherwise batch it in the same style as buildRepoMap(), so symbol-to-file
resolution does not trigger an extra full repository scan.
In `@src/tools/RepoMapTool/UI.tsx`:
- Around line 11-18: The local Output type in UI.tsx duplicates the
schema-inferred shape from RepoMapTool.ts and can drift out of sync; replace the
manual type with the exported inferred type from RepoMapTool.ts and update the
UI component to import and use that shared Output definition instead of
redefining it here.
---
Outside diff comments:
In `@src/commands/repomap/repomap.test.ts`:
- Around line 1-57: Add tests for the repomap command handler itself, not just
parseArgs: cover the call() branches for default, --stats, and --invalidate so
the formatting and getCwd/buildRepoMap wiring are exercised. Use the existing
parseArgs and call symbols in repomap.ts to locate the command entrypoint, and
assert the expected output/side effects for each mode.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 72fe41d8-2d4b-4721-9e31-d1aee0ce6936
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (38)
.gitattributesREADME.mddocs/repo-map.mdpackage.jsonscripts/build.tsscripts/externals.tssrc/commands.tssrc/commands/repomap/index.tssrc/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/__fixtures__/mini-repo/fileA.tssrc/context/repoMap/__fixtures__/mini-repo/fileB.tssrc/context/repoMap/__fixtures__/mini-repo/fileC.tssrc/context/repoMap/__fixtures__/mini-repo/fileD.tssrc/context/repoMap/__fixtures__/mini-repo/fileE.tssrc/context/repoMap/cache.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/graph.tssrc/context/repoMap/index.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/parser.tssrc/context/repoMap/queries.test.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/javascript-tags.scmsrc/context/repoMap/queries/python-tags.scmsrc/context/repoMap/queries/typescript-tags.scmsrc/context/repoMap/renderer.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/tokenize.tssrc/context/repoMap/types.tssrc/tools.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/tools/RepoMapTool/UI.tsxsrc/tools/RepoMapTool/prompt.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
##[group]Run bun run check
�[36;1mbun run check�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
$ bun run smoke && bun run deadcode && bun run test:full
$ bun run build && node dist/cli.mjs --version
$ bun run scripts/build.ts
🔇 no-telemetry: stubbed 10 modules
✓ Built openclaude v0.21.0 → dist/cli.mjs
Building SDK bundle...
🔇 no-telemetry: stubbed 10 modules
✓ Built SDK bundle → dist/sdk.mjs
🔄 feature-flags: transformed 193 files during bundling
✓ SDK bundle: no React/Ink leakage detected
Validating external lists...
✓ CLI bundle: All dependencies accounted for (0 missing, 12 external)
✓ SDK bundle: All dependencies accounted for (0 missing, 16 external)
✓ INTENTIONALLY_BUNDLED: All entries still exist in package.json (61 entries)
✓ All external lists valid.
✓ SDK type declarations in sync (62 exports match).
✓ Bundle guard: no unexpected missing-module stubs
0.21.0 (OpenClaude)
$ knip --include files,dependencies
Unused files (5)
src/context/repoMap/__fixtures__/mini-repo/fileA.ts
Configuration hints (8)
src/integrations/generated/** knip.json Remove from ignore
src/test/fixtures/** knip.json Remove from ignore
src/tools/VerifyPlanExecutionTool/** knip.json Remove from ignore
src/commands/agents-platform/** knip.json Remove from ignore
src/assistant/AssistantSessionChooser.tsx knip.json Remove from ignore
src/utils/protectedNamespace.ts knip.json Remove from ignore
src/utils/providerAutoDetect.ts knip.json Remove from ignore
`@types/bun` knip.json Remove from ignoreDependencies
src/context/repoMap/__fixtures__/mini-repo/fileB.ts
src/context/repoMap/__fixtures__/mini-repo/fileC.ts
src/context/repoMap/__fixtures__/mini-repo/fileD.ts
src/context/repoMap/__fixtures__/mini-repo/fileE.ts
Unused dependencies (1)
graphology-operators package.json:109:6
error: script "deadcode" exited with code 1
...
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
##[group]Run bun run check
�[36;1mbun run check�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
$ bun run smoke && bun run deadcode && bun run test:full
$ bun run build && node dist/cli.mjs --version
$ bun run scripts/build.ts
🔇 no-telemetry: stubbed 10 modules
✓ Built openclaude v0.21.0 → dist/cli.mjs
Building SDK bundle...
🔇 no-telemetry: stubbed 10 modules
✓ Built SDK bundle → dist/sdk.mjs
🔄 feature-flags: transformed 193 files during bundling
✓ SDK bundle: no React/Ink leakage detected
Validating external lists...
✓ CLI bundle: All dependencies accounted for (0 missing, 12 external)
✓ SDK bundle: All dependencies accounted for (0 missing, 16 external)
✓ INTENTIONALLY_BUNDLED: All entries still exist in package.json (61 entries)
✓ All external lists valid.
✓ SDK type declarations in sync (62 exports match).
✓ Bundle guard: no unexpected missing-module stubs
0.21.0 (OpenClaude)
$ knip --include files,dependencies
Unused files (5)
src/context/repoMap/__fixtures__/mini-repo/fileA.ts
Configuration hints (8)
src/integrations/generated/** knip.json Remove from ignore
src/test/fixtures/** knip.json Remove from ignore
src/tools/VerifyPlanExecutionTool/** knip.json Remove from ignore
src/commands/agents-platform/** knip.json Remove from ignore
src/assistant/AssistantSessionChooser.tsx knip.json Remove from ignore
src/utils/protectedNamespace.ts knip.json Remove from ignore
src/utils/providerAutoDetect.ts knip.json Remove from ignore
`@types/bun` knip.json Remove from ignoreDependencies
src/context/repoMap/__fixtures__/mini-repo/fileB.ts
src/context/repoMap/__fixtures__/mini-repo/fileC.ts
src/context/repoMap/__fixtures__/mini-repo/fileD.ts
src/context/repoMap/__fixtures__/mini-repo/fileE.ts
Unused dependencies (1)
graphology-operators package.json:109:6
error: script "deadcode" exited with code 1
...
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/context/repoMap/__fixtures__/mini-repo/fileD.tssrc/context/repoMap/__fixtures__/mini-repo/fileE.tssrc/commands/repomap/index.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/queries.test.tssrc/context/repoMap/__fixtures__/mini-repo/fileB.tssrc/context/repoMap/__fixtures__/mini-repo/fileC.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/prompt.tssrc/context/repoMap/tokenize.tssrc/context.repoMap.test.tssrc/tools.tssrc/context/repoMap/queries.tssrc/commands.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/__fixtures__/mini-repo/fileA.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/graph.tssrc/context/repoMap/symbolExtractor.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/renderer.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/parser.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/context/repoMap/__fixtures__/mini-repo/fileD.tssrc/context/repoMap/__fixtures__/mini-repo/fileE.tssrc/commands/repomap/index.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/queries.test.tssrc/context/repoMap/__fixtures__/mini-repo/fileB.tsdocs/repo-map.mdsrc/context/repoMap/__fixtures__/mini-repo/fileC.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/prompt.tssrc/context/repoMap/tokenize.tssrc/context.repoMap.test.tssrc/tools.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/typescript-tags.scmscripts/build.tssrc/commands.tssrc/context/repoMap/queries/python-tags.scmsrc/context/repoMap/pagerank.tsREADME.mdsrc/context/repoMap/__fixtures__/mini-repo/fileA.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/graph.tssrc/context/repoMap/symbolExtractor.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/commands/repomap/repomap.tspackage.jsonsrc/context/repoMap/renderer.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/repoMap.test.tsscripts/externals.tssrc/context/repoMap/queries/javascript-tags.scmsrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/parser.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/context/repoMap/__fixtures__/mini-repo/fileD.tssrc/context/repoMap/__fixtures__/mini-repo/fileE.tssrc/commands/repomap/index.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/queries.test.tssrc/context/repoMap/__fixtures__/mini-repo/fileB.tsdocs/repo-map.mdsrc/context/repoMap/__fixtures__/mini-repo/fileC.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/prompt.tssrc/context/repoMap/tokenize.tssrc/context.repoMap.test.tssrc/tools.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/typescript-tags.scmscripts/build.tssrc/commands.tssrc/context/repoMap/queries/python-tags.scmsrc/context/repoMap/pagerank.tsREADME.mdsrc/context/repoMap/__fixtures__/mini-repo/fileA.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/graph.tssrc/context/repoMap/symbolExtractor.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/commands/repomap/repomap.tspackage.jsonsrc/context/repoMap/renderer.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/repoMap.test.tsscripts/externals.tssrc/context/repoMap/queries/javascript-tags.scmsrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/parser.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.tssrc/context/repoMap/queries.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/repoMap.test.ts
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}
⚙️ CodeRabbit configuration file
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.
Files:
docs/repo-map.mdREADME.md
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/prompt.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/UI.tsxsrc/tools/RepoMapTool/RepoMapTool.ts
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}
⚙️ CodeRabbit configuration file
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}: Review install, launcher, build, packaging, startup, and entrypoint changes for cross-platform compatibility, tracked-source rewrites, env/config precedence, and release safety. Block on changes that can break Windows/macOS/Linux startup or publish unexpected artifacts.
Files:
scripts/build.tspackage.jsonscripts/externals.ts
🪛 ast-grep (0.44.1)
src/context/repoMap/gitFiles.ts
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
src/context/repoMap/cache.ts
[warning] 16-16: Avoid SHA1 security protocol
Context: createHash('sha1')
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm (SHA-1).
(avoid-crypto-sha1-typescript)
[warning] 122-122: Avoid SHA1 security protocol
Context: createHash('sha1')
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm (SHA-1).
(avoid-crypto-sha1-typescript)
[warning] 16-16: Do not use weak hash functions (MD5/SHA1)
Context: createHash('sha1')
Note: [CWE-328] Use of Weak Hash.
(insecure-hash-typescript)
[warning] 122-122: Do not use weak hash functions (MD5/SHA1)
Context: createHash('sha1')
Note: [CWE-328] Use of Weak Hash.
(insecure-hash-typescript)
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/context/repoMap/__fixtures__/mini-repo/fileD.ts
[error] 1-1: knip: Unused file.
src/context/repoMap/__fixtures__/mini-repo/fileE.ts
[error] 1-1: knip: Unused file.
src/context/repoMap/__fixtures__/mini-repo/fileB.ts
[error] 1-1: knip: Unused file.
src/context/repoMap/__fixtures__/mini-repo/fileC.ts
[error] 1-1: knip: Unused file.
src/context/repoMap/__fixtures__/mini-repo/fileA.ts
[error] 1-1: knip: Unused file.
package.json
[error] 109-109: knip: Unused dependency 'graphology-operators' (package.json:109:6).
🪛 markdownlint-cli2 (0.22.1)
docs/repo-map.md
[warning] 45-45: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (28)
src/context/repoMap/__fixtures__/mini-repo/fileB.ts (1)
1-24: Same knip unused-file CI failure asfileA.ts— see comment there for the root cause and suggested fix (knip config, not this file).src/context/repoMap/__fixtures__/mini-repo/fileC.ts (1)
1-23: Same knip unused-file CI failure asfileA.ts— see comment there for the root cause and suggested fix.src/context/repoMap/__fixtures__/mini-repo/fileD.ts (1)
1-10: Same knip unused-file CI failure asfileA.ts— see comment there for the root cause and suggested fix.src/context/repoMap/__fixtures__/mini-repo/fileE.ts (1)
1-26: Same knip unused-file CI failure asfileA.ts— see comment there for the root cause and suggested fix.src/context.ts (2)
34-34: LGTM!
173-179: LGTM!src/context/repoMap/__fixtures__/mini-repo/fileA.ts (1)
1-30: 📐 Maintainability & Code QualityDrop this—
src/context/repoMap/__fixtures__/**is already ignored inknip.json.> Likely an incorrect or invalid review comment.src/tools/RepoMapTool/UI.tsx (1)
20-96: LGTM!src/tools/RepoMapTool/prompt.ts (1)
1-31: LGTM!src/tools.ts (1)
51-51: LGTM!Also applies to: 192-192
src/tools/RepoMapTool/RepoMapTool.test.ts (1)
32-58: LGTM!Also applies to: 146-167
src/commands.ts (1)
30-30: LGTM!Also applies to: 335-335
src/commands/repomap/index.ts (1)
1-18: LGTM!src/context/repoMap/types.ts (1)
1-66: LGTM!scripts/externals.ts (1)
28-34: LGTM!Correct split: WASM-resolving libs (
web-tree-sitter,tree-sitter-wasms) externalized to avoid freezing build-host paths, while pure-JS graph/tokenizer libs are intentionally bundled.Also applies to: 134-139
scripts/build.ts (1)
103-105: LGTM!.gitattributes (1)
62-62: LGTM!src/context/repoMap/tokenize.ts (1)
1-15: LGTM!Matches documented
js-tiktokenusage (getEncoding('cl100k_base')), and the module-level singleton encoder is a reasonable pattern here.src/context/repoMap/renderer.ts (1)
56-72: LGTM!src/context/repoMap/queries/typescript-tags.scm (1)
20-21: 🎯 Functional CorrectnessNo blocker here. The duplicate
interface_declarationcapture only changessubKind, andsubKindisn’t consumed outsidesymbolExtractor.ts, so it doesn’t affect repo-map output.> Likely an incorrect or invalid review comment.src/context/repoMap/parser.ts (2)
39-48: 🎯 Functional Correctness | ⚡ Quick winBare
requirein an ESM module risksReferenceErrorat runtime.This file only uses
import(ESM) elsewhere, butrequire.resolveis called directly at Lines 40 and 58. In a genuine ESM context (e.g. the publisheddist/cli.mjs), Node throwsReferenceError: require is not defined in ES module scopeunless the bundler explicitly injects a shim. Depending on howscripts/build.tsbundles this, the primary resolution branch here could throw on every install, silently falling into the__projectRoot-based fallback (or failing outright if that also breaks — see next comment).Use the standard fix instead:
🔧 Suggested fix
+import { createRequire } from 'module' import { join, resolve } from 'path' import { fileURLToPath } from 'url' ... +const require = createRequire(import.meta.url)As per coding guidelines,
src/**/*.{ts,tsx}should "Use ESM imports in TypeScript source files" — please verify againstbun run build/bun run smokethatrequireactually resolves in the bundleddist/cli.mjsoutput before relying on it.Also applies to: 56-66
Source: Coding guidelines
52-66: 🎯 Functional Correctness | ⚡ Quick win
.tsxfiles are parsed with the plain TypeScript grammar, not the TSX grammar.
gitFiles.tsmaps.tsx→'typescript', and heregetLanguageWasmPath('typescript')always resolvestree-sitter-typescript.wasm.tree-sitter-typescriptships two distinct dialects specifically because TSX and TypeScript are incompatible grammars — TSX requires the separatetsxgrammar/wasm to correctly parse JSX syntax. Since this project itself is React/Ink-heavy (lots of.tsxUI components), running the repo-map's own bootstrap against this repo would likely produce degraded or broken symbol extraction for a large share of its files.🔧 Suggested direction
-const wasmName = language === 'typescript' ? 'tree-sitter-typescript' : - language === 'javascript' ? 'tree-sitter-javascript' : - `tree-sitter-${language}` +const wasmName = language === 'typescript' ? 'tree-sitter-typescript' : + language === 'tsx' ? 'tree-sitter-tsx' : + language === 'javascript' ? 'tree-sitter-javascript' : + `tree-sitter-${language}`(requires adding a distinct
'tsx'SupportedLanguagevariant and mapping.tsxto it ingitFiles.ts, plus a matchingtsx-tags.scm/bundled query)src/context/repoMap/queries.ts (1)
1-183: LGTM!src/context/repoMap/queries.test.ts (1)
1-31: LGTM!src/context/repoMap/gitFiles.ts (1)
1-114: LGTM!src/context/repoMap/queries/javascript-tags.scm (1)
1-93: LGTM!src/context/repoMap/queries/python-tags.scm (1)
1-17: LGTM!src/context/repoMap/cache.ts (1)
150-158: 🩺 Stability & AvailabilityNo change needed here. The codebase already uses lazy
require()in ESM source, so thisfsaccess is not a blocker.> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/context.ts (1)
124-153: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winAvoid caching a failed repo-map build as the session result
src/context.ts:115-153
A timeout or caught error returnsnull, andmemoize()will cache thatnullfor the rest of the process, so one slow cold build disables repo-map for the whole session. Clear the cache on timeout/error, or only memoize successful results.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/context.ts` around lines 124 - 153, The repo-map builder in context.ts is memoized even when buildRepoMap times out or throws, which can cache a null result for the rest of the process. Update the repo-map path around getRepoMapContext/buildRepoMap so only successful results are memoized, or explicitly clear/invalidate the memoized value when the Promise.race times out or the catch block runs. Keep the existing diagnostics logging, but ensure failures do not poison later calls in the same session.src/tools/RepoMapTool/RepoMapTool.ts (1)
137-182: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAvoid the extra cache write here.
RepoMapToolreloads and rewrites the repo-map cache before callingbuildRepoMap(), andloadCache/saveCacheare plain read/overwrite helpers. Because this tool is marked concurrency-safe, overlapping calls can clobber newer tag entries; the fallout is limited to cache effectiveness, but it’s worth reusing the same cache flow or merging on save.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/RepoMapTool/RepoMapTool.ts` around lines 137 - 182, The RepoMapTool symbol-resolution path is performing an extra load-and-save of the repo-map cache that can overwrite newer entries during concurrent runs. Update the focus_symbols handling in RepoMapTool.ts so it reuses the existing cache flow used by buildRepoMap() or merges changes before writing, and avoid calling loadCache/saveCache as a separate plain overwrite cycle from this block. Keep the symbol lookup logic around getRepoFiles, extractTags, and initParser, but ensure cache updates do not clobber concurrent writes.
♻️ Duplicate comments (1)
src/tools/RepoMapTool/RepoMapTool.test.ts (1)
150-174: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
call()still isn't exercised end-to-end.These new tests check
getPath's type and manually construct an output object formapToolResultToToolResultBlockParam, but neither invokesRepoMapTool.call(). Thefocus_symbols→ file resolution path (the code that was flagged for the caching/perf fix) pluscheckPermissionsremain untested at the tool-surface level. Per path instructions for test files, risky runtime changes need focused regression coverage of the changed behavior itself, not just adjacent unit checks.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/RepoMapTool/RepoMapTool.test.ts` around lines 150 - 174, The new tests do not exercise RepoMapTool.call() end-to-end, so the focus_symbols-to-file resolution path and checkPermissions behavior are still unverified at the tool-surface level. Add a focused regression test that invokes RepoMapTool.call() with a representative input, asserts it resolves the expected repo map output, and covers the caching/perf path plus permission gating through the call flow rather than only checking getPath and mapToolResultToToolResultBlockParam directly.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Line 251: Update the README summary for the repo map feature to mention both
opt-in paths: the compile-time REPO_MAP flag and the runtime REPO_MAP
environment variable handled in src/context.ts. Keep the wording concise but
make it clear that codebase intelligence can be auto-injected when either the
build-time flag is enabled or the launch-time env var turns it on, so readers
don’t miss the runtime path.
In `@src/commands/repomap/repomap.ts`:
- Around line 62-101: The new error-handling paths in call() for repomap are
untested, especially the try/catch branches around invalidateCache,
buildRepoMap, and renderError. Add focused regression tests in repomap.test.ts
that exercise the user-visible behavior for both the stats/invalidate flow and
the normal build flow, including a failure case that verifies renderError is
returned with the expected message when buildRepoMap throws.
- Around line 62-101: The `buildRepoMap` success formatting is duplicated in
both the cache-invalidation branch and the normal rebuild branch in `repomap`’s
command handler. Extract the shared `type: 'text'` response construction into a
small helper (for example, a formatter used by both `invalidateCache(root)` and
the plain `buildRepoMap` path) so the summary line and appended map stay
consistent in one place. Keep the existing `renderError` handling unchanged.
- Around line 62-81: The current try/catch in repomap’s cache rebuild flow makes
every failure look like rebuild-only failure, even when invalidateCache(root) is
the step that throws. Split the invalidateCache(root) call from the
buildRepoMap(...) call or otherwise branch the catch handling so the error
message from renderError accurately reflects whether cache invalidation failed
or the repository map rebuild failed. Use the invalidateCache and buildRepoMap
symbols in the control flow to keep the messages specific.
In `@src/context/repoMap/graph.ts`:
- Line 16: Add a regression test in repoMap.test.ts for the
MAX_DEFINITION_FANOUT cap used by graph.ts: cover the case where a single symbol
is defined in more than 100 files and verify that edge creation is skipped. Use
the repoMap/graph behavior around the fan-out limit to construct the fixture and
assert the resulting graph does not include those edges when the threshold is
exceeded.
In `@src/context/repoMap/parser.ts`:
- Around line 8-10: The source-root detection in the `__projectRoot`
initialization uses a hardcoded slash-based
`__filename.includes('/src/context/repoMap/')`, which breaks on Windows path
separators. Update this check in `parser.ts` to use an OS-agnostic path
comparison so the `__projectRoot` branch is chosen correctly across platforms.
Use the existing `__projectRoot` logic as the place to fix the source/bundled
distinction.
In `@src/tools/RepoMapTool/RepoMapTool.test.ts`:
- Around line 150-153: The current RepoMapTool.getPath test only checks that the
hook exists as a function, which does not validate the security-sensitive path
decision behavior. Update the test in RepoMapTool.test.ts to call
RepoMapTool.getPath and assert the returned value is the expected stable path
(for example, matching getCwd() or the tool’s known working directory), so the
test verifies the actual hook output rather than just its type.
---
Outside diff comments:
In `@src/context.ts`:
- Around line 124-153: The repo-map builder in context.ts is memoized even when
buildRepoMap times out or throws, which can cache a null result for the rest of
the process. Update the repo-map path around getRepoMapContext/buildRepoMap so
only successful results are memoized, or explicitly clear/invalidate the
memoized value when the Promise.race times out or the catch block runs. Keep the
existing diagnostics logging, but ensure failures do not poison later calls in
the same session.
In `@src/tools/RepoMapTool/RepoMapTool.ts`:
- Around line 137-182: The RepoMapTool symbol-resolution path is performing an
extra load-and-save of the repo-map cache that can overwrite newer entries
during concurrent runs. Update the focus_symbols handling in RepoMapTool.ts so
it reuses the existing cache flow used by buildRepoMap() or merges changes
before writing, and avoid calling loadCache/saveCache as a separate plain
overwrite cycle from this block. Keep the symbol lookup logic around
getRepoFiles, extractTags, and initParser, but ensure cache updates do not
clobber concurrent writes.
---
Duplicate comments:
In `@src/tools/RepoMapTool/RepoMapTool.test.ts`:
- Around line 150-174: The new tests do not exercise RepoMapTool.call()
end-to-end, so the focus_symbols-to-file resolution path and checkPermissions
behavior are still unverified at the tool-surface level. Add a focused
regression test that invokes RepoMapTool.call() with a representative input,
asserts it resolves the expected repo map output, and covers the caching/perf
path plus permission gating through the call flow rather than only checking
getPath and mapToolResultToToolResultBlockParam directly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d1cad268-4ace-467e-a231-35ca56cec3a2
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
README.mddocs/repo-map.mdpackage.jsonsrc/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/cache.tssrc/context/repoMap/graph.tssrc/context/repoMap/index.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/parser.tssrc/context/repoMap/renderer.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/tools/RepoMapTool/UI.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
d structured Bash JSON in streaming responses [2.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [1.00ms]
(pass) repairs truncated JSON objects even without command field [1.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [2.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [1.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [1.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [2.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [2.00ms]
(pass) strips credentials and query params from URL in fetch network error message [1.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-co...
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
autoCompactIfNeeded circuit breaker > trips after three non-user failures and records a retry time [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > active cooldown skips compaction attempts [5.00ms]
(pass) autoCompactIfNeeded circuit breaker > expired cooldown allows a half-open compaction attempt [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > half-open failure immediately re-trips instead of growing unbounded [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > failed compaction cooldown starts at failure time, not attempt start [1.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort does not increment failures or trip cooldown [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort during half-open retry clears expired cooldown without retripping [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > below-threshold conversations clear stale breaker state [2.00ms]
##[endgroup]
##[group]src/services/compact/snipCompact.test.ts:
(pass) isSnipRuntimeEnabled > returns true
(pass) SNIP_NUDGE_TEXT > is a non-empty string mentioning snip
(pass) snipCompactIfNeeded > no-ops when nothing is pending [1.00ms]
(pass) snipCompactIfNeeded > removes a message whose short ID was marked for snip
(pass) snipCompactIfNeeded > returns a boundary message with snipMetadata.removedUuids
(pass) snipCompactIfNeeded > clears pending set after execution so second call is a no-op
(pass) snipCompactIfNeeded > also removes tool-result messages for snipped assistant tool calls [1.00ms]
(pass) snipCompactIfNeeded > records paired tool-result UUIDs in removedUuids so replay drops the same set
(pass) snipCompactIfNeeded > snipping a tool-result user message also drops the paired assistant tool-use
(pass) snipCompactIfNeeded > does not drop a mixed-content assistant turn (text + tool_use) when only its result is snipped
(pass) snipCompactIfNeeded > does not snip a tool result when its paired assistant tool_use would survive [1.00ms]
(pass) snip...
🧰 Additional context used
📓 Path-based instructions (7)
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
README.mdsrc/commands/repomap/repomap.test.tsdocs/repo-map.mdpackage.jsonsrc/context.repoMap.test.tssrc/context/repoMap/renderer.tssrc/commands/repomap/repomap.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/graph.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/parser.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
README.mdsrc/commands/repomap/repomap.test.tsdocs/repo-map.mdpackage.jsonsrc/context.repoMap.test.tssrc/context/repoMap/renderer.tssrc/commands/repomap/repomap.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/graph.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/parser.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.ts
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}
⚙️ CodeRabbit configuration file
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.
Files:
README.mddocs/repo-map.md
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/context/repoMap/renderer.tssrc/commands/repomap/repomap.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/graph.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/UI.tsxsrc/context/repoMap/parser.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/repoMap.test.ts
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}
⚙️ CodeRabbit configuration file
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}: Review install, launcher, build, packaging, startup, and entrypoint changes for cross-platform compatibility, tracked-source rewrites, env/config precedence, and release safety. Block on changes that can break Windows/macOS/Linux startup or publish unexpected artifacts.
Files:
package.json
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/UI.tsxsrc/tools/RepoMapTool/RepoMapTool.ts
🔇 Additional comments (19)
docs/repo-map.md (1)
1-68: LGTM!src/context.repoMap.test.ts (2)
82-89: 📐 Maintainability & Code Quality | 💤 Low valueStill a text-based check, not the parsed config value.
Regex-matching
scripts/build.tssource text is more forgiving thantoContain, but this is still asserting against raw file text rather than the parsed/evaluated build config, per the earlier feedback on this test.
3-23: 🎯 Functional CorrectnessRemove the
bun:bundleshim concern.feature('REPO_MAP')is available under Bun tests, sogetRepoMapContext()doesn’t reject here; the remaining source-text assertion is just a test-style nit.> Likely an incorrect or invalid review comment.src/commands/repomap/repomap.ts (2)
42-50: 🩺 Stability & Availability | ⚡ Quick winImport and
getCacheStatsare still unguarded.The try/catch was added around the rebuild calls, but the lazy
import(...)(lines 43-47) andgetCacheStats(root)(line 50) can still throw uncaught, surfacing a raw stack trace to the user instead of a friendly message — this was the original ask in the prior review.🛡️ Proposed fix
- const { - buildRepoMap, - invalidateCache, - getCacheStats, - } = await import('../../context/repoMap/index.js') + let buildRepoMap, invalidateCache, getCacheStats + try { + ;({ buildRepoMap, invalidateCache, getCacheStats } = await import( + '../../context/repoMap/index.js' + )) + } catch (err) { + return renderError('Failed to load repo map module', err) + } if (stats) { - const cacheStats = getCacheStats(root) - const lines = [...] - return { type: 'text', value: lines.join('\n') } + try { + const cacheStats = getCacheStats(root) + const lines = [...] + return { type: 'text', value: lines.join('\n') } + } catch (err) { + return renderError('Failed to read repository map cache stats', err) + } }
1-36: 🎯 Functional Correctness | ⚡ Quick winToken default (2048) vs docs (1024) still unresolved.
Prior review flagged that README/
docs/repo-map.mdstate 1024 tokens as default whileparseArgsdefaults to 2048 (confirmed byrepomap.test.ts). This line range is unchanged in the current diff, so the discrepancy persists.src/context.ts (1)
167-176: LGTM! Correctly resolves the prior "not actually parallel" finding.
gitStatusPromiseis now started beforePromise.allawaits both promises, sogitStatusandrepoMapgenuinely run concurrently.src/commands/repomap/repomap.test.ts (1)
1-56: LGTM!src/tools/RepoMapTool/RepoMapTool.ts (1)
96-98:getPathfix confirmed.Resolves the earlier finding that
checkReadPermissionForToolfell back toaskon every call since there was no stable path.src/tools/RepoMapTool/UI.tsx (1)
10-10: LGTM! Resolves the earlier duplicateOutputtype finding by importing fromRepoMapTool.ts.src/context/repoMap/types.ts (1)
53-69: LGTM!package.json (1)
108-115: LGTM!Also applies to: 133-138
src/context/repoMap/parser.ts (1)
28-28: LGTM! Single-flightinitPromiseguard correctly resolves the previously-flagged re-entrancy concern, andclearParserCachesconsistently resets it.Also applies to: 66-90, 151-158
src/context/repoMap/symbolExtractor.ts (1)
7-44: LGTM! This resolves the previously-flagged Tree/Query leak: the tree is deleted infinally, and the query is now compiled once per language and cached/reused rather than rebuilt per file.Also applies to: 69-120
src/context/repoMap/graph.ts (1)
1-16: LGTM!Also applies to: 59-87
src/context/repoMap/pagerank.ts (1)
38-39: LGTM!src/context/repoMap/renderer.ts (1)
42-45: LGTM!src/context/repoMap/cache.ts (1)
1-32: LGTM!Also applies to: 40-53, 66-109, 120-189, 192-224
src/context/repoMap/index.ts (1)
5-12: LGTM!Also applies to: 31-139
src/context/repoMap/repoMap.test.ts (1)
200-247: LGTM!Also applies to: 272-294
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/context/repoMap/symbolExtractor.ts (1)
29-51: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
getQuerycache isn't concurrency-safe — can leakQueryWASM objects.If
extractTagsruns concurrently for files of the same not-yet-cached language, multiple callers race throughgetQuery's check-then-set, each constructing aQuery. Only the last one survives inqueryCache; the others are dropped without.delete(), soclearSymbolExtractorCachesnever frees them. This is the same race class already fixed forinitParserinparser.tsvia a single-flight promise.♻️ Suggested fix: single-flight guard per language
+const queryLoadPromises = new Map<string, Promise<TreeSitterQuery | null>>() + async function getQuery(language: NonNullable<ReturnType<typeof getLanguageForFile>>) { const cached = queryCache.get(language) if (cached) return cached - const querySource = loadQuery(language) - if (!querySource) return null - - const lang = await loadLanguage(language) - if (!lang) return null - - const { Query } = await import('web-tree-sitter') - const query = new Query(lang, querySource) as TreeSitterQuery - queryCache.set(language, query) - return query + const inFlight = queryLoadPromises.get(language) + if (inFlight) return inFlight + + const promise = (async () => { + const querySource = loadQuery(language) + if (!querySource) return null + + const lang = await loadLanguage(language) + if (!lang) return null + + const { Query } = await import('web-tree-sitter') + const query = new Query(lang, querySource) as TreeSitterQuery + queryCache.set(language, query) + return query + })() + queryLoadPromises.set(language, promise) + try { + return await promise + } finally { + queryLoadPromises.delete(language) + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/context/repoMap/symbolExtractor.ts` around lines 29 - 51, The getQuery cache in symbolExtractor.ts is not concurrency-safe, so concurrent callers can each create a separate web-tree-sitter Query and leak the discarded WASM objects. Update getQuery to use a single-flight per language, similar to the initParser pattern in parser.ts, so only one loadQuery/loadLanguage/new Query path runs at a time and all callers share the same in-flight promise. Keep queryCache as the final store and ensure any query that is not retained is properly deleted or never created redundantly.
♻️ Duplicate comments (1)
src/commands/repomap/repomap.ts (1)
71-111: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winError-handling paths (
stats/invalidate/build failures) still lack regression tests.
repomap.test.tsonly covers success cases; none exerciserenderErrorwhenbuildRepoMap/invalidateCachethrow. This is a repeat of prior feedback and still unaddressed.As per path instructions, "Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/commands/repomap/repomap.ts` around lines 71 - 111, The repomap command’s error-handling paths still have no regression coverage, so add focused tests around `repomap`/`renderError` for the `invalidate` and normal build flows when `buildRepoMap` or `invalidateCache` throw. In `repomap.test.ts`, mock those failures and assert the user-visible error response is returned for both paths, while keeping the existing success-case coverage intact.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/tools/RepoMapTool/RepoMapTool.test.ts`:
- Around line 61-73: The RepoMapTool.call() test is not isolated and is
building/caching against the real working directory instead of a temp repo.
Update the call returns the declared output shape test in RepoMapTool.test.ts to
follow the same isolation pattern as the other RepoMapTool tests by running it
from a temporary directory or mocked cwd, and make sure any cache state is
cleaned up afterward with invalidateCache. Use RepoMapTool.call and
invalidateCache as the key symbols to locate and fix this test.
---
Outside diff comments:
In `@src/context/repoMap/symbolExtractor.ts`:
- Around line 29-51: The getQuery cache in symbolExtractor.ts is not
concurrency-safe, so concurrent callers can each create a separate
web-tree-sitter Query and leak the discarded WASM objects. Update getQuery to
use a single-flight per language, similar to the initParser pattern in
parser.ts, so only one loadQuery/loadLanguage/new Query path runs at a time and
all callers share the same in-flight promise. Keep queryCache as the final store
and ensure any query that is not retained is properly deleted or never created
redundantly.
---
Duplicate comments:
In `@src/commands/repomap/repomap.ts`:
- Around line 71-111: The repomap command’s error-handling paths still have no
regression coverage, so add focused tests around `repomap`/`renderError` for the
`invalidate` and normal build flows when `buildRepoMap` or `invalidateCache`
throw. In `repomap.test.ts`, mock those failures and assert the user-visible
error response is returned for both paths, while keeping the existing
success-case coverage intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 58f55bad-2c18-4a9f-b0d1-e834ae42da38
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
package.jsonscripts/externals.tssrc/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.tssrc/context.repoMap.test.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/parser.tssrc/context/repoMap/queries.test.tssrc/context/repoMap/queries.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/RepoMapTool.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
e [4.00ms]
(pass) autoCompactIfNeeded circuit breaker > active cooldown skips compaction attempts [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > expired cooldown allows a half-open compaction attempt [7.00ms]
(pass) autoCompactIfNeeded circuit breaker > half-open failure immediately re-trips instead of growing unbounded [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > failed compaction cooldown starts at failure time, not attempt start [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort does not increment failures or trip cooldown [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort during half-open retry clears expired cooldown without retripping [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > below-threshold conversations clear stale breaker state [7.00ms]
##[endgroup]
##[group]src/services/compact/snipCompact.test.ts:
(pass) isSnipRuntimeEnabled > returns true [3.00ms]
(pass) SNIP_NUDGE_TEXT > is a non-empty string mentioning snip [1.00ms]
(pass) snipCompactIfNeeded > no-ops when nothing is pending
(pass) snipCompactIfNeeded > removes a message whose short ID was marked for snip
(pass) snipCompactIfNeeded > returns a boundary message with snipMetadata.removedUuids
(pass) snipCompactIfNeeded > clears pending set after execution so second call is a no-op
(pass) snipCompactIfNeeded > also removes tool-result messages for snipped assistant tool calls
(pass) snipCompactIfNeeded > records paired tool-result UUIDs in removedUuids so replay drops the same set
(pass) snipCompactIfNeeded > snipping a tool-result user message also drops the paired assistant tool-use
(pass) snipCompactIfNeeded > does not drop a mixed-content assistant turn (text + tool_use) when only its result is snipped [1.00ms]
(pass) snipCompactIfNeeded > does not snip a tool result when its paired assistant tool_use would survive
(pass) snipCompactIfNeeded > pending snips are scoped per conversation by resolved UUID
(pass) snipCompactIf...
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
responses [2.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [2.00ms]
(pass) repairs truncated JSON objects even without command field [2.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [1.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [2.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [2.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [2.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [1.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [2.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [1.00ms]
(pass) strips credentials and query params from URL in fetch network error message [2.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [2.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 failures with...
🧰 Additional context used
📓 Path-based instructions (6)
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
scripts/externals.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/queries.test.tssrc/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tspackage.jsonsrc/context/repoMap/queries.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/types.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/repoMap.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/parser.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
scripts/externals.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/queries.test.tssrc/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tspackage.jsonsrc/context/repoMap/queries.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/types.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/repoMap.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/parser.ts
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}
⚙️ CodeRabbit configuration file
{bin/**,scripts/**,package.json,src/setup.ts,src/main.tsx,src/entrypoints/**}: Review install, launcher, build, packaging, startup, and entrypoint changes for cross-platform compatibility, tracked-source rewrites, env/config precedence, and release safety. Block on changes that can break Windows/macOS/Linux startup or publish unexpected artifacts.
Files:
scripts/externals.tspackage.json
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/context/repoMap/gitFiles.tssrc/context/repoMap/queries.test.tssrc/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/queries.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/types.tssrc/context/repoMap/pagerank.tssrc/context/repoMap/repoMap.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/parser.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/context/repoMap/queries.test.tssrc/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/repoMap.test.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.test.ts
🪛 ast-grep (0.44.1)
src/context/repoMap/gitFiles.ts
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🔇 Additional comments (16)
src/context/repoMap/types.ts (1)
1-78: LGTM!scripts/externals.ts (1)
28-34: LGTM!Externalizing
web-tree-sitter/tree-sitter-wasms(avoiding frozen absolute WASM paths) and bundlinggraphology-metricsinstead of the now-deprecated pagerank package are both sound calls.Also applies to: 134-138
src/context/repoMap/parser.ts (1)
3-8: LGTM!tsx grammar wiring,
createRequireusage, and the cachedloadQuery/createParserpaths look correct.Also applies to: 50-66, 117-133, 135-151
src/context/repoMap/queries.ts (1)
174-183: LGTM!src/context/repoMap/queries.test.ts (1)
27-34: LGTM!Good coverage for the tsx-aliasing behavior and the unknown-language negative case.
src/context/repoMap/gitFiles.ts (1)
8-8: LGTM!Also applies to: 40-47
src/context/repoMap/symbolExtractor.ts (1)
52-127: LGTM!Tag extraction, dedup, and the
tree?.delete?.()/parser.delete()cleanup infinallycorrectly address the prior leak finding.package.json (1)
108-115: 🔒 Security & PrivacyNo
graphology-pagerankdependency remains here.> Likely an incorrect or invalid review comment.src/context/repoMap/pagerank.ts (1)
2-2: LGTM! Confirms the previously flagged unmaintainedgraphology-pagerank→graphology-metrics/centrality/pagerankswap, and the API surface (alpha,maxIterations,tolerance,getEdgeWeight) is compatible per the library's documented options.Also applies to: 52-58
src/context.repoMap.test.ts (2)
82-121: Good fix: AST-based check replaces brittle string match.Parsing
scripts/build.tsvia the TypeScript compiler API instead of matching raw text directly resolves the earlier flakiness concern (fails correctly ifREPO_MAPisn't found or isn'tfalse).
1-81: LGTM! Both previously flagged gaps (tests not exercisinggetRepoMapContext/getSystemContext) are now fixed — the tests call the real functions and assert on their return values.src/commands/repomap/repomap.ts (1)
71-91: 🎯 Functional Correctness | ⚡ Quick winStill misleading if
invalidateCacheitself throws.
invalidateCache(root)andbuildRepoMap(...)share one try/catch, so a failure in invalidation alone is reported as "Cache invalidated, but rebuilding... failed" — implying invalidation succeeded when it may not have.✏️ Proposed fix
if (invalidate) { + try { + invalidateCache(root) + } catch (err) { + return renderError('Failed to invalidate repository map cache', err) + } try { - invalidateCache(root) const result = await buildRepoMap({src/tools/RepoMapTool/RepoMapTool.test.ts (2)
61-73: 📐 Maintainability & Code Quality | ⚡ Quick winGood progress calling
RepoMapTool.call()directly, butfocus_symbolsresolution still untested through the public tool surface.This addresses part of the earlier "tests never call
.call()" feedback, but only exercisesmax_tokens. Thefocus_symbols→ file resolution logic (the specific concern flagged previously) still appears to be tested only via directbuildRepoMapcalls elsewhere in this file, not throughRepoMapTool.call().Source: Path instructions
191-205: LGTM!src/context/repoMap/repoMap.test.ts (1)
6-7: LGTM! The per-file cache verification now directly inspectsgetCachedTags/statFileinstead of relying on a fullinvalidateCache, which properly exercises the fingerprint-based invalidation contract incache.ts. TSX parsing test and cache-cleanup addition also look correct.Also applies to: 25-25, 58-79, 318-331
src/commands/repomap/repomap.test.ts (1)
1-120: LGTM! Tests now callrunRepoMapCommanddirectly (viarunTextCommand), properly isolated with temp dirs and cache invalidation infinally. Missing error-path coverage is a repeat of the gap flagged at the source (repomap.ts), not duplicated here.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/tools/RepoMapTool/RepoMapTool.ts (1)
137-189: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAbort before the repo-map build
The cancellation check only stops symbol resolution;buildRepoMap(...)still runs even afterabortController.signal.aborted. Bail out before that call, or add signal plumbing tobuildRepoMap, so an aborted request doesn’t pay for the full parse/rank/render pass.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/RepoMapTool/RepoMapTool.ts` around lines 137 - 189, The abort check in RepoMapTool’s focus-symbol resolution only stops the search loop, but RepoMapTool.run still calls buildRepoMap afterward even when abortController.signal is already aborted. Add an early return or throw immediately before the buildRepoMap(...) call in RepoMapTool.ts, or pass the abort signal through to buildRepoMap and honor it there, so aborted requests do not continue into the expensive parse/rank/render work.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/tools/RepoMapTool/RepoMapTool.ts`:
- Line 3: The abort handling in RepoMapTool still allows expensive work to
continue after cancellation because focus_symbols only checks
abortController.signal.aborted between batches. Update focus_symbols and the
RepoMapTool buildRepoMap/saveCache flow so it short-circuits immediately when
the signal is aborted, or pass the AbortSignal through to those calls and stop
early before triggering further work.
In `@src/utils/cwd.ts`:
- Around line 8-18: The module-level async_hooks hook in cwd.ts is doing
process-wide init/destroy tracking that AsyncLocalStorage already covers for the
cwd override path. Remove the global createHook(...).enable() usage and the
cwdOverridesByAsyncId cleanup tied to it, and instead rely on the existing ALS
propagation in the cwd override flow. If a non-ALS gap remains, scope the hook
to the specific override window inside the cwd utility rather than keeping it
enabled for the entire process.
---
Outside diff comments:
In `@src/tools/RepoMapTool/RepoMapTool.ts`:
- Around line 137-189: The abort check in RepoMapTool’s focus-symbol resolution
only stops the search loop, but RepoMapTool.run still calls buildRepoMap
afterward even when abortController.signal is already aborted. Add an early
return or throw immediately before the buildRepoMap(...) call in RepoMapTool.ts,
or pass the abort signal through to buildRepoMap and honor it there, so aborted
requests do not continue into the expensive parse/rank/render work.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 280fffdd-85ff-41df-8183-9880184548af
📒 Files selected for processing (10)
README.mdsrc/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/gitFiles.tssrc/context/repoMap/parser.tssrc/context/repoMap/repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/utils/cwd.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
) autoCompactIfNeeded circuit breaker > active cooldown skips compaction attempts [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > expired cooldown allows a half-open compaction attempt [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > half-open failure immediately re-trips instead of growing unbounded [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > failed compaction cooldown starts at failure time, not attempt start [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort does not increment failures or trip cooldown [8.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort during half-open retry clears expired cooldown without retripping [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > below-threshold conversations clear stale breaker state [1.00ms]
##[endgroup]
##[group]src/services/compact/snipCompact.test.ts:
(pass) isSnipRuntimeEnabled > returns true [4.00ms]
(pass) SNIP_NUDGE_TEXT > is a non-empty string mentioning snip
(pass) snipCompactIfNeeded > no-ops when nothing is pending [1.00ms]
(pass) snipCompactIfNeeded > removes a message whose short ID was marked for snip
(pass) snipCompactIfNeeded > returns a boundary message with snipMetadata.removedUuids
(pass) snipCompactIfNeeded > clears pending set after execution so second call is a no-op
(pass) snipCompactIfNeeded > also removes tool-result messages for snipped assistant tool calls [1.00ms]
(pass) snipCompactIfNeeded > records paired tool-result UUIDs in removedUuids so replay drops the same set
(pass) snipCompactIfNeeded > snipping a tool-result user message also drops the paired assistant tool-use
(pass) snipCompactIfNeeded > does not drop a mixed-content assistant turn (text + tool_use) when only its result is snipped
(pass) snipCompactIfNeeded > does not snip a tool result when its paired assistant tool_use would survive
(pass) snipCompactIfNeeded > pending snips are scoped per conversation by resolved UUID
(pass) snipCompactIfNeeded > ignores ...
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
streaming responses [1.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [2.00ms]
(pass) repairs truncated JSON objects even without command field [2.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [1.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [1.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [2.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [2.00ms]
(pass) strips credentials and query params from URL in fetch network error message [1.00ms]
(pass) classifies localhost transport failures with actionable category marker [3.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 fai...
🧰 Additional context used
📓 Path-based instructions (6)
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
README.mdsrc/commands/repomap/repomap.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/parser.tssrc/commands/repomap/repomap.tssrc/context/repoMap/gitFiles.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
README.mdsrc/commands/repomap/repomap.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/parser.tssrc/commands/repomap/repomap.tssrc/context/repoMap/gitFiles.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}
⚙️ CodeRabbit configuration file
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.
Files:
README.md
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/parser.tssrc/commands/repomap/repomap.tssrc/context/repoMap/gitFiles.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/repoMap.test.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.ts
🪛 ast-grep (0.44.1)
src/context/repoMap/gitFiles.ts
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🔇 Additional comments (8)
README.md (1)
251-251: LGTM!src/context/repoMap/parser.ts (1)
12-19: LGTM!src/context/repoMap/gitFiles.ts (1)
53-81: LGTM!src/context/repoMap/cache.ts (1)
56-65: LGTM!src/context/repoMap/repoMap.test.ts (1)
109-152: LGTM!Also applies to: 322-336, 416-438
src/commands/repomap/repomap.ts (1)
47-140: LGTM!Past concerns (default token mismatch, unhandled
buildRepoMap/initParsererrors, misleading invalidate-vs-rebuild error messages, missing regression tests, duplicated result formatting) are all resolved:invalidateCacheandbuildRepoMapnow have separate try/catch blocks with distinctrenderErrormessages, andformatRepoMapResultdeduplicates the success-path formatting.src/commands/repomap/repomap.test.ts (1)
153-219: LGTM!Good coverage of the new error paths — build failure, invalidate-vs-rebuild distinction, stats failure, and lazy-import rejection are all exercised with assertions matching the exact
renderErroroutput.src/tools/RepoMapTool/RepoMapTool.test.ts (1)
48-70: LGTM!The
RepoMapTool.call()path is now exercised end-to-end viacallRepoMapToolInCwd(coveringfocus_symbolsresolution, permissions, and output mapping), and per-test isolation/cleanup (temp dirs +invalidateCache) is consistent throughout. This resolves the prior review's blocking concerns.Also applies to: 100-120, 199-217, 220-230
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/context/repoMap/symbolExtractor.ts (1)
130-138: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueDedup key doesn't include
subKind.
key = ${kind}:${name}:${lineRow}will collide if two different capture kinds (e.g.def/method vsdef/class) on the same line share a name — only the first-seen tag survives, silently dropping the other. Given the current query set this is unlikely in practice, but worth a defensive tweak since it's a one-line change.🛡️ Include subKind in the dedup key
- const key = `${kind}:${name}:${lineRow}` + const key = `${kind}:${subKind}:${name}:${lineRow}`🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/context/repoMap/symbolExtractor.ts` around lines 130 - 138, The deduplication key in symbolExtractor should include subKind in addition to kind, name, and lineRow so distinct captures on the same line do not collide. Update the key generation inside the tag collection logic in symbolExtractor to incorporate subKind, keeping the existing seen set behavior but making it specific enough to preserve both symbols when their kinds differ.src/tools/RepoMapTool/RepoMapTool.ts (1)
154-181: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate batch-extraction/cache logic vs.
buildRepoMap.This 50-item-batch,
getCachedTags/extractTags/setCachedTagsloop mirrors the same pattern inbuildRepoMap(src/context/repoMap/index.ts:31-139). Worth extracting into a shared helper (e.g.,extractTagsWithCache(files, root, cache)) so cache-key/invalidation fixes don't need to land in two places.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tools/RepoMapTool/RepoMapTool.ts` around lines 154 - 181, The batch tag extraction in RepoMapTool duplicates the same cache-aware logic used by buildRepoMap, so consolidate the repeated getCachedTags/extractTags/setCachedTags flow into a shared helper (for example, extractTagsWithCache) and have RepoMapTool use that helper instead of maintaining its own copy. Keep the existing batching, abort checks, and symbol filtering in RepoMapTool, but move the shared cache/invalidation behavior into one place so future fixes only need to be applied once.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/context/repoMap/repoMap.test.ts`:
- Around line 149-174: The concurrent load test in repoMap.test.ts is using a
`.js` fixture that contains TypeScript-only syntax in the generated function
string, so it is not actually validating valid JavaScript parsing. Update the
fixture generation inside the shares concurrent query loads test to emit plain
JS syntax only, while keeping the same concurrent extractTags and Promise.all
flow, so the test remains focused on JS tag extraction behavior and not
tree-sitter error recovery.
In `@src/context/repoMap/symbolExtractor.ts`:
- Around line 52-61: The cleanup in `symbolExtractor` is redundant because the
`catch` block deletes `queryLoadPromises` and rethrows, while the `finally`
block already performs the guarded delete for both success and failure. Remove
the explicit `catch` from this `try`/`finally` flow, keep the `finally` check
against `promise`, and let the rejection propagate naturally from the awaited
`promise`.
---
Outside diff comments:
In `@src/context/repoMap/symbolExtractor.ts`:
- Around line 130-138: The deduplication key in symbolExtractor should include
subKind in addition to kind, name, and lineRow so distinct captures on the same
line do not collide. Update the key generation inside the tag collection logic
in symbolExtractor to incorporate subKind, keeping the existing seen set
behavior but making it specific enough to preserve both symbols when their kinds
differ.
In `@src/tools/RepoMapTool/RepoMapTool.ts`:
- Around line 154-181: The batch tag extraction in RepoMapTool duplicates the
same cache-aware logic used by buildRepoMap, so consolidate the repeated
getCachedTags/extractTags/setCachedTags flow into a shared helper (for example,
extractTagsWithCache) and have RepoMapTool use that helper instead of
maintaining its own copy. Keep the existing batching, abort checks, and symbol
filtering in RepoMapTool, but move the shared cache/invalidation behavior into
one place so future fixes only need to be applied once.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c7942319-56c8-457d-854b-f536a6ab7162
📒 Files selected for processing (8)
src/context/repoMap/queries.tssrc/context/repoMap/queries/javascript-tags.scmsrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/utils/cwd.test.tssrc/utils/cwd.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/utils/cwd.test.tssrc/context/repoMap/queries.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/repoMap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/utils/cwd.test.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/javascript-tags.scmsrc/tools/RepoMapTool/RepoMapTool.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/repoMap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/utils/cwd.test.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/javascript-tags.scmsrc/tools/RepoMapTool/RepoMapTool.test.tssrc/utils/cwd.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/symbolExtractor.tssrc/context/repoMap/repoMap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/utils/cwd.test.tssrc/tools/RepoMapTool/RepoMapTool.test.tssrc/context/repoMap/repoMap.test.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.test.tssrc/tools/RepoMapTool/RepoMapTool.ts
🪛 GitHub Actions: PR Checks / 2_smoke-and-tests.txt
src/utils/cwd.test.ts
[error] 11-11: Test failed: expect(received).toBe(expected) in 'runWithCwdOverride' test. Expected "/tmp/outer-cwd" but received "C:\repo".
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/utils/cwd.test.ts
[error] 11-11: Jest test failed in 'runWithCwdOverride' - expect(received).toBe(expected). Expected: "/tmp/outer-cwd", Received: "C:\repo".
🪛 GitHub Check: smoke-and-tests
src/utils/cwd.test.ts
[failure] 34-34: error:
Expected promise that resolves
Received promise that rejected: Promise { }
at <anonymous> (/home/runner/work/openclaude/openclaude/src/utils/cwd.test.ts:34:57)
[failure] 11-11: error: expect(received).toBe(expected)
Expected: "/tmp/outer-cwd"
Received: "C:\repo"
at <anonymous> (/home/runner/work/openclaude/openclaude/src/utils/cwd.test.ts:11:24)
at run (node:async_hooks:62:22)
at <anonymous> (/home/runner/work/openclaude/openclaude/src/utils/cwd.test.ts:10:5)
🔇 Additional comments (10)
src/context/repoMap/queries/javascript-tags.scm (1)
47-47: 🎯 Functional Correctness | ⚡ Quick winSame
function→function_expressionchange here; keep in sync withqueries.ts.This is the canonical source for the mirrored
JAVASCRIPT_TAGSconstant insrc/context/repoMap/queries.ts. The drift-guard test (queries.test.ts) requires the two to stay byte-for-byte identical, so any correction to the grammar node name here must be mirrored there. See the companion comment onqueries.tsfor the verification/test-coverage concern regarding thevariable_declaratorpath (lines 47, 58) — that pattern isn't exercised by the current fixtures/tests, only theassignment_expressionpath (lines 69-70) is.Also applies to: 58-58, 69-74
src/context/repoMap/symbolExtractor.ts (1)
28-62: Past resource-leak issue looks resolved.Query objects are now cached per language via
queryCache(line 46) instead of rebuilt per file, and the parsedtreeis explicitly deleted infinally(line 145/tree?.delete?.()). This addresses the earlier review finding aboutweb-tree-sitterTree/Queryleaks.Also applies to: 144-147
src/context/repoMap/queries.ts (1)
108-108: 🎯 Functional CorrectnessNo change needed here.
function_expressionis the correct node type for anonymous function expressions.> Likely an incorrect or invalid review comment.src/context/repoMap/repoMap.test.ts (2)
82-118: LGTM!
120-147: LGTM!src/tools/RepoMapTool/RepoMapTool.ts (2)
65-133: LGTM! Abort short-circuiting, cached-tag reuse forfocus_symbols, andgetPathall look correctly addressed from prior review rounds.Also applies to: 138-138, 188-206
207-212: LGTM!src/tools/RepoMapTool/RepoMapTool.test.ts (1)
10-10: LGTM! Abort-path test correctly exercisesRepoMapTool.call()end-to-end with proper isolation/cleanup.Also applies to: 219-249
src/utils/cwd.test.ts (1)
9-39: 🩺 Stability & AvailabilityThese tests are currently failing in CI (see root-cause discussion on
src/utils/cwd.ts).Per the pipeline logs, both tests in this file fail on the Windows runner: Line 11's nested-override assertion returns the real cwd instead of the override, and Line 34's concurrent-override
Promise.allrejects. The tests themselves look well-designed (isolation, no leaked global state, concurrent-safety intent) — the failure appears to be in therunWithCwdOverride/getCwdimplementation itself. See the corresponding comment onsrc/utils/cwd.ts(Lines 20-38) for the blocking issue; this file is the evidence that surfaces it and must stay red until that's fixed.Sources: Linters/SAST tools, Pipeline failures
src/utils/cwd.ts (1)
20-38: 🩺 Stability & AvailabilityBlocking: cwd override tests are failing
src/utils/cwd.test.tsfails in both the nested sync override case and the overlapping async override case, sorunWithCwdOverride/getCwd()are still dropping the active override in this environment. This needs follow-up before merge.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/context/repoMap/index.ts`:
- Around line 44-81: The file collection logic in the repo map flow emits cached
hits before uncached misses, which makes the input order to rankFiles() depend
on cache state and causes unstable rendering for tied scores. Update the
aggregation in the get/repo-map tag extraction path so the returned FileTags are
always in the original files order, or add a deterministic secondary sort key in
rankFiles() to break score ties consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0a9537c5-7e31-4bea-b9d3-227db01ef098
📒 Files selected for processing (6)
src/context/repoMap/index.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/symbolExtractor.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/utils/cwd.tssrc/utils/user.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
eaker > expired cooldown allows a half-open compaction attempt [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > half-open failure immediately re-trips instead of growing unbounded [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > failed compaction cooldown starts at failure time, not attempt start [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort does not increment failures or trip cooldown [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort during half-open retry clears expired cooldown without retripping [6.00ms]
(pass) autoCompactIfNeeded circuit breaker > below-threshold conversations clear stale breaker state [3.00ms]
##[endgroup]
##[group]src/services/compact/snipCompact.test.ts:
(pass) isSnipRuntimeEnabled > returns true [4.00ms]
(pass) SNIP_NUDGE_TEXT > is a non-empty string mentioning snip
(pass) snipCompactIfNeeded > no-ops when nothing is pending
(pass) snipCompactIfNeeded > removes a message whose short ID was marked for snip
(pass) snipCompactIfNeeded > returns a boundary message with snipMetadata.removedUuids [1.00ms]
(pass) snipCompactIfNeeded > clears pending set after execution so second call is a no-op
(pass) snipCompactIfNeeded > also removes tool-result messages for snipped assistant tool calls
(pass) snipCompactIfNeeded > records paired tool-result UUIDs in removedUuids so replay drops the same set
(pass) snipCompactIfNeeded > snipping a tool-result user message also drops the paired assistant tool-use
(pass) snipCompactIfNeeded > does not drop a mixed-content assistant turn (text + tool_use) when only its result is snipped
(pass) snipCompactIfNeeded > does not snip a tool result when its paired assistant tool_use would survive [1.00ms]
(pass) snipCompactIfNeeded > pending snips are scoped per conversation by resolved UUID
(pass) snipCompactIfNeeded > ignores short IDs that do not match any message (graceful)
(pass) markForSnip > returns only the UUIDs that resolved against the convers...
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
ured Bash JSON in streaming responses [1.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [1.00ms]
(pass) repairs truncated JSON objects even without command field [2.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [2.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [1.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [2.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [2.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [2.00ms]
(pass) strips credentials and query params from URL in fetch network error message [1.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completion...
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/context/repoMap/index.tssrc/utils/cwd.tssrc/context/repoMap/symbolExtractor.tssrc/utils/user.test.tssrc/context/repoMap/repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/context/repoMap/index.tssrc/utils/cwd.tssrc/context/repoMap/symbolExtractor.tssrc/utils/user.test.tssrc/context/repoMap/repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/context/repoMap/index.tssrc/utils/cwd.tssrc/context/repoMap/symbolExtractor.tssrc/utils/user.test.tssrc/context/repoMap/repoMap.test.tssrc/tools/RepoMapTool/RepoMapTool.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/utils/user.test.tssrc/context/repoMap/repoMap.test.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.ts
🔇 Additional comments (5)
src/context/repoMap/symbolExtractor.ts (1)
102-128: LGTM!src/context/repoMap/repoMap.test.ts (1)
156-156: LGTM!src/tools/RepoMapTool/RepoMapTool.ts (1)
8-188: LGTM!src/utils/cwd.ts (1)
1-5: LGTM!Also applies to: 13-51, 60-81
src/utils/user.test.ts (1)
21-31: LGTM!Also applies to: 44-90, 101-103
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/context.ts (1)
126-146: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winLosing
buildRepoMappromise can produce an unhandled rejection.
Promise.racedoesn't cancelbuildRepoMap(...). If it rejects after the timeout has already resolved the race (function has already returnednull), that rejection is never observed — the enclosingtry/catchhas already exited. On Node's default unhandled-rejection behavior this can crash the process.🛡️ Proposed fix: swallow late rejections independently of the race outcome
const { buildRepoMap } = await import('./context/repoMap/index.js') + const buildPromise = buildRepoMap({ root: getCwd(), maxTokens: 1024 }) + // Prevent an unhandled rejection if this promise loses the race below. + buildPromise.catch(() => {}) const result = await Promise.race([ - buildRepoMap({ root: getCwd(), maxTokens: 1024 }), + buildPromise, new Promise<typeof REPO_MAP_TIMEOUT>(resolve => setTimeout(() => resolve(REPO_MAP_TIMEOUT), REPO_MAP_CONTEXT_TIMEOUT_MS), ), ])🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/context.ts` around lines 126 - 146, Wrap the `buildRepoMap` call in `src/context.ts` so its promise is always observed even if `Promise.race` times out; the current `Promise.race` in the repo map branch can drop a late rejection after `return null`. Update the `buildRepoMap`/`REPO_MAP_TIMEOUT` flow to attach an independent rejection handler (or equivalent catch) to the `buildRepoMap({ root: getCwd(), maxTokens: 1024 })` promise while still keeping the timeout behavior, so any late failure is swallowed or logged instead of becoming an unhandled rejection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/context.ts`:
- Around line 126-146: Wrap the `buildRepoMap` call in `src/context.ts` so its
promise is always observed even if `Promise.race` times out; the current
`Promise.race` in the repo map branch can drop a late rejection after `return
null`. Update the `buildRepoMap`/`REPO_MAP_TIMEOUT` flow to attach an
independent rejection handler (or equivalent catch) to the `buildRepoMap({ root:
getCwd(), maxTokens: 1024 })` promise while still keeping the timeout behavior,
so any late failure is swallowed or logged instead of becoming an unhandled
rejection.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ee93f681-6a61-4c00-bdec-486eaa0e274c
📒 Files selected for processing (8)
src/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/types.tssrc/tools/RepoMapTool/RepoMapTool.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
down allows a half-open compaction attempt [7.00ms]
(pass) autoCompactIfNeeded circuit breaker > half-open failure immediately re-trips instead of growing unbounded [2.00ms]
(pass) autoCompactIfNeeded circuit breaker > failed compaction cooldown starts at failure time, not attempt start [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort does not increment failures or trip cooldown [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > user abort during half-open retry clears expired cooldown without retripping [3.00ms]
(pass) autoCompactIfNeeded circuit breaker > below-threshold conversations clear stale breaker state [5.00ms]
##[endgroup]
##[group]src/services/compact/snipCompact.test.ts:
(pass) isSnipRuntimeEnabled > returns true
(pass) SNIP_NUDGE_TEXT > is a non-empty string mentioning snip [1.00ms]
(pass) snipCompactIfNeeded > no-ops when nothing is pending
(pass) snipCompactIfNeeded > removes a message whose short ID was marked for snip
(pass) snipCompactIfNeeded > returns a boundary message with snipMetadata.removedUuids
(pass) snipCompactIfNeeded > clears pending set after execution so second call is a no-op [1.00ms]
(pass) snipCompactIfNeeded > also removes tool-result messages for snipped assistant tool calls
(pass) snipCompactIfNeeded > records paired tool-result UUIDs in removedUuids so replay drops the same set
(pass) snipCompactIfNeeded > snipping a tool-result user message also drops the paired assistant tool-use
(pass) snipCompactIfNeeded > does not drop a mixed-content assistant turn (text + tool_use) when only its result is snipped
(pass) snipCompactIfNeeded > does not snip a tool result when its paired assistant tool_use would survive
(pass) snipCompactIfNeeded > pending snips are scoped per conversation by resolved UUID
(pass) snipCompactIfNeeded > ignores short IDs that do not match any message (graceful)
(pass) markForSnip > returns only the UUIDs that resolved against the conversation
(pass) markForSnip > a...
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
responses [1.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [1.00ms]
(pass) repairs truncated JSON objects even without command field [2.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [2.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [1.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [2.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [2.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [2.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [2.00ms]
(pass) strips credentials and query params from URL in fetch network error message [1.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 failures with...
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/types.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context/repoMap/repoMap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/commands/repomap/repomap.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/types.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context/repoMap/repoMap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/commands/repomap/repomap.test.tssrc/tools/RepoMapTool/RepoMapTool.tssrc/context/repoMap/types.tssrc/context.repoMap.test.tssrc/context.tssrc/context/repoMap/cache.tssrc/context/repoMap/index.tssrc/context/repoMap/repoMap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.tssrc/context.repoMap.test.tssrc/context/repoMap/repoMap.test.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**
⚙️ CodeRabbit configuration file
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.
Files:
src/tools/RepoMapTool/RepoMapTool.ts
🔇 Additional comments (7)
src/context/repoMap/types.ts (1)
1-82: LGTM!src/context/repoMap/repoMap.test.ts (1)
244-278: LGTM!Also applies to: 369-381, 384-469, 471-563
src/context/repoMap/cache.ts (1)
39-53: LGTM!Also applies to: 71-114, 125-146, 223-231
src/context/repoMap/index.ts (1)
94-178: LGTM!Also applies to: 190-214
src/context.repoMap.test.ts (1)
1-17: LGTM!Also applies to: 75-101
src/tools/RepoMapTool/RepoMapTool.ts (1)
8-8: LGTM!Also applies to: 138-140
src/commands/repomap/repomap.test.ts (1)
6-7: 🎯 Functional CorrectnessNew cwd-override test looks correct.
> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/repomap/repomap.test.ts`:
- Around line 78-82: Add regression coverage for the shell-quote misalignment in
parseArgs by testing an unquoted --focus glob/operator case, such as
parseArgs('--focus src/*.ts --tokens 4096'), and verify both the focus value and
tokens still parse correctly. Update the repomap.test.ts suite alongside the
existing parseArgs quoted-path test so the behavior in parseArgs (and the
underlying repomap.ts handling of non-string shell-quote tokens) is locked in
against future filtering regressions.
In `@src/commands/repomap/repomap.ts`:
- Line 7: Keep shell-quote tokens positional in parseArgs: tryParseShellCommand
can return non-string entries such as glob objects and control operators, so the
current filtering in repomap.ts shifts flag/value pairing and breaks options
like --focus and --tokens. Update parseArgs to preserve token positions while
normalizing tokens, converting glob objects to their pattern value and leaving
placeholders for operators before scanning flags so indices remain aligned.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 84a68a96-123f-43ae-bab4-eb97cdf0716f
📒 Files selected for processing (6)
src/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.tssrc/context/repoMap/graph.tssrc/context/repoMap/queries.tssrc/context/repoMap/queries/typescript-tags.scmsrc/context/repoMap/repoMap.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
eaming responses [1.00ms]
(pass) does not normalize incomplete streamed Bash commands when finish_reason is length [2.00ms]
(pass) repairs truncated JSON objects even without command field [1.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [2.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [1.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [1.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [2.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [1.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [2.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [1.00ms]
(pass) strips credentials and query params from URL in fetch network error message [2.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 failur...
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
snip a tool result when its paired assistant tool_use would survive
(pass) snipCompactIfNeeded > pending snips are scoped per conversation by resolved UUID
(pass) snipCompactIfNeeded > ignores short IDs that do not match any message (graceful)
(pass) markForSnip > returns only the UUIDs that resolved against the conversation
(pass) markForSnip > accepts legacy bracketed id syntax from older contexts [1.00ms]
(pass) markForSnip > accepts snip_id-prefixed metadata syntax
(pass) markForSnip > accepts copied system-reminder metadata syntax
(pass) shouldNudgeForSnips > returns false for an empty message list
(pass) shouldNudgeForSnips > returns false when there is a compact_boundary in recent history
(pass) shouldNudgeForSnips > returns false when there is a snip boundary in recent history
(pass) shouldNudgeForSnips > resets at a previous context-efficiency nudge until enough new content accumulates
(pass) shouldNudgeForSnips > returns true when enough tokens have accumulated since last reset
(pass) shouldNudgeForSnips > respects a custom interval threshold
##[endgroup]
##[group]src/services/compact/compact.test.ts:
(pass) compactConversation provider gate > skips forked-agent cache-sharing for non-Anthropic providers [11.00ms]
(pass) compactConversation provider gate > uses forked-agent cache-sharing for Anthropic providers [2.00ms]
(pass) compactConversation provider gate > uses forked-agent cache-sharing for GitHub Native Anthropic mode [2.00ms]
(pass) compactConversation compactModel override > resolves a compact model alias to full model ID before comparing and sending [6.00ms]
(pass) compactConversation compactModel override > skips cache-sharing and routes streaming compaction to compactModel when it differs from mainLoopModel [2.00ms]
(pass) partialCompactConversation tool-pair-safe boundaries > up_to pivot on a tool_result keeps the dangling result out of the kept side [4.00ms]
(pass) partialCompactConversation tool-pair-safe boundaries ...
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/context/repoMap/queries.tssrc/commands/repomap/repomap.tssrc/context/repoMap/graph.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/repoMap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/context/repoMap/queries.tssrc/context/repoMap/queries/typescript-tags.scmsrc/commands/repomap/repomap.tssrc/context/repoMap/graph.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/repoMap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/context/repoMap/queries.tssrc/context/repoMap/queries/typescript-tags.scmsrc/commands/repomap/repomap.tssrc/context/repoMap/graph.tssrc/commands/repomap/repomap.test.tssrc/context/repoMap/repoMap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.tssrc/context/repoMap/repoMap.test.ts
🔇 Additional comments (6)
src/context/repoMap/queries.ts (2)
177-186: LGTM!
46-55: 🎯 Functional CorrectnessNo JS follow-up needed —
JAVASCRIPT_TAGSalready includes the samelexical_declarationandvariable_declarationcaptures forarrow_function/function_expression, so this change is complete.> Likely an incorrect or invalid review comment.src/context/repoMap/queries/typescript-tags.scm (1)
32-41: LGTM! Matches the bundledTYPESCRIPT_TAGSstring inqueries.ts, and the drift-guard test enforces this stays in sync.src/context/repoMap/graph.ts (1)
71-72: LGTM! These guards correctly reject non-positive/NaN weights (e.g. whendocFreq >= totalFilesmakesMath.lognon-positive), preventing zero/negative-weight edges from reaching PageRank, which typically expects non-negative weights.Also applies to: 80-81
src/context/repoMap/repoMap.test.ts (2)
55-89: LGTM! Good coverage for both extraction (extractTags) and end-to-end rendering (buildRepoMap) of the new arrow/function-expression definition capture.
279-306: 🎯 Functional Correctness | ⚡ Quick winTest doesn't actually verify the zero-weight edge exclusion.
The assertions (
fileCount,mapcontaining file headers) would pass even if zero-weight edges were still being created — they don't inspect graph edges or weights at all.graph.ts's own inline test (viabuildGraph(...).outDegree(...)) is a more direct check; consider asserting onbuildGraph()output here too (e.g., edge weight/count betweena.tsandb.ts) so the test actually fails without thegraph.tsfix.As per path instructions, "Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."
Source: Path instructions
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/repomap/repomap.ts`:
- Around line 49-62: The token normalization in normalizeParsedToken currently
uses unknown plus manual property checks for shell-quote parse results. Update
the function to accept shell-quote’s ParseEntry type instead of unknown, and
adjust the import so TypeScript can narrow the glob case natively. Keep the
existing behavior in normalizeParsedToken and ArgPart handling, but rely on the
library type rather than custom shape probing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: eeb1b017-85d6-48ed-b71f-d70bff768bf8
📒 Files selected for processing (2)
src/commands/repomap/repomap.test.tssrc/commands/repomap/repomap.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
n finish_reason is length [2.00ms]
(pass) repairs truncated JSON objects even without command field [1.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [2.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [1.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [2.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [2.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [3.00ms]
(pass) non-streaming: strips <think> tag block from assistant content
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [2.00ms]
(pass) strips credentials and query params from URL in fetch network error message [1.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 failures with endpoint_not_found marker [2.00ms]
(pass) self-heals localhost resolution failures by retr...
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
ms]
(pass) goal continuation controller > maxBudgetUsd exhaustion still allows maxTurns pause without evaluator spend
(pass) goal continuation controller > pending interactive dialog prevents continuation [1.00ms]
(pass) goal continuation controller > maxTurns pauses without evaluating or continuing
(pass) goal continuation controller > incomplete evaluation that reaches maxTurns does not continue
##[endgroup]
##[group]src/services/goal/evaluator.test.ts:
(pass) goal evaluator > valid complete JSON [1.00ms]
(pass) goal evaluator > valid incomplete JSON
(pass) goal evaluator > malformed JSON retries once [2.00ms]
(pass) goal evaluator > malformed JSON after retry returns fail-closed decision
(pass) goal evaluator > model caller errors return fail-closed decision
(pass) goal evaluator > bounded context size
(pass) goal evaluator > includes visible tool-use summary text in bounded context
(pass) goal evaluator > no tools passed to evaluator
##[endgroup]
##[group]src/services/tools/queryActivityLease.test.ts:
(pass) query activity leases for tools > foreground Bash with explicit timeout gets a bounded lease
(pass) query activity leases for tools > foreground PowerShell with explicit timeout gets a bounded lease
(pass) query activity leases for tools > foreground Bash without explicit timeout uses the safe default timeout
(pass) query activity leases for tools > foreground Bash explicit timeout is clamped to the configured maximum
(pass) query activity leases for tools > foreground Bash invalid timeout values fall back to the safe default
(pass) query activity leases for tools > explicit background shell commands skip foreground query leases
(pass) query activity leases for tools > non-shell tools skip query leases
(pass) query activity leases for tools > non-record tool inputs skip query leases
(pass) query activity leases for tools > successful shell tool execution reports the full query activity lease lifecycle [3.00ms]
(pass) query activi...
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.tssrc/commands/repomap/repomap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/commands/repomap/repomap.tssrc/commands/repomap/repomap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/commands/repomap/repomap.tssrc/commands/repomap/repomap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/commands/repomap/repomap.test.ts
🔇 Additional comments (3)
src/commands/repomap/repomap.ts (2)
9-10: 🎯 Functional CorrectnessShell-quote positional bug fixed.
ArgPart = string | null+normalizeParsedTokennow preserves array positions instead of filtering non-string entries (globs, control operators like&&, comment objects), so--focus/--tokensvalue pairing no longer shifts. Confirmed againstshell-quote'sParseEntryshape (string | {op} | {op:'glob',pattern} | {comment}) — all cases resolve to a string or anullplaceholder correctly. This resolves the previously flagged critical issue about misaligned flag parsing.Also applies to: 19-21, 27-44, 49-62
156-162: LGTM!src/commands/repomap/repomap.test.ts (1)
84-94: LGTM! Good regression coverage locking in the shell-quote positional fix.
f0fef22 to
89cae03
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/context/repoMap/repoMap.test.ts`:
- Around line 559-594: This repo map cache test mutates shared environment state
without synchronization, so it can race with other tests that also alter
config-home resolution. Update the test around getCacheStats and the
process.env.OPENCLAUDE_CONFIG_DIR / CLAUDE_CONFIG_DIR setup to run under the
shared acquireEnvMutex() lock, keeping the existing helper calls like
getClaudeConfigHomeDir and setClaudeConfigHomeDirForTesting inside that
protected block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: f71392c3-a9d9-4c5e-b2b2-223b98b5cd8b
📒 Files selected for processing (3)
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.tssrc/context/repoMap/cache.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/context/repoMap/repoMap.test.ts
🪛 GitHub Actions: PR Checks / 2_smoke-and-tests.txt
src/context/repoMap/repoMap.test.ts
[error] 578-578: Test failed in repoMap.test.ts. expect(received).toBe(expected) failed for stats.cacheDir. Expected: "/tmp/repomap-config-home-Tm1xWv/repomap-cache"; Received: "/tmp/openclaude-paths-test-2gF1JD/.openclaude/repomap-cache".
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/context/repoMap/repoMap.test.ts
[error] 578-578: Jest assertion failed in repoMap.test.ts. expect(stats.cacheDir).toBe(expected) mismatch. Expected: "/tmp/repomap-config-home-Tm1xWv/repomap-cache"; Received: "/tmp/openclaude-paths-test-2gF1JD/.openclaude/repomap-cache".
🪛 GitHub Check: smoke-and-tests
src/context/repoMap/repoMap.test.ts
[failure] 578-578: error: expect(received).toBe(expected)
Expected: "/tmp/repomap-config-home-Tm1xWv/repomap-cache"
Received: "/tmp/openclaude-paths-test-2gF1JD/.openclaude/repomap-cache"
at <anonymous> (/home/runner/work/openclaude/openclaude/src/context/repoMap/repoMap.test.ts:578:30)
🔇 Additional comments (2)
src/commands/repomap/repomap.ts (1)
7-7: LGTM!Also applies to: 50-61
src/context/repoMap/cache.ts (1)
23-30: LGTM!Also applies to: 220-220
89cae03 to
4d4d4ed
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/context/repoMap/repoMap.test.ts (1)
564-594: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winFlaky/failing test: env state not isolated with the shared mutex — currently failing in CI.
Pipeline evidence confirms this test is failing right now:
stats.cacheDirresolved to a path from an unrelated suite (openclaude-paths-test-.../. openclaude/repomap-cache) instead of the expectedrepomap-config-home-.../repomap-cache. This is exactly the race previously flagged: the test mutatesprocess.env.OPENCLAUDE_CONFIG_DIR/CLAUDE_CONFIG_DIRand the memoizedgetClaudeConfigHomeDircache without acquiring the shared env mutex, so it can interleave with other suites (e.g.openclaudePaths.test.ts) that also patch config-home/HOME state.Per path instructions, "Block when risky runtime changes lack focused regression coverage" and treat CI status honestly: this check is currently red, so the PR is not merge-ready from a CI standpoint regardless of code review outcome.
🔧 Suggested fix
test('stores repo map cache under OPENCLAUDE_CONFIG_DIR when configured', () => { + const release = acquireEnvMutex() const previousOpenClaudeConfigDir = process.env.OPENCLAUDE_CONFIG_DIR const previousLegacyConfigDir = process.env.CLAUDE_CONFIG_DIR const previousConfigHomeOverride = getClaudeConfigHomeDirOverrideForTesting() const configDir = mkdtempSync(join(tmpdir(), 'repomap-config-home-')) try { ... } finally { ... rmSync(configDir, { recursive: true, force: true }) + release() } })Please verify the exact mutex helper name/import path (e.g.
acquireEnvMutexfromsrc/entrypoints/sdk/shared.tsor similar) used by other tests that mutate this same global state.#!/bin/bash rg -nP "acquireEnvMutex|releaseEnvMutex" src --type=ts -C2🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/context/repoMap/repoMap.test.ts` around lines 564 - 594, The repo map cache test is mutating shared env/config-home state without isolation, which causes CI flakes with other suites. Wrap the body of the failing test in the same env mutex used by other tests that change process.env or config-home state, and make sure the mutex is released in finally; the likely locations to update are the test around getCacheStats, setClaudeConfigHomeDirForTesting, and the shared helper/import used by openclaudePaths-related tests. Keep the existing cache reset/restore logic, but ensure it runs under the mutex so OPENCLAUDE_CONFIG_DIR, CLAUDE_CONFIG_DIR, and getClaudeConfigHomeDir.cache cannot interleave with concurrent tests.Sources: Path instructions, Pipeline failures
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/context/repoMap/repoMap.test.ts`:
- Around line 564-594: The repo map cache test is mutating shared
env/config-home state without isolation, which causes CI flakes with other
suites. Wrap the body of the failing test in the same env mutex used by other
tests that change process.env or config-home state, and make sure the mutex is
released in finally; the likely locations to update are the test around
getCacheStats, setClaudeConfigHomeDirForTesting, and the shared helper/import
used by openclaudePaths-related tests. Keep the existing cache reset/restore
logic, but ensure it runs under the mutex so OPENCLAUDE_CONFIG_DIR,
CLAUDE_CONFIG_DIR, and getClaudeConfigHomeDir.cache cannot interleave with
concurrent tests.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c9893af5-f020-49d8-814d-aa8a2f97edb5
📒 Files selected for processing (3)
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/context/repoMap/cache.tssrc/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/context/repoMap/cache.tssrc/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/context/repoMap/cache.tssrc/commands/repomap/repomap.tssrc/context/repoMap/repoMap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/context/repoMap/repoMap.test.ts
🪛 GitHub Actions: PR Checks / 0_smoke-and-tests.txt
src/context/repoMap/repoMap.test.ts
[error] 578-578: Jest assertion failed in repoMap.test.ts. expect(received).toBe(expected) failed: Expected "/tmp/repomap-config-home-cIjgdF/repomap-cache" but received "/tmp/openclaude-paths-test-9KNEvF/.openclaude/repomap-cache".
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/context/repoMap/repoMap.test.ts
[error] 578-578: repoMap test failed: expect(received).toBe(expected). Expected cacheDir to be "/tmp/repomap-config-home-cIjgdF/repomap-cache" but received "/tmp/openclaude-paths-test-9KNEvF/.openclaude/repomap-cache".
🪛 GitHub Check: smoke-and-tests
src/context/repoMap/repoMap.test.ts
[failure] 578-578: error: expect(received).toBe(expected)
Expected: "/tmp/repomap-config-home-cIjgdF/repomap-cache"
Received: "/tmp/openclaude-paths-test-9KNEvF/.openclaude/repomap-cache"
at <anonymous> (/home/runner/work/openclaude/openclaude/src/context/repoMap/repoMap.test.ts:578:30)
🔇 Additional comments (3)
src/context/repoMap/repoMap.test.ts (1)
6-16: LGTM!src/context/repoMap/cache.ts (1)
11-11: LGTM!Also applies to: 23-41, 220-220
src/commands/repomap/repomap.ts (1)
7-7: LGTM!Also applies to: 50-61
4d4d4ed to
71972a7
Compare
b4fea6b to
837f246
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/context/repoMap/repoMap.test.ts`:
- Around line 45-62: The helper withWritableConfigHome can leak the shared
mutation lock if mkdtempSync fails before the try/finally starts. Move the
temporary config directory creation inside the protected try block (around
acquireSharedMutationLock, setClaudeConfigHomeDirForTesting, and
releaseSharedMutationLock) so any error still reaches the cleanup path. Keep the
cleanup logic in withWritableConfigHome responsible for restoring the previous
override, clearing getClaudeConfigHomeDir.cache, removing the temp dir, and
always releasing the lock.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 45ed9402-f44d-41b2-89f9-2a45e1a6696d
📒 Files selected for processing (3)
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: add repo map codebase intelligence
Conclusion: failure
oller > maxBudgetUsd exhaustion still allows maxTurns pause without evaluator spend [1.00ms]
(pass) goal continuation controller > pending interactive dialog prevents continuation
(pass) goal continuation controller > maxTurns pauses without evaluating or continuing
(pass) goal continuation controller > incomplete evaluation that reaches maxTurns does not continue [1.00ms]
##[endgroup]
##[group]src/services/goal/evaluator.test.ts:
(pass) goal evaluator > valid complete JSON
(pass) goal evaluator > valid incomplete JSON [1.00ms]
(pass) goal evaluator > malformed JSON retries once
(pass) goal evaluator > malformed JSON after retry returns fail-closed decision
(pass) goal evaluator > model caller errors return fail-closed decision
(pass) goal evaluator > bounded context size [1.00ms]
(pass) goal evaluator > includes visible tool-use summary text in bounded context
(pass) goal evaluator > no tools passed to evaluator
##[endgroup]
##[group]src/services/tools/queryActivityLease.test.ts:
(pass) query activity leases for tools > foreground Bash with explicit timeout gets a bounded lease
(pass) query activity leases for tools > foreground PowerShell with explicit timeout gets a bounded lease
(pass) query activity leases for tools > foreground Bash without explicit timeout uses the safe default timeout
(pass) query activity leases for tools > foreground Bash explicit timeout is clamped to the configured maximum
(pass) query activity leases for tools > foreground Bash invalid timeout values fall back to the safe default
(pass) query activity leases for tools > explicit background shell commands skip foreground query leases
(pass) query activity leases for tools > non-shell tools skip query leases
(pass) query activity leases for tools > non-record tool inputs skip query leases [1.00ms]
(pass) query activity leases for tools > successful shell tool execution reports the full query activity lease lifecycle [2.00ms]
(pass) query activity leases for too...
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: add repo map codebase intelligence
Conclusion: failure
incomplete streamed Bash commands when finish_reason is length [1.00ms]
(pass) repairs truncated JSON objects even without command field [2.00ms]
(pass) preserves raw input for unknown plain string tool arguments [1.00ms]
(pass) preserves parsed string input for unknown JSON string tool arguments [1.00ms]
(pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [2.00ms]
(pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
(pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
(pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [1.00ms]
(pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
(pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
(pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
(pass) non-streaming: preserves response body when usage parsing fails [2.00ms]
(pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
(pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
(pass) streaming: thinking block closed before tool call [1.00ms]
(pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
(pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
(pass) streaming: preserves prose without tags (no phrase-based false positive) [1.00ms]
(pass) strips credentials and query params from URL in fetch network error message [2.00ms]
(pass) classifies localhost transport failures with actionable category marker [2.00ms]
(pass) transport failures are not labeled with HTTP status 503 [1.00ms]
(pass) propagates AbortError without wrapping it as transport failure [1.00ms]
(pass) classifies chat-completions endpoint 404 failures with endpoint_not_found marker [2.00ms]
(pass) se...
🧰 Additional context used
📓 Path-based instructions (4)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Use TypeScript with strict mode
Use ESM imports in TypeScript source files
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.src/integrations/- provider and model integration metadata.src/entrypoints/- CLI, MCP, SDK, and generated public types.src/tasks/- local, remote, workflow, and monitor tas...
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/commands/repomap/repomap.tssrc/context/repoMap/cache.tssrc/context/repoMap/repoMap.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/context/repoMap/repoMap.test.ts
🔇 Additional comments (3)
src/context/repoMap/cache.ts (1)
11-41: LGTM!Also applies to: 220-220
src/context/repoMap/repoMap.test.ts (1)
2-20: LGTM!Also applies to: 39-43, 588-633, 635-654, 656-709
src/commands/repomap/repomap.ts (1)
7-7: LGTM!Also applies to: 50-61
837f246 to
058cb04
Compare
- Add explicit 10000ms timeout to the feature-flag-off context test to avoid cold-import flakes. - Add --focus-symbols flag to /repomap and forward it to buildRepoMap, matching the RepoMap tool. - Add parsing/command tests and docs coverage for --focus-symbols.
…cherry-pick Cluster E (Twigpine#1784 zero-warning install) cherry-pick added a `scripts/externalsValidation.ts` post-build check that requires all OPTIONAL_RUNTIME_EXTERNALS to be explicit devDependencies. Several entries that OpenCC's 3-provider scope (anthropic/ollama/openai-compatible) does not need at runtime were still listed: - Removed from `src/utils/proxy.ts`: `getAWSClientProxyConfig()` function + AWS SDK dynamic imports. The function was added by upstream Twigpine#1784 but never called from OpenCC source (verified `grep -rn 'getAWSClientProxyConfig' src/`). The unused `importOptionalRuntimeModule` import was also removed. - Removed from `scripts/externals.ts` (COMMON_EXTERNALS + OPTIONAL_RUNTIME_EXTERNALS): `@aws-sdk/client-bedrock`, `@aws-sdk/client-bedrock-runtime`, `@aws-sdk/client-sts`, `@aws-sdk/credential-provider-node`, `@aws-sdk/credential-providers`, `@smithy/core`, `@smithy/node-http-handler`, `@azure/identity`. These were added by Twigpine#1784 for AWS proxy / Bedrock / Vertex support that OpenCC does not use. - Removed from `INTENTIONALLY_BUNDLED`: `graphology`, `graphology-metrics`, `js-tiktoken`. These are for upstream's Twigpine#1867 repo-map feature (Tier 3, not ported to OpenCC) and were never imported in `src/`. - Added explicit `devDependencies`: `@anthropic-ai/bedrock-sdk`, `@anthropic-ai/foundry-sdk`, `google-auth-library`. These are still referenced from the optional-runtime-module tests + the Vertex auth path in `src/utils/auth.ts` (transitive deps already installed but not declared; required by the new externals validator). After this commit `bun run build` passes the post-build externals validation (55 bundled packages, all devDependencies-only). `bun run dev` reaches the CLI launch step and only fails with "Input must be provided" when run without stdin or --print args, which is expected CLI behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Adds repo-map codebase intelligence to OpenClaude and refreshes/supersedes #966 on current
main.The feature builds a structural repository map by parsing supported source files with tree-sitter, extracting definitions/references, ranking files with an IDF-weighted graph + PageRank, and rendering a token-budgeted summary. It is available on demand through the
RepoMaptool and/repomapcommand, with optional auto-injection behindREPO_MAP=1.User-facing surface
RepoMaptool withmax_tokens,focus_files, andfocus_symbols./repomapcommand with--tokens,--focus,--stats, and--invalidate.REPO_MAP=1.docs/repo-map.mdand README command coverage.Implementation notes
.scmsource files remain in the repo with a drift-guard test.getPath()hook so read permission grants forRepoMapcan persist correctly.graphology-metricspackage.What changed from #966
main.maincommand registrations, lockfile state, and build externals.I also checked for duplication against current
main: there is still no existingRepoMaptool,/repomapcommand,src/context/repoMap/implementation, or repo-map docs onmain. The merged LSP code-intelligence work is adjacent but does not duplicate this feature.Validation
bun install --frozen-lockfile- passbun test src/context/repoMap/repoMap.test.ts src/context/repoMap/queries.test.ts src/tools/RepoMapTool/RepoMapTool.test.ts src/commands/repomap/repomap.test.ts src/context.repoMap.test.ts- 47 pass / 0 failbun run typecheck- passbun run deadcode- passbun run smoke- passbun run check- pass, 5779 pass / 2 skip / 0 failbun run security:pr-scan -- --base origin/main --head HEAD- passgit diff --check- passSupersedes #966.
Summary by CodeRabbit
/repomapcommand with--tokens(default 2048; 256–16384),--focusand--focus-symbols, plus--statsand--invalidaterebuild controls.