@jaggerxtrm/specialists 3.3.3 → 3.4.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.
- package/README.md +4 -2
- package/bin/install.js +15 -204
- package/config/skills/using-specialists/SKILL.md +1 -1
- package/config/specialists/debugger.specialist.yaml +111 -0
- package/config/specialists/explorer.specialist.yaml +1 -1
- package/dist/index.js +877 -623
- package/package.json +1 -1
- package/config/skills/specialists-usage-workspace/iteration-1/eval-bead-background/old_skill/outputs/result.md +0 -105
- package/config/skills/specialists-usage-workspace/iteration-1/eval-bead-background/with_skill/outputs/result.md +0 -93
- package/config/skills/specialists-usage-workspace/iteration-1/eval-fresh-setup/old_skill/outputs/result.md +0 -113
- package/config/skills/specialists-usage-workspace/iteration-1/eval-fresh-setup/with_skill/outputs/result.md +0 -131
- package/config/skills/specialists-usage-workspace/iteration-1/eval-yaml-debug/old_skill/outputs/result.md +0 -159
- package/config/skills/specialists-usage-workspace/iteration-1/eval-yaml-debug/with_skill/outputs/result.md +0 -150
- package/config/skills/specialists-usage-workspace/iteration-2/eval-bug-investigation/with_skill/outputs/result.md +0 -180
- package/config/skills/specialists-usage-workspace/iteration-2/eval-bug-investigation/with_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/iteration-2/eval-bug-investigation/without_skill/outputs/result.md +0 -223
- package/config/skills/specialists-usage-workspace/iteration-2/eval-bug-investigation/without_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/iteration-2/eval-code-review/with_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/iteration-2/eval-code-review/without_skill/outputs/result.md +0 -146
- package/config/skills/specialists-usage-workspace/iteration-2/eval-code-review/without_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/iteration-2/eval-test-coverage/with_skill/outputs/result.md +0 -89
- package/config/skills/specialists-usage-workspace/iteration-2/eval-test-coverage/with_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/iteration-2/eval-test-coverage/without_skill/outputs/result.md +0 -96
- package/config/skills/specialists-usage-workspace/iteration-2/eval-test-coverage/without_skill/timing.json +0 -5
- package/config/skills/specialists-usage-workspace/skill-snapshot/SKILL.md.old +0 -237
- package/config/specialists/bug-hunt.specialist.yaml +0 -96
package/README.md
CHANGED
|
@@ -28,18 +28,20 @@ specialists list
|
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
sp list
|
|
31
|
-
sp run bug-hunt --bead <id>
|
|
31
|
+
sp run bug-hunt --bead <id>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Tracked work:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
bd create "Investigate auth bug" -t bug -p 1 --json
|
|
38
|
-
specialists run bug-hunt --bead <id>
|
|
38
|
+
specialists run bug-hunt --bead <id>
|
|
39
39
|
specialists feed -f
|
|
40
40
|
bd close <id> --reason "Done"
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
`specialists run` prints `[job started: <id>]` early and also writes the id to `.specialists/jobs/latest`.
|
|
44
|
+
|
|
43
45
|
Ad-hoc work:
|
|
44
46
|
|
|
45
47
|
```bash
|
package/bin/install.js
CHANGED
|
@@ -1,209 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
chmodSync,
|
|
6
|
-
copyFileSync,
|
|
7
|
-
existsSync,
|
|
8
|
-
mkdirSync,
|
|
9
|
-
readdirSync,
|
|
10
|
-
readFileSync,
|
|
11
|
-
writeFileSync,
|
|
12
|
-
} from 'node:fs';
|
|
13
|
-
import { homedir } from 'node:os';
|
|
14
|
-
import { join } from 'node:path';
|
|
3
|
+
// DEPRECATED: This script is deprecated. Use `specialists init` instead.
|
|
15
4
|
|
|
16
|
-
const CWD = process.cwd();
|
|
17
|
-
const CLAUDE_DIR = join(CWD, '.claude');
|
|
18
|
-
const HOOKS_DIR = join(CLAUDE_DIR, 'hooks');
|
|
19
|
-
const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
|
|
20
|
-
const MCP_FILE = join(CWD, '.mcp.json');
|
|
21
|
-
const BUNDLED_HOOKS_DIR = new URL('../hooks', import.meta.url).pathname;
|
|
22
|
-
const BUNDLED_SPECIALISTS_DIR = new URL('../specialists', import.meta.url).pathname;
|
|
23
|
-
const USER_SPECIALISTS_DIR = join(homedir(), '.agents', 'specialists');
|
|
24
|
-
|
|
25
|
-
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
26
|
-
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
27
|
-
const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
|
|
28
5
|
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
function section(label) {
|
|
32
|
-
const line = '─'.repeat(Math.max(0, 44 - label.length));
|
|
33
|
-
console.log(`\n${bold(`── ${label} ${line}`)}`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function ok(label) { console.log(` ${green('✓')} ${label}`); }
|
|
37
|
-
function skip(label) { console.log(` ${yellow('○')} ${label}`); }
|
|
38
|
-
function info(label) { console.log(` ${dim(label)}`); }
|
|
39
|
-
function fail(label) { console.log(` ${red('✗')} ${label}`); }
|
|
40
|
-
|
|
41
|
-
function run(cmd, args, options = {}) {
|
|
42
|
-
return spawnSync(cmd, args, {
|
|
43
|
-
encoding: 'utf8',
|
|
44
|
-
stdio: 'pipe',
|
|
45
|
-
...options,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function commandOk(cmd, args = ['--version']) {
|
|
50
|
-
const result = run(cmd, args);
|
|
51
|
-
return result.status === 0 && !result.error;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function loadJson(path, fallback) {
|
|
55
|
-
if (!existsSync(path)) return structuredClone(fallback);
|
|
56
|
-
try {
|
|
57
|
-
return JSON.parse(readFileSync(path, 'utf8'));
|
|
58
|
-
} catch {
|
|
59
|
-
return structuredClone(fallback);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function saveJson(path, value) {
|
|
64
|
-
writeFileSync(path, JSON.stringify(value, null, 2) + '\n', 'utf8');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function sameFileContent(a, b) {
|
|
68
|
-
if (!existsSync(a) || !existsSync(b)) return false;
|
|
69
|
-
return readFileSync(a, 'utf8') === readFileSync(b, 'utf8');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const HOOKS = [
|
|
73
|
-
{
|
|
74
|
-
event: 'UserPromptSubmit',
|
|
75
|
-
file: 'specialists-complete.mjs',
|
|
76
|
-
timeout: 5000,
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
event: 'SessionStart',
|
|
80
|
-
file: 'specialists-session-start.mjs',
|
|
81
|
-
timeout: 8000,
|
|
82
|
-
},
|
|
83
|
-
];
|
|
84
|
-
|
|
85
|
-
function findHookCommands(settings, event, fileName) {
|
|
86
|
-
const entries = settings?.hooks?.[event];
|
|
87
|
-
if (!Array.isArray(entries)) return [];
|
|
88
|
-
return entries.flatMap((entry) =>
|
|
89
|
-
(entry.hooks ?? [])
|
|
90
|
-
.map((hook) => hook.command)
|
|
91
|
-
.filter((command) => typeof command === 'string' && command.includes(fileName)),
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function ensureHook(settings, hook) {
|
|
96
|
-
const dest = join(HOOKS_DIR, hook.file);
|
|
97
|
-
const source = join(BUNDLED_HOOKS_DIR, hook.file);
|
|
98
|
-
const existingCommands = findHookCommands(settings, hook.event, hook.file);
|
|
99
|
-
const externalOwner = existingCommands.find((command) => command !== dest);
|
|
100
|
-
|
|
101
|
-
if (externalOwner) {
|
|
102
|
-
skip(`${hook.file} already managed externally — deferring`);
|
|
103
|
-
info(`existing command: ${externalOwner}`);
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
mkdirSync(HOOKS_DIR, { recursive: true });
|
|
108
|
-
const changed = !sameFileContent(source, dest);
|
|
109
|
-
if (changed) {
|
|
110
|
-
copyFileSync(source, dest);
|
|
111
|
-
chmodSync(dest, 0o755);
|
|
112
|
-
ok(`${hook.file} installed in .claude/hooks/`);
|
|
113
|
-
} else {
|
|
114
|
-
skip(`${hook.file} already up to date`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
settings.hooks ??= {};
|
|
118
|
-
settings.hooks[hook.event] ??= [];
|
|
119
|
-
settings.hooks[hook.event] = settings.hooks[hook.event].filter(
|
|
120
|
-
(entry) => !(entry.hooks ?? []).some((h) => h.command === dest),
|
|
121
|
-
);
|
|
122
|
-
settings.hooks[hook.event].push({
|
|
123
|
-
hooks: [{ type: 'command', command: dest, timeout: hook.timeout }],
|
|
124
|
-
});
|
|
125
|
-
ok(`${hook.file} registered for ${hook.event}`);
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function installBundledSpecialists() {
|
|
130
|
-
if (!existsSync(BUNDLED_SPECIALISTS_DIR)) {
|
|
131
|
-
skip('bundled specialists dir not found — skipping');
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
mkdirSync(USER_SPECIALISTS_DIR, { recursive: true });
|
|
135
|
-
const files = readdirSync(BUNDLED_SPECIALISTS_DIR).filter(f => f.endsWith('.specialist.yaml'));
|
|
136
|
-
for (const file of files) {
|
|
137
|
-
const source = join(BUNDLED_SPECIALISTS_DIR, file);
|
|
138
|
-
const dest = join(USER_SPECIALISTS_DIR, file);
|
|
139
|
-
if (sameFileContent(source, dest)) {
|
|
140
|
-
skip(`${file} already up to date`);
|
|
141
|
-
} else {
|
|
142
|
-
copyFileSync(source, dest);
|
|
143
|
-
ok(`${file} installed in ~/.agents/specialists/`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function ensureMcpRegistration() {
|
|
149
|
-
const mcp = loadJson(MCP_FILE, { mcpServers: {} });
|
|
150
|
-
mcp.mcpServers ??= {};
|
|
151
|
-
const existing = mcp.mcpServers.specialists;
|
|
152
|
-
const desired = { command: 'specialists', args: [] };
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
existing &&
|
|
156
|
-
existing.command === desired.command &&
|
|
157
|
-
Array.isArray(existing.args) &&
|
|
158
|
-
existing.args.length === 0
|
|
159
|
-
) {
|
|
160
|
-
skip('.mcp.json already registers specialists');
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
mcp.mcpServers.specialists = desired;
|
|
165
|
-
saveJson(MCP_FILE, mcp);
|
|
166
|
-
ok('registered specialists in .mcp.json');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
console.log(`\n${bold('Specialists installer')}`);
|
|
170
|
-
console.log(dim('Project scope: prerequisite check, bundled specialists, hooks, MCP registration'));
|
|
171
|
-
|
|
172
|
-
section('Prerequisite check');
|
|
173
|
-
const prereqs = [
|
|
174
|
-
{ name: 'pi', ok: commandOk('pi', ['--version']), required: true, help: 'Install pi first.' },
|
|
175
|
-
{ name: 'bd', ok: commandOk('bd', ['--version']), required: true, help: 'Install beads (bd) first.' },
|
|
176
|
-
{ name: 'xt', ok: commandOk('xt', ['--version']), required: true, help: 'xtrm-tools is required for hooks and workflow integration.' },
|
|
177
|
-
];
|
|
178
|
-
|
|
179
|
-
let prereqFailed = false;
|
|
180
|
-
for (const prereq of prereqs) {
|
|
181
|
-
if (prereq.ok) {
|
|
182
|
-
ok(`${prereq.name} available`);
|
|
183
|
-
} else {
|
|
184
|
-
prereqFailed = prereqFailed || prereq.required;
|
|
185
|
-
fail(`${prereq.name} not found`);
|
|
186
|
-
info(prereq.help);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (prereqFailed) {
|
|
191
|
-
console.log(`\n${red('Install aborted: required prerequisites are missing.')}`);
|
|
192
|
-
process.exit(1);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
section('Specialists hooks');
|
|
196
|
-
mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
197
|
-
const settings = loadJson(SETTINGS_FILE, {});
|
|
198
|
-
for (const hook of HOOKS) ensureHook(settings, hook);
|
|
199
|
-
saveJson(SETTINGS_FILE, settings);
|
|
200
|
-
ok(`updated ${SETTINGS_FILE}`);
|
|
201
|
-
|
|
202
|
-
section('Bundled specialists');
|
|
203
|
-
installBundledSpecialists();
|
|
204
|
-
|
|
205
|
-
section('MCP registration');
|
|
206
|
-
ensureMcpRegistration();
|
|
6
|
+
const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
|
|
7
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
207
8
|
|
|
208
|
-
console.log(
|
|
209
|
-
console.log(
|
|
9
|
+
console.log('');
|
|
10
|
+
console.log(yellow('⚠ DEPRECATED: `bin/install.js` is deprecated'));
|
|
11
|
+
console.log('');
|
|
12
|
+
console.log(` Use ${bold('specialists init')} instead.`);
|
|
13
|
+
console.log('');
|
|
14
|
+
console.log(' The init command handles all setup tasks:');
|
|
15
|
+
console.log(' • creates specialists/ and .specialists/ directories');
|
|
16
|
+
console.log(' • registers the MCP server in .mcp.json');
|
|
17
|
+
console.log(' • injects workflow context into AGENTS.md/CLAUDE.md');
|
|
18
|
+
console.log('');
|
|
19
|
+
console.log(` ${dim('Run: specialists init --help for full details')}`);
|
|
20
|
+
console.log('');
|
|
@@ -73,7 +73,7 @@ Run `specialists list` to see what's available. Match by task type:
|
|
|
73
73
|
|
|
74
74
|
| Task type | Look for |
|
|
75
75
|
|-----------|----------|
|
|
76
|
-
| Bug / regression investigation | `
|
|
76
|
+
| Bug / regression investigation | `debugger`, `overthinker` |
|
|
77
77
|
| Code review | `parallel-review`, `codebase-explorer` |
|
|
78
78
|
| Test generation | `test-runner` |
|
|
79
79
|
| Architecture / exploration | `codebase-explorer`, `feature-design` |
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
specialist:
|
|
2
|
+
metadata:
|
|
3
|
+
name: debugger
|
|
4
|
+
version: 1.2.0
|
|
5
|
+
description: >-
|
|
6
|
+
Autonomous debugger: given any symptom, error, or stack trace, systematically
|
|
7
|
+
traces call chains with GitNexus, identifies root cause at file:line precision,
|
|
8
|
+
ranks hypotheses, and delivers a prioritized, evidence-backed remediation plan.
|
|
9
|
+
category: debugging
|
|
10
|
+
tags:
|
|
11
|
+
- debugging
|
|
12
|
+
- root-cause
|
|
13
|
+
- investigation
|
|
14
|
+
- remediation
|
|
15
|
+
- gitnexus
|
|
16
|
+
- call-chain
|
|
17
|
+
- autonomous
|
|
18
|
+
updated: "2026-03-27"
|
|
19
|
+
|
|
20
|
+
execution:
|
|
21
|
+
mode: tool
|
|
22
|
+
model: anthropic/claude-sonnet-4-6
|
|
23
|
+
fallback_model: qwen-cli/qwen3-coder-plus
|
|
24
|
+
timeout_ms: 600000
|
|
25
|
+
response_format: markdown
|
|
26
|
+
permission_required: LOW
|
|
27
|
+
thinking_level: low
|
|
28
|
+
|
|
29
|
+
prompt:
|
|
30
|
+
system: |
|
|
31
|
+
You are an autonomous debugger specialist. Given a symptom, error message, or
|
|
32
|
+
stack trace, you conduct a disciplined, tool-driven investigation to identify
|
|
33
|
+
the root cause and deliver an actionable remediation plan.
|
|
34
|
+
|
|
35
|
+
## Investigation Workflow
|
|
36
|
+
|
|
37
|
+
Work through these phases in order. Stop as soon as you have enough evidence.
|
|
38
|
+
|
|
39
|
+
### Phase 0 — GitNexus Triage (preferred, skip if unavailable)
|
|
40
|
+
|
|
41
|
+
Use the knowledge graph to orient yourself before touching any source files.
|
|
42
|
+
|
|
43
|
+
1. `gitnexus_query({query: "<error text or symptom>"})`
|
|
44
|
+
2. `gitnexus_context({name: "<suspect symbol>"})`
|
|
45
|
+
3. Read `gitnexus://repo/{name}/process/{processName}` for execution trace details
|
|
46
|
+
4. Optional: `gitnexus_cypher({query: "MATCH path = ..."})` for custom traversal
|
|
47
|
+
|
|
48
|
+
Then read source files only for pinpointed suspects — never the whole codebase.
|
|
49
|
+
|
|
50
|
+
### Phase 1 — File Discovery (fallback if GitNexus unavailable)
|
|
51
|
+
|
|
52
|
+
Parse the symptom for candidate locations:
|
|
53
|
+
- stack trace file paths + line numbers
|
|
54
|
+
- module/import names in errors
|
|
55
|
+
- error codes or exception types tied to subsystems
|
|
56
|
+
|
|
57
|
+
Use `grep` and `find` to locate code quickly; read only relevant sections.
|
|
58
|
+
|
|
59
|
+
### Phase 2 — Root Cause Analysis
|
|
60
|
+
|
|
61
|
+
Determine:
|
|
62
|
+
- the exact line/expression causing failure
|
|
63
|
+
- causal explanation of observed symptom
|
|
64
|
+
- whether root cause or downstream effect
|
|
65
|
+
- likely side effects on related components
|
|
66
|
+
|
|
67
|
+
### Phase 3 — Hypothesis Ranking
|
|
68
|
+
|
|
69
|
+
Produce 3–5 ranked hypotheses, each with:
|
|
70
|
+
- hypothesis statement
|
|
71
|
+
- supporting evidence
|
|
72
|
+
- quick confirmation experiment/command
|
|
73
|
+
- confidence (HIGH/MEDIUM/LOW)
|
|
74
|
+
|
|
75
|
+
### Phase 4 — Remediation Plan
|
|
76
|
+
|
|
77
|
+
Produce up to 5 prioritized remediation steps with:
|
|
78
|
+
- file/line scope
|
|
79
|
+
- expected outcome
|
|
80
|
+
- verification command
|
|
81
|
+
- residual risks
|
|
82
|
+
|
|
83
|
+
## Output Format
|
|
84
|
+
|
|
85
|
+
Always output a complete **Bug Investigation Report**:
|
|
86
|
+
- Symptoms
|
|
87
|
+
- Investigation path (GitNexus traces or files analyzed)
|
|
88
|
+
- Root cause (with file:line references)
|
|
89
|
+
- Ranked hypotheses
|
|
90
|
+
- Fix plan
|
|
91
|
+
- Concise summary
|
|
92
|
+
|
|
93
|
+
EFFICIENCY RULE: Stop using tools and write the final report after at most 15 tool calls.
|
|
94
|
+
|
|
95
|
+
task_template: |
|
|
96
|
+
Debug the following issue:
|
|
97
|
+
|
|
98
|
+
$prompt
|
|
99
|
+
|
|
100
|
+
Working directory: $cwd
|
|
101
|
+
|
|
102
|
+
Start with gitnexus_query for the symptom/error text if GitNexus is available.
|
|
103
|
+
Then trace call chains with gitnexus_context. Read source files for pinpointed suspects.
|
|
104
|
+
Fall back to grep/find if GitNexus is unavailable. Produce a full Bug Investigation Report.
|
|
105
|
+
|
|
106
|
+
capabilities:
|
|
107
|
+
required_tools: [bash, grep, find, read]
|
|
108
|
+
external_commands: [grep]
|
|
109
|
+
|
|
110
|
+
communication:
|
|
111
|
+
next_specialists: auto-remediation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
specialist:
|
|
2
2
|
metadata:
|
|
3
|
-
name:
|
|
3
|
+
name: explorer
|
|
4
4
|
version: 1.1.0
|
|
5
5
|
description: "Explores the codebase structure, identifies patterns, and answers architecture questions using GitNexus knowledge graph for deep call-chain and execution-flow awareness."
|
|
6
6
|
category: analysis
|