Claude Code persists hook stdout over 10,000 characters to a file and shows the model a 2 KB preview. The prompt-hook MAX of 16,000 always hit that path once explore filled the budget. Cap at 9,000 (exported + unit-tested) so the payload lands inline, with headroom for the wrapper and projectPath nudges. Lands the approach from #1695 with a testable helper. Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
This commit is contained in:
co-authored by
Colby McHenry
parent
b715eb6374
commit
4105249843
@@ -41,7 +41,7 @@ try {
|
||||
import { Command } from 'commander';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import { getCodeGraphDir, isInitialized, unsafeIndexRootReason, findNearestCodeGraphRoot, planFrontload, hasStructuralKeyword, extractCodeTokens } from '../directory';
|
||||
import { getCodeGraphDir, isInitialized, unsafeIndexRootReason, findNearestCodeGraphRoot, planFrontload, hasStructuralKeyword, extractCodeTokens, capPromptHookInjection } from '../directory';
|
||||
import { extractProseCandidates } from '../search/identifier-segments';
|
||||
import { detectWorktreeIndexMismatch, worktreeMismatchWarning } from '../sync/worktree';
|
||||
import { createShimmerProgress } from '../ui/shimmer-progress';
|
||||
@@ -1412,8 +1412,11 @@ program
|
||||
const text = result.content[0]?.text ?? '';
|
||||
if (!result.isError && text.trim()) {
|
||||
// Cap the injection so a large-repo explore can't flood the prompt.
|
||||
const MAX = 16000;
|
||||
const body = text.length > MAX ? `${text.slice(0, MAX)}\n…(truncated; call codegraph_explore for the rest)` : text;
|
||||
// Claude Code shows hook stdout inline only up to 10,000 characters;
|
||||
// above that it persists the output to a file and the model sees a
|
||||
// 2 KB preview (#1694). PROMPT_HOOK_INJECTION_MAX (9,000) leaves
|
||||
// room for the wrapper and the projectPath nudge lines below.
|
||||
const body = capPromptHookInjection(text);
|
||||
// For a front-loaded SUB-project, a follow-up explore needs its path.
|
||||
const more = plan.viaSubScan
|
||||
? `call codegraph_explore with projectPath: "${plan.exploreRoot}" for more`
|
||||
|
||||
@@ -568,6 +568,33 @@ export function isStructuralPrompt(prompt: string): boolean {
|
||||
return hasStructuralKeyword(prompt) || extractCodeTokens(prompt).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Claude Code persists `UserPromptSubmit` hook stdout above this many
|
||||
* characters to a file and shows the model a ~2 KB preview instead (#1694).
|
||||
* Measured on Claude Code 2.1.261; documented in the hooks reference as a
|
||||
* 10,000-character cap on hook output strings.
|
||||
*/
|
||||
export const CLAUDE_CODE_INLINE_HOOK_OUTPUT_LIMIT = 10_000;
|
||||
|
||||
/**
|
||||
* Max characters of explore text injected by `codegraph prompt-hook` before
|
||||
* truncation. Must stay under {@link CLAUDE_CODE_INLINE_HOOK_OUTPUT_LIMIT} so
|
||||
* the host delivers the payload inline. 9,000 leaves ~1k for the
|
||||
* `<codegraph_context>` wrapper and the `projectPath` nudge lines appended
|
||||
* after the cap is applied.
|
||||
*/
|
||||
export const PROMPT_HOOK_INJECTION_MAX = 9_000;
|
||||
|
||||
/**
|
||||
* Cap explore text for the prompt-hook injection, preserving the existing
|
||||
* "call codegraph_explore for the rest" notice when truncated.
|
||||
*/
|
||||
export function capPromptHookInjection(text: string, max = PROMPT_HOOK_INJECTION_MAX): string {
|
||||
return text.length > max
|
||||
? `${text.slice(0, max)}\n…(truncated; call codegraph_explore for the rest)`
|
||||
: text;
|
||||
}
|
||||
|
||||
/**
|
||||
* What the front-load hook should do for a prompt issued from a directory.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user