| import { registerBundledSkill } from '../bundledSkills.js' |
|
|
| |
| |
| |
| const STUCK_PROMPT = `# /stuck β diagnose frozen/slow Codev sessions |
| |
| The user thinks another Codev session on this machine is frozen, stuck, or very slow. Investigate and post a report to #codev-feedback. |
| |
| ## What to look for |
| |
| Scan for other Codev processes (excluding the current one β PID is in \`process.pid\` but for shell commands just exclude the PID you see running this prompt). Process names are typically \`claude\` (installed) or \`cli\` (native dev build). |
| |
| Signs of a stuck session: |
| - **High CPU (β₯90%) sustained** β likely an infinite loop. Sample twice, 1-2s apart, to confirm it's not a transient spike. |
| - **Process state \`D\` (uninterruptible sleep)** β often an I/O hang. The \`state\` column in \`ps\` output; first character matters (ignore modifiers like \`+\`, \`s\`, \`<\`). |
| - **Process state \`T\` (stopped)** β user probably hit Ctrl+Z by accident. |
| - **Process state \`Z\` (zombie)** β parent isn't reaping. |
| - **Very high RSS (β₯4GB)** β possible memory leak making the session sluggish. |
| - **Stuck child process** β a hung \`git\`, \`node\`, or shell subprocess can freeze the parent. Check \`pgrep -lP <pid>\` for each session. |
| |
| ## Investigation steps |
| |
| 1. **List all Codev processes** (macOS/Linux): |
| \`\`\` |
| ps -axo pid=,pcpu=,rss=,etime=,state=,comm=,command= | grep -E '(claude|cli)' | grep -v grep |
| \`\`\` |
| Filter to rows where \`comm\` is \`claude\` or (\`cli\` AND the command path contains "claude"). |
| |
| 2. **For anything suspicious**, gather more context: |
| - Child processes: \`pgrep -lP <pid>\` |
| - If high CPU: sample again after 1-2s to confirm it's sustained |
| - If a child looks hung (e.g., a git command), note its full command line with \`ps -p <child_pid> -o command=\` |
| - Check the session's debug log if you can infer the session ID: \`~/.claude/debug/<session-id>.txt\` (the last few hundred lines often show what it was doing before hanging) |
| |
| 3. **Consider a stack dump** for a truly frozen process (advanced, optional): |
| - macOS: \`sample <pid> 3\` gives a 3-second native stack sample |
| - This is big β only grab it if the process is clearly hung and you want to know *why* |
| |
| ## Report |
| |
| **Only post to Slack if you actually found something stuck.** If every session looks healthy, tell the user that directly β do not post an all-clear to the channel. |
| |
| If you did find a stuck/slow session, post to **#codev-feedback** (channel ID: \`C07VBSHV7EV\`) using the Slack MCP tool. Use ToolSearch to find \`slack_send_message\` if it's not already loaded. |
| |
| **Use a two-message structure** to keep the channel scannable: |
| |
| 1. **Top-level message** β one short line: hostname, Codev version, and a terse symptom (e.g. "session PID 12345 pegged at 100% CPU for 10min" or "git subprocess hung in D state"). No code blocks, no details. |
| 2. **Thread reply** β the full diagnostic dump. Pass the top-level message's \`ts\` as \`thread_ts\`. Include: |
| - PID, CPU%, RSS, state, uptime, command line, child processes |
| - Your diagnosis of what's likely wrong |
| - Relevant debug log tail or \`sample\` output if you captured it |
| |
| If Slack MCP isn't available, format the report as a message the user can copy-paste into #codev-feedback (and let them know to thread the details themselves). |
| |
| ## Notes |
| - Don't kill or signal any processes β this is diagnostic only. |
| - If the user gave an argument (e.g., a specific PID or symptom), focus there first. |
| ` |
|
|
| export function registerStuckSkill(): void { |
| if (process.env.USER_TYPE !== 'ant') { |
| return |
| } |
|
|
| registerBundledSkill({ |
| name: 'stuck', |
| description: |
| '[ANT-ONLY] Investigate frozen/stuck/slow Claude Code sessions on this machine and post a diagnostic report to #codev-feedback.', |
| userInvocable: true, |
| async getPromptForCommand(args) { |
| let prompt = STUCK_PROMPT |
| if (args) { |
| prompt += `\n## User-provided context\n\n${args}\n` |
| } |
| return [{ type: 'text', text: prompt }] |
| }, |
| }) |
| } |
|
|