adaptive-director-skill 0.1.0 → 1.0.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 (26) hide show
  1. package/README.md +110 -34
  2. package/package.json +8 -6
  3. package/scripts/cli.mjs +55 -0
  4. package/scripts/discover.mjs +22 -9
  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 +50 -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/{scripts → skills/adaptive-director/scripts}/route.mjs +30 -21
  16. package/skills/adaptive-director/templates/fix-brief.md +27 -0
  17. package/skills/adaptive-director/templates/implement-brief.md +28 -0
  18. package/skills/adaptive-director/templates/plan-brief.md +31 -0
  19. package/skills/adaptive-director/templates/review-brief.md +42 -0
  20. package/skills/adaptive-director/templates/verify-brief.md +28 -0
  21. package/data/registry.json +0 -42
  22. /package/{references → skills/adaptive-director/references}/delegate-integration.md +0 -0
  23. /package/{references → skills/adaptive-director/references}/handoff-schema.md +0 -0
  24. /package/{references → skills/adaptive-director/references}/routing-rules.md +0 -0
  25. /package/{scripts → skills/adaptive-director/scripts}/resume.mjs +0 -0
  26. /package/{scripts → skills/adaptive-director/scripts}/run-state.mjs +0 -0
package/scripts/setup.mjs CHANGED
@@ -1,123 +1,149 @@
1
- #!/usr/bin/env node
2
- /**
3
- * setup.mjs
4
- * ──────────
5
- * Interactive setup: discovers environment, shows summary, saves config.
6
- *
7
- * Usage:
8
- * node scripts/setup.mjs
9
- * node scripts/setup.mjs --yes (non-interactive, accept defaults)
10
- */
11
-
12
- import { execFileSync } from 'node:child_process'
13
- import { mkdirSync, writeFileSync, existsSync } from 'node:fs'
14
- import { join } from 'node:path'
15
- import { homedir } from 'node:os'
16
- import { createInterface } from 'node:readline'
17
-
18
- const CONFIG_DIR = join(homedir(), '.adaptive-director')
19
- const CONFIG_PATH = join(CONFIG_DIR, 'config.yaml')
20
-
21
- // ─── Helpers ──────────────────────────────────────────────────────────────────
22
-
23
- function run(script, args = []) {
24
- try {
25
- const out = execFileSync(process.execPath, [script, ...args], {
26
- encoding: 'utf8', timeout: 15000,
27
- cwd: process.cwd(),
28
- })
29
- return JSON.parse(out.trim())
30
- } catch (e) {
31
- return null
32
- }
33
- }
34
-
35
- function ask(rl, question) {
36
- return new Promise(resolve => rl.question(question, resolve))
37
- }
38
-
39
- function icon(ok) { return ok ? '✓' : '✗' }
40
-
41
- // ─── Main ─────────────────────────────────────────────────────────────────────
42
-
43
- async function main() {
44
- const nonInteractive = process.argv.includes('--yes')
45
- const scriptDir = new URL('.', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1')
46
- const discoverScript = join(scriptDir, 'discover.mjs')
47
-
48
- console.log('\n Adaptive Director — Setup\n')
49
- console.log(' Discovering environment...\n')
50
-
51
- // ── 1. Run discovery ──────────────────────────────────────────────────────
52
- const discovery = run(discoverScript)
53
-
54
- if (!discovery) {
55
- console.error(' Error: discovery failed. Make sure Node.js 18+ is available.')
56
- process.exit(1)
57
- }
58
-
59
- // ── 2. Print agents ───────────────────────────────────────────────────────
60
- console.log(' Agents:')
61
- for (const [id, info] of Object.entries(discovery.agents ?? {})) {
62
- const mark = info.available ? '✓' : info.installed ? '~' : '✗'
63
- const note = info.available ? (info.version ?? 'available')
64
- : info.installed ? 'installed (auth unknown)'
65
- : 'not installed'
66
- console.log(` ${mark} ${id.padEnd(14)} ${note}`)
67
- }
68
-
69
- // ── 3. Delegate fleet ────────────────────────────────────────────────────
70
- console.log('')
71
- const ds = discovery.delegateSkills ?? { installed: false, lanes: {} }
72
- if (ds.installed) {
73
- const laneNames = Object.keys(ds.lanes ?? {})
74
- console.log(` ✓ delegate-skills fleet detected (${laneNames.length} lane(s))`)
75
- for (const [name, lane] of Object.entries(ds.lanes ?? {})) {
76
- console.log(` ${name} → ${lane.implementer ?? lane.agent ?? '?'}${lane.model ? ' / ' + lane.model : ''}`)
77
- }
78
- } else {
79
- console.log(' ✗ delegate-skills fleet not detected')
80
- if (!nonInteractive) {
81
- const rl = createInterface({ input: process.stdin, output: process.stdout })
82
- const ans = await ask(rl, '\n Install delegate-skills now? [y/N] ')
83
- rl.close()
84
- if (ans.trim().toLowerCase() === 'y') {
85
- console.log('\n Run: npx skills add amElnagdy/delegate-skills')
86
- console.log(' Then: node scripts/setup.mjs\n')
87
- process.exit(0)
88
- }
89
- }
90
- }
91
-
92
- // ── 4. Write config ───────────────────────────────────────────────────────
93
- mkdirSync(CONFIG_DIR, { recursive: true })
94
-
95
- const config = [
96
- '# Adaptive Orchestrator config',
97
- '# Generated by setup.mjs',
98
- '',
99
- 'defaultBudget: balanced',
100
- '',
101
- '# Agent overrides (uncomment and edit to override routing):',
102
- '# agentOverrides.plan: claude',
103
- '# agentOverrides.implement: codex',
104
- '# agentOverrides.review: claude',
105
- '# agentOverrides.verify: claude',
106
- '',
107
- ].join('\n')
108
-
109
- writeFileSync(CONFIG_PATH, config, 'utf8')
110
-
111
- console.log('\n Default policies:')
112
- console.log(' Budget: balanced')
113
- console.log(' Delegate: disabled (use --delegate at runtime)')
114
- console.log(' Max: disabled (use --allow-max at runtime)')
115
- console.log('')
116
- console.log(` Setup complete. Config: ${CONFIG_PATH}`)
117
- console.log('')
118
- }
119
-
120
- main().catch(err => {
121
- console.error('Setup error:', err.message)
122
- process.exit(1)
123
- })
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from 'node:child_process';
3
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ import { createInterface } from 'node:readline';
7
+
8
+ const CONFIG_DIR = join(homedir(), '.adaptive-director');
9
+ const CONFIG_PATH = join(CONFIG_DIR, 'config.json');
10
+
11
+ function run(script, args = []) {
12
+ try {
13
+ const out = execFileSync(process.execPath, [script, ...args], {
14
+ encoding: 'utf8', timeout: 15000,
15
+ cwd: process.cwd(),
16
+ });
17
+ return JSON.parse(out.trim());
18
+ } catch (e) {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ function ask(rl, question) {
24
+ return new Promise(resolve => rl.question(question, resolve));
25
+ }
26
+
27
+ async function main() {
28
+ const nonInteractive = process.argv.includes('--yes');
29
+ const scriptDir = new URL('.', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1');
30
+ const discoverScript = join(scriptDir, 'discover.mjs');
31
+ const installScript = join(scriptDir, 'install.mjs');
32
+
33
+ console.log('\n Adaptive Director — Setup\n');
34
+ console.log(' Discovering environment...\n');
35
+
36
+ const discovery = run(discoverScript);
37
+ if (!discovery) {
38
+ console.error(' Error: discovery failed.');
39
+ process.exit(1);
40
+ }
41
+
42
+ const hostsWithSkillDir = [];
43
+ console.log(' Detected hosts:');
44
+
45
+ let anyInstalled = false;
46
+ for (const [id, info] of Object.entries(discovery.agents ?? {})) {
47
+ if (!info.installed) continue;
48
+ anyInstalled = true;
49
+ const mark = '✓';
50
+ console.log(`\n ${mark} ${id}`);
51
+ if (info.skillPath) {
52
+ console.log(` Skill directory: ${info.skillPath}`);
53
+ hostsWithSkillDir.push({ id, path: info.skillPath });
54
+ } else {
55
+ console.log(` Skill directory could not be resolved. Skipping automatic installation.`);
56
+ }
57
+ }
58
+
59
+ if (!anyInstalled) {
60
+ console.log(' None');
61
+ }
62
+
63
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
64
+
65
+ if (hostsWithSkillDir.length > 0) {
66
+ console.log('\n Install Adaptive Director into:');
67
+ for (const h of hostsWithSkillDir) {
68
+ console.log(` [x] ${h.id}`);
69
+ }
70
+
71
+ if (!nonInteractive) {
72
+ const ans = await ask(rl, '\n Continue? [Y/n] ');
73
+ if (ans.trim().toLowerCase() !== 'n') {
74
+ const paths = hostsWithSkillDir.map(h => h.path);
75
+ try {
76
+ execFileSync(process.execPath, [installScript, ...paths], { stdio: 'inherit' });
77
+ } catch(e) {
78
+ console.error(" Installation failed");
79
+ }
80
+ } else {
81
+ console.log(' Skipping installation.');
82
+ }
83
+ } else {
84
+ const paths = hostsWithSkillDir.map(h => h.path);
85
+ try {
86
+ execFileSync(process.execPath, [installScript, ...paths], { stdio: 'inherit' });
87
+ } catch(e) {
88
+ console.error(" Installation failed");
89
+ }
90
+ }
91
+ } else {
92
+ console.log('\n No known host skill directories found. Skipping automatic installation.');
93
+ }
94
+
95
+ console.log('');
96
+ const ds = discovery.delegateSkills ?? { installed: false, lanes: {} };
97
+ if (ds.installed) {
98
+ console.log(` ✓ delegate-skills fleet detected (${Object.keys(ds.lanes ?? {}).length} lane(s))`);
99
+ } else {
100
+ console.log(' delegate-skills not found.');
101
+ console.log('\n Adaptive Director works without it.');
102
+ if (!nonInteractive) {
103
+ const ans = await ask(rl, '\n Install delegate support now? [y/N] ');
104
+ if (ans.trim().toLowerCase() === 'y') {
105
+ console.log('\n Run: npx skills add amElnagdy/delegate-skills');
106
+ console.log(' Then re-run setup.\n');
107
+ process.exit(0);
108
+ }
109
+ }
110
+ }
111
+ rl.close();
112
+
113
+ // Create JSON config
114
+ mkdirSync(CONFIG_DIR, { recursive: true });
115
+ let existingConfig = {};
116
+ if (existsSync(CONFIG_PATH)) {
117
+ try {
118
+ existingConfig = JSON.parse(readFileSync(CONFIG_PATH, 'utf8'));
119
+ } catch {}
120
+ }
121
+
122
+ const config = {
123
+ version: 1,
124
+ defaultBudget: existingConfig.defaultBudget || 'balanced',
125
+ allowMax: existingConfig.allowMax || false,
126
+ delegateEnabled: existingConfig.delegateEnabled || false,
127
+ hosts: {},
128
+ overrides: existingConfig.overrides || {}
129
+ };
130
+
131
+ for (const [id, info] of Object.entries(discovery.agents ?? {})) {
132
+ if (info.installed) {
133
+ config.hosts[id] = {
134
+ enabled: true,
135
+ skillPath: info.skillPath
136
+ };
137
+ }
138
+ }
139
+
140
+ writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
141
+
142
+ console.log('\n Config written to:', CONFIG_PATH);
143
+ console.log(' Setup complete. Run "adaptive-director doctor" to verify.\n');
144
+ }
145
+
146
+ main().catch(err => {
147
+ console.error('Setup error:', err.message);
148
+ process.exit(1);
149
+ });
@@ -1,89 +1,138 @@
1
- import { execFileSync } from 'node:child_process'
2
- import { join } from 'node:path'
3
-
4
- const scriptDir = process.cwd()
5
-
6
- function runScript(script, args) {
7
- const out = execFileSync(process.execPath, [join(scriptDir, script), ...args], {
8
- encoding: 'utf8', timeout: 10000, cwd: scriptDir
9
- })
10
- return JSON.parse(out.trim())
11
- }
12
-
13
- function routePhase(taskSize, phase, budget = 'balanced', allowMax = false, delegateEnabled = false) {
14
- const input = JSON.stringify({ taskSize, phase, budget, allowMax, delegateEnabled })
15
- const out = execFileSync(
16
- process.execPath,
17
- [join(scriptDir, 'scripts/route.mjs'), '--input', input],
18
- { encoding: 'utf8', timeout: 10000, cwd: scriptDir }
19
- )
20
- return JSON.parse(out.trim())
21
- }
22
-
23
- function runStateCmd(command, args) {
24
- const out = execFileSync(process.execPath, [join(scriptDir, 'scripts/run-state.mjs'), command, ...args], {
25
- encoding: 'utf8', timeout: 10000, cwd: scriptDir
26
- })
27
- return JSON.parse(out.trim())
28
- }
29
-
30
- console.log('\n=== Smoke Tests ===\n')
31
-
32
- // Test 1: route — medium / review
33
- const r1 = routePhase('medium', 'review', 'balanced', false, false)
34
- console.log('route medium/review/balanced:', JSON.stringify(r1))
35
- console.assert(r1.effort === 'high', 'review effort should be high in balanced mode')
36
-
37
- // Test 2: route — small / implement
38
- const r2 = routePhase('small', 'implement', 'conservative', false, false)
39
- console.log('route small/implement/conservative:', JSON.stringify(r2))
40
- console.assert(r2.effort === 'medium', 'implement effort should be medium in conservative mode')
41
-
42
- // Test 3: route — large / plan / quality
43
- const r3 = routePhase('large', 'plan', 'quality', false, false)
44
- console.log('route large/plan/quality:', JSON.stringify(r3))
45
- console.assert(r3.effort === 'high', 'plan effort should be high in quality mode')
46
-
47
- // Test 4: run-state init + update + read
48
- const initResult = runStateCmd('init', ['--task', 'Test task', '--size', 'small', '--budget', 'balanced'])
49
- console.log('\nrun-state init:', JSON.stringify(initResult))
50
- const runId = initResult.runId
51
- console.assert(runId.startsWith('run-'), 'runId should start with run-')
52
-
53
- runStateCmd('update', ['--run-id', runId, '--status', 'running', '--phase', 'implement'])
54
-
55
- const meta = runStateCmd('read', ['--run-id', runId])
56
- console.log('run-state read status:', meta.status, '| phase:', meta.currentPhase)
57
- console.assert(meta.status === 'running', 'status should be running')
58
- console.assert(meta.currentPhase === 'implement', 'phase should be implement')
59
-
60
- // Test 5: write-phase + read-phase
61
- const findings = JSON.stringify([{severity:'critical',title:'Test finding',description:'A test critical issue'}])
62
- runStateCmd('write-phase', [
63
- '--run-id', runId, '--phase', 'review',
64
- '--status', 'completed', '--summary', 'Found 1 critical issue',
65
- '--findings-json', findings
66
- ])
67
- const phaseResult = runStateCmd('read-phase', ['--run-id', runId, '--phase', 'review'])
68
- console.log('\nwrite/read-phase:', phaseResult.phase, '| findings:', phaseResult.findings?.length)
69
- console.assert(phaseResult.findings?.length === 1, 'should have 1 finding')
70
- console.assert(phaseResult.findings[0].severity === 'critical', 'finding should be critical')
71
-
72
- // Test 6: build-brief
73
- const { execFileSync: ef2 } = await import('node:child_process')
74
- const brief = ef2(process.execPath, [join(scriptDir, 'scripts/run-state.mjs'), 'build-brief', '--run-id', runId, '--phase', 'review'], {
75
- encoding: 'utf8', timeout: 10000, cwd: scriptDir
76
- })
77
- console.log('\nbuild-brief review (first 80 chars):', brief.slice(0, 80).replace(/\n/g, ' '))
78
- console.assert(brief.includes('Independent Reviewer'), 'brief should contain reviewer role')
79
-
80
- // Test 7: resume (should find our running run)
81
- const { execFileSync: ef3 } = await import('node:child_process')
82
- const resumeOut = ef3(process.execPath, [join(scriptDir, 'scripts/resume.mjs')], {
83
- encoding: 'utf8', timeout: 10000, cwd: scriptDir
84
- })
85
- const resumeResult = JSON.parse(resumeOut.trim())
86
- console.log('\nresume found:', resumeResult?.runId, '| status:', resumeResult?.status)
87
- console.assert(resumeResult?.runId === runId || resumeResult !== null, 'should find a resumable run')
88
-
89
- console.log('\n=== All tests passed ✓ ===\n')
1
+ import { execFileSync } from 'node:child_process'
2
+ import { existsSync, mkdirSync, rmSync, readdirSync } from 'node:fs'
3
+ import { join } from 'node:path'
4
+ import { tmpdir } from 'node:os'
5
+
6
+ const scriptDir = process.cwd()
7
+ const skillDir = join(scriptDir, 'skills', 'adaptive-director')
8
+
9
+ function runSync(script, args = []) {
10
+ return execFileSync(process.execPath, [join(scriptDir, script), ...args], {
11
+ encoding: 'utf8', timeout: 10000, cwd: scriptDir
12
+ })
13
+ }
14
+
15
+ function routePhase(taskSize, phase, budget = 'balanced', allowMax = false, delegateEnabled = false) {
16
+ const input = JSON.stringify({ taskSize, phase, budget, allowMax, delegateEnabled })
17
+ const out = execFileSync(
18
+ process.execPath,
19
+ [join(skillDir, 'scripts/route.mjs'), '--input', input],
20
+ { encoding: 'utf8', timeout: 10000, cwd: scriptDir }
21
+ )
22
+ return JSON.parse(out.trim())
23
+ }
24
+
25
+ function runStateCmd(command, args) {
26
+ const out = execFileSync(process.execPath, [join(skillDir, 'scripts/run-state.mjs'), command, ...args], {
27
+ encoding: 'utf8', timeout: 10000, cwd: scriptDir
28
+ })
29
+ return JSON.parse(out.trim())
30
+ }
31
+
32
+ console.log('\n=== Smoke Tests ===\n')
33
+
34
+ // Test 1: Structure verification
35
+ console.assert(existsSync(skillDir), 'skills/adaptive-director/ must exist')
36
+ console.assert(existsSync(join(skillDir, 'SKILL.md')), 'SKILL.md must exist in skill directory')
37
+ console.assert(existsSync(join(skillDir, 'data', 'registry.json')), 'registry.json must exist in skill directory')
38
+ console.assert(existsSync(join(skillDir, 'references')), 'references/ must exist in skill directory')
39
+ console.assert(existsSync(join(skillDir, 'templates')), 'templates/ must exist in skill directory')
40
+ console.assert(existsSync(join(skillDir, 'examples')), 'examples/ must exist in skill directory')
41
+ console.assert(existsSync(join(skillDir, 'scripts', 'route.mjs')), 'route.mjs must exist in skill scripts')
42
+ console.assert(existsSync(join(skillDir, 'scripts', 'run-state.mjs')), 'run-state.mjs must exist in skill scripts')
43
+ console.assert(existsSync(join(skillDir, 'scripts', 'resume.mjs')), 'resume.mjs must exist in skill scripts')
44
+ console.log('structure check: OK')
45
+
46
+ // Test 2: CLI Help
47
+ try {
48
+ const cliHelp = runSync('scripts/cli.mjs', ['help']);
49
+ if (!cliHelp.includes('Adaptive Director Skill CLI')) {
50
+ throw new Error('cli help output invalid');
51
+ }
52
+ console.log('cli help: OK');
53
+ } catch (e) {
54
+ console.error('cli help failed: ' + e.message);
55
+ process.exit(1);
56
+ }
57
+
58
+ // Test 3: Doctor runs cleanly
59
+ try {
60
+ const doctorOut = runSync('scripts/doctor.mjs');
61
+ console.assert(doctorOut.includes('Ready.') || doctorOut.includes('Adaptive Director Doctor'), 'doctor output invalid');
62
+ console.log('doctor check: OK');
63
+ } catch (e) {
64
+ console.error('doctor check failed: ' + e.message);
65
+ process.exit(1);
66
+ }
67
+
68
+ // Test 4: route — small / implement
69
+ const r2 = routePhase('small', 'implement', 'conservative', false, false)
70
+ console.log('route small/implement/conservative:', JSON.stringify(r2))
71
+ console.assert(r2.effort === 'medium', 'implement effort should be medium in conservative mode')
72
+ console.assert(r2.model !== null, 'model should be resolved')
73
+
74
+ // Test 5: route — large / plan / quality
75
+ const r3 = routePhase('large', 'plan', 'quality', false, false)
76
+ console.log('route large/plan/quality:', JSON.stringify(r3))
77
+ console.assert(r3.effort === 'high', 'plan effort should be high in quality mode')
78
+
79
+ // Test 6: run-state init + update + read
80
+ const initResult = runStateCmd('init', ['--task', 'Test task', '--size', 'small', '--budget', 'balanced'])
81
+ console.log('\nrun-state init:', JSON.stringify(initResult))
82
+ const runId = initResult.runId
83
+ console.assert(runId.startsWith('run-'), 'runId should start with run-')
84
+
85
+ runStateCmd('update', ['--run-id', runId, '--status', 'running', '--phase', 'implement'])
86
+
87
+ const meta = runStateCmd('read', ['--run-id', runId])
88
+ console.log('run-state read status:', meta.status, '| phase:', meta.currentPhase)
89
+ console.assert(meta.status === 'running', 'status should be running')
90
+ console.assert(meta.currentPhase === 'implement', 'phase should be implement')
91
+
92
+ // Test 7: write-phase + read-phase
93
+ const findings = JSON.stringify([{severity:'critical',title:'Test finding',description:'A test critical issue'}])
94
+ runStateCmd('write-phase', [
95
+ '--run-id', runId, '--phase', 'review',
96
+ '--status', 'completed', '--summary', 'Found 1 critical issue',
97
+ '--findings-json', findings
98
+ ])
99
+ const phaseResult = runStateCmd('read-phase', ['--run-id', runId, '--phase', 'review'])
100
+ console.log('\nwrite/read-phase:', phaseResult.phase, '| findings:', phaseResult.findings?.length)
101
+ console.assert(phaseResult.findings?.length === 1, 'should have 1 finding')
102
+ console.assert(phaseResult.findings[0].severity === 'critical', 'finding should be critical')
103
+
104
+ // Test 8: build-brief
105
+ const brief = execFileSync(process.execPath, [join(skillDir, 'scripts/run-state.mjs'), 'build-brief', '--run-id', runId, '--phase', 'review'], {
106
+ encoding: 'utf8', timeout: 10000, cwd: scriptDir
107
+ })
108
+ console.log('\nbuild-brief review (first 80 chars):', brief.slice(0, 80).replace(/\n/g, ' '))
109
+ console.assert(brief.includes('Independent Reviewer'), 'brief should contain reviewer role')
110
+
111
+ // Test 9: resume (should find our running run)
112
+ const resumeOut = execFileSync(process.execPath, [join(skillDir, 'scripts/resume.mjs')], {
113
+ encoding: 'utf8', timeout: 10000, cwd: scriptDir
114
+ })
115
+ const resumeResult = JSON.parse(resumeOut.trim())
116
+ console.log('\nresume found:', resumeResult?.runId, '| status:', resumeResult?.status)
117
+ console.assert(resumeResult?.runId === runId || resumeResult !== null, 'should find a resumable run')
118
+
119
+ // Test 10: Temporary host install verification
120
+ const tempHostDir = join(tmpdir(), 'test-adaptive-director-host-' + Date.now())
121
+ try {
122
+ mkdirSync(tempHostDir, { recursive: true })
123
+ execFileSync(process.execPath, [join(scriptDir, 'scripts/install.mjs'), tempHostDir], {
124
+ encoding: 'utf8', timeout: 15000, cwd: scriptDir
125
+ })
126
+ const installedDest = join(tempHostDir, 'adaptive-director')
127
+ console.assert(existsSync(join(installedDest, 'SKILL.md')), 'SKILL.md should be copied to host')
128
+ console.assert(existsSync(join(installedDest, 'scripts', 'route.mjs')), 'route.mjs should be copied')
129
+ console.assert(existsSync(join(installedDest, 'data', 'registry.json')), 'registry.json should be copied')
130
+ console.assert(existsSync(join(installedDest, 'references')), 'references/ should be copied')
131
+ console.assert(existsSync(join(installedDest, 'templates')), 'templates/ should be copied')
132
+ console.assert(existsSync(join(installedDest, 'examples')), 'examples/ should be copied')
133
+ console.log('temporary host install test: OK')
134
+ } finally {
135
+ rmSync(tempHostDir, { recursive: true, force: true })
136
+ }
137
+
138
+ console.log('\n=== All tests passed ✓ ===\n')
@@ -1,10 +1,10 @@
1
1
  ---
2
- name: adaptive-director-skill
3
- description: >
4
- Adaptive multi-agent director for coding tasks.
5
- Routes every phase (plan, implement, review, fix, verify) to the right
6
- agent, model, and reasoning effort automatically.
7
- version: 0.1.0
2
+ name: adaptive-director
3
+ description: >-
4
+ Adaptive multi-agent director for coding tasks. Use this skill whenever the user
5
+ asks to implement features, fix complex bugs, refactor architecture, or coordinate
6
+ multiple coding agents across planning, implementation, independent review, and verification phases.
7
+ version: 1.0.0
8
8
  ---
9
9
 
10
10
  # Adaptive Director Skill
@@ -31,9 +31,7 @@ You do NOT implement, review, or verify yourself unless you are the best availab
31
31
 
32
32
  ## Core Rules
33
33
 
34
- These rules are absolute:
35
-
36
- ```
34
+ <critical_rules>
37
35
  1. Max reasoning is DISABLED by default.
38
36
  → Only use if --allow-max was passed.
39
37
 
@@ -58,7 +56,7 @@ These rules are absolute:
58
56
 
59
57
  10. Never guess unavailable agent capabilities.
60
58
  → If unknown, mark as unknown.
61
- ```
59
+ </critical_rules>
62
60
 
63
61
  ---
64
62
 
@@ -163,8 +161,10 @@ node scripts/run-state.mjs build-brief \
163
161
  --phase plan
164
162
  ```
165
163
 
166
- The brief is a self-contained prompt. Pass it to the assigned agent.
164
+ The brief is a self-contained prompt generated from standardized templates in `templates/` (`plan-brief.md`, `implement-brief.md`, `review-brief.md`, `fix-brief.md`, `verify-brief.md`).
165
+ Pass it to the assigned agent.
167
166
  **Do not share full chat history with the agent — use the brief only.**
167
+ See `examples/clean-run-walkthrough.md` and `examples/critical-fix-cycle-walkthrough.md` for complete reference runs.
168
168
 
169
169
  ### 3. Execute the phase
170
170
 
@@ -0,0 +1,50 @@
1
+ {
2
+ "models": {
3
+ "gpt-6-astra": { "planning": 5, "coding": 5, "review": 5 },
4
+ "gpt-5.6-sol": { "planning": 5, "coding": 5, "review": 5 },
5
+ "gpt-5.5": { "planning": 5, "coding": 5, "review": 4 },
6
+ "gpt-5.4-mini": { "planning": 3, "coding": 4, "review": 3 },
7
+ "o3": { "planning": 5, "coding": 5, "review": 4 },
8
+ "o3-mini": { "planning": 5, "coding": 5, "review": 4 },
9
+ "o1": { "planning": 5, "coding": 4, "review": 4 },
10
+ "gpt-4o": { "planning": 3, "coding": 4, "review": 3 },
11
+ "gpt-4o-mini": { "planning": 2, "coding": 3, "review": 2 },
12
+ "claude-3-7-sonnet": { "planning": 5, "coding": 5, "review": 5 },
13
+ "claude-3-5-sonnet": { "planning": 5, "coding": 5, "review": 4 },
14
+ "claude-3-opus": { "planning": 5, "coding": 4, "review": 5 },
15
+ "claude-3-5-haiku": { "planning": 2, "coding": 3, "review": 2 },
16
+ "deepseek-r1": { "planning": 5, "coding": 4, "review": 4 },
17
+ "deepseek-v3": { "planning": 3, "coding": 4, "review": 3 },
18
+ "gemini-2-5-pro": { "planning": 5, "coding": 4, "review": 4 },
19
+ "gemini-2-0-pro": { "planning": 5, "coding": 4, "review": 4 },
20
+ "gemini-2-0-flash": { "planning": 2, "coding": 3, "review": 2 },
21
+ "codex-default": { "planning": 5, "coding": 5, "review": 4 },
22
+ "unknown": { "planning": 1, "coding": 1, "review": 1 }
23
+ },
24
+ "phase_requirements": {
25
+ "plan": { "min_planning": 3 },
26
+ "implement": { "min_coding": 2 },
27
+ "review": { "min_review": 3 },
28
+ "fix": { "min_coding": 2 },
29
+ "verify": { "min_planning": 2 }
30
+ },
31
+ "effort_table": {
32
+ "conservative": {
33
+ "plan": "medium", "implement": "medium",
34
+ "review": "high", "fix": "medium", "verify": "medium"
35
+ },
36
+ "balanced": {
37
+ "plan": "high", "implement": "medium",
38
+ "review": "high", "fix": "medium", "verify": "medium"
39
+ },
40
+ "quality": {
41
+ "plan": "high", "implement": "medium",
42
+ "review": "high", "fix": "medium", "verify": "high"
43
+ }
44
+ },
45
+ "phase_map": {
46
+ "small": ["implement", "review"],
47
+ "medium": ["plan", "implement", "review", "verify"],
48
+ "large": ["plan", "implement", "review", "fix", "verify"]
49
+ }
50
+ }