debuganything 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.claude-plugin/plugin.json +15 -0
  2. package/DISCLAIMER.md +101 -0
  3. package/GEMINI.md +97 -0
  4. package/LICENSE +21 -0
  5. package/README.md +283 -2
  6. package/assets/README.md +9 -0
  7. package/assets/debuganything-logo.png +0 -0
  8. package/assets/debuganything-mark-512.png +0 -0
  9. package/dist/chunk-32IDKAZK.js +9 -0
  10. package/dist/chunk-32IDKAZK.js.map +1 -0
  11. package/dist/chunk-5BXTDASF.js +135 -0
  12. package/dist/chunk-5BXTDASF.js.map +1 -0
  13. package/dist/chunk-5RAKTYW5.js +292 -0
  14. package/dist/chunk-5RAKTYW5.js.map +1 -0
  15. package/dist/chunk-7MMXFUUN.js +79 -0
  16. package/dist/chunk-7MMXFUUN.js.map +1 -0
  17. package/dist/chunk-D742WJPT.js +436 -0
  18. package/dist/chunk-D742WJPT.js.map +1 -0
  19. package/dist/chunk-EMR42ZJQ.js +102 -0
  20. package/dist/chunk-EMR42ZJQ.js.map +1 -0
  21. package/dist/chunk-MLDOO673.js +1416 -0
  22. package/dist/chunk-MLDOO673.js.map +1 -0
  23. package/dist/chunk-NFL22T3H.js +309 -0
  24. package/dist/chunk-NFL22T3H.js.map +1 -0
  25. package/dist/chunk-STFC7C5C.js +245 -0
  26. package/dist/chunk-STFC7C5C.js.map +1 -0
  27. package/dist/chunk-VGYXHXTY.js +1015 -0
  28. package/dist/chunk-VGYXHXTY.js.map +1 -0
  29. package/dist/chunk-YY6M5RIJ.js +215 -0
  30. package/dist/chunk-YY6M5RIJ.js.map +1 -0
  31. package/dist/cli.js +254 -0
  32. package/dist/cli.js.map +1 -0
  33. package/dist/docker-ORXYMES4.js +23 -0
  34. package/dist/docker-ORXYMES4.js.map +1 -0
  35. package/dist/hook-QYLLBUNK.js +14 -0
  36. package/dist/hook-QYLLBUNK.js.map +1 -0
  37. package/dist/import-CT55AEEE.js +268 -0
  38. package/dist/import-CT55AEEE.js.map +1 -0
  39. package/dist/investigate-2GFD6EWB.js +102 -0
  40. package/dist/investigate-2GFD6EWB.js.map +1 -0
  41. package/dist/lsof-GBLZJBJR.js +22 -0
  42. package/dist/lsof-GBLZJBJR.js.map +1 -0
  43. package/dist/psmem-UB3VCMG3.js +20 -0
  44. package/dist/psmem-UB3VCMG3.js.map +1 -0
  45. package/dist/report_html-2ENM7HLC.js +99 -0
  46. package/dist/report_html-2ENM7HLC.js.map +1 -0
  47. package/dist/server.js +190 -0
  48. package/dist/server.js.map +1 -0
  49. package/dist/setup-NTPRUTMT.js +265 -0
  50. package/dist/setup-NTPRUTMT.js.map +1 -0
  51. package/dist/target-WJE4WFYA.js +36 -0
  52. package/dist/target-WJE4WFYA.js.map +1 -0
  53. package/gemini-extension.json +9 -0
  54. package/hooks/debuganything-hook.mjs +36 -0
  55. package/hooks/hooks.json +10 -0
  56. package/package.json +85 -3
  57. package/server.json +30 -0
  58. package/skills/debug-anything/SKILL.md +102 -0
  59. package/skills/inspect-product/SKILL.md +138 -0
package/dist/cli.js ADDED
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runTool
4
+ } from "./chunk-VGYXHXTY.js";
5
+ import "./chunk-YY6M5RIJ.js";
6
+ import "./chunk-EMR42ZJQ.js";
7
+ import "./chunk-MLDOO673.js";
8
+ import "./chunk-NFL22T3H.js";
9
+ import {
10
+ humanBytes
11
+ } from "./chunk-5BXTDASF.js";
12
+ import "./chunk-5RAKTYW5.js";
13
+ import {
14
+ listSessions,
15
+ pruneSessions
16
+ } from "./chunk-D742WJPT.js";
17
+ import {
18
+ VERSION
19
+ } from "./chunk-32IDKAZK.js";
20
+ import "./chunk-STFC7C5C.js";
21
+
22
+ // src/cli.ts
23
+ import { Command } from "commander";
24
+ import pc from "picocolors";
25
+ var program = new Command();
26
+ program.name("debuganything").description("\u25CE Debug Anything. Observe any running process. No breakpoints, no restarts, no instrumentation.\n https://debuganything.dev").version(VERSION, "-v, --version").option("--json", "print the raw ToolResult JSON").showHelpAfterError();
27
+ function wantJson(cmd) {
28
+ return Boolean(cmd.optsWithGlobals().json);
29
+ }
30
+ async function emit(cmd, result) {
31
+ if (wantJson(cmd)) {
32
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
33
+ } else {
34
+ process.stdout.write(renderHuman(result));
35
+ }
36
+ if (!result.ok) process.exitCode = 1;
37
+ }
38
+ var SEV = { high: pc.red, warn: pc.yellow, info: pc.cyan };
39
+ function renderHuman(r) {
40
+ const out = [];
41
+ const head = `${r.ok ? pc.green("\u2714") : pc.red("\u2716")} ${pc.bold(r.tool)}${r.run_id ? pc.dim(` (${r.run_id})`) : ""}${r.session_id ? pc.dim(` session ${r.session_id}`) : ""} ${pc.dim(`${r.duration_ms} ms`)}`;
42
+ out.push(head);
43
+ if (r.error) out.push(` ${pc.red("error:")} ${r.error}`);
44
+ if (r.findings.length) {
45
+ out.push(pc.bold(" Findings"));
46
+ for (const f of r.findings) {
47
+ const color = SEV[f.severity];
48
+ out.push(` ${color(pad(f.severity.toUpperCase(), 5))} ${f.summary} ${pc.dim(`[${f.confidence}; ${f.evidence_ids.join(",")}]`)}`);
49
+ if (f.detail) out.push(` ${pc.dim(f.detail)}`);
50
+ }
51
+ }
52
+ if (r.evidence.length) {
53
+ out.push(pc.bold(" Evidence"));
54
+ for (const e of r.evidence.slice(0, 25)) {
55
+ out.push(` ${pc.dim(pad(e.id, 4))} ${pad(e.kind, 15)} ${e.summary}${e.artifact ? pc.dim(` \u2192 ${short(e.artifact)}${e.lines ? `:${e.lines[0]}-${e.lines[1]}` : ""}`) : ""}`);
56
+ }
57
+ if (r.evidence.length > 25) out.push(pc.dim(` \u2026 ${r.evidence.length - 25} more (use --json)`));
58
+ }
59
+ if (r.limitations.length) {
60
+ out.push(pc.bold(" Limitations"));
61
+ for (const l of r.limitations) out.push(` ${pc.yellow("!")} ${l}`);
62
+ }
63
+ if (r.artifacts.length) {
64
+ out.push(pc.bold(" Artifacts"));
65
+ for (const a of r.artifacts) out.push(` ${pc.dim("\u2022")} ${a.path} ${pc.dim(`(${a.kind}, ${humanBytes(a.bytes)}${a.truncated ? ", truncated" : ""})`)}`);
66
+ }
67
+ if (r.suggested_next.length) out.push(` ${pc.dim("next:")} ${r.suggested_next.join(", ")}`);
68
+ return out.join("\n") + "\n";
69
+ }
70
+ function pad(s, n) {
71
+ return s.length >= n ? s : s + " ".repeat(n - s.length);
72
+ }
73
+ function short(p) {
74
+ const i = p.lastIndexOf("/");
75
+ return i >= 0 ? p.slice(i + 1) : p;
76
+ }
77
+ program.command("serve").alias("mcp").description("run the MCP server over stdio").action(async () => {
78
+ const { serve } = await import("./server.js");
79
+ await serve();
80
+ });
81
+ program.command("setup").description("register Debug Anything's MCP server and skill with Claude Code / Codex / Cursor / Gemini CLI").option("--yes", "do not ask for confirmation").option("--home <dir>", "home directory to write configs into (for testing)").option("--agents <list>", "comma-separated subset: claude,codex,cursor,gemini").option("--dry-run", "show what would change without writing").option("--no-hooks", "do not install the Claude Code proactive hook").action(async (opts) => {
82
+ const { setup } = await import("./setup-NTPRUTMT.js");
83
+ await setup({ yes: Boolean(opts.yes), home: opts.home, agents: opts.agents?.split(",").map((s) => s.trim()), dryRun: Boolean(opts.dryRun), hooks: opts.hooks !== false });
84
+ });
85
+ program.command("hook").argument("[event]", "PostToolUse | UserPromptSubmit (read from stdin JSON when omitted)").description("agent hook: read a hook event on stdin, print a Debug Anything nudge when the output/prompt shows a runtime-problem signal").action(async (_event) => {
86
+ const { detectTriggers, renderNudge } = await import("./hook-QYLLBUNK.js");
87
+ let raw = "";
88
+ for await (const c of process.stdin) raw += c;
89
+ let ev = {};
90
+ try {
91
+ ev = JSON.parse(raw);
92
+ } catch {
93
+ return;
94
+ }
95
+ const scope = ev.hook_event_name === "UserPromptSubmit" ? "prompt" : "output";
96
+ const text = scope === "prompt" ? String(ev.prompt ?? "") : [ev.tool_response?.stdout, ev.tool_response?.stderr, ev.tool_response?.output].filter(Boolean).join("\n");
97
+ const nudge = renderNudge(detectTriggers(text, scope), scope);
98
+ if (nudge) process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: ev.hook_event_name, additionalContext: nudge } }) + "\n");
99
+ });
100
+ program.command("init").description("set up THIS repo for Debug Anything: .mcp.json + .cursor/mcp.json entries and an agent rule in AGENTS.md/CLAUDE.md (commit them)").option("--dir <path>", "project directory (default: cwd)").option("--dry-run", "show what would change without writing").action(async (opts) => {
101
+ const { init } = await import("./setup-NTPRUTMT.js");
102
+ await init({ dir: opts.dir, dryRun: Boolean(opts.dryRun) });
103
+ });
104
+ program.command("readiness").alias("doctor").description("probe OS, tools on PATH and permissions").action(async function() {
105
+ await emit(this, await runTool("readiness", {}));
106
+ });
107
+ program.command("ps").alias("list-processes").description("list processes to pick a target").option("--filter <text>", "substring filter on command/args/user").option("--limit <n>", "max rows", "50").action(async function(opts) {
108
+ const r = await runTool("list_processes", { filter: opts.filter, limit: Number(opts.limit) });
109
+ if (wantJson(this)) return emit(this, r);
110
+ const rows = r.evidence[0]?.data ?? [];
111
+ process.stdout.write(`${pad("PID", 8)}${pad("USER", 12)}${pad("%CPU", 7)}${pad("RSS", 10)}${pad("CONTAINER", 14)}COMMAND
112
+ `);
113
+ for (const p of rows) {
114
+ process.stdout.write(`${pad(String(p.pid), 8)}${pad(String(p.user).slice(0, 11), 12)}${pad(String(p.cpu), 7)}${pad(humanBytes(Number(p.rss_kb) * 1024), 10)}${pad(String(p.container ?? "-"), 14)}${String(p.comm)} ${pc.dim(String(p.args ?? "").slice(0, 80))}
115
+ `);
116
+ }
117
+ if (!r.ok) await emit(this, r);
118
+ });
119
+ program.command("attach").description("attach to <pid|container|pod> or `-- cmd args...` and print a session id").argument("<target...>", "pid, container, pod, or a command after --").option("--kind <kind>", "pid|container|pod|command (default: auto)").action(async function(targetParts, opts) {
120
+ const target = targetParts.join(" ");
121
+ const kind = opts.kind ?? (targetParts.length > 1 ? "command" : void 0);
122
+ const r = await runTool("attach", { target, kind });
123
+ await emit(this, r);
124
+ if (r.ok && !wantJson(this)) process.stdout.write(`
125
+ ${pc.bold("session:")} ${r.session_id}
126
+ `);
127
+ });
128
+ program.command("detach").requiredOption("--session <id>", "session id").description("stop captures, write report, keep artifacts").action(async function(opts) {
129
+ await emit(this, await runTool("detach", { session_id: opts.session }));
130
+ });
131
+ var sessionTool = (name, tool, desc, extra, map) => {
132
+ let c = program.command(name).description(desc).requiredOption("--session <id>", "session id");
133
+ if (extra) c = extra(c);
134
+ c.action(async function(opts) {
135
+ const args = { session_id: opts.session, ...map ? map(opts) : {} };
136
+ await emit(this, await runTool(tool, args));
137
+ });
138
+ };
139
+ sessionTool(
140
+ "trace",
141
+ "trace_syscalls",
142
+ "strace the target (Linux)",
143
+ (c) => c.option("--duration <s>", "seconds (max 60)", "10").option("--categories <list>", "network,file,process,signal,memory,all", "all"),
144
+ (o) => ({ duration_s: Number(o.duration), categories: String(o.categories).split(",") })
145
+ );
146
+ sessionTool("profile", "profile_cpu", "CPU profile (py-spy / perf / sample)", (c) => c.option("--duration <s>", "seconds (max 60)", "15").option("--consent", "consent for heavy profiling"), (o) => ({ duration_s: Number(o.duration), consent: Boolean(o.consent) }));
147
+ sessionTool("stacks", "dump_stacks", "dump all thread stacks");
148
+ sessionTool("sockets", "inspect_sockets", "listening ports, connections, states, fd counts");
149
+ sessionTool("files", "inspect_files", "open fds by type, growth, deleted-but-open", (c) => c.option("--window <s>", "growth window seconds", "3"), (o) => ({ window_s: Number(o.window) }));
150
+ sessionTool(
151
+ "capture",
152
+ "capture_traffic",
153
+ "tcpdump scoped to the target's ports (requires --consent)",
154
+ (c) => c.option("--duration <s>", "seconds (max 30)", "10").option("--filter <bpf>", "extra BPF filter").option("--consent", "I have authorization to capture this traffic"),
155
+ (o) => ({ duration_s: Number(o.duration), filter: o.filter, consent: Boolean(o.consent) })
156
+ );
157
+ sessionTool("memory", "snapshot_memory", "RSS over time + heap snapshot/retainers", (c) => c.option("--no-heap", "skip heap snapshot").option("--window <s>", "RSS sampling window seconds", "3"), (o) => ({ heap: o.heap !== false, window_s: Number(o.window) }));
158
+ sessionTool("container", "container_info", "docker inspect/stats/logs + cgroup limits");
159
+ program.command("diff").requiredOption("--session <id>", "session id").argument("<a>", "earlier run id (snapshot_memory#1), or <session_id>:<run> for a baseline from another session").argument("<b>", "later run id, e.g. snapshot_memory#2").description("diff two runs \u2014 within a session, or against a recorded healthy baseline session").action(async function(a, b, opts) {
160
+ await emit(this, await runTool("diff_runs", { session_id: opts.session, a, b }));
161
+ });
162
+ program.command("report").requiredOption("--session <id>", "session id").option("--md <file>", "also write markdown to this file").option("--html", "also render a self-contained, shareable report.html (embedded flamegraphs)").description("markdown report of the session").action(async function(opts) {
163
+ const r = await runTool("report", { session_id: opts.session, out: opts.md, html: Boolean(opts.html) });
164
+ if (wantJson(this)) return emit(this, r);
165
+ const md = r.evidence[0]?.data?.markdown_preview;
166
+ if (md) process.stdout.write(md + (md.length >= 3e3 ? "\n\u2026(full report in artifact)\n" : "\n"));
167
+ await emit(this, r);
168
+ });
169
+ program.command("why").alias("investigate").argument("<target...>", "pid, container, pod, or a command after --").option("--symptom <s>", "slow | leak | hang | crash | triage (default: triage)", "triage").option("--kind <kind>", "pid|container|pod|command (default: auto)").option("--wait <s>", "leak: seconds between the two memory snapshots", "15").option("--duration <s>", "profile/trace seconds", "10").description("one-command investigation: attach \u2192 the right tools for the symptom \u2192 report \u2192 detach").action(async function(targetParts, opts) {
170
+ const { investigate, summarizeFindings } = await import("./investigate-2GFD6EWB.js");
171
+ const json = wantJson(this);
172
+ const target = targetParts.join(" ");
173
+ const symptom = ["slow", "leak", "hang", "crash", "triage"].includes(opts.symptom) ? opts.symptom : "triage";
174
+ if (!json) process.stdout.write(`${pc.bold("Debug Anything")} investigating ${pc.cyan(target)} for ${pc.cyan(symptom)} \u2026
175
+
176
+ `);
177
+ const out = await investigate(target, {
178
+ symptom,
179
+ kind: opts.kind ?? (targetParts.length > 1 ? "command" : void 0),
180
+ waitS: Number(opts.wait),
181
+ durationS: Number(opts.duration),
182
+ onResult: (r) => {
183
+ if (!json) process.stdout.write(renderHuman(r) + "\n");
184
+ },
185
+ onNote: (s) => {
186
+ if (!json) process.stdout.write(pc.dim(`\u2026 ${s}
187
+ `));
188
+ }
189
+ });
190
+ if (json) return void process.stdout.write(JSON.stringify(out, null, 2) + "\n");
191
+ const ranked = summarizeFindings(out.results.filter((r) => !["attach", "detach", "report"].includes(r.tool)));
192
+ process.stdout.write(pc.bold("\n=== Summary ===\n"));
193
+ if (!ranked.length) process.stdout.write("no findings \u2014 see limitations above\n");
194
+ for (const f of ranked.slice(0, 12)) process.stdout.write(`${SEV[f.severity](pad(f.severity.toUpperCase(), 5))} ${f.summary} ${pc.dim(`[${f.confidence}; ${f.ref}]`)}
195
+ `);
196
+ if (out.report_path) process.stdout.write(`
197
+ ${pc.dim("report:")} ${out.report_path}
198
+ `);
199
+ if (out.results.some((r) => !r.ok)) process.exitCode = 1;
200
+ });
201
+ program.command("import").argument("<tool>", "strace | fs_usage | perf_script | folded | pyspy_dump | sample | gdb | lldb | lsof | tcpdump").argument("<file>", "raw output file you captured yourself (e.g. with sudo)").requiredOption("--session <id>", "session id").option("--duration <s>", "how long the capture ran (for profiles without timestamps)").description("analyze tool output you captured yourself \u2014 same evidence and findings as a live run").action(async function(tool, file, opts) {
202
+ await emit(this, await runTool("import_artifact", { session_id: opts.session, tool, path: file, duration_s: opts.duration ? Number(opts.duration) : void 0 }));
203
+ });
204
+ program.command("call").argument("<tool>", "MCP tool name, e.g. trace_syscalls").argument("[args]", "JSON object of arguments", "{}").description("call any tool by name with JSON args and print the ToolResult (used by the Python SDK and scripts)").action(async (tool, args) => {
205
+ let parsed;
206
+ try {
207
+ parsed = JSON.parse(args);
208
+ } catch {
209
+ process.stdout.write(JSON.stringify({ ok: false, tool, error: "args must be a JSON object" }) + "\n");
210
+ process.exitCode = 1;
211
+ return;
212
+ }
213
+ const r = await runTool(tool, parsed);
214
+ process.stdout.write(JSON.stringify(r, null, 2) + "\n");
215
+ if (!r.ok) process.exitCode = 1;
216
+ });
217
+ program.command("port").argument("<port>", "TCP/UDP port number").description("who holds a port? (lsof -i :PORT, no session needed)").action(async function(port) {
218
+ const { whoHoldsPort } = await import("./lsof-GBLZJBJR.js");
219
+ const r = await whoHoldsPort(Number(port));
220
+ await emit(this, r);
221
+ });
222
+ var sessions = program.command("sessions").description("manage ~/.debuganything/sessions");
223
+ sessions.command("list").description("list sessions").action(async function() {
224
+ const list = await listSessions();
225
+ if (wantJson(this)) return void process.stdout.write(JSON.stringify(list, null, 2) + "\n");
226
+ if (!list.length) return void process.stdout.write("no sessions\n");
227
+ process.stdout.write(`${pad("SESSION", 26)}${pad("STATE", 10)}${pad("RUNS", 6)}${pad("SIZE", 10)}TARGET
228
+ `);
229
+ for (const s of list) process.stdout.write(`${pad(s.id, 26)}${pad(s.state, 10)}${pad(String(s.runs), 6)}${pad(humanBytes(s.bytes), 10)}${s.target}
230
+ `);
231
+ });
232
+ sessions.command("prune").description("remove detached sessions older than N days (default 7)").option("--days <n>", "age threshold", "7").option("--all", "remove every session").action(async (opts) => {
233
+ const removed = await pruneSessions({ olderThanDays: Number(opts.days), all: Boolean(opts.all) });
234
+ process.stdout.write(removed.length ? `removed ${removed.length}: ${removed.join(", ")}
235
+ ` : "nothing to prune\n");
236
+ });
237
+ program.command("update").description("update Debug Anything to the latest published version").action(async () => {
238
+ const { execa } = await import("execa");
239
+ process.stdout.write(pc.dim("$ npm install --global debuganything@latest\n"));
240
+ const r = await execa("npm", ["install", "--global", "debuganything@latest"], { reject: false, stdio: "inherit" });
241
+ if (r.exitCode !== 0) {
242
+ process.stdout.write(`${pc.yellow("global install failed.")} If you use npx, nothing to do: \`npx -y debuganything@latest\` always fetches the latest.
243
+ `);
244
+ process.exitCode = 1;
245
+ }
246
+ });
247
+ program.parseAsync(process.argv).catch((err) => {
248
+ console.error(pc.red(err instanceof Error ? err.message : String(err)));
249
+ process.exit(1);
250
+ });
251
+ export {
252
+ renderHuman
253
+ };
254
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["/**\n * commander CLI, 1:1 with the MCP tools. `--json` prints the exact ToolResult.\n */\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { runTool } from \"./tools.js\";\nimport type { ToolResult } from \"./contracts.js\";\nimport { listSessions, pruneSessions } from \"./session.js\";\nimport { humanBytes } from \"./evidence.js\";\nimport { VERSION } from \"./version.js\";\n\nconst program = new Command();\nprogram\n .name(\"debuganything\")\n .description(\"◎ Debug Anything. Observe any running process. No breakpoints, no restarts, no instrumentation.\\n https://debuganything.dev\")\n .version(VERSION, \"-v, --version\")\n .option(\"--json\", \"print the raw ToolResult JSON\")\n .showHelpAfterError();\n\nfunction wantJson(cmd: Command): boolean {\n return Boolean(cmd.optsWithGlobals().json);\n}\n\nasync function emit(cmd: Command, result: ToolResult): Promise<void> {\n if (wantJson(cmd)) {\n process.stdout.write(JSON.stringify(result, null, 2) + \"\\n\");\n } else {\n process.stdout.write(renderHuman(result));\n }\n if (!result.ok) process.exitCode = 1;\n}\n\nconst SEV = { high: pc.red, warn: pc.yellow, info: pc.cyan } as const;\n\nexport function renderHuman(r: ToolResult): string {\n const out: string[] = [];\n const head = `${r.ok ? pc.green(\"✔\") : pc.red(\"✖\")} ${pc.bold(r.tool)}${r.run_id ? pc.dim(` (${r.run_id})`) : \"\"}${r.session_id ? pc.dim(` session ${r.session_id}`) : \"\"} ${pc.dim(`${r.duration_ms} ms`)}`;\n out.push(head);\n if (r.error) out.push(` ${pc.red(\"error:\")} ${r.error}`);\n if (r.findings.length) {\n out.push(pc.bold(\" Findings\"));\n for (const f of r.findings) {\n const color = SEV[f.severity];\n out.push(` ${color(pad(f.severity.toUpperCase(), 5))} ${f.summary} ${pc.dim(`[${f.confidence}; ${f.evidence_ids.join(\",\")}]`)}`);\n if (f.detail) out.push(` ${pc.dim(f.detail)}`);\n }\n }\n if (r.evidence.length) {\n out.push(pc.bold(\" Evidence\"));\n for (const e of r.evidence.slice(0, 25)) {\n out.push(` ${pc.dim(pad(e.id, 4))} ${pad(e.kind, 15)} ${e.summary}${e.artifact ? pc.dim(` → ${short(e.artifact)}${e.lines ? `:${e.lines[0]}-${e.lines[1]}` : \"\"}`) : \"\"}`);\n }\n if (r.evidence.length > 25) out.push(pc.dim(` … ${r.evidence.length - 25} more (use --json)`));\n }\n if (r.limitations.length) {\n out.push(pc.bold(\" Limitations\"));\n for (const l of r.limitations) out.push(` ${pc.yellow(\"!\")} ${l}`);\n }\n if (r.artifacts.length) {\n out.push(pc.bold(\" Artifacts\"));\n for (const a of r.artifacts) out.push(` ${pc.dim(\"•\")} ${a.path} ${pc.dim(`(${a.kind}, ${humanBytes(a.bytes)}${a.truncated ? \", truncated\" : \"\"})`)}`);\n }\n if (r.suggested_next.length) out.push(` ${pc.dim(\"next:\")} ${r.suggested_next.join(\", \")}`);\n return out.join(\"\\n\") + \"\\n\";\n}\n\nfunction pad(s: string, n: number): string {\n return s.length >= n ? s : s + \" \".repeat(n - s.length);\n}\nfunction short(p: string): string {\n const i = p.lastIndexOf(\"/\");\n return i >= 0 ? p.slice(i + 1) : p;\n}\n\n// --- commands -------------------------------------------------------------\n\nprogram\n .command(\"serve\")\n .alias(\"mcp\")\n .description(\"run the MCP server over stdio\")\n .action(async () => {\n const { serve } = await import(\"./server.js\");\n await serve();\n });\n\nprogram\n .command(\"setup\")\n .description(\"register Debug Anything's MCP server and skill with Claude Code / Codex / Cursor / Gemini CLI\")\n .option(\"--yes\", \"do not ask for confirmation\")\n .option(\"--home <dir>\", \"home directory to write configs into (for testing)\")\n .option(\"--agents <list>\", \"comma-separated subset: claude,codex,cursor,gemini\")\n .option(\"--dry-run\", \"show what would change without writing\")\n .option(\"--no-hooks\", \"do not install the Claude Code proactive hook\")\n .action(async (opts) => {\n const { setup } = await import(\"./setup.js\");\n await setup({ yes: Boolean(opts.yes), home: opts.home, agents: opts.agents?.split(\",\").map((s: string) => s.trim()), dryRun: Boolean(opts.dryRun), hooks: opts.hooks !== false });\n });\n\nprogram\n .command(\"hook\")\n .argument(\"[event]\", \"PostToolUse | UserPromptSubmit (read from stdin JSON when omitted)\")\n .description(\"agent hook: read a hook event on stdin, print a Debug Anything nudge when the output/prompt shows a runtime-problem signal\")\n .action(async (_event?: string) => {\n const { detectTriggers, renderNudge } = await import(\"./hook.js\");\n let raw = \"\";\n for await (const c of process.stdin) raw += c;\n let ev: any = {};\n try {\n ev = JSON.parse(raw);\n } catch {\n return;\n }\n const scope = ev.hook_event_name === \"UserPromptSubmit\" ? \"prompt\" : \"output\";\n const text = scope === \"prompt\" ? String(ev.prompt ?? \"\") : [ev.tool_response?.stdout, ev.tool_response?.stderr, ev.tool_response?.output].filter(Boolean).join(\"\\n\");\n const nudge = renderNudge(detectTriggers(text, scope), scope);\n if (nudge) process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: ev.hook_event_name, additionalContext: nudge } }) + \"\\n\");\n });\n\nprogram\n .command(\"init\")\n .description(\"set up THIS repo for Debug Anything: .mcp.json + .cursor/mcp.json entries and an agent rule in AGENTS.md/CLAUDE.md (commit them)\")\n .option(\"--dir <path>\", \"project directory (default: cwd)\")\n .option(\"--dry-run\", \"show what would change without writing\")\n .action(async (opts) => {\n const { init } = await import(\"./setup.js\");\n await init({ dir: opts.dir, dryRun: Boolean(opts.dryRun) });\n });\n\nprogram\n .command(\"readiness\")\n .alias(\"doctor\")\n .description(\"probe OS, tools on PATH and permissions\")\n .action(async function (this: Command) {\n await emit(this, await runTool(\"readiness\", {}));\n });\n\nprogram\n .command(\"ps\")\n .alias(\"list-processes\")\n .description(\"list processes to pick a target\")\n .option(\"--filter <text>\", \"substring filter on command/args/user\")\n .option(\"--limit <n>\", \"max rows\", \"50\")\n .action(async function (this: Command, opts) {\n const r = await runTool(\"list_processes\", { filter: opts.filter, limit: Number(opts.limit) });\n if (wantJson(this)) return emit(this, r);\n const rows = (r.evidence[0]?.data as Array<Record<string, unknown>> | undefined) ?? [];\n process.stdout.write(`${pad(\"PID\", 8)}${pad(\"USER\", 12)}${pad(\"%CPU\", 7)}${pad(\"RSS\", 10)}${pad(\"CONTAINER\", 14)}COMMAND\\n`);\n for (const p of rows) {\n process.stdout.write(`${pad(String(p.pid), 8)}${pad(String(p.user).slice(0, 11), 12)}${pad(String(p.cpu), 7)}${pad(humanBytes(Number(p.rss_kb) * 1024), 10)}${pad(String(p.container ?? \"-\"), 14)}${String(p.comm)} ${pc.dim(String(p.args ?? \"\").slice(0, 80))}\\n`);\n }\n if (!r.ok) await emit(this, r);\n });\n\nprogram\n .command(\"attach\")\n .description(\"attach to <pid|container|pod> or `-- cmd args...` and print a session id\")\n .argument(\"<target...>\", \"pid, container, pod, or a command after --\")\n .option(\"--kind <kind>\", \"pid|container|pod|command (default: auto)\")\n .action(async function (this: Command, targetParts: string[], opts) {\n const target = targetParts.join(\" \");\n const kind = opts.kind ?? (targetParts.length > 1 ? \"command\" : undefined);\n const r = await runTool(\"attach\", { target, kind });\n await emit(this, r);\n if (r.ok && !wantJson(this)) process.stdout.write(`\\n${pc.bold(\"session:\")} ${r.session_id}\\n`);\n });\n\nprogram\n .command(\"detach\")\n .requiredOption(\"--session <id>\", \"session id\")\n .description(\"stop captures, write report, keep artifacts\")\n .action(async function (this: Command, opts) {\n await emit(this, await runTool(\"detach\", { session_id: opts.session }));\n });\n\nconst sessionTool = (name: string, tool: string, desc: string, extra?: (c: Command) => Command, map?: (o: Record<string, unknown>) => Record<string, unknown>) => {\n let c = program.command(name).description(desc).requiredOption(\"--session <id>\", \"session id\");\n if (extra) c = extra(c);\n c.action(async function (this: Command, opts: Record<string, unknown>) {\n const args = { session_id: opts.session, ...(map ? map(opts) : {}) };\n await emit(this, await runTool(tool, args));\n });\n};\n\nsessionTool(\n \"trace\",\n \"trace_syscalls\",\n \"strace the target (Linux)\",\n (c) => c.option(\"--duration <s>\", \"seconds (max 60)\", \"10\").option(\"--categories <list>\", \"network,file,process,signal,memory,all\", \"all\"),\n (o) => ({ duration_s: Number(o.duration), categories: String(o.categories).split(\",\") }),\n);\nsessionTool(\"profile\", \"profile_cpu\", \"CPU profile (py-spy / perf / sample)\", (c) => c.option(\"--duration <s>\", \"seconds (max 60)\", \"15\").option(\"--consent\", \"consent for heavy profiling\"), (o) => ({ duration_s: Number(o.duration), consent: Boolean(o.consent) }));\nsessionTool(\"stacks\", \"dump_stacks\", \"dump all thread stacks\");\nsessionTool(\"sockets\", \"inspect_sockets\", \"listening ports, connections, states, fd counts\");\nsessionTool(\"files\", \"inspect_files\", \"open fds by type, growth, deleted-but-open\", (c) => c.option(\"--window <s>\", \"growth window seconds\", \"3\"), (o) => ({ window_s: Number(o.window) }));\nsessionTool(\n \"capture\",\n \"capture_traffic\",\n \"tcpdump scoped to the target's ports (requires --consent)\",\n (c) => c.option(\"--duration <s>\", \"seconds (max 30)\", \"10\").option(\"--filter <bpf>\", \"extra BPF filter\").option(\"--consent\", \"I have authorization to capture this traffic\"),\n (o) => ({ duration_s: Number(o.duration), filter: o.filter, consent: Boolean(o.consent) }),\n);\nsessionTool(\"memory\", \"snapshot_memory\", \"RSS over time + heap snapshot/retainers\", (c) => c.option(\"--no-heap\", \"skip heap snapshot\").option(\"--window <s>\", \"RSS sampling window seconds\", \"3\"), (o) => ({ heap: o.heap !== false, window_s: Number(o.window) }));\nsessionTool(\"container\", \"container_info\", \"docker inspect/stats/logs + cgroup limits\");\n\nprogram\n .command(\"diff\")\n .requiredOption(\"--session <id>\", \"session id\")\n .argument(\"<a>\", \"earlier run id (snapshot_memory#1), or <session_id>:<run> for a baseline from another session\")\n .argument(\"<b>\", \"later run id, e.g. snapshot_memory#2\")\n .description(\"diff two runs — within a session, or against a recorded healthy baseline session\")\n .action(async function (this: Command, a: string, b: string, opts) {\n await emit(this, await runTool(\"diff_runs\", { session_id: opts.session, a, b }));\n });\n\nprogram\n .command(\"report\")\n .requiredOption(\"--session <id>\", \"session id\")\n .option(\"--md <file>\", \"also write markdown to this file\")\n .option(\"--html\", \"also render a self-contained, shareable report.html (embedded flamegraphs)\")\n .description(\"markdown report of the session\")\n .action(async function (this: Command, opts) {\n const r = await runTool(\"report\", { session_id: opts.session, out: opts.md, html: Boolean(opts.html) });\n if (wantJson(this)) return emit(this, r);\n const md = (r.evidence[0]?.data as { markdown_preview?: string } | undefined)?.markdown_preview;\n if (md) process.stdout.write(md + (md.length >= 3000 ? \"\\n…(full report in artifact)\\n\" : \"\\n\"));\n await emit(this, r);\n });\n\nprogram\n .command(\"why\")\n .alias(\"investigate\")\n .argument(\"<target...>\", \"pid, container, pod, or a command after --\")\n .option(\"--symptom <s>\", \"slow | leak | hang | crash | triage (default: triage)\", \"triage\")\n .option(\"--kind <kind>\", \"pid|container|pod|command (default: auto)\")\n .option(\"--wait <s>\", \"leak: seconds between the two memory snapshots\", \"15\")\n .option(\"--duration <s>\", \"profile/trace seconds\", \"10\")\n .description(\"one-command investigation: attach → the right tools for the symptom → report → detach\")\n .action(async function (this: Command, targetParts: string[], opts) {\n const { investigate, summarizeFindings } = await import(\"./investigate.js\");\n const json = wantJson(this);\n const target = targetParts.join(\" \");\n const symptom = [\"slow\", \"leak\", \"hang\", \"crash\", \"triage\"].includes(opts.symptom) ? opts.symptom : \"triage\";\n if (!json) process.stdout.write(`${pc.bold(\"Debug Anything\")} investigating ${pc.cyan(target)} for ${pc.cyan(symptom)} …\\n\\n`);\n const out = await investigate(target, {\n symptom,\n kind: opts.kind ?? (targetParts.length > 1 ? \"command\" : undefined),\n waitS: Number(opts.wait),\n durationS: Number(opts.duration),\n onResult: (r) => {\n if (!json) process.stdout.write(renderHuman(r) + \"\\n\");\n },\n onNote: (s) => {\n if (!json) process.stdout.write(pc.dim(`… ${s}\\n`));\n },\n });\n if (json) return void process.stdout.write(JSON.stringify(out, null, 2) + \"\\n\");\n const ranked = summarizeFindings(out.results.filter((r) => ![\"attach\", \"detach\", \"report\"].includes(r.tool)));\n process.stdout.write(pc.bold(\"\\n=== Summary ===\\n\"));\n if (!ranked.length) process.stdout.write(\"no findings — see limitations above\\n\");\n for (const f of ranked.slice(0, 12)) process.stdout.write(`${SEV[f.severity as keyof typeof SEV](pad(f.severity.toUpperCase(), 5))} ${f.summary} ${pc.dim(`[${f.confidence}; ${f.ref}]`)}\\n`);\n if (out.report_path) process.stdout.write(`\\n${pc.dim(\"report:\")} ${out.report_path}\\n`);\n if (out.results.some((r) => !r.ok)) process.exitCode = 1;\n });\n\nprogram\n .command(\"import\")\n .argument(\"<tool>\", \"strace | fs_usage | perf_script | folded | pyspy_dump | sample | gdb | lldb | lsof | tcpdump\")\n .argument(\"<file>\", \"raw output file you captured yourself (e.g. with sudo)\")\n .requiredOption(\"--session <id>\", \"session id\")\n .option(\"--duration <s>\", \"how long the capture ran (for profiles without timestamps)\")\n .description(\"analyze tool output you captured yourself — same evidence and findings as a live run\")\n .action(async function (this: Command, tool: string, file: string, opts) {\n await emit(this, await runTool(\"import_artifact\", { session_id: opts.session, tool, path: file, duration_s: opts.duration ? Number(opts.duration) : undefined }));\n });\n\nprogram\n .command(\"call\")\n .argument(\"<tool>\", \"MCP tool name, e.g. trace_syscalls\")\n .argument(\"[args]\", \"JSON object of arguments\", \"{}\")\n .description(\"call any tool by name with JSON args and print the ToolResult (used by the Python SDK and scripts)\")\n .action(async (tool: string, args: string) => {\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(args) as Record<string, unknown>;\n } catch {\n process.stdout.write(JSON.stringify({ ok: false, tool, error: \"args must be a JSON object\" }) + \"\\n\");\n process.exitCode = 1;\n return;\n }\n const r = await runTool(tool, parsed);\n process.stdout.write(JSON.stringify(r, null, 2) + \"\\n\");\n if (!r.ok) process.exitCode = 1;\n });\n\nprogram\n .command(\"port\")\n .argument(\"<port>\", \"TCP/UDP port number\")\n .description(\"who holds a port? (lsof -i :PORT, no session needed)\")\n .action(async function (this: Command, port: string) {\n const { whoHoldsPort } = await import(\"./adapters/lsof.js\");\n const r = await whoHoldsPort(Number(port));\n await emit(this, r);\n });\n\nconst sessions = program.command(\"sessions\").description(\"manage ~/.debuganything/sessions\");\nsessions\n .command(\"list\")\n .description(\"list sessions\")\n .action(async function (this: Command) {\n const list = await listSessions();\n if (wantJson(this)) return void process.stdout.write(JSON.stringify(list, null, 2) + \"\\n\");\n if (!list.length) return void process.stdout.write(\"no sessions\\n\");\n process.stdout.write(`${pad(\"SESSION\", 26)}${pad(\"STATE\", 10)}${pad(\"RUNS\", 6)}${pad(\"SIZE\", 10)}TARGET\\n`);\n for (const s of list) process.stdout.write(`${pad(s.id, 26)}${pad(s.state, 10)}${pad(String(s.runs), 6)}${pad(humanBytes(s.bytes), 10)}${s.target}\\n`);\n });\nsessions\n .command(\"prune\")\n .description(\"remove detached sessions older than N days (default 7)\")\n .option(\"--days <n>\", \"age threshold\", \"7\")\n .option(\"--all\", \"remove every session\")\n .action(async (opts) => {\n const removed = await pruneSessions({ olderThanDays: Number(opts.days), all: Boolean(opts.all) });\n process.stdout.write(removed.length ? `removed ${removed.length}: ${removed.join(\", \")}\\n` : \"nothing to prune\\n\");\n });\n\nprogram\n .command(\"update\")\n .description(\"update Debug Anything to the latest published version\")\n .action(async () => {\n const { execa } = await import(\"execa\");\n process.stdout.write(pc.dim(\"$ npm install --global debuganything@latest\\n\"));\n const r = await execa(\"npm\", [\"install\", \"--global\", \"debuganything@latest\"], { reject: false, stdio: \"inherit\" });\n if (r.exitCode !== 0) {\n process.stdout.write(`${pc.yellow(\"global install failed.\")} If you use npx, nothing to do: \\`npx -y debuganything@latest\\` always fetches the latest.\\n`);\n process.exitCode = 1;\n }\n });\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(pc.red(err instanceof Error ? err.message : String(err)));\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ attachInfoFromInspect,
4
+ dockerAdapter,
5
+ dockerInspectForAttach,
6
+ parseDockerInspect,
7
+ parseDockerStats,
8
+ parseDockerTop,
9
+ readCgroupStats
10
+ } from "./chunk-YY6M5RIJ.js";
11
+ import "./chunk-5BXTDASF.js";
12
+ import "./chunk-D742WJPT.js";
13
+ import "./chunk-STFC7C5C.js";
14
+ export {
15
+ attachInfoFromInspect,
16
+ dockerAdapter,
17
+ dockerInspectForAttach,
18
+ parseDockerInspect,
19
+ parseDockerStats,
20
+ parseDockerTop,
21
+ readCgroupStats
22
+ };
23
+ //# sourceMappingURL=docker-ORXYMES4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ HOOK_SCRIPT,
4
+ TRIGGERS,
5
+ detectTriggers,
6
+ renderNudge
7
+ } from "./chunk-7MMXFUUN.js";
8
+ export {
9
+ HOOK_SCRIPT,
10
+ TRIGGERS,
11
+ detectTriggers,
12
+ renderNudge
13
+ };
14
+ //# sourceMappingURL=hook-QYLLBUNK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,268 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ parseFsUsage,
4
+ parseGdbBacktrace,
5
+ parseJstack,
6
+ parseLldbBacktrace,
7
+ parsePySpyDump,
8
+ parseStrace,
9
+ parseTcpdump,
10
+ perfScriptToFolded,
11
+ sampleToFolded,
12
+ summarizeCaptureEvidence,
13
+ summarizeJavaStacks,
14
+ summarizeNativeStacks,
15
+ summarizeProfile,
16
+ summarizePySpyDump,
17
+ summarizeSyscallRecords
18
+ } from "./chunk-MLDOO673.js";
19
+ import {
20
+ parseLsofFields,
21
+ summarizeFiles,
22
+ summarizeSockets
23
+ } from "./chunk-NFL22T3H.js";
24
+ import {
25
+ ResultBuilder,
26
+ humanBytes
27
+ } from "./chunk-5BXTDASF.js";
28
+ import "./chunk-5RAKTYW5.js";
29
+ import "./chunk-D742WJPT.js";
30
+ import {
31
+ LIMITS
32
+ } from "./chunk-STFC7C5C.js";
33
+
34
+ // src/import.ts
35
+ import { readFile, stat } from "fs/promises";
36
+ import { basename } from "path";
37
+
38
+ // src/adapters/goruntime.ts
39
+ function parseGoroutines(raw) {
40
+ const out = [];
41
+ let cur;
42
+ let lastFunc;
43
+ for (const line of raw.split("\n")) {
44
+ const head = line.match(/^goroutine\s+(\d+)\s+\[([^\],]+)(?:,\s*(\d+)\s*minutes)?\]:/);
45
+ if (head) {
46
+ cur = { id: Number(head[1]), state: head[2].trim(), minutes: head[3] ? Number(head[3]) : void 0, frames: [] };
47
+ out.push(cur);
48
+ lastFunc = void 0;
49
+ continue;
50
+ }
51
+ if (!cur) continue;
52
+ const loc = line.match(/^\s+(\S+\.go:\d+)/);
53
+ if (loc && lastFunc) {
54
+ cur.frames[cur.frames.length - 1].loc = loc[1];
55
+ lastFunc = void 0;
56
+ continue;
57
+ }
58
+ const fn = line.match(/^(\S+?)\(.*\)$/) ?? line.match(/^(created by .+)$/);
59
+ if (fn && line && !line.startsWith(" ")) {
60
+ cur.frames.push({ func: fn[1] });
61
+ lastFunc = fn[1];
62
+ }
63
+ }
64
+ return out;
65
+ }
66
+ var BLOCKED_STATES = /^(chan receive|chan send|select|semacquire|sync\.(Mutex|RWMutex)\.|IO wait|sleep|GC assist wait|force gc \(idle\)|sync\.Cond\.Wait)/;
67
+ async function summarizeGoroutines(b, gs, artifact) {
68
+ if (!gs.length) {
69
+ b.limitation("no goroutines parsed (expected `curl localhost:PORT/debug/pprof/goroutine?debug=2` or SIGQUIT dump output)");
70
+ return b.fail("goroutines: none parsed").build();
71
+ }
72
+ const byState = /* @__PURE__ */ new Map();
73
+ for (const g of gs) byState.set(g.state, [...byState.get(g.state) ?? [], g]);
74
+ const states = [...byState].sort((a, c) => c[1].length - a[1].length);
75
+ const summaryEv = b.evidenceOf(
76
+ "stack_summary",
77
+ `${gs.length} goroutine(s): ${states.slice(0, 6).map(([s, v]) => `${s}=${v.length}`).join(" ")}`,
78
+ states.map(([s, v]) => ({ state: s, count: v.length, example_top: v[0]?.frames[0]?.func })),
79
+ { artifact }
80
+ );
81
+ const bySite = /* @__PURE__ */ new Map();
82
+ for (const g of gs) {
83
+ if (!BLOCKED_STATES.test(g.state)) continue;
84
+ const site = `${g.state} @ ${g.frames[0]?.func ?? "?"}`;
85
+ bySite.set(site, [...bySite.get(site) ?? [], g]);
86
+ }
87
+ const hot = [...bySite].sort((a, c) => c[1].length - a[1].length)[0];
88
+ if (hot && hot[1].length >= 100) {
89
+ const g0 = hot[1][0];
90
+ const ev = b.evidenceOf("stack", `${hot[1].length} goroutines parked at ${hot[0]}`, { site: hot[0], example: g0.frames.slice(0, 8).map((f) => `${f.func}${f.loc ? ` (${f.loc})` : ""}`) }, { artifact });
91
+ b.finding(hot[1].length >= 1e3 ? "high" : "warn", `goroutine leak: ${hot[1].length} goroutines blocked at ${hot[0]}${g0.frames[0]?.loc ? ` (${g0.frames[0].loc})` : ""} \u2014 something creates them and never lets them finish`, [ev, summaryEv], "inferred", "Find who spawns them: the `created by` frame in the dump names the call site.");
92
+ }
93
+ const old = gs.filter((g) => (g.minutes ?? 0) >= 10).sort((a, c) => (c.minutes ?? 0) - (a.minutes ?? 0));
94
+ if (old.length) {
95
+ const ev = b.evidenceOf("lock_wait", `${old.length} goroutine(s) blocked \u226510 minutes; oldest ${old[0].minutes} min in ${old[0].state} at ${old[0].frames[0]?.func ?? "?"}`, old.slice(0, 15).map((g) => ({ id: g.id, state: g.state, minutes: g.minutes, top: g.frames[0]?.func, loc: g.frames[0]?.loc })), { artifact });
96
+ b.finding(old[0].minutes >= 60 ? "high" : "warn", `${old.length} goroutine(s) stuck for ${old[0].minutes}+ minutes (${old[0].state} at ${old[0].frames[0]?.func ?? "?"}) \u2014 a peer, channel or lock never delivered`, [ev], "observed");
97
+ }
98
+ const mutex = gs.filter((g) => /^sync\.(Mutex|RWMutex)/.test(g.state) || g.state === "semacquire" && /sync\.\(\*(Mutex|RWMutex)\)/.test(g.frames[0]?.func ?? ""));
99
+ if (mutex.length >= 5) {
100
+ const ev = b.evidenceOf("lock_wait", `${mutex.length} goroutines acquiring mutexes; top site ${mutex[0].frames.find((f) => !/^sync\./.test(f.func))?.func ?? "?"}`, mutex.slice(0, 10).map((g) => ({ id: g.id, top: g.frames.find((f) => !/^sync\./.test(f.func))?.func })), { artifact });
101
+ b.finding("warn", `mutex contention: ${mutex.length} goroutines waiting to lock`, [ev], "observed");
102
+ }
103
+ const running = byState.get("running") ?? [];
104
+ if (!running.length && gs.length > 1 && gs.every((g) => BLOCKED_STATES.test(g.state) || g.state === "runnable")) {
105
+ b.finding(gs.length <= 20 ? "high" : "warn", `no goroutine is running \u2014 all ${gs.length} are parked (${states.slice(0, 3).map(([s, v]) => `${v.length} in ${s}`).join(", ")})`, [summaryEv], "inferred", "If the process should be serving traffic, this is a global stall: check channel senders and lock holders.");
106
+ }
107
+ if (!b.findingCount) b.finding("info", `${gs.length} goroutines, ${running.length} running \u2014 nothing alarming in this snapshot`, [summaryEv]);
108
+ b.next("inspect_sockets", "profile_cpu", "trace_syscalls");
109
+ return b.build();
110
+ }
111
+
112
+ // src/analyze.ts
113
+ var IMPORT_TOOL_MAP = {
114
+ strace: "trace_syscalls",
115
+ fs_usage: "trace_syscalls",
116
+ perf_script: "profile_cpu",
117
+ folded: "profile_cpu",
118
+ pyspy_dump: "dump_stacks",
119
+ sample: "profile_cpu",
120
+ gdb: "dump_stacks",
121
+ lldb: "dump_stacks",
122
+ lsof: "inspect_sockets",
123
+ tcpdump: "capture_traffic",
124
+ jstack: "dump_stacks",
125
+ goroutines: "dump_stacks"
126
+ };
127
+ function spanSeconds(records) {
128
+ const ts = records.map((r) => r.time).filter((t) => Boolean(t));
129
+ if (ts.length < 2) return void 0;
130
+ const toS = (t) => {
131
+ const [h, m, s] = t.split(":");
132
+ return Number(h) * 3600 + Number(m) * 60 + Number(s);
133
+ };
134
+ let span = toS(ts[ts.length - 1]) - toS(ts[0]);
135
+ if (span < 0) span += 86400;
136
+ return Math.max(1, Math.round(span));
137
+ }
138
+ async function analyzeRaw(b, args) {
139
+ const raw = args.raw;
140
+ const art = args.art;
141
+ switch (args.tool) {
142
+ case "strace":
143
+ case "fs_usage": {
144
+ const records = args.tool === "strace" ? parseStrace(raw) : parseFsUsage(raw);
145
+ if (!records.length) return b.fail(`no ${args.tool} records parsed; expected ${args.tool === "strace" ? "strace -f -T -tt" : "fs_usage -w"} output`).build();
146
+ const duration = args.duration_s ?? spanSeconds(records) ?? 1;
147
+ summarizeSyscallRecords(b, records, duration, art);
148
+ if (args.tool === "fs_usage") b.limitation("fs_usage shows file and network calls only; futex/select/kevent waits are not included");
149
+ b.next("profile_cpu", "inspect_sockets");
150
+ return b.build();
151
+ }
152
+ case "perf_script":
153
+ case "folded":
154
+ case "sample": {
155
+ const folded = args.tool === "perf_script" ? perfScriptToFolded(raw) : args.tool === "sample" ? sampleToFolded(raw) : raw;
156
+ if (!folded.trim()) return b.fail(`no stacks parsed from ${args.tool} output`).build();
157
+ await b.writeArtifact("imported-folded.txt", folded, "folded_stacks", "folded stacks");
158
+ const duration = args.duration_s ?? 10;
159
+ if (!args.duration_s) b.limitation("duration not given; assumed 10 s for rate estimates (pass duration_s)");
160
+ const hz = args.tool === "perf_script" ? 99 : args.tool === "sample" ? 1e3 : void 0;
161
+ return summarizeProfile(b, folded, duration, args.tool === "perf_script" ? "perf" : args.tool, hz);
162
+ }
163
+ case "pyspy_dump": {
164
+ const dump = parsePySpyDump(raw);
165
+ if (!dump.threads.length) return b.fail("no threads parsed; expected `py-spy dump` output").build();
166
+ await summarizePySpyDump(b, dump, art, void 0);
167
+ b.limitation("relative source paths could not be resolved (no live process); run with --locals or from the app directory for lock classification");
168
+ return b.build();
169
+ }
170
+ case "jstack": {
171
+ const dump = parseJstack(raw);
172
+ return summarizeJavaStacks(b, dump, art);
173
+ }
174
+ case "goroutines": {
175
+ const gs = parseGoroutines(raw);
176
+ return summarizeGoroutines(b, gs, art);
177
+ }
178
+ case "gdb":
179
+ case "lldb": {
180
+ const threads = args.tool === "gdb" ? parseGdbBacktrace(raw) : parseLldbBacktrace(raw);
181
+ return summarizeNativeStacks(b, threads, art, args.tool);
182
+ }
183
+ case "lsof": {
184
+ const entries = parseLsofFields(raw);
185
+ if (!entries.length) return b.fail("no lsof entries parsed; expected `lsof -nP -F pcufatsinTP` output").build();
186
+ const s = summarizeSockets(entries);
187
+ const f = summarizeFiles(entries);
188
+ const listenEv = b.evidenceOf("socket_summary", s.listening.length ? `listening: ${s.listening.map((l) => `${l.proto} ${l.addr}:${l.port} (pid ${l.pid})`).join(", ")}` : "no listening sockets", s.listening, { artifact: art });
189
+ const stateEv = b.evidenceOf("socket_summary", `${s.total_sockets} inet socket(s): ${Object.entries(s.byState).map(([k, v]) => `${k}=${v}`).join(" ") || "none established"}; udp=${s.udp}; unix=${s.unix_sockets}`, { by_state: s.byState, total: s.total_sockets }, { artifact: art });
190
+ const remoteEv = b.evidenceOf("socket", s.byRemote.length ? `top remotes: ${s.byRemote.slice(0, 5).map((r) => `${r.remote} \xD7${r.count}`).join(", ")}` : "no remote connections", s.byRemote.slice(0, 30), { artifact: art });
191
+ const fdEv = b.evidenceOf("fd_summary", `${f.total_fds} fd(s): ${Object.entries(f.byType).sort((a, c) => c[1] - a[1]).map(([k, v]) => `${k}=${v}`).join(" ")}`, Object.entries(f.byType).map(([type, count]) => ({ type, count })), { artifact: art });
192
+ if (s.listening.length) b.finding("info", `listening on ${s.listening.map((l) => `${l.proto}/${l.port}`).join(", ")}`, [listenEv]);
193
+ const cw = s.byState.CLOSE_WAIT ?? 0;
194
+ if (cw >= 20) b.finding("high", `${cw} sockets in CLOSE_WAIT \u2014 the peer closed and the target never called close()`, [stateEv], "inferred");
195
+ else if (cw >= 5) b.finding("warn", `${cw} sockets in CLOSE_WAIT`, [stateEv], "inferred");
196
+ if ((s.byState.TIME_WAIT ?? 0) >= 100) b.finding("warn", `${s.byState.TIME_WAIT} sockets in TIME_WAIT \u2014 connection churn`, [stateEv], "inferred");
197
+ if (s.byRemote[0] && s.byRemote[0].count >= 50) b.finding("warn", `${s.byRemote[0].count} connections to ${s.byRemote[0].remote}`, [remoteEv], "inferred");
198
+ if (f.deleted.length) {
199
+ const delEv = b.evidenceOf("fd", `${f.deleted.length} deleted-but-open file(s), ${humanBytes(f.deleted.reduce((n, d) => n + d.size, 0))} held`, f.deleted.slice(0, 20), { artifact: art });
200
+ b.finding("high", `${f.deleted.length} file(s) deleted while still open hold ${humanBytes(f.deleted.reduce((n, d) => n + d.size, 0))} of disk`, [delEv]);
201
+ }
202
+ if (b.findingCount === 0) b.finding("info", `${f.total_fds} fds, ${s.total_sockets} inet sockets, nothing alarming`, [fdEv, stateEv]);
203
+ b.next("inspect_files", "trace_syscalls");
204
+ return b.build();
205
+ }
206
+ case "tcpdump": {
207
+ const pkts = parseTcpdump(raw);
208
+ if (!pkts.length) return b.fail("no packets parsed; expected `tcpdump -nn -tt` text output (not a .pcap)").build();
209
+ const freq = /* @__PURE__ */ new Map();
210
+ for (const p of pkts) for (const port of [p.sport, p.dport]) if (port) freq.set(port, (freq.get(port) ?? 0) + 1);
211
+ const local = new Set([...freq].sort((a, c) => c[1] - a[1]).slice(0, 2).map(([p]) => p));
212
+ b.limitation(`local ports inferred as ${[...local].join(", ")} (most frequent); per-remote grouping may be inverted for other flows`);
213
+ summarizeCaptureEvidence(b, pkts, local, { filter: "(imported)", duration: args.duration_s ?? 0, textPath: art });
214
+ return b.build();
215
+ }
216
+ }
217
+ }
218
+ async function analyzeText(tool, raw, opts = {}) {
219
+ const b = new ResultBuilder(IMPORT_TOOL_MAP[tool], { id: "paste", dir: ":memory:" }, { kind: "command", id: "(pasted output)", host: "browser" });
220
+ if (!raw.trim()) return b.fail("pasted text is empty").build();
221
+ const art = await b.writeArtifact(`${tool}.txt`, raw, "raw_text", `pasted ${tool} output`);
222
+ b.limitation("analyzed from pasted output: Debug Anything did not run the tool, so flags, timing and target scope are whatever you used");
223
+ return analyzeRaw(b, { tool, raw, duration_s: opts.duration_s, art });
224
+ }
225
+ function detectTool(raw) {
226
+ const head = raw.slice(0, 2e4);
227
+ if (/^goroutine \d+ \[/m.test(head)) return "goroutines";
228
+ if (/java\.lang\.Thread\.State:/.test(head) || /^Full thread dump /m.test(head)) return "jstack";
229
+ if (/^Process\s+\d+:|^Thread (0x[0-9a-f]+|\d+) \((idle|active)\)/m.test(head)) return "pyspy_dump";
230
+ if (/^\* thread #\d+/m.test(head)) return "lldb";
231
+ if (/^Thread \d+ \(.*\):\s*$/m.test(head) && /^#\d+\s/m.test(head)) return "gdb";
232
+ if (/^Call graph:/m.test(head) || /^Analysis of sampling/m.test(head)) return "sample";
233
+ if (/^p\d+\s*$/m.test(head) && /^f\d+/m.test(head)) return "lsof";
234
+ if (/^\d+\.\d+\s+(\S+\s+(In|Out)\s+)?IP6? /m.test(head) || /^\d{2}:\d{2}:\d{2}\.\d+\s+(\S+\s+(In|Out)\s+)?IP6? /m.test(head)) return "tcpdump";
235
+ if (/^[\w.$:;<>()[\]~/+-]+(;[^ ]+)+ \d+$/m.test(head)) return "folded";
236
+ if (/^\s*[0-9a-f]+ .+ \(.*\)$/m.test(head) && /^\S+\s+\d+(\/\d+)? (\[\d+\] )?\d+\.\d+:/m.test(head)) return "perf_script";
237
+ if (/\b\w+\(.*\)\s+=\s+(-?\d+|0x[0-9a-f]+|\?)/.test(head) && /<\d+\.\d+>|^\d{2}:\d{2}:\d{2}/m.test(head)) return "strace";
238
+ if (/\b\w+\(.*\)\s+=\s+(-?\d+|0x[0-9a-f]+)/.test(head)) return "strace";
239
+ if (/^\d{2}:\d{2}:\d{2}(\.\d+)?\s+\S+/m.test(head) && /\S+\.\d+\s*$/m.test(head)) return "fs_usage";
240
+ return void 0;
241
+ }
242
+
243
+ // src/import.ts
244
+ async function importArtifact(session, args) {
245
+ const toolName = IMPORT_TOOL_MAP[args.tool];
246
+ const b = new ResultBuilder(toolName, session, session.target);
247
+ let raw;
248
+ try {
249
+ const st = await stat(args.path);
250
+ if (!st.isFile()) return b.fail(`${args.path} is not a regular file`).build();
251
+ if (st.size > LIMITS.MAX_RAW_BYTES) return b.fail(`${args.path} is ${Math.round(st.size / 1024 / 1024)} MB; the import cap is ${LIMITS.MAX_RAW_BYTES / 1024 / 1024} MB (trim it first)`).build();
252
+ raw = await readFile(args.path, "utf8");
253
+ } catch (err) {
254
+ return b.fail(`cannot read ${args.path}: ${err.message}`).build();
255
+ }
256
+ if (!raw.trim()) return b.fail(`${args.path} is empty`).build();
257
+ const art = await b.writeArtifact(`imported-${basename(args.path)}`, raw, "raw_text", `imported ${args.tool} output from ${args.path}`);
258
+ b.limitation(`imported from ${args.path}: Debug Anything did not run the tool, so flags, timing and target scope are whatever you used`);
259
+ return analyzeRaw(b, { tool: args.tool, raw, duration_s: args.duration_s, art });
260
+ }
261
+ export {
262
+ IMPORT_TOOL_MAP,
263
+ analyzeText,
264
+ detectTool,
265
+ importArtifact,
266
+ spanSeconds
267
+ };
268
+ //# sourceMappingURL=import-CT55AEEE.js.map