source dump of claude code
at main 103 lines 4.2 kB view raw
1import { open, stat } from 'fs/promises' 2import { CLAUDE_CODE_GUIDE_AGENT_TYPE } from 'src/tools/AgentTool/built-in/claudeCodeGuideAgent.js' 3import { getSettingsFilePathForSource } from 'src/utils/settings/settings.js' 4import { enableDebugLogging, getDebugLogPath } from '../../utils/debug.js' 5import { errorMessage, isENOENT } from '../../utils/errors.js' 6import { formatFileSize } from '../../utils/format.js' 7import { registerBundledSkill } from '../bundledSkills.js' 8 9const DEFAULT_DEBUG_LINES_READ = 20 10const TAIL_READ_BYTES = 64 * 1024 11 12export function registerDebugSkill(): void { 13 registerBundledSkill({ 14 name: 'debug', 15 description: 16 process.env.USER_TYPE === 'ant' 17 ? 'Debug your current Claude Code session by reading the session debug log. Includes all event logging' 18 : 'Enable debug logging for this session and help diagnose issues', 19 allowedTools: ['Read', 'Grep', 'Glob'], 20 argumentHint: '[issue description]', 21 // disableModelInvocation so that the user has to explicitly request it in 22 // interactive mode and so the description does not take up context. 23 disableModelInvocation: true, 24 userInvocable: true, 25 async getPromptForCommand(args) { 26 // Non-ants don't write debug logs by default — turn logging on now so 27 // subsequent activity in this session is captured. 28 const wasAlreadyLogging = enableDebugLogging() 29 const debugLogPath = getDebugLogPath() 30 31 let logInfo: string 32 try { 33 // Tail the log without reading the whole thing - debug logs grow 34 // unbounded in long sessions and reading them in full spikes RSS. 35 const stats = await stat(debugLogPath) 36 const readSize = Math.min(stats.size, TAIL_READ_BYTES) 37 const startOffset = stats.size - readSize 38 const fd = await open(debugLogPath, 'r') 39 try { 40 const { buffer, bytesRead } = await fd.read({ 41 buffer: Buffer.alloc(readSize), 42 position: startOffset, 43 }) 44 const tail = buffer 45 .toString('utf-8', 0, bytesRead) 46 .split('\n') 47 .slice(-DEFAULT_DEBUG_LINES_READ) 48 .join('\n') 49 logInfo = `Log size: ${formatFileSize(stats.size)}\n\n### Last ${DEFAULT_DEBUG_LINES_READ} lines\n\n\`\`\`\n${tail}\n\`\`\`` 50 } finally { 51 await fd.close() 52 } 53 } catch (e) { 54 logInfo = isENOENT(e) 55 ? 'No debug log exists yet — logging was just enabled.' 56 : `Failed to read last ${DEFAULT_DEBUG_LINES_READ} lines of debug log: ${errorMessage(e)}` 57 } 58 59 const justEnabledSection = wasAlreadyLogging 60 ? '' 61 : ` 62## Debug Logging Just Enabled 63 64Debug logging was OFF for this session until now. Nothing prior to this /debug invocation was captured. 65 66Tell the user that debug logging is now active at \`${debugLogPath}\`, ask them to reproduce the issue, then re-read the log. If they can't reproduce, they can also restart with \`claude --debug\` to capture logs from startup. 67` 68 69 const prompt = `# Debug Skill 70 71Help the user debug an issue they're encountering in this current Claude Code session. 72${justEnabledSection} 73## Session Debug Log 74 75The debug log for the current session is at: \`${debugLogPath}\` 76 77${logInfo} 78 79For additional context, grep for [ERROR] and [WARN] lines across the full file. 80 81## Issue Description 82 83${args || 'The user did not describe a specific issue. Read the debug log and summarize any errors, warnings, or notable issues.'} 84 85## Settings 86 87Remember that settings are in: 88* user - ${getSettingsFilePathForSource('userSettings')} 89* project - ${getSettingsFilePathForSource('projectSettings')} 90* local - ${getSettingsFilePathForSource('localSettings')} 91 92## Instructions 93 941. Review the user's issue description 952. The last ${DEFAULT_DEBUG_LINES_READ} lines show the debug file format. Look for [ERROR] and [WARN] entries, stack traces, and failure patterns across the file 963. Consider launching the ${CLAUDE_CODE_GUIDE_AGENT_TYPE} subagent to understand the relevant Claude Code features 974. Explain what you found in plain language 985. Suggest concrete fixes or next steps 99` 100 return [{ type: 'text', text: prompt }] 101 }, 102 }) 103}