fix: add file_path parameter to save_deliverable for large reports (#123)

* fix: add file_path parameter to save_deliverable for large reports

Large deliverable reports can exceed output token limits when passed as
inline content. This change allows agents to write reports to disk first
and pass a file_path instead.

Changes:
- Add file_path parameter to save_deliverable MCP tool with path
  traversal protection
- Pass CLAUDE_CODE_MAX_OUTPUT_TOKENS env var to SDK subprocesses
- Fix false positive error detection by extracting only text content
  (not tool_use JSON) when checking for API errors
- Update all prompts to instruct agents to use file_path for large
  reports and stop immediately after completion

* docs: simplify and condense CLAUDE.md

Reduce verbosity while preserving all essential information for AI
assistance. Makes the documentation more scannable and focused.

* feat: add issue number detection to pr command

The /pr command now automatically detects issue numbers from:
1. Explicit arguments (e.g., /pr 123 or /pr 123,456)
2. Branch name patterns (e.g., fix/123-bug, issue-456-feature)

Adds "Closes #X" lines to PR body to auto-close issues on merge.

* chore: remove CLAUDE_CODE_MAX_OUTPUT_TOKENS env var handling

No longer needed with the new Claude Agent SDK version.

* fix: restore max_output_tokens error handling
This commit is contained in:
Arjun Malleswaran
2026-02-11 13:40:49 -08:00
committed by GitHub
parent 2e1fe3454a
commit 2f4fa89e7b
17 changed files with 293 additions and 328 deletions
+11
View File
@@ -218,6 +218,16 @@ export async function runClaudePrompt(
console.log(chalk.blue(` Running Claude Code: ${description}...`));
const mcpServers = buildMcpServers(sourceDir, agentName);
// Build env vars to pass to SDK subprocesses
const sdkEnv: Record<string, string> = {};
if (process.env.ANTHROPIC_API_KEY) {
sdkEnv.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
}
if (process.env.CLAUDE_CODE_OAUTH_TOKEN) {
sdkEnv.CLAUDE_CODE_OAUTH_TOKEN = process.env.CLAUDE_CODE_OAUTH_TOKEN;
}
const options = {
model: 'claude-sonnet-4-5-20250929',
maxTurns: 10_000,
@@ -225,6 +235,7 @@ export async function runClaudePrompt(
permissionMode: 'bypassPermissions' as const,
allowDangerouslySkipPermissions: true,
mcpServers,
env: sdkEnv,
};
if (!execContext.useCleanOutput) {
+18 -1
View File
@@ -50,6 +50,20 @@ export function extractMessageContent(message: AssistantMessage): string {
return String(messageContent.content);
}
// Extracts only text content (no tool_use JSON) to avoid false positives in error detection
export function extractTextOnlyContent(message: AssistantMessage): string {
const messageContent = message.message;
if (Array.isArray(messageContent.content)) {
return messageContent.content
.filter((c: ContentBlock) => c.type === 'text' || c.text)
.map((c: ContentBlock) => c.text || '')
.join('\n');
}
return String(messageContent.content);
}
export function detectApiError(content: string): ApiErrorDetection {
if (!content || typeof content !== 'string') {
return { detected: false };
@@ -175,11 +189,14 @@ export function handleAssistantMessage(
const cleanedContent = filterJsonToolCalls(content);
// Prefer structured error field from SDK, fall back to text-sniffing
// Use text-only content for error detection to avoid false positives
// from tool_use JSON (e.g. security reports containing "usage limit")
let errorDetection: ApiErrorDetection;
if (message.error) {
errorDetection = handleStructuredError(message.error, content);
} else {
errorDetection = detectApiError(content);
const textOnlyContent = extractTextOnlyContent(message);
errorDetection = detectApiError(textOnlyContent);
}
const result: AssistantResult = {