@jaggerxtrm/specialists 3.5.0 → 3.6.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 (37) hide show
  1. package/README.md +12 -1
  2. package/config/hooks/specialists-session-start.mjs +105 -0
  3. package/config/nodes/research-multi.node.json +11 -0
  4. package/config/nodes/research.node.json +27 -0
  5. package/config/presets.json +26 -0
  6. package/config/skills/specialists-creator/SKILL.md +323 -145
  7. package/config/skills/specialists-creator/scripts/scaffold-specialist.ts +228 -0
  8. package/config/skills/using-nodes/SKILL.md +333 -0
  9. package/config/skills/using-specialists/SKILL.md +843 -173
  10. package/config/specialists/debugger.specialist.json +74 -0
  11. package/config/specialists/executor.specialist.json +117 -0
  12. package/config/specialists/explorer.specialist.json +82 -0
  13. package/config/specialists/memory-processor.specialist.json +65 -0
  14. package/config/specialists/node-coordinator.specialist.json +64 -0
  15. package/config/specialists/overthinker.specialist.json +65 -0
  16. package/config/specialists/parallel-review.specialist.json +65 -0
  17. package/config/specialists/planner.specialist.json +93 -0
  18. package/config/specialists/researcher.specialist.json +65 -0
  19. package/config/specialists/reviewer.specialist.json +60 -0
  20. package/config/specialists/specialists-creator.specialist.json +68 -0
  21. package/config/specialists/sync-docs.specialist.json +80 -0
  22. package/config/specialists/test-runner.specialist.json +67 -0
  23. package/config/specialists/xt-merge.specialist.json +60 -0
  24. package/dist/index.js +13818 -2743
  25. package/package.json +6 -3
  26. package/config/specialists/debugger.specialist.yaml +0 -121
  27. package/config/specialists/executor.specialist.yaml +0 -257
  28. package/config/specialists/explorer.specialist.yaml +0 -85
  29. package/config/specialists/memory-processor.specialist.yaml +0 -154
  30. package/config/specialists/overthinker.specialist.yaml +0 -76
  31. package/config/specialists/parallel-review.specialist.yaml +0 -75
  32. package/config/specialists/planner.specialist.yaml +0 -94
  33. package/config/specialists/reviewer.specialist.yaml +0 -142
  34. package/config/specialists/specialists-creator.specialist.yaml +0 -90
  35. package/config/specialists/sync-docs.specialist.yaml +0 -68
  36. package/config/specialists/test-runner.specialist.yaml +0 -65
  37. package/config/specialists/xt-merge.specialist.yaml +0 -159
package/README.md CHANGED
@@ -40,6 +40,13 @@ specialists feed -f
40
40
  bd close <id> --reason "Done"
41
41
  ```
42
42
 
43
+ Merge worktree branches:
44
+
45
+ ```bash
46
+ specialists merge <bead-id> # single chain or epic (topological)
47
+ specialists merge <bead-id> --rebuild # rebuild after merge
48
+ ```
49
+
43
50
  `specialists run` prints `[job started: <id>]` early and also writes the id to `.specialists/jobs/latest`.
44
51
 
45
52
  Ad-hoc work:
@@ -81,6 +88,7 @@ specialists doctor
81
88
  | xtrm / worktree integration | [docs/worktree.md](docs/worktree.md) |
82
89
  | RPC mode notes | [docs/pi-rpc.md](docs/pi-rpc.md) |
83
90
  | Pi subprocess isolation and extensions | [docs/pi-session.md](docs/pi-session.md) |
91
+ | NodeSupervisor architecture, node lifecycle, and `sp node` CLI | [docs/nodes.md](docs/nodes.md) |
84
92
 
85
93
  ## Project structure
86
94
 
@@ -125,11 +133,14 @@ Use `specialists init` instead.
125
133
 
126
134
  ```bash
127
135
  bun run build
128
- bun test
136
+ bun test # bun vitest run (default)
137
+ bun run test:node # node vitest run (subprocess-safe alternative)
129
138
  specialists help
130
139
  specialists quickstart
131
140
  ```
132
141
 
142
+ `test:node` uses plain `node vitest run` as an alternative to `bun --bun vitest`. Useful for executor/codex subprocess chains that may trigger stall detection during vitest's tinypool worker initialization silence.
143
+
133
144
  ## License
134
145
 
135
146
  MIT
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+ // specialists-session-start — Claude Code SessionStart hook
3
+ // Injects specialists context at the start of every session:
4
+ // • Active background jobs (if any)
5
+ // • Available specialists list
6
+ // • Key CLI commands reminder
7
+ //
8
+ // Installed by: specialists init
9
+ // Hook type: SessionStart
10
+
11
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ import { homedir } from 'node:os';
14
+
15
+ const cwd = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
16
+ const HOME = homedir();
17
+ const jobsDir = join(cwd, '.specialists', 'jobs');
18
+ const lines = [];
19
+
20
+ // ── 1. Active background jobs ──────────────────────────────────────────────
21
+ if (existsSync(jobsDir)) {
22
+ let entries = [];
23
+ try { entries = readdirSync(jobsDir); } catch { /* ignore */ }
24
+
25
+ const activeJobs = [];
26
+ for (const jobId of entries) {
27
+ const statusPath = join(jobsDir, jobId, 'status.json');
28
+ if (!existsSync(statusPath)) continue;
29
+ try {
30
+ const s = JSON.parse(readFileSync(statusPath, 'utf-8'));
31
+ if (s.status === 'running' || s.status === 'starting') {
32
+ const elapsed = s.elapsed_s !== undefined ? ` (${s.elapsed_s}s)` : '';
33
+ activeJobs.push(
34
+ ` • ${s.specialist ?? jobId} [${s.status}]${elapsed} → specialists result ${jobId}`
35
+ );
36
+ }
37
+ } catch { /* malformed status.json */ }
38
+ }
39
+
40
+ if (activeJobs.length > 0) {
41
+ lines.push('## Specialists — Active Background Jobs');
42
+ lines.push('');
43
+ lines.push(...activeJobs);
44
+ lines.push('');
45
+ lines.push('Use `specialists feed <job-id> --follow` to stream events, or `specialists result <job-id>` when done.');
46
+ lines.push('');
47
+ }
48
+ }
49
+
50
+ // ── 2. Available specialists (read YAML dirs directly) ────────────────────
51
+ function readSpecialistNames(dir) {
52
+ if (!existsSync(dir)) return [];
53
+ try {
54
+ return readdirSync(dir)
55
+ .filter(f => f.endsWith('.specialist.yaml'))
56
+ .map(f => f.replace('.specialist.yaml', ''));
57
+ } catch {
58
+ return [];
59
+ }
60
+ }
61
+
62
+ const projectNames = readSpecialistNames(join(cwd, 'specialists'));
63
+ const userNames = readSpecialistNames(join(HOME, '.agents', 'specialists'));
64
+
65
+ // Merge, deduplicate, sort
66
+ const allNames = [...new Set([...projectNames, ...userNames])].sort();
67
+
68
+ if (allNames.length > 0) {
69
+ lines.push('## Specialists — Available');
70
+ lines.push('');
71
+ if (projectNames.length > 0) {
72
+ lines.push(`project (${projectNames.length}): ${projectNames.join(', ')}`);
73
+ }
74
+ if (userNames.length > 0) {
75
+ // Only show user-scope names not already in project
76
+ const extraUser = userNames.filter(n => !projectNames.includes(n));
77
+ if (extraUser.length > 0) {
78
+ lines.push(`user (${extraUser.length}): ${extraUser.join(', ')}`);
79
+ }
80
+ }
81
+ lines.push('');
82
+ }
83
+
84
+ // ── 3. Key commands reminder ───────────────────────────────────────────────
85
+ lines.push('## Specialists — Session Quick Reference');
86
+ lines.push('');
87
+ lines.push('```');
88
+ lines.push('specialists list # discover available specialists');
89
+ lines.push('specialists run <name> --prompt "..." # run foreground (streams output)');
90
+ lines.push('specialists run <name> --prompt "..." # run; job ID prints on stderr');
91
+ lines.push('specialists feed <job-id> --follow # tail live events');
92
+ lines.push('specialists result <job-id> # read final output');
93
+ lines.push('specialists status # system health');
94
+ lines.push('specialists doctor # troubleshoot issues');
95
+ lines.push('```');
96
+ lines.push('');
97
+ lines.push('MCP tools: use_specialist (foreground only)');
98
+
99
+ // ── Output ─────────────────────────────────────────────────────────────────
100
+ if (lines.length === 0) process.exit(0);
101
+
102
+ process.stdout.write(JSON.stringify({
103
+ type: 'inject',
104
+ content: lines.join('\n'),
105
+ }) + '\n');
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "research-multi",
3
+ "coordinator": "node-coordinator",
4
+ "members": [],
5
+ "initialPrompt": "You are coordinating a multi-researcher discovery node. There are NO pre-spawned members — you must spawn all members yourself via sp node spawn-member.\n\nYour mission: gather deep, wide research across both the codebase and online sources, then synthesize.\n\nOrchestration plan:\n\nPhase 1 — parallel discovery (spawn all at once, then wait-phase):\n - explorer-1: codebase explorer — map the current context injection pipeline (what gets injected at specialist spawn, where bd prime runs, how runner.ts builds the prompt, what gitnexus cheatsheet injection looks like, token costs)\n - researcher-1: search for agent/LLM context efficiency patterns — how do frontier agent frameworks (LangMem, MemGPT, AgentOS, CrewAI) handle memory retrieval and context injection? token budget strategies?\n - researcher-2: search for bun:sqlite FTS5 and vector/embedding search capabilities — can bun:sqlite do semantic search? what scoring approaches work for memory retrieval without embeddings? SQLite FTS5 rank() function?\n - researcher-3: search for specialist memory system patterns across GitHub — find real implementations of agent memory stores, typed retrieval, decay/scoring. Use ghgrep to find patterns.\n\nPhase 2 — synthesis (spawn after phase 1 evidence is in):\n - overthinker-1: deep analysis of the research findings — design the optimal bd prime filtering strategy and the specialist memory SQLite schema. Critique assumptions. Synthesize across all phase 1 findings.\n\nExecution rules:\n - Spawn all 4 phase-1 members simultaneously, then call wait-phase with all 4 member keys.\n - After wait-phase completes, read ALL member results with sp node result before spawning overthinker.\n - Do not advance to phase 2 until you have read every phase 1 result.\n - After overthinker completes, read its result and synthesize final recommendations, then remain in waiting for operator closure.",
6
+ "memoryNamespace": "research-multi",
7
+ "completion_strategy": "manual",
8
+ "max_retries": 3,
9
+ "default_context_depth": 1,
10
+ "base_branch": "master"
11
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "research",
3
+ "coordinator": "node-coordinator",
4
+ "members": [
5
+ {
6
+ "memberId": "explorer",
7
+ "specialist": "explorer",
8
+ "role": "Codebase exploration and discovery. Read files, search code, map architecture. Report findings."
9
+ },
10
+ {
11
+ "memberId": "overthinker",
12
+ "specialist": "overthinker",
13
+ "role": "Deep multi-phase analysis. Reason about tradeoffs, critique assumptions, synthesize insights."
14
+ },
15
+ {
16
+ "memberId": "researcher",
17
+ "specialist": "researcher",
18
+ "role": "Documentation and code researcher. Targeted lookup via ctx7/deepwiki CLIs, or discovery mode via ghgrep to find real-world patterns across GitHub. Report findings with code examples."
19
+ }
20
+ ],
21
+ "initialPrompt": "You are coordinating a research node with an explorer, an overthinker, and a researcher. Plan an explicit explore phase first, then wait for the phase barrier, read every member result, synthesize the evidence, and decide whether a design or implementation phase is actually needed. On start, launch the explorer for codebase findings. Use the researcher only when external docs or ecosystem patterns are needed. Use the overthinker after evidence is gathered to analyze tradeoffs and synthesize insights. Maintain memory_patch entries (facts, questions, decisions) throughout.",
22
+ "memoryNamespace": "research",
23
+ "completion_strategy": "pr",
24
+ "max_retries": 3,
25
+ "default_context_depth": 1,
26
+ "base_branch": "master"
27
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "cheap": {
3
+ "description": "Low-cost, fast responses — best for exploration and simple tasks",
4
+ "fields": {
5
+ "specialist.execution.model": "dashscope/qwen3.5-plus",
6
+ "specialist.execution.thinking_level": "off",
7
+ "specialist.execution.stall_timeout_ms": 60000
8
+ }
9
+ },
10
+ "medium": {
11
+ "description": "Balanced cost/quality — good default for most tasks",
12
+ "fields": {
13
+ "specialist.execution.model": "anthropic/claude-sonnet-4-6",
14
+ "specialist.execution.thinking_level": "low",
15
+ "specialist.execution.stall_timeout_ms": 120000
16
+ }
17
+ },
18
+ "power": {
19
+ "description": "Maximum capability — complex implementation and reasoning",
20
+ "fields": {
21
+ "specialist.execution.model": "openai-codex/gpt-5.4",
22
+ "specialist.execution.thinking_level": "high",
23
+ "specialist.execution.stall_timeout_ms": 300000
24
+ }
25
+ }
26
+ }