@jaggerxtrm/specialists 3.5.0 → 3.5.1

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 (34) hide show
  1. package/README.md +1 -0
  2. package/config/hooks/specialists-session-start.mjs +105 -0
  3. package/config/presets.json +26 -0
  4. package/config/skills/specialists-creator/SKILL.md +323 -145
  5. package/config/skills/specialists-creator/scripts/scaffold-specialist.ts +228 -0
  6. package/config/skills/using-specialists/SKILL.md +644 -173
  7. package/config/specialists/debugger.specialist.json +74 -0
  8. package/config/specialists/executor.specialist.json +117 -0
  9. package/config/specialists/explorer.specialist.json +82 -0
  10. package/config/specialists/memory-processor.specialist.json +64 -0
  11. package/config/specialists/node-coordinator.specialist.json +315 -0
  12. package/config/specialists/overthinker.specialist.json +65 -0
  13. package/config/specialists/parallel-review.specialist.json +65 -0
  14. package/config/specialists/planner.specialist.json +93 -0
  15. package/config/specialists/researcher.specialist.json +64 -0
  16. package/config/specialists/reviewer.specialist.json +60 -0
  17. package/config/specialists/specialists-creator.specialist.json +68 -0
  18. package/config/specialists/sync-docs.specialist.json +80 -0
  19. package/config/specialists/test-runner.specialist.json +67 -0
  20. package/config/specialists/xt-merge.specialist.json +60 -0
  21. package/dist/index.js +8461 -1708
  22. package/package.json +5 -3
  23. package/config/specialists/debugger.specialist.yaml +0 -121
  24. package/config/specialists/executor.specialist.yaml +0 -257
  25. package/config/specialists/explorer.specialist.yaml +0 -85
  26. package/config/specialists/memory-processor.specialist.yaml +0 -154
  27. package/config/specialists/overthinker.specialist.yaml +0 -76
  28. package/config/specialists/parallel-review.specialist.yaml +0 -75
  29. package/config/specialists/planner.specialist.yaml +0 -94
  30. package/config/specialists/reviewer.specialist.yaml +0 -142
  31. package/config/specialists/specialists-creator.specialist.yaml +0 -90
  32. package/config/specialists/sync-docs.specialist.yaml +0 -68
  33. package/config/specialists/test-runner.specialist.yaml +0 -65
  34. package/config/specialists/xt-merge.specialist.yaml +0 -159
package/README.md CHANGED
@@ -81,6 +81,7 @@ specialists doctor
81
81
  | xtrm / worktree integration | [docs/worktree.md](docs/worktree.md) |
82
82
  | RPC mode notes | [docs/pi-rpc.md](docs/pi-rpc.md) |
83
83
  | Pi subprocess isolation and extensions | [docs/pi-session.md](docs/pi-session.md) |
84
+ | NodeSupervisor architecture, node lifecycle, and `sp node` CLI | [docs/nodes.md](docs/nodes.md) |
84
85
 
85
86
  ## Project structure
86
87
 
@@ -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,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
+ }