feat: ship context-plane tooling surface#58
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore the at-least-one-node behavior in compileContextPack so review packs do not become empty when the first candidate exceeds budget. Add a focused regression test covering the over-budget first review node case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep raw full-prompt token counts distinct from effective session-aware counts in compare reports, and add regression coverage for follow-up delta prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore the pre-Task 6 vite version and remove the unrelated package metadata assertions so the Task 6 surface stays focused on docs/proof framing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add get_neighbors to the full-profile README tool list and assert the README stays aligned with the shipped MCP surface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR introduces a comprehensive "context plane" and "context compiler" system. It adds contract types for context packs and sessions, implements compilation and session state management, refactors retrieval/impact/compare to attach evidence metadata, builds a structured prompt system with cache reuse, and extends MCP with new context-aware tools. The CLI gains ChangesContext Plane & Compiler Implementation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (7)
tests/unit/stdio-tool-profile.test.ts (1)
215-235: ⚡ Quick winExercise the
tools/callgate for all three full-only context tools.This only proves
context_packis blocked in the core profile. Ifcontext_promptorcontext_session_resetend up mis-registered,tools/listwould still pass while invocation stays incorrectly reachable. A small parameterized assertion over all three names would close that gap.🤖 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 `@tests/unit/stdio-tool-profile.test.ts` around lines 215 - 235, The test only checks that 'context_pack' is blocked; update the spec in the it block to iterate over all three full-only tool names (context_pack, context_prompt, context_session_reset) and for each call handleStdioRequest (using withProfile('core', ...)) assert the response.error has code -32601 and that the message contains the tool name and 'GRAPHIFY_TOOL_PROFILE=full'; locate the current test that calls handleStdioRequest and replace the single-name assertion with a small loop/parameterized map over the three names so each is exercised the same way.tests/unit/context-pack-command.test.ts (1)
164-246: ⚡ Quick winMake the impact-target test prove the selection logic.
The fixture only returns one matched node, so this currently validates the happy path, not “highest-signal” selection. Add at least one lower-signal candidate and assert
analyzeImpact()still receivesAuthService; otherwise a first-match/last-match regression would slip through.🤖 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 `@tests/unit/context-pack-command.test.ts` around lines 164 - 246, The test currently only returns one matched node so it doesn't verify “highest-signal” selection; update the retrieveContext mock (the object returned by dependencies.retrieveContext in this test) to include at least one additional matched_nodes entry with a lower signal (e.g., lower match_score and/or less favorable relevance_band, label like 'OtherService'), then keep the existing expectation that analyzeImpact is called with { label: 'AuthService', depth: 3 } and the same output assertion to prove the highest-signal node ('AuthService') is chosen by runContextPackCommand.tests/unit/retrieve.test.ts (1)
2718-2731: ⚡ Quick winAlso lock down
expandablein the stdio compaction test.This helper now carries truncated-evidence hints, but the new assertion only preserves
claimsandcoverage. IfcompactRetrieveResultForStdio()starts droppingexpandable, MCP clients would silently lose the “fetch more context” signal without this test catching it.🤖 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 `@tests/unit/retrieve.test.ts` around lines 2718 - 2731, The stdio compaction test omits asserting the expandable field, so add an assertion that compactRetrieveResultForStdio preserves the expandable signal: after computing compactResult in the test (it 'strips evidence_class from compact stdio retrieve payloads'), assert that compactResult.expandable equals rawResult.expandable (or that compactResult has the expandable property and its value matches rawResult.expandable) so the test will fail if compactRetrieveResultForStdio starts dropping expandable.tests/unit/context-prompt.test.ts (1)
75-75: ⚡ Quick winMake the invalidation assertion formatting-tolerant.
This assertion is tied to exact JSON whitespace, so harmless serialization formatting changes can break the test without behavior regressions.
Suggested test tweak
- expect(followUp.session_payload).toContain('"invalidated": [\n "beta"\n ]') + expect(followUp.session_payload).toMatch(/"invalidated":\s*\[\s*"beta"\s*\]/)🤖 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 `@tests/unit/context-prompt.test.ts` at line 75, The assertion is brittle because it depends on exact JSON whitespace; instead parse the JSON from followUp.session_payload and assert the invalidated array contains "beta". Locate the test that uses followUp.session_payload and replace the string-contains check with JSON.parse(followUp.session_payload) and an assertion like parsed.invalidated.includes('beta') (or the test framework equivalent, e.g., expect(parsed.invalidated).toContain('beta')) to make the check formatting-tolerant.tests/unit/review-compare.test.ts (1)
173-181: ⚡ Quick winAvoid source-string coupling in this unit test.
This test enforces internal implementation details via string matching, which is fragile against harmless refactors. Prefer asserting behavior/output contracts 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 `@tests/unit/review-compare.test.ts` around lines 173 - 181, The unit test is brittle because it inspects source strings of generateReviewCompareArtifacts; instead, update the test to assert behavior by importing generateReviewCompareArtifacts and the shared helper renderReviewPrompt (or mocking/spying on it) and verifying that calling generateReviewCompareArtifacts results in invoking renderReviewPrompt and/or produces the expected output contract, rather than searching for 'renderReviewPrompt(' or 'buildContextPrompt(' in the file text; replace the readFileSync/string matching logic with a behavioral assertion using the function generateReviewCompareArtifacts and a spy/mock on renderReviewPrompt.src/infrastructure/context-prompt.ts (1)
45-47: 💤 Low valueConsider documenting the reserved ref prefix.
The
__stable_prefix:prefix for internal refs (instructions, title) could theoretically collide with user-provided section refs. Consider adding a brief comment noting this is a reserved namespace, or validating user refs don't use this prefix.🤖 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/infrastructure/context-prompt.ts` around lines 45 - 47, Document that "__stable_prefix:" is a reserved namespace and prevent collisions by either adding a clear inline comment next to STABLE_PREFIX_INSTRUCTIONS_REF and STABLE_PREFIX_TITLE_REF stating they are internal/reserved, and/or add validation where user section refs are accepted (e.g., in the function that processes user refs) to reject or escape refs that start with "__stable_prefix:". Update symbols STABLE_PREFIX_INSTRUCTIONS_REF and STABLE_PREFIX_TITLE_REF and the user-ref validation logic so any user-provided ref beginning with that prefix triggers an error or is normalized.src/runtime/stdio/tools.ts (1)
428-429: 💤 Low valueInconsistent indentation.
Lines 428-429 have extra leading spaces compared to the surrounding code in the same object literal.
🔧 Suggested fix
...(retrieveCommunity !== null ? { community: retrieveCommunity } : {}), - ...(retrieveFileType ? { fileType: retrieveFileType } : {}), - })) + ...(retrieveFileType ? { fileType: retrieveFileType } : {}), + }))🤖 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/runtime/stdio/tools.ts` around lines 428 - 429, The object spread line with ...(retrieveFileType ? { fileType: retrieveFileType } : {}) inside the object literal in src/runtime/stdio/tools.ts is indented inconsistently; fix it by aligning the leading spaces to match the surrounding properties in the same object (adjust the indentation of the spread expression so it lines up with the other entries in the object where it appears).
🤖 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/infrastructure/context-prompt-command.ts`:
- Around line 74-80: The returned JSON always hardcodes task: "explain" which
mislabels outputs; update the return in runContextPromptCommand to use the
actual task from the input (e.g., options.task) or omit the task key when not
provided so downstream consumers see correct metadata; locate the return that
builds providerCompiled and replace the fixed "explain" with a conditional
inclusion of options.task (or remove the field) while leaving provider, prompt,
graph_path, and compiled as-is.
- Around line 38-57: In compilePromptForProvider, keep token_count semantically
consistent by returning the full prompt cost (promptPack.token_count) for all
providers; for the 'claude' branch add a separate field
session_payload_token_count (or session_payload_size) that contains
promptPack.session_payload_token_count and still include effective_token_count,
reused_context_tokens and session_state as before so the raw-vs-effective split
is preserved; ensure the Gemini (non-claude) branch remains unchanged and that
the returned object keys (provider, format, prompt, token_count,
session_payload_token_count, effective_token_count, reused_context_tokens,
session_state) are present only where appropriate.
In `@src/runtime/context-session.ts`:
- Around line 77-97: The reused_token_count is currently computed by
concatenating reused ref texts into reusedContent and re-tokenizing via
estimateQueryTokens, which can cause order-dependent drift; instead compute
reused_token_count by summing each reused ref's existing token count (e.g.,
ref.token_count or ref.tokensCount) from orderedRefs where
reusedRefSet.has(ref.ref), and only fall back to
estimateQueryTokens(ref.content) for refs that lack a stored token count; update
the session_delta.reused_token_count assignment to use this summed-per-ref value
rather than estimateQueryTokens(reusedContent).
In `@src/runtime/relevant-files.ts`:
- Around line 149-152: The current assignment unconditionally sets
missing_context to [] which conflates “no coverage computed” with “no missing
context”; update the object construction around retrieveResult to only include
missing_context when retrieveResult.coverage is present (or make it nullable) so
downstream can distinguish the cases—e.g., mirror the coverage spread pattern
using retrieveResult.coverage and retrieveResult.coverage.missing_required (or
set missing_context to null when coverage exists but missing_required is
absent); touch the lines referencing retrieveResult.coverage, missing_context,
and missing_required to implement this conditional inclusion.
In `@src/runtime/stdio-server.ts`:
- Around line 588-591: The current setContextPromptSession implementation stores
every sessionId indefinitely; modify setContextPromptSession (and reuse
ensureContextPromptSessions/sessionState) to enforce a fixed max size (e.g.,
MAX_CONTEXT_PROMPT_SESSIONS) and perform FIFO eviction: when inserting a new
sessionId, if the Map size exceeds the limit, remove the oldest entry (use the
Map's insertion order to find the first key) before calling set(sessionId,
nextState); keep clearContextPromptSession as-is to delete specific entries.
Ensure the MAX constant is defined near the other session-state logic and apply
the same bounded Map handling for any other callers of
ensureContextPromptSessions.
In `@src/runtime/stdio/definitions.ts`:
- Around line 236-278: The new tools are defined but not exposed because
activeMcpTools() still defaults to the core profile and CORE_TOOL_NAMES omits
the three new tool names; update the MCP exposure by adding 'context_pack',
'context_prompt', and 'context_session_reset' to CORE_TOOL_NAMES (or change
activeMcpTools() default/profile logic to include them) so these definitions are
included in the default/core toolset that activeMcpTools() returns.
---
Nitpick comments:
In `@src/infrastructure/context-prompt.ts`:
- Around line 45-47: Document that "__stable_prefix:" is a reserved namespace
and prevent collisions by either adding a clear inline comment next to
STABLE_PREFIX_INSTRUCTIONS_REF and STABLE_PREFIX_TITLE_REF stating they are
internal/reserved, and/or add validation where user section refs are accepted
(e.g., in the function that processes user refs) to reject or escape refs that
start with "__stable_prefix:". Update symbols STABLE_PREFIX_INSTRUCTIONS_REF and
STABLE_PREFIX_TITLE_REF and the user-ref validation logic so any user-provided
ref beginning with that prefix triggers an error or is normalized.
In `@src/runtime/stdio/tools.ts`:
- Around line 428-429: The object spread line with ...(retrieveFileType ? {
fileType: retrieveFileType } : {}) inside the object literal in
src/runtime/stdio/tools.ts is indented inconsistently; fix it by aligning the
leading spaces to match the surrounding properties in the same object (adjust
the indentation of the spread expression so it lines up with the other entries
in the object where it appears).
In `@tests/unit/context-pack-command.test.ts`:
- Around line 164-246: The test currently only returns one matched node so it
doesn't verify “highest-signal” selection; update the retrieveContext mock (the
object returned by dependencies.retrieveContext in this test) to include at
least one additional matched_nodes entry with a lower signal (e.g., lower
match_score and/or less favorable relevance_band, label like 'OtherService'),
then keep the existing expectation that analyzeImpact is called with { label:
'AuthService', depth: 3 } and the same output assertion to prove the
highest-signal node ('AuthService') is chosen by runContextPackCommand.
In `@tests/unit/context-prompt.test.ts`:
- Line 75: The assertion is brittle because it depends on exact JSON whitespace;
instead parse the JSON from followUp.session_payload and assert the invalidated
array contains "beta". Locate the test that uses followUp.session_payload and
replace the string-contains check with JSON.parse(followUp.session_payload) and
an assertion like parsed.invalidated.includes('beta') (or the test framework
equivalent, e.g., expect(parsed.invalidated).toContain('beta')) to make the
check formatting-tolerant.
In `@tests/unit/retrieve.test.ts`:
- Around line 2718-2731: The stdio compaction test omits asserting the
expandable field, so add an assertion that compactRetrieveResultForStdio
preserves the expandable signal: after computing compactResult in the test (it
'strips evidence_class from compact stdio retrieve payloads'), assert that
compactResult.expandable equals rawResult.expandable (or that compactResult has
the expandable property and its value matches rawResult.expandable) so the test
will fail if compactRetrieveResultForStdio starts dropping expandable.
In `@tests/unit/review-compare.test.ts`:
- Around line 173-181: The unit test is brittle because it inspects source
strings of generateReviewCompareArtifacts; instead, update the test to assert
behavior by importing generateReviewCompareArtifacts and the shared helper
renderReviewPrompt (or mocking/spying on it) and verifying that calling
generateReviewCompareArtifacts results in invoking renderReviewPrompt and/or
produces the expected output contract, rather than searching for
'renderReviewPrompt(' or 'buildContextPrompt(' in the file text; replace the
readFileSync/string matching logic with a behavioral assertion using the
function generateReviewCompareArtifacts and a spy/mock on renderReviewPrompt.
In `@tests/unit/stdio-tool-profile.test.ts`:
- Around line 215-235: The test only checks that 'context_pack' is blocked;
update the spec in the it block to iterate over all three full-only tool names
(context_pack, context_prompt, context_session_reset) and for each call
handleStdioRequest (using withProfile('core', ...)) assert the response.error
has code -32601 and that the message contains the tool name and
'GRAPHIFY_TOOL_PROFILE=full'; locate the current test that calls
handleStdioRequest and replace the single-name assertion with a small
loop/parameterized map over the three names so each is exercised the same way.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3259743d-fd04-4b30-aa6e-bf2f5e2992a5
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (45)
README.mddocs/benchmarks/2026-04-30-govalidate/README.mddocs/benchmarks/2026-05-02-govalidate-pr-review/README.mdexamples/mcp-tool-examples.mdexamples/why-graphify.mdpackage.jsonsrc/cli/main.tssrc/cli/parser.tssrc/contracts/context-pack.tssrc/contracts/context-session.tssrc/infrastructure/benchmark.tssrc/infrastructure/benchmark/questions.tssrc/infrastructure/benchmark/runner.tssrc/infrastructure/compare.tssrc/infrastructure/context-pack-command.tssrc/infrastructure/context-prompt-command.tssrc/infrastructure/context-prompt.tssrc/infrastructure/review-compare.tssrc/runtime/context-pack.tssrc/runtime/context-session.tssrc/runtime/feature-map.tssrc/runtime/pr-impact.tssrc/runtime/relevant-files.tssrc/runtime/retrieve.tssrc/runtime/stdio-server.tssrc/runtime/stdio/definitions.tssrc/runtime/stdio/prompts.tssrc/runtime/stdio/tools.tstests/unit/benchmark-artifact.test.tstests/unit/benchmark.test.tstests/unit/cli.test.tstests/unit/compare.test.tstests/unit/context-pack-command.test.tstests/unit/context-pack.test.tstests/unit/context-prompt-command.test.tstests/unit/context-prompt.test.tstests/unit/package-metadata.test.tstests/unit/pr-impact.test.tstests/unit/retrieve.test.tstests/unit/review-compare.test.tstests/unit/stdio-pr-impact.test.tstests/unit/stdio-prompts.test.tstests/unit/stdio-server.test.tstests/unit/stdio-tool-profile.test.tstests/unit/why-graphify-doc.test.ts
| { | ||
| name: 'context_pack', | ||
| description: | ||
| 'Build a compact explain/review/impact context pack for a downstream agent. Use when you need expandable refs plus coverage and missing-context signals instead of the full graph payload.', | ||
| inputSchema: { | ||
| type: 'object', | ||
| required: ['prompt'], | ||
| properties: { | ||
| prompt: { type: 'string', description: 'Task prompt or question to build context for' }, | ||
| task: { type: 'string', enum: ['explain', 'review', 'impact'], description: 'Context-pack mode (default: explain)' }, | ||
| budget: { type: 'number', description: 'Optional: maximum token budget for the pack (default 3000)' }, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| name: 'context_prompt', | ||
| description: | ||
| 'Compile a provider-ready context prompt. Use provider=claude with session_id for cache-aware follow-ups, or provider=gemini for a plain prompt string.', | ||
| inputSchema: { | ||
| type: 'object', | ||
| required: ['prompt', 'provider'], | ||
| properties: { | ||
| prompt: { type: 'string', description: 'Task prompt or question to compile' }, | ||
| provider: { type: 'string', enum: ['claude', 'gemini'], description: 'Target prompt consumer' }, | ||
| budget: { type: 'number', description: 'Optional: retrieval budget used to gather graph evidence (default 3000)' }, | ||
| session_id: { type: 'string', description: 'Optional: server-managed Claude session key for cache-aware follow-ups.' }, | ||
| reset_session: { type: 'boolean', description: 'Optional: clear any stored server-side session before compiling this prompt.' }, | ||
| session_state: { type: 'object', description: 'Optional: explicit previous session_state payload to continue without using session_id.' }, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| name: 'context_session_reset', | ||
| description: | ||
| 'Reset a stored context_prompt session when switching topics or when you want the next Claude prompt to resend the full stable context.', | ||
| inputSchema: { | ||
| type: 'object', | ||
| required: ['session_id'], | ||
| properties: { | ||
| session_id: { type: 'string', description: 'Server-managed context_prompt session key to clear' }, | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
These tools still won't show up on the default MCP server profile.
Registering the definitions here is not enough by itself: activeMcpTools() defaults to the core profile, and CORE_TOOL_NAMES in this file still omits context_pack, context_prompt, and context_session_reset. In a normal server boot, these new tools stay filtered out unless the user explicitly opts into GRAPHIFY_TOOL_PROFILE=full, which means the shipped MCP surface is narrower than this PR advertises.
🤖 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/runtime/stdio/definitions.ts` around lines 236 - 278, The new tools are
defined but not exposed because activeMcpTools() still defaults to the core
profile and CORE_TOOL_NAMES omits the three new tool names; update the MCP
exposure by adding 'context_pack', 'context_prompt', and 'context_session_reset'
to CORE_TOOL_NAMES (or change activeMcpTools() default/profile logic to include
them) so these definitions are included in the default/core toolset that
activeMcpTools() returns.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/runtime/context-session.ts (1)
38-74:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse null-prototype object and
Object.hasOwn()for safe property storage.Line 42 writes arbitrary
refkeys into a plain object, and line 72 usesref in nextRefs. While current ref values are hardcoded constants and safe section names, using a null-prototype object withObject.hasOwn()protects against accidental introduction of special keys (like__proto__,constructor) in future code changes.Proposed fix
- const nextRefs: ContextSessionState['refs'] = {} + const nextRefs: ContextSessionState['refs'] = Object.create(null) as ContextSessionState['refs'] @@ const invalidated = Object.keys(baseState.refs) - .filter((ref) => !(ref in nextRefs)) + .filter((ref) => !Object.hasOwn(nextRefs, ref)) .sort((left, right) => left.localeCompare(right))🤖 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/runtime/context-session.ts` around lines 38 - 74, Create nextRefs as a null-prototype object (e.g., Object.create(null)) and replace any uses of the "in" operator with Object.hasOwn(nextRefs, ref) to avoid prototype key collisions; specifically update the nextRefs initialization (ContextSessionState['refs'] nextRefs), the invalidated computation (replace "ref in nextRefs" with !Object.hasOwn(nextRefs, ref)), and the reusedTokenCount reduce (when reading nextRefs[ref]?.token_count guard with Object.hasOwn(nextRefs, ref) or prefer baseState.refs[ref]?.token_count ?? (Object.hasOwn(nextRefs, ref) ? nextRefs[ref].token_count : 0)) so all property checks and reads on nextRefs are prototype-safe.
🤖 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/runtime/context-session.ts`:
- Around line 33-69: Detect and ignore duplicate ref keys before building
session deltas: when iterating sortedRefs in the loop that builds
nextRefs/added/updated/reused_refs, keep a Set (e.g., seenRefs) of ref.ref
values and skip any subsequent entries with the same ref.ref so only the first
occurrence is processed; this ensures nextRefs, added, updated and reused_refs
remain consistent with baseState.refs (update the loop that references
sortedRefs, nextRefs, added, updated, reused_refs and baseState.refs
accordingly), and optionally emit a warning/log when a duplicate is skipped for
visibility.
---
Duplicate comments:
In `@src/runtime/context-session.ts`:
- Around line 38-74: Create nextRefs as a null-prototype object (e.g.,
Object.create(null)) and replace any uses of the "in" operator with
Object.hasOwn(nextRefs, ref) to avoid prototype key collisions; specifically
update the nextRefs initialization (ContextSessionState['refs'] nextRefs), the
invalidated computation (replace "ref in nextRefs" with !Object.hasOwn(nextRefs,
ref)), and the reusedTokenCount reduce (when reading nextRefs[ref]?.token_count
guard with Object.hasOwn(nextRefs, ref) or prefer
baseState.refs[ref]?.token_count ?? (Object.hasOwn(nextRefs, ref) ?
nextRefs[ref].token_count : 0)) so all property checks and reads on nextRefs are
prototype-safe.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5ce0846d-5474-4829-b6cb-00934bf16fa6
📒 Files selected for processing (13)
src/infrastructure/context-prompt-command.tssrc/infrastructure/context-prompt.tssrc/runtime/context-session.tssrc/runtime/feature-map.tssrc/runtime/relevant-files.tssrc/runtime/stdio-server.tssrc/runtime/stdio/tools.tstests/unit/context-prompt-command.test.tstests/unit/context-session.test.tstests/unit/feature-map.test.tstests/unit/relevant-files.test.tstests/unit/stdio-server.test.tstests/unit/stdio-tool-profile.test.ts
✅ Files skipped from review due to trivial changes (2)
- tests/unit/context-session.test.ts
- src/runtime/stdio/tools.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/infrastructure/context-prompt.ts
- tests/unit/context-prompt-command.test.ts
- tests/unit/stdio-server.test.ts
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
pack/promptCLI commands and MCP context-plane toolsTest Plan
Summary by CodeRabbit
New Features
packandpromptCLI commands, provider-specific prompt compilation, context-pack tooling, and three context-session MCP tools (context_pack,context_prompt,context_session_reset).Enhancements
Documentation
Tests
Chores