104 lines
4.1 KiB
TypeScript
104 lines
4.1 KiB
TypeScript
import { open, stat } from 'fs/promises'
|
|
import { CLAUDE_CODE_GUIDE_AGENT_TYPE } from 'src/tools/AgentTool/built-in/claudeCodeGuideAgent.js'
|
|
import { getSettingsFilePathForSource } from 'src/utils/settings/settings.js'
|
|
import { enableDebugLogging, getDebugLogPath } from '../../utils/debug.js'
|
|
import { errorMessage, isENOENT } from '../../utils/errors.js'
|
|
import { formatFileSize } from '../../utils/format.js'
|
|
import { registerBundledSkill } from '../bundledSkills.js'
|
|
|
|
const DEFAULT_DEBUG_LINES_READ = 20
|
|
const TAIL_READ_BYTES = 64 * 1024
|
|
|
|
export function registerDebugSkill(): void {
|
|
registerBundledSkill({
|
|
name: 'debug',
|
|
description:
|
|
process.env.USER_TYPE === 'ant'
|
|
? 'Debug your current Claude Code session by reading the session debug log. Includes all event logging'
|
|
: 'Enable debug logging for this session and help diagnose issues',
|
|
allowedTools: ['Read', 'Grep', 'Glob'],
|
|
argumentHint: '[issue description]',
|
|
// disableModelInvocation so that the user has to explicitly request it in
|
|
// interactive mode and so the description does not take up context.
|
|
disableModelInvocation: true,
|
|
userInvocable: true,
|
|
async getPromptForCommand(args) {
|
|
// Non-ants don't write debug logs by default — turn logging on now so
|
|
// subsequent activity in this session is captured.
|
|
const wasAlreadyLogging = enableDebugLogging()
|
|
const debugLogPath = getDebugLogPath()
|
|
|
|
let logInfo: string
|
|
try {
|
|
// Tail the log without reading the whole thing - debug logs grow
|
|
// unbounded in long sessions and reading them in full spikes RSS.
|
|
const stats = await stat(debugLogPath)
|
|
const readSize = Math.min(stats.size, TAIL_READ_BYTES)
|
|
const startOffset = stats.size - readSize
|
|
const fd = await open(debugLogPath, 'r')
|
|
try {
|
|
const { buffer, bytesRead } = await fd.read({
|
|
buffer: Buffer.alloc(readSize),
|
|
position: startOffset,
|
|
})
|
|
const tail = buffer
|
|
.toString('utf-8', 0, bytesRead)
|
|
.split('\n')
|
|
.slice(-DEFAULT_DEBUG_LINES_READ)
|
|
.join('\n')
|
|
logInfo = `Log size: ${formatFileSize(stats.size)}\n\n### Last ${DEFAULT_DEBUG_LINES_READ} lines\n\n\`\`\`\n${tail}\n\`\`\``
|
|
} finally {
|
|
await fd.close()
|
|
}
|
|
} catch (e) {
|
|
logInfo = isENOENT(e)
|
|
? 'No debug log exists yet — logging was just enabled.'
|
|
: `Failed to read last ${DEFAULT_DEBUG_LINES_READ} lines of debug log: ${errorMessage(e)}`
|
|
}
|
|
|
|
const justEnabledSection = wasAlreadyLogging
|
|
? ''
|
|
: `
|
|
## Debug Logging Just Enabled
|
|
|
|
Debug logging was OFF for this session until now. Nothing prior to this /debug invocation was captured.
|
|
|
|
Tell 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.
|
|
`
|
|
|
|
const prompt = `# Debug Skill
|
|
|
|
Help the user debug an issue they're encountering in this current Claude Code session.
|
|
${justEnabledSection}
|
|
## Session Debug Log
|
|
|
|
The debug log for the current session is at: \`${debugLogPath}\`
|
|
|
|
${logInfo}
|
|
|
|
For additional context, grep for [ERROR] and [WARN] lines across the full file.
|
|
|
|
## Issue Description
|
|
|
|
${args || 'The user did not describe a specific issue. Read the debug log and summarize any errors, warnings, or notable issues.'}
|
|
|
|
## Settings
|
|
|
|
Remember that settings are in:
|
|
* user - ${getSettingsFilePathForSource('userSettings')}
|
|
* project - ${getSettingsFilePathForSource('projectSettings')}
|
|
* local - ${getSettingsFilePathForSource('localSettings')}
|
|
|
|
## Instructions
|
|
|
|
1. Review the user's issue description
|
|
2. 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
|
|
3. Consider launching the ${CLAUDE_CODE_GUIDE_AGENT_TYPE} subagent to understand the relevant Claude Code features
|
|
4. Explain what you found in plain language
|
|
5. Suggest concrete fixes or next steps
|
|
`
|
|
return [{ type: 'text', text: prompt }]
|
|
},
|
|
})
|
|
}
|