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.
- package/README.md +132 -36
- package/package.json +8 -6
- package/scripts/cli.mjs +55 -0
- package/scripts/discover.mjs +99 -20
- package/scripts/doctor.mjs +141 -0
- package/scripts/install.mjs +97 -0
- package/scripts/refresh.mjs +62 -0
- package/scripts/setup.mjs +149 -123
- package/scripts/smoke-test.mjs +138 -89
- package/{SKILL.md → skills/adaptive-director/SKILL.md} +11 -11
- package/skills/adaptive-director/data/registry.json +103 -0
- package/skills/adaptive-director/examples/clean-run-walkthrough.md +83 -0
- package/skills/adaptive-director/examples/critical-fix-cycle-walkthrough.md +70 -0
- package/{references → skills/adaptive-director/references}/capability-registry.md +17 -10
- package/skills/adaptive-director/scripts/discover-models.mjs +198 -0
- package/skills/adaptive-director/scripts/route.mjs +355 -0
- package/skills/adaptive-director/templates/fix-brief.md +27 -0
- package/skills/adaptive-director/templates/implement-brief.md +28 -0
- package/skills/adaptive-director/templates/plan-brief.md +31 -0
- package/skills/adaptive-director/templates/review-brief.md +42 -0
- package/skills/adaptive-director/templates/verify-brief.md +28 -0
- package/data/registry.json +0 -42
- package/scripts/route.mjs +0 -244
- /package/{references → skills/adaptive-director/references}/delegate-integration.md +0 -0
- /package/{references → skills/adaptive-director/references}/handoff-schema.md +0 -0
- /package/{references → skills/adaptive-director/references}/routing-rules.md +0 -0
- /package/{scripts → skills/adaptive-director/scripts}/resume.mjs +0 -0
- /package/{scripts → skills/adaptive-director/scripts}/run-state.mjs +0 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/adaptive-director-skill)
|
|
4
4
|
[](https://nodejs.org)
|
|
5
|
-
[-blue.svg)](#
|
|
5
|
+
[-blue.svg)](#core-principles)
|
|
6
6
|
[](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
|
|
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
|
-
|
|
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
|
-
|
|
72
|
-
cd Adaptive-Orchestrator
|
|
73
|
+
adaptive-director setup
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
|
|
76
|
+
Or without a global install:
|
|
77
|
+
|
|
76
78
|
```bash
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
###
|
|
109
|
+
### 4. Run with Your AI Agent
|
|
82
110
|
|
|
83
|
-
|
|
111
|
+
The Skill is now installed in your agent's skills directory. Prompt your agent:
|
|
84
112
|
|
|
85
113
|
```text
|
|
86
|
-
Use $adaptive-director
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
├──
|
|
113
|
-
├──
|
|
114
|
-
├──
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
161
|
+
---
|
|
123
162
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
144
|
-
defaultBudget: balanced # conservative | balanced | quality
|
|
230
|
+
After a package upgrade, re-install the Skill into your host environments:
|
|
145
231
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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": "
|
|
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-
|
|
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
|
-
"
|
|
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",
|
package/scripts/cli.mjs
ADDED
|
@@ -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);
|
package/scripts/discover.mjs
CHANGED
|
@@ -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
|
|
93
|
-
|
|
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
|
-
|
|
96
|
-
const
|
|
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
|
-
|
|
99
|
-
|
|
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
|
-
|
|
103
|
-
|
|
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:
|
|
121
|
-
available:
|
|
122
|
-
version:
|
|
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
|
+
}
|