adaptive-director-skill 0.1.1 → 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 +105 -36
  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/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
+
78
+ ```bash
79
+ npx adaptive-director-skill setup
80
+ ```
81
+
82
+ ### 3. Verify
83
+
76
84
  ```bash
77
- node scripts/setup.mjs
78
- node scripts/smoke-test.mjs
85
+ adaptive-director doctor
79
86
  ```
80
87
 
81
- ### 2. Run with Your AI Agent
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.
107
+ ```
82
108
 
83
- Load `SKILL.md` into your coding agent (Claude Code, Antigravity, Codex, etc.) and prompt:
109
+ ### 4. Run with Your AI Agent
110
+
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,33 +131,50 @@ 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
+ - **Routing Priority:** User overrides → Delegate fleet lanes → Capability registry → Default fallback.
133
178
  - **Independent Review:** The coder never reviews its own work.
134
179
  - **Max Reasoning Opt-in:** `max` effort is locked by default; requires `--allow-max`.
135
180
  - **Runaway Loop Protection:** Maximum 1 automated fix cycle before alerting the user.
@@ -138,19 +183,43 @@ adaptive-director/
138
183
 
139
184
  ---
140
185
 
141
- ## Configuration (`~/.adaptive-director/config.yaml`)
186
+ ## Configuration (`~/.adaptive-director/config.json`)
187
+
188
+ ```json
189
+ {
190
+ "version": 1,
191
+ "defaultBudget": "balanced",
192
+ "overrides": {
193
+ "plan": "claude",
194
+ "implement": "codex"
195
+ }
196
+ }
197
+ ```
198
+
199
+ ---
142
200
 
143
- ```yaml
144
- defaultBudget: balanced # conservative | balanced | quality
201
+ ## Upgrading
145
202
 
146
- # Optional overrides:
147
- agentOverrides.plan: claude
148
- agentOverrides.implement: codex
149
- agentOverrides.review: claude
203
+ After a package upgrade, re-install the Skill into your host environments:
204
+
205
+ ```bash
206
+ npm install -g adaptive-director-skill@latest
207
+ adaptive-director install
208
+ adaptive-director doctor
150
209
  ```
151
210
 
152
211
  ---
153
212
 
213
+ ## Uninstalling
214
+
215
+ ```bash
216
+ npm uninstall -g adaptive-director-skill
217
+ ```
218
+
219
+ > **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/`).
220
+
221
+ ---
222
+
154
223
  ## License
155
224
 
156
225
  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.0.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.0.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);
@@ -20,15 +20,15 @@ import { homedir } from 'node:os'
20
20
  // ─── Known agents ─────────────────────────────────────────────────────────────
21
21
 
22
22
  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'] },
23
+ { id: 'claude', bins: ['claude'], versionArgs: ['--version'], skillPaths: ['.claude/skills', '.config/claude/skills'] },
24
+ { id: 'codex', bins: ['codex'], versionArgs: ['--version'], skillPaths: ['.codex/skills'] },
25
+ { id: 'agy', bins: ['agy'], versionArgs: ['--version'], skillPaths: ['.gemini/antigravity/builtin/skills', '.gemini/antigravity/skills', '.gemini/antigravity-ide/skills'] },
26
+ { id: 'gemini', bins: ['gemini'], versionArgs: ['--version'], skillPaths: ['.gemini/skills'] },
27
+ { id: 'opencode', bins: ['opencode'], versionArgs: ['--version'], skillPaths: ['.opencode/skills'] },
28
+ { id: 'aider', bins: ['aider'], versionArgs: ['--version'], skillPaths: ['.aider/skills'] },
29
+ { id: 'cursor', bins: ['cursor-agent'], versionArgs: ['--version'], skillPaths: ['.cursor/skills'] },
30
+ { id: 'cline', bins: ['cline'], versionArgs: ['--version'], skillPaths: ['.cline/skills'] },
31
+ { id: 'copilot', bins: ['copilot'], versionArgs: ['--version'], skillPaths: ['.copilot/skills'] },
32
32
  ]
33
33
 
34
34
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -116,10 +116,23 @@ function discover() {
116
116
  }
117
117
 
118
118
  const version = getVersion(bin, desc.versionArgs)
119
+ let detectedSkillPath = null
120
+ if (desc.skillPaths) {
121
+ for (const sp of desc.skillPaths) {
122
+ const fullPath = join(homedir(), sp)
123
+ if (existsSync(fullPath)) {
124
+ detectedSkillPath = fullPath
125
+ break
126
+ }
127
+ }
128
+ }
129
+
119
130
  agents[desc.id] = {
120
131
  installed: true,
121
132
  available: version !== null,
122
133
  version: version ?? 'unknown',
134
+ skillPath: detectedSkillPath,
135
+ hasSkill: detectedSkillPath ? existsSync(join(detectedSkillPath, 'adaptive-director')) || existsSync(join(detectedSkillPath, 'Adaptive-Director')) || existsSync(join(detectedSkillPath, 'adaptive-director-skill')) : false
123
136
  }
124
137
  }
125
138
 
@@ -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
+ }
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from 'node:child_process';
3
+ import { mkdirSync, cpSync, rmSync, existsSync } from 'node:fs';
4
+ import { join, dirname } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const projectRoot = join(__dirname, '..');
9
+
10
+ const args = process.argv.slice(2);
11
+ const targets = args.filter(a => !a.startsWith('-'));
12
+
13
+ const canonicalSkillSource = join(projectRoot, 'skills', 'adaptive-director');
14
+
15
+ /**
16
+ * Copy Adaptive Director Skill files into a host skill directory.
17
+ * Idempotent: removes old copy first, then copies fresh from skills/adaptive-director.
18
+ */
19
+ function installInto(hostSkillDir) {
20
+ const dest = join(hostSkillDir, 'adaptive-director');
21
+ console.log(` Installing into ${dest}...`);
22
+ if (!existsSync(canonicalSkillSource)) {
23
+ console.error(` Error: Canonical skill source not found at ${canonicalSkillSource}`);
24
+ process.exit(1);
25
+ }
26
+ // Remove legacy title-case folder if different and present
27
+ const legacyDest = join(hostSkillDir, 'Adaptive-Director');
28
+ if (legacyDest.toLowerCase() === dest.toLowerCase() && existsSync(legacyDest)) {
29
+ rmSync(legacyDest, { recursive: true, force: true });
30
+ } else if (existsSync(dest)) {
31
+ rmSync(dest, { recursive: true, force: true });
32
+ }
33
+ mkdirSync(dest, { recursive: true });
34
+ cpSync(canonicalSkillSource, dest, { recursive: true });
35
+ console.log(` ✓ Installed successfully at ${dest}`);
36
+ }
37
+
38
+ // ─── If paths were passed as arguments, install into those directly ─────────
39
+ if (targets.length > 0) {
40
+ for (const target of targets) {
41
+ installInto(target);
42
+ }
43
+ process.exit(0);
44
+ }
45
+
46
+ // ─── No args: auto-discover hosts and install ───────────────────────────────
47
+ const discoverScript = join(__dirname, 'discover.mjs');
48
+
49
+ function runDiscover() {
50
+ try {
51
+ const out = execFileSync(process.execPath, [discoverScript], {
52
+ encoding: 'utf8', timeout: 15000, cwd: process.cwd(),
53
+ });
54
+ return JSON.parse(out.trim());
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ console.log('\n Adaptive Director — Install\n');
61
+ console.log(' Discovering hosts...\n');
62
+
63
+ const discovery = runDiscover();
64
+ if (!discovery) {
65
+ console.error(' Error: discovery failed.');
66
+ process.exit(1);
67
+ }
68
+
69
+ const hostsWithSkillDir = [];
70
+ for (const [id, info] of Object.entries(discovery.agents ?? {})) {
71
+ if (info.installed && info.skillPath) {
72
+ hostsWithSkillDir.push({ id, path: info.skillPath });
73
+ } else if (info.installed) {
74
+ console.log(` ! ${id}: installed but skill directory could not be resolved. Skipping.`);
75
+ }
76
+ }
77
+
78
+ if (hostsWithSkillDir.length === 0) {
79
+ console.log(' No known host skill directories found. Nothing to install.');
80
+ process.exit(0);
81
+ }
82
+
83
+ console.log(' Installing into detected hosts:');
84
+ for (const h of hostsWithSkillDir) {
85
+ console.log(` [→] ${h.id} — ${h.path}`);
86
+ }
87
+ console.log('');
88
+
89
+ for (const h of hostsWithSkillDir) {
90
+ try {
91
+ installInto(h.path);
92
+ } catch (e) {
93
+ console.error(` ✗ Failed to install for ${h.id}: ${e.message}`);
94
+ }
95
+ }
96
+
97
+ console.log('\n Done. Run "adaptive-director doctor" to verify.\n');
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ import { execFileSync } from 'node:child_process';
3
+ import { existsSync, readFileSync, writeFileSync } 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 (e) {
18
+ return null;
19
+ }
20
+ }
21
+
22
+ const configDir = join(homedir(), '.adaptive-director');
23
+ const configPath = join(configDir, 'config.json');
24
+
25
+ console.log('Refreshing Adaptive Director config...\n');
26
+
27
+ const discovery = run(join(__dirname, 'discover.mjs'));
28
+ if (!discovery) {
29
+ console.error('✗ Discovery failed.');
30
+ process.exit(1);
31
+ }
32
+
33
+ let existingConfig = {};
34
+ if (existsSync(configPath)) {
35
+ try {
36
+ existingConfig = JSON.parse(readFileSync(configPath, 'utf8'));
37
+ } catch {
38
+ console.warn('! Existing config is invalid, creating a new one.');
39
+ }
40
+ }
41
+
42
+ const config = {
43
+ version: 1,
44
+ defaultBudget: existingConfig.defaultBudget || 'balanced',
45
+ allowMax: existingConfig.allowMax || false,
46
+ delegateEnabled: existingConfig.delegateEnabled || false,
47
+ hosts: {},
48
+ overrides: existingConfig.overrides || {}
49
+ };
50
+
51
+ for (const [id, info] of Object.entries(discovery.agents ?? {})) {
52
+ if (info.installed) {
53
+ config.hosts[id] = {
54
+ enabled: existingConfig.hosts?.[id]?.enabled ?? true,
55
+ skillPath: info.skillPath
56
+ };
57
+ }
58
+ }
59
+
60
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
61
+
62
+ console.log(`✓ Config updated successfully.`);