adaptive-director-skill 0.1.1 → 1.1.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 (28) hide show
  1. package/README.md +132 -36
  2. package/package.json +8 -6
  3. package/scripts/cli.mjs +55 -0
  4. package/scripts/discover.mjs +99 -20
  5. package/scripts/doctor.mjs +141 -0
  6. package/scripts/install.mjs +97 -0
  7. package/scripts/refresh.mjs +62 -0
  8. package/scripts/setup.mjs +149 -123
  9. package/scripts/smoke-test.mjs +138 -89
  10. package/{SKILL.md → skills/adaptive-director/SKILL.md} +11 -11
  11. package/skills/adaptive-director/data/registry.json +103 -0
  12. package/skills/adaptive-director/examples/clean-run-walkthrough.md +83 -0
  13. package/skills/adaptive-director/examples/critical-fix-cycle-walkthrough.md +70 -0
  14. package/{references → skills/adaptive-director/references}/capability-registry.md +17 -10
  15. package/skills/adaptive-director/scripts/discover-models.mjs +198 -0
  16. package/skills/adaptive-director/scripts/route.mjs +355 -0
  17. package/skills/adaptive-director/templates/fix-brief.md +27 -0
  18. package/skills/adaptive-director/templates/implement-brief.md +28 -0
  19. package/skills/adaptive-director/templates/plan-brief.md +31 -0
  20. package/skills/adaptive-director/templates/review-brief.md +42 -0
  21. package/skills/adaptive-director/templates/verify-brief.md +28 -0
  22. package/data/registry.json +0 -42
  23. package/scripts/route.mjs +0 -244
  24. /package/{references → skills/adaptive-director/references}/delegate-integration.md +0 -0
  25. /package/{references → skills/adaptive-director/references}/handoff-schema.md +0 -0
  26. /package/{references → skills/adaptive-director/references}/routing-rules.md +0 -0
  27. /package/{scripts → skills/adaptive-director/scripts}/resume.mjs +0 -0
  28. /package/{scripts → skills/adaptive-director/scripts}/run-state.mjs +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/adaptive-director-skill.svg)](https://www.npmjs.com/package/adaptive-director-skill)
4
4
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg)](https://nodejs.org)
5
- [![Zero Dependencies](https://img.shields.io/badge/dependencies-0%20(pure%20built--ins)-blue.svg)](#architecture)
5
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0%20(pure%20built--ins)-blue.svg)](#core-principles)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
 
8
8
  > **One task in. The right agents take it from there.**
@@ -59,31 +59,59 @@ flowchart LR
59
59
 
60
60
  Adaptive Director runs with **zero external npm dependencies** (pure Node.js built-ins).
61
61
 
62
- ### 1. Install & Setup
62
+ ### 1. Install Globally
63
63
 
64
- Via npm:
65
64
  ```bash
66
- npm install adaptive-director-skill
65
+ npm install -g adaptive-director-skill
67
66
  ```
68
67
 
69
- Or clone directly:
68
+ ### 2. Set Up
69
+
70
+ > `adaptive-director setup` registers the Skill with your coding-agent hosts, discovers available agents, detects optional delegate-skills integration, and creates the local Adaptive Director configuration.
71
+
70
72
  ```bash
71
- git clone https://github.com/tamourax/Adaptive-Orchestrator.git
72
- cd Adaptive-Orchestrator
73
+ adaptive-director setup
73
74
  ```
74
75
 
75
- Initialize local configuration and run verification:
76
+ Or without a global install:
77
+
76
78
  ```bash
77
- node scripts/setup.mjs
78
- node scripts/smoke-test.mjs
79
+ npx adaptive-director-skill setup
80
+ ```
81
+
82
+ ### 3. Verify
83
+
84
+ ```bash
85
+ adaptive-director doctor
86
+ ```
87
+
88
+ Expected output:
89
+ ```
90
+ ✓ Package installed
91
+ ✓ Skill source exists
92
+ ✓ SKILL.md exists
93
+ ✓ references/ exists
94
+ ✓ templates/ exists
95
+ ✓ examples/ exists
96
+ ✓ Registry exists
97
+ ✓ Registry valid
98
+ ✓ Config exists
99
+ ✓ Config valid
100
+ ✓ Routing script works
101
+ ✓ Run state script exists
102
+ ✓ Resume script exists
103
+ ✓ codex detected
104
+ ✓ Skill installed for codex
105
+
106
+ Ready.
79
107
  ```
80
108
 
81
- ### 2. Run with Your AI Agent
109
+ ### 4. Run with Your AI Agent
82
110
 
83
- Load `SKILL.md` into your coding agent (Claude Code, Antigravity, Codex, etc.) and prompt:
111
+ The Skill is now installed in your agent's skills directory. Prompt your agent:
84
112
 
85
113
  ```text
86
- Use $adaptive-director-skill to implement Stripe checkout in Flutter
114
+ Use $adaptive-director to implement Stripe checkout in Flutter
87
115
  ```
88
116
 
89
117
  ---
@@ -103,34 +131,53 @@ Use $adaptive-director-skill to implement Stripe checkout in Flutter
103
131
 
104
132
  ---
105
133
 
106
- ## Architecture
134
+ ## Repository Architecture
135
+
136
+ The repository separates the **npm management/installer layer** from the **self-contained Agent Skill**:
107
137
 
108
- > *"Reasoning stays with agents. Deterministic operations stay in scripts."*
138
+ - **Repository Root:** npm distribution, CLI tools, setup, host discovery, and health diagnostics (`scripts/`).
139
+ - **`skills/adaptive-director/`:** The canonical, portable Agent Skill (procedural brain, runtime scripts, templates, references, and registry data).
109
140
 
110
141
  ```text
111
- adaptive-director/
112
- ├── SKILL.md # The brain: instructions read by your AI agent
113
- ├── data/registry.json # Baseline model capability scores (1–5)
114
- ├── references/ # Handoff schemas, rules, and delegate docs
115
- └── scripts/ # Deterministic Node.js helpers (pure built-ins)
116
- ├── discover.mjs # Detects local agent CLIs
117
- ├── route.mjs # Computes agent + effort assignments
118
- ├── run-state.mjs # Manages isolated phase briefs & workspaces
119
- └── resume.mjs # Recovers interrupted runs
142
+ Adaptive-Director-Skill/
143
+ ├── scripts/ # Management & CLI layer
144
+ ├── cli.mjs # Main CLI router
145
+ ├── setup.mjs # Interactive host setup
146
+ │ ├── install.mjs # Idempotent skill copier
147
+ ├── refresh.mjs # Safe config refresher
148
+ ├── discover.mjs # Local agent discovery
149
+ ├── doctor.mjs # Installation diagnostics
150
+ └── smoke-test.mjs # Automated test suite
151
+
152
+ └── skills/adaptive-director/ # Portable Agent Skill (the brain)
153
+ ├── SKILL.md # Procedural runbook
154
+ ├── scripts/ # Runtime scripts (route, run-state, resume)
155
+ ├── references/ # Deep documentation & schemas
156
+ ├── templates/ # Standardized phase brief templates
157
+ ├── examples/ # Realistic execution walkthroughs
158
+ └── data/ # Capability registry
120
159
  ```
121
160
 
122
- ### Routing Priority Order
161
+ ---
123
162
 
124
- 1. **User Overrides:** Explicit settings in `~/.adaptive-director/config.yaml`
125
- 2. **Delegate Lanes:** Optional `delegate-skills` fleet lanes (when `--delegate` is active)
126
- 3. **Capability Registry:** Best available local model meeting phase requirements
127
- 4. **Fallback:** Default host agent
163
+ ## CLI Commands
164
+
165
+ ```bash
166
+ adaptive-director setup # Interactive: discover hosts, install Skill, create config
167
+ adaptive-director install # Re-install/update Skill in host directories
168
+ adaptive-director refresh # Re-discover hosts & update config (preserves overrides)
169
+ adaptive-director doctor # Validate installation and health
170
+ adaptive-director help # Show usage
171
+ ```
128
172
 
129
173
  ---
130
174
 
131
175
  ## Core Principles
132
176
 
177
+ - **Dynamic Discovery:** Discovers installed host CLIs and inspects locally available models at runtime rather than assuming static pairings.
178
+ - **Routing Priority:** User overrides → Delegate fleet lanes → Dynamic Host Discovery → Capability registry → Default fallback.
133
179
  - **Independent Review:** The coder never reviews its own work.
180
+ - **Verification Dimension:** Independent verification requires dedicated verification capabilities (`min_verification: 3`).
134
181
  - **Max Reasoning Opt-in:** `max` effort is locked by default; requires `--allow-max`.
135
182
  - **Runaway Loop Protection:** Maximum 1 automated fix cycle before alerting the user.
136
183
  - **Context Isolation:** Each agent receives only a self-contained brief on disk (`.adaptive-director/runs/`), preventing context window bloat.
@@ -138,19 +185,68 @@ adaptive-director/
138
185
 
139
186
  ---
140
187
 
141
- ## Configuration (`~/.adaptive-director/config.yaml`)
188
+ ## Dynamic Model Discovery & Heuristics
189
+
190
+ Adaptive Director does **not** rely on rigid, hardcoded host-to-model pairings. Real-world model availability depends on local CLI versions, host configurations, and account subscriptions.
191
+
192
+ ### Routing Pipeline
193
+
194
+ ```text
195
+ Detect Host CLI
196
+
197
+ Discover Locally Available Models (cache / config / env)
198
+
199
+ Resolve Aliases (e.g. 'astra' → 'gpt-6-astra')
200
+
201
+ Intersect with Registry Capabilities & Phase Requirements
202
+
203
+ Score Compatible Candidates for Current Phase
204
+
205
+ Route to Optimal Candidate (with Graceful Fallback)
206
+ ```
207
+
208
+ > [!NOTE]
209
+ > **Heuristic Calibration Disclaimer:** Capability scores (1–5) in `data/registry.json` represent internal routing heuristics and priors calibrated for phase allocation. They are **not** vendor laboratory benchmarks or absolute leaderboards.
210
+
211
+ ---
212
+
213
+ ## Configuration (`~/.adaptive-director/config.json`)
214
+
215
+ ```json
216
+ {
217
+ "version": 1,
218
+ "defaultBudget": "balanced",
219
+ "overrides": {
220
+ "plan": "claude",
221
+ "implement": "codex"
222
+ }
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Upgrading
142
229
 
143
- ```yaml
144
- defaultBudget: balanced # conservative | balanced | quality
230
+ After a package upgrade, re-install the Skill into your host environments:
145
231
 
146
- # Optional overrides:
147
- agentOverrides.plan: claude
148
- agentOverrides.implement: codex
149
- agentOverrides.review: claude
232
+ ```bash
233
+ npm install -g adaptive-director-skill@latest
234
+ adaptive-director install
235
+ adaptive-director doctor
150
236
  ```
151
237
 
152
238
  ---
153
239
 
240
+ ## Uninstalling
241
+
242
+ ```bash
243
+ npm uninstall -g adaptive-director-skill
244
+ ```
245
+
246
+ > **Note:** npm uninstall removes the package, but does **not** remove Skill copies that were installed into your coding-agent host directories. To clean those up, manually delete the `Adaptive-Director/` folder from each host skill directory (e.g. `~/.codex/skills/Adaptive-Director/`).
247
+
248
+ ---
249
+
154
250
  ## License
155
251
 
156
252
  MIT License © 2026 [Ahmed Tamer](https://github.com/tamourax). See [LICENSE](LICENSE) for details.
package/package.json CHANGED
@@ -1,26 +1,28 @@
1
1
  {
2
2
  "name": "adaptive-director-skill",
3
- "version": "0.1.1",
3
+ "version": "1.1.0",
4
4
  "description": "Adaptive Director Skill — Skill-first adaptive multi-agent orchestration for AI coding agents",
5
5
  "type": "module",
6
+ "bin": {
7
+ "adaptive-director": "scripts/cli.mjs"
8
+ },
6
9
  "license": "MIT",
7
10
  "author": "Ahmed Tamer",
8
11
  "repository": {
9
12
  "type": "git",
10
- "url": "https://github.com/tamourax/Adaptive-Orchestrator.git"
13
+ "url": "git+https://github.com/tamourax/Adaptive-Director-Skill.git"
11
14
  },
12
15
  "files": [
13
- "SKILL.md",
14
16
  "README.md",
15
17
  "LICENSE",
16
18
  "scripts/",
17
- "references/",
18
- "data/"
19
+ "skills/"
19
20
  ],
20
21
  "scripts": {
21
22
  "test": "node scripts/smoke-test.mjs",
22
23
  "setup": "node scripts/setup.mjs",
23
- "discover": "node scripts/discover.mjs"
24
+ "discover": "node scripts/discover.mjs",
25
+ "doctor": "node scripts/doctor.mjs"
24
26
  },
25
27
  "keywords": [
26
28
  "ai",
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import fs from 'node:fs';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ const args = process.argv.slice(2);
11
+ const command = args[0] || 'help';
12
+
13
+ const commands = {
14
+ setup: 'setup.mjs',
15
+ install: 'install.mjs',
16
+ refresh: 'refresh.mjs',
17
+ doctor: 'doctor.mjs',
18
+ };
19
+
20
+ if (command === 'help' || command === '--help' || command === '-h') {
21
+ console.log(`Adaptive Director Skill CLI v1.1.0
22
+
23
+ Usage:
24
+ adaptive-director <command>
25
+
26
+ Commands:
27
+ setup - Initial interactive setup and installation
28
+ install - Install/copy the Skill into supported host skill directories
29
+ refresh - Re-run discovery and update config without destroying user overrides
30
+ doctor - Validate installation and report health
31
+ help - Show this help message
32
+ `);
33
+ process.exit(0);
34
+ }
35
+
36
+ const targetScript = commands[command];
37
+
38
+ if (!targetScript) {
39
+ console.error(`Unknown command: ${command}`);
40
+ console.log(`Run 'adaptive-director help' for usage.`);
41
+ process.exit(1);
42
+ }
43
+
44
+ const scriptPath = path.join(__dirname, targetScript);
45
+
46
+ if (!fs.existsSync(scriptPath)) {
47
+ console.error(`Command not yet implemented: ${command}`);
48
+ process.exit(1);
49
+ }
50
+
51
+ const result = spawnSync('node', [scriptPath, ...args.slice(1)], {
52
+ stdio: 'inherit'
53
+ });
54
+
55
+ process.exit(result.status ?? 1);
@@ -16,19 +16,20 @@ import { execFileSync, execSync } from 'node:child_process'
16
16
  import { existsSync, readFileSync } from 'node:fs'
17
17
  import { join } from 'node:path'
18
18
  import { homedir } from 'node:os'
19
+ import { discoverHostModels } from '../skills/adaptive-director/scripts/discover-models.mjs'
19
20
 
20
21
  // ─── Known agents ─────────────────────────────────────────────────────────────
21
22
 
22
23
  const KNOWN_AGENTS = [
23
- { id: 'claude', bins: ['claude'], versionArgs: ['--version'] },
24
- { id: 'codex', bins: ['codex'], versionArgs: ['--version'] },
25
- { id: 'agy', bins: ['agy'], versionArgs: ['--version'] },
26
- { id: 'gemini', bins: ['gemini'], versionArgs: ['--version'] },
27
- { id: 'opencode', bins: ['opencode'], versionArgs: ['--version'] },
28
- { id: 'aider', bins: ['aider'], versionArgs: ['--version'] },
29
- { id: 'cursor', bins: ['cursor-agent'], versionArgs: ['--version'] },
30
- { id: 'cline', bins: ['cline'], versionArgs: ['--version'] },
31
- { id: 'copilot', bins: ['copilot'], versionArgs: ['--version'] },
24
+ { id: 'claude', bins: ['claude'], versionArgs: ['--version'], skillPaths: ['.claude/skills', '.config/claude/skills'] },
25
+ { id: 'codex', bins: ['codex'], versionArgs: ['--version'], skillPaths: ['.codex/skills'] },
26
+ { id: 'agy', bins: ['agy'], versionArgs: ['--version'], skillPaths: ['.gemini/antigravity/builtin/skills', '.gemini/antigravity/skills', '.gemini/antigravity-ide/skills'] },
27
+ { id: 'gemini', bins: ['gemini'], versionArgs: ['--version'], skillPaths: ['.gemini/skills'] },
28
+ { id: 'opencode', bins: ['opencode'], versionArgs: ['--version'], skillPaths: ['.opencode/skills'] },
29
+ { id: 'aider', bins: ['aider'], versionArgs: ['--version'], skillPaths: ['.aider/skills'] },
30
+ { id: 'cursor', bins: ['cursor-agent'], versionArgs: ['--version'], skillPaths: ['.cursor/skills'] },
31
+ { id: 'cline', bins: ['cline'], versionArgs: ['--version'], skillPaths: ['.cline/skills'] },
32
+ { id: 'copilot', bins: ['copilot'], versionArgs: ['--version'], skillPaths: ['.copilot/skills'] },
32
33
  ]
33
34
 
34
35
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -88,19 +89,83 @@ function readFleet(path) {
88
89
  }
89
90
  }
90
91
 
92
+ function readJsonConfig(path) {
93
+ if (!existsSync(path)) return null
94
+ try {
95
+ const raw = JSON.parse(readFileSync(path, 'utf8'))
96
+ if (raw.lanes && typeof raw.lanes === 'object') {
97
+ const result = {}
98
+ for (const [lane, def] of Object.entries(raw.lanes)) {
99
+ result[lane] = {
100
+ agent: def.implementer ?? def.agent,
101
+ model: def.model ?? null,
102
+ effort: def.effort ?? def.variant ?? null,
103
+ implementer: def.implementer ?? def.agent,
104
+ }
105
+ }
106
+ return Object.keys(result).length > 0 ? result : null
107
+ }
108
+ } catch {}
109
+ return null
110
+ }
111
+
91
112
  function discoverDelegate() {
92
- const globalPath = join(homedir(), '.delegate', 'fleet.yaml')
93
- const projectPath = join(process.cwd(), '.delegate', 'fleet.yaml')
113
+ const paths = [
114
+ join(process.cwd(), '.delegate', 'fleet.yaml'),
115
+ join(homedir(), '.delegate', 'fleet.yaml'),
116
+ join(process.cwd(), '.delegate', 'config.json'),
117
+ join(homedir(), '.config', 'delegate-skills', 'config.json'),
118
+ ]
119
+
120
+ let lanes = {}
121
+ for (const p of paths) {
122
+ if (p.endsWith('.json')) {
123
+ const jsonLanes = readJsonConfig(p)
124
+ if (jsonLanes) lanes = { ...lanes, ...jsonLanes }
125
+ } else {
126
+ const fleetLanes = readFleet(p)
127
+ if (fleetLanes) lanes = { ...lanes, ...fleetLanes }
128
+ }
129
+ }
94
130
 
95
- const globalLanes = readFleet(globalPath)
96
- const projectLanes = readFleet(projectPath)
131
+ // Check if delegate-skills is installed on disk
132
+ const agentsSkillsDir = join(homedir(), '.agents', 'skills')
133
+ const codexSkillsDir = join(homedir(), '.codex', 'skills')
134
+ const hasAgentsSkills = existsSync(join(agentsSkillsDir, 'delegate-setup')) ||
135
+ existsSync(join(agentsSkillsDir, 'codex-delegate')) ||
136
+ existsSync(join(agentsSkillsDir, 'agy-delegate')) ||
137
+ existsSync(join(codexSkillsDir, 'delegate-review-loop'))
138
+
139
+ let hasSkillLock = false
140
+ const skillLockPath = join(homedir(), '.agents', '.skill-lock.json')
141
+ if (existsSync(skillLockPath)) {
142
+ try {
143
+ const lockContent = readFileSync(skillLockPath, 'utf8')
144
+ if (lockContent.includes('delegate-skills')) hasSkillLock = true
145
+ } catch {}
146
+ }
147
+
148
+ const installed = Object.keys(lanes).length > 0 || hasAgentsSkills || hasSkillLock
97
149
 
98
- if (!globalLanes && !projectLanes) {
99
- return { installed: false, lanes: {} }
150
+ // If installed but no explicit fleet lanes file configured, synthesize lanes from installed delegate skills
151
+ if (installed && Object.keys(lanes).length === 0 && hasAgentsSkills) {
152
+ if (existsSync(join(agentsSkillsDir, 'codex-delegate'))) {
153
+ lanes.feature = { agent: 'codex', implementer: 'codex' }
154
+ lanes.implement = { agent: 'codex', implementer: 'codex' }
155
+ lanes.fix = { agent: 'codex', implementer: 'codex' }
156
+ }
157
+ if (existsSync(join(agentsSkillsDir, 'agy-delegate'))) {
158
+ lanes.plan = { agent: 'agy', implementer: 'agy' }
159
+ lanes.review = { agent: 'agy', implementer: 'agy' }
160
+ lanes.verify = { agent: 'agy', implementer: 'agy' }
161
+ }
100
162
  }
101
163
 
102
- const merged = { ...(globalLanes ?? {}), ...(projectLanes ?? {}) }
103
- return { installed: true, lanes: merged }
164
+ return {
165
+ installed,
166
+ lanes,
167
+ source: hasSkillLock ? 'amElnagdy/delegate-skills' : (hasAgentsSkills ? 'local-skills' : (Object.keys(lanes).length > 0 ? 'fleet-config' : null))
168
+ }
104
169
  }
105
170
 
106
171
  // ─── Main ─────────────────────────────────────────────────────────────────────
@@ -116,10 +181,24 @@ function discover() {
116
181
  }
117
182
 
118
183
  const version = getVersion(bin, desc.versionArgs)
184
+ let detectedSkillPath = null
185
+ if (desc.skillPaths) {
186
+ for (const sp of desc.skillPaths) {
187
+ const fullPath = join(homedir(), sp)
188
+ if (existsSync(fullPath)) {
189
+ detectedSkillPath = fullPath
190
+ break
191
+ }
192
+ }
193
+ }
194
+
119
195
  agents[desc.id] = {
120
- installed: true,
121
- available: version !== null,
122
- version: version ?? 'unknown',
196
+ installed: true,
197
+ available: version !== null,
198
+ version: version ?? 'unknown',
199
+ skillPath: detectedSkillPath,
200
+ hasSkill: detectedSkillPath ? existsSync(join(detectedSkillPath, 'adaptive-director')) || existsSync(join(detectedSkillPath, 'Adaptive-Director')) || existsSync(join(detectedSkillPath, 'adaptive-director-skill')) : false,
201
+ availableModels: discoverHostModels(desc.id),
123
202
  }
124
203
  }
125
204
 
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from 'node:child_process';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+
10
+ function run(script, args = []) {
11
+ try {
12
+ const out = execFileSync(process.execPath, [script, ...args], {
13
+ encoding: 'utf8', timeout: 15000,
14
+ cwd: process.cwd(),
15
+ });
16
+ return JSON.parse(out.trim());
17
+ } catch {
18
+ return null;
19
+ }
20
+ }
21
+
22
+ function check(label, condition, fix = null) {
23
+ if (condition) {
24
+ console.log(`✓ ${label}`);
25
+ return true;
26
+ } else {
27
+ console.log(`✗ ${label}`);
28
+ if (fix) console.log(` Fix: ${fix}`);
29
+ return false;
30
+ }
31
+ }
32
+
33
+ function warn(label) {
34
+ console.log(`! ${label}`);
35
+ }
36
+
37
+ const configDir = join(homedir(), '.adaptive-director');
38
+ const configPath = join(configDir, 'config.json');
39
+ const pkgRoot = join(__dirname, '..');
40
+ const skillRoot = join(pkgRoot, 'skills', 'adaptive-director');
41
+
42
+ console.log('Adaptive Director Doctor\n');
43
+
44
+ let allGood = true;
45
+
46
+ // ── Package & Skill files ──────────────────────────────────────────────────
47
+ allGood &= check('Package installed', existsSync(join(pkgRoot, 'package.json')));
48
+ allGood &= check('Skill source exists', existsSync(skillRoot));
49
+ allGood &= check('SKILL.md exists', existsSync(join(skillRoot, 'SKILL.md')));
50
+ allGood &= check('references/ exists', existsSync(join(skillRoot, 'references')));
51
+ allGood &= check('templates/ exists', existsSync(join(skillRoot, 'templates')));
52
+ allGood &= check('examples/ exists', existsSync(join(skillRoot, 'examples')));
53
+
54
+ // ── Registry ──────────────────────────────────────────────────────────────
55
+ const registryPath = join(skillRoot, 'data', 'registry.json');
56
+ if (check('Registry exists', existsSync(registryPath))) {
57
+ try {
58
+ JSON.parse(readFileSync(registryPath, 'utf8'));
59
+ check('Registry valid', true);
60
+ } catch {
61
+ allGood &= check('Registry valid', false, 'Reinstall package');
62
+ }
63
+ } else {
64
+ allGood = false;
65
+ }
66
+
67
+ // ── Config ────────────────────────────────────────────────────────────────
68
+ if (check('Config exists', existsSync(configPath), 'adaptive-director setup')) {
69
+ try {
70
+ JSON.parse(readFileSync(configPath, 'utf8'));
71
+ check('Config valid', true);
72
+ } catch {
73
+ allGood &= check('Config valid', false, 'rm ~/.adaptive-director/config.json && adaptive-director setup');
74
+ }
75
+ } else {
76
+ allGood = false;
77
+ }
78
+
79
+ // ── Runtime Skill Scripts ─────────────────────────────────────────────────
80
+ const routePath = join(skillRoot, 'scripts', 'route.mjs');
81
+ if (existsSync(routePath)) {
82
+ try {
83
+ const testPayload = JSON.stringify({ taskSize: 'small', phase: 'implement', budget: 'balanced', allowMax: false, delegateEnabled: false });
84
+ const out = execFileSync(process.execPath, [routePath, '--input', testPayload], {
85
+ encoding: 'utf8', timeout: 8000
86
+ });
87
+ const result = JSON.parse(out.trim());
88
+ const valid = result && result.agent && result.effort && result.execution;
89
+ allGood &= check('Routing script works', valid, 'Check Node version or reinstall');
90
+ } catch (e) {
91
+ allGood &= check('Routing script works', false, `Error: ${e.message}`);
92
+ }
93
+ } else {
94
+ allGood &= check('Routing script works', false, 'Script missing in skills/adaptive-director/scripts — reinstall package');
95
+ }
96
+
97
+ allGood &= check('Run state script exists', existsSync(join(skillRoot, 'scripts', 'run-state.mjs')));
98
+ allGood &= check('Resume script exists', existsSync(join(skillRoot, 'scripts', 'resume.mjs')));
99
+
100
+ // ── Host discovery ────────────────────────────────────────────────────────
101
+ console.log('');
102
+ const discovery = run(join(__dirname, 'discover.mjs'));
103
+ if (discovery) {
104
+ let anyHost = false;
105
+ for (const [id, info] of Object.entries(discovery.agents ?? {})) {
106
+ if (!info.installed) continue;
107
+ anyHost = true;
108
+ check(`${id} detected`, true);
109
+ const hostHasSkill = info.skillPath && (
110
+ existsSync(join(info.skillPath, 'adaptive-director', 'SKILL.md')) ||
111
+ existsSync(join(info.skillPath, 'Adaptive-Director', 'SKILL.md'))
112
+ );
113
+ if (hostHasSkill) {
114
+ check(`Skill installed for ${id}`, true);
115
+ } else if (info.skillPath) {
116
+ allGood &= check(`Skill installed for ${id}`, false,
117
+ `adaptive-director install ${info.skillPath}`);
118
+ } else {
119
+ warn(`Skill for ${id}: skill directory unknown (run setup after configuring host)`);
120
+ }
121
+ }
122
+ if (!anyHost) warn('No supported hosts detected');
123
+
124
+ console.log('');
125
+ const ds = discovery.delegateSkills ?? { installed: false };
126
+ if (ds.installed) {
127
+ check(`delegate-skills detected (${Object.keys(ds.lanes ?? {}).length} lane(s))`, true);
128
+ } else {
129
+ warn('delegate-skills not detected (optional)');
130
+ }
131
+ } else {
132
+ allGood &= check('Discovery script works', false, 'Check Node version or reinstall');
133
+ }
134
+
135
+ console.log('');
136
+ if (allGood) {
137
+ console.log('Ready.');
138
+ } else {
139
+ console.log('Some checks failed. Run "adaptive-director setup" to fix.');
140
+ process.exitCode = 1;
141
+ }