mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-11-07 09:16:16 +08:00
fix(prompt-hook): desktop reminders and other sessions' messages no longer drive the hook (#2798)
Claude Code's desktop app puts <system-reminder> blocks (which local sessions are linked, and similar status) in front of the prompt it submits, and UserPromptSubmit hooks receive them inside `prompt`. The hook gated, picked the project and explored on the whole string, so the reminder's words drove it: a linked session titled after its work, like "trace-order-flow", carries structural keywords, so every turn, a bare "yes" included, got a full explore of the reminder. A reminder in front of a task notification or a subagent hand-back also defeated the start-anchored envelope checks, and a message from another session (a <cross-session-message from=...> envelope) was never skipped at all. The hook now removes every complete <system-reminder> block before the envelope checks, the gate, project selection and explore, returns early when nothing is left, and skips a prompt that is entirely a <cross-session-message> envelope, as it already did for task notifications and subagent hand-backs. The scan stops at the last closing tag and the attribute run stops at `<`, so a pasted prompt full of unclosed tags stays linear (520 KB in under 1 ms; the `[^>]*` form took 83 ms on a tenth of that and grows quadratically). Validation: - Prompt shapes come from the Claude Code desktop transcripts on this machine (314 transcripts): reminders always lead, one to four of them, separated by one or two newlines, and cross-session messages follow one to four reminders. - frontload-hook.test.ts: 15 new tests (8 spawn the built hook with Claude Code-shaped payloads) fail on main and pass with the fix; the file's 48 other tests pass on both. - Built CLI, private HOME, 13 payloads: on main every prompt behind a reminder got a full explore of the reminder (2.1 to 5.0 KB); with the fix the 8 that are not user input inject nothing and exit in about 200 ms instead of 680 ms, and a question behind reminders injects byte-for-byte what the same question alone does. Issue #2635. Contributor PR #2642 (yang0228) was read for guidance. Fixes #2635 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
407efb1c65
commit
c1744e7e76
@@ -53,7 +53,7 @@ try {
|
||||
import { Command } from 'commander';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import { getCodeGraphDir, isInitialized, hasSchemalessDb, hasForeignDbFile, unsafeIndexRootReason, findNearestCodeGraphRoot, planFrontload, isTaskNotification, isAgentMessage, hasStructuralKeyword, extractCodeTokens, capPromptHookInjection, codeGraphDirName, DEFAULT_CODEGRAPH_DIR } from '../directory';
|
||||
import { getCodeGraphDir, isInitialized, hasSchemalessDb, hasForeignDbFile, unsafeIndexRootReason, findNearestCodeGraphRoot, planFrontload, isTaskNotification, isAgentMessage, isCrossSessionMessage, stripSystemReminders, hasStructuralKeyword, extractCodeTokens, capPromptHookInjection, codeGraphDirName, DEFAULT_CODEGRAPH_DIR } from '../directory';
|
||||
import { extractProseCandidates } from '../search/identifier-segments';
|
||||
import { detectWorktreeIndexMismatch, worktreeMismatchWarning } from '../sync/worktree';
|
||||
import { createShimmerProgress } from '../ui/shimmer-progress';
|
||||
@@ -1512,11 +1512,14 @@ program
|
||||
|
||||
let input: { prompt?: string; cwd?: string } = {};
|
||||
try { input = JSON.parse(raw); } catch { return; }
|
||||
const prompt = String(input.prompt || '');
|
||||
// System-injected task notifications and subagent hand-backs are not
|
||||
// user prompts: exit before any project lookup or explore work (#1832,
|
||||
// #2184).
|
||||
if (isTaskNotification(prompt) || isAgentMessage(prompt)) return;
|
||||
// The desktop app's <system-reminder> blocks are host status, not what
|
||||
// the user typed: gate, pick the project and explore on the rest
|
||||
// (#2635).
|
||||
const prompt = stripSystemReminders(String(input.prompt || ''));
|
||||
// System-injected task notifications, subagent hand-backs and messages
|
||||
// from other sessions are not user prompts, and neither is nothing:
|
||||
// exit before any project lookup or explore work (#1832, #2184, #2635).
|
||||
if (!prompt || isTaskNotification(prompt) || isAgentMessage(prompt) || isCrossSessionMessage(prompt)) return;
|
||||
|
||||
// Gate telemetry: how often each tier fires vs. no-ops — counter names
|
||||
// only, NEVER prompt content (see TELEMETRY.md). This is the data that
|
||||
|
||||
Reference in New Issue
Block a user