adaptive-director-skill 1.1.0 → 1.1.2
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 +340 -152
- package/package.json +2 -2
- package/scripts/cli.mjs +12 -7
- package/scripts/delegate-cli.mjs +106 -0
- package/scripts/discover.mjs +57 -16
- package/scripts/doctor.mjs +15 -6
- package/scripts/install.mjs +97 -97
- package/scripts/refresh.mjs +14 -3
- package/scripts/run.mjs +427 -0
- package/scripts/setup.mjs +254 -52
- package/scripts/smoke-test.mjs +133 -1
- package/scripts/test-run-flow.mjs +119 -0
- package/scripts/test-setup-delegate.mjs +380 -0
- package/scripts/verify-evidence.mjs +98 -0
- package/skills/adaptive-director/SKILL.md +99 -39
- package/skills/adaptive-director/data/registry.json +103 -103
- package/skills/adaptive-director/examples/clean-run-walkthrough.md +83 -83
- package/skills/adaptive-director/examples/critical-fix-cycle-walkthrough.md +70 -70
- package/skills/adaptive-director/references/delegate-integration.md +71 -22
- package/skills/adaptive-director/scripts/delegate-relay.mjs +237 -0
- package/skills/adaptive-director/scripts/discover-models.mjs +198 -198
- package/skills/adaptive-director/scripts/route.mjs +249 -29
- package/skills/adaptive-director/scripts/run-state.mjs +217 -41
- package/skills/adaptive-director/templates/fix-brief.md +27 -27
- package/skills/adaptive-director/templates/implement-brief.md +28 -28
- package/skills/adaptive-director/templates/plan-brief.md +31 -31
- package/skills/adaptive-director/templates/review-brief.md +42 -42
- package/skills/adaptive-director/templates/verify-brief.md +28 -28
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync, spawnSync } 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
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const subcmd = args[0] || 'help';
|
|
12
|
+
|
|
13
|
+
function run(script, scriptArgs = []) {
|
|
14
|
+
try {
|
|
15
|
+
const out = execFileSync(process.execPath, [script, ...scriptArgs], {
|
|
16
|
+
encoding: 'utf8',
|
|
17
|
+
timeout: 15000,
|
|
18
|
+
cwd: process.cwd(),
|
|
19
|
+
env: process.env,
|
|
20
|
+
});
|
|
21
|
+
return JSON.parse(out.trim());
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (subcmd === 'help' || subcmd === '--help' || subcmd === '-h') {
|
|
28
|
+
console.log(`Adaptive Director — Delegate Skills Management
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
adaptive-director delegate <subcommand> [options]
|
|
32
|
+
|
|
33
|
+
Subcommands:
|
|
34
|
+
install Install delegate-skills via official installer and update config
|
|
35
|
+
status Display delegate-skills discovery, detected relays, and lanes
|
|
36
|
+
help Show this help message
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
adaptive-director delegate install
|
|
40
|
+
adaptive-director delegate status
|
|
41
|
+
`);
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (subcmd === 'install') {
|
|
46
|
+
const setupScript = join(__dirname, 'setup.mjs');
|
|
47
|
+
const forwardArgs = [setupScript, '--with-delegate', '--delegate-only', ...args.slice(1)];
|
|
48
|
+
const res = spawnSync(process.execPath, forwardArgs, {
|
|
49
|
+
stdio: 'inherit',
|
|
50
|
+
env: process.env,
|
|
51
|
+
});
|
|
52
|
+
process.exit(res.status ?? 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (subcmd === 'status') {
|
|
56
|
+
console.log('\nAdaptive Director — Delegate Integration Status\n');
|
|
57
|
+
|
|
58
|
+
const configPath = join(homedir(), '.adaptive-director', 'config.json');
|
|
59
|
+
let config = {};
|
|
60
|
+
if (existsSync(configPath)) {
|
|
61
|
+
try {
|
|
62
|
+
config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
63
|
+
} catch {}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const discovery = run(join(__dirname, 'discover.mjs'));
|
|
67
|
+
const ds = discovery?.delegateSkills ?? { installed: false, relays: [], lanes: {} };
|
|
68
|
+
|
|
69
|
+
console.log(` Installed: ${ds.installed ? 'Yes' : 'No'}`);
|
|
70
|
+
console.log(` Config execution: ${config.execution || 'native'}`);
|
|
71
|
+
console.log(` Config enabled: ${config.delegate?.enabled ?? config.delegateEnabled ?? false}`);
|
|
72
|
+
if (config.delegate?.lastInstallAttempt) {
|
|
73
|
+
console.log(` Last install attempt: ${config.delegate.lastInstallAttempt}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const skills = ds.skills ?? ds.relays ?? [];
|
|
77
|
+
const relays = ds.relays ?? [];
|
|
78
|
+
console.log(`\n Detected Delegate Skills (${skills.length}):`);
|
|
79
|
+
if (skills.length > 0) {
|
|
80
|
+
for (const s of skills) {
|
|
81
|
+
const isRelay = relays.includes(s);
|
|
82
|
+
console.log(` - ${s}${isRelay ? ' (execution relay)' : ''}`);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
console.log(' (none detected)');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const lanes = ds.lanes ?? {};
|
|
89
|
+
const laneKeys = Object.keys(lanes);
|
|
90
|
+
console.log(`\n Active Execution Lanes (${laneKeys.length}):`);
|
|
91
|
+
if (laneKeys.length > 0) {
|
|
92
|
+
for (const k of laneKeys) {
|
|
93
|
+
const lane = lanes[k];
|
|
94
|
+
console.log(` - ${k}: agent=${lane.agent || lane.implementer || 'unknown'}${lane.model ? `, model=${lane.model}` : ''}`);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
console.log(' (none configured)');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log('');
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.error(`Unknown delegate subcommand: ${subcmd}`);
|
|
105
|
+
console.log(`Run 'adaptive-director delegate help' for usage.`);
|
|
106
|
+
process.exit(1);
|
package/scripts/discover.mjs
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { execFileSync, execSync } from 'node:child_process'
|
|
16
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
16
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
17
17
|
import { join } from 'node:path'
|
|
18
18
|
import { homedir } from 'node:os'
|
|
19
19
|
import { discoverHostModels } from '../skills/adaptive-director/scripts/discover-models.mjs'
|
|
@@ -53,16 +53,27 @@ function findBinary(bins) {
|
|
|
53
53
|
return null
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function getVersion(bin, args) {
|
|
57
|
-
try {
|
|
58
|
-
const out = execFileSync(bin, args, {
|
|
59
|
-
encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore']
|
|
60
|
-
})
|
|
61
|
-
return out.trim().split('\n')[0].trim()
|
|
62
|
-
} catch {
|
|
63
|
-
return null
|
|
64
|
-
|
|
65
|
-
}
|
|
56
|
+
function getVersion(bin, args) {
|
|
57
|
+
try {
|
|
58
|
+
const out = execFileSync(bin, args, {
|
|
59
|
+
encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore']
|
|
60
|
+
})
|
|
61
|
+
return out.trim().split('\n')[0].trim()
|
|
62
|
+
} catch {
|
|
63
|
+
if (process.platform !== 'win32') return null
|
|
64
|
+
try {
|
|
65
|
+
const quotedBin = `"${bin.replace(/"/g, '""')}"`
|
|
66
|
+
const quotedArgs = args.map(a => `"${String(a).replace(/"/g, '""')}"`).join(' ')
|
|
67
|
+
const out = execSync(`${quotedBin} ${quotedArgs}`, {
|
|
68
|
+
encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'],
|
|
69
|
+
windowsHide: true,
|
|
70
|
+
})
|
|
71
|
+
return out.trim().split('\n')[0].trim()
|
|
72
|
+
} catch {
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
66
77
|
|
|
67
78
|
// ─── Delegate-skills fleet ────────────────────────────────────────────────────
|
|
68
79
|
|
|
@@ -145,16 +156,44 @@ function discoverDelegate() {
|
|
|
145
156
|
} catch {}
|
|
146
157
|
}
|
|
147
158
|
|
|
148
|
-
|
|
159
|
+
// Detect installed delegate relays across candidate directories
|
|
160
|
+
const relayDirs = [
|
|
161
|
+
agentsSkillsDir,
|
|
162
|
+
codexSkillsDir,
|
|
163
|
+
join(process.cwd(), '.agents', 'skills'),
|
|
164
|
+
join(process.cwd(), 'delegate-skills', 'skills'),
|
|
165
|
+
join(homedir(), '.skills', 'amElnagdy', 'delegate-skills', 'skills'),
|
|
166
|
+
]
|
|
167
|
+
const skillsSet = new Set()
|
|
168
|
+
const relaysSet = new Set()
|
|
169
|
+
for (const dir of relayDirs) {
|
|
170
|
+
if (!existsSync(dir)) continue
|
|
171
|
+
try {
|
|
172
|
+
const entries = readdirSync(dir, { withFileTypes: true })
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
if (!entry.isDirectory()) continue
|
|
175
|
+
if (entry.name.endsWith('-delegate') || entry.name === 'delegate-setup' || entry.name.startsWith('delegate-')) {
|
|
176
|
+
skillsSet.add(entry.name)
|
|
177
|
+
if (entry.name.endsWith('-delegate')) {
|
|
178
|
+
relaysSet.add(entry.name)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} catch {}
|
|
183
|
+
}
|
|
184
|
+
const skills = Array.from(skillsSet).sort()
|
|
185
|
+
const relays = Array.from(relaysSet).sort()
|
|
186
|
+
|
|
187
|
+
const installed = Object.keys(lanes).length > 0 || hasAgentsSkills || hasSkillLock || skills.length > 0
|
|
149
188
|
|
|
150
189
|
// 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'))) {
|
|
190
|
+
if (installed && Object.keys(lanes).length === 0 && (hasAgentsSkills || relays.length > 0)) {
|
|
191
|
+
if (relays.includes('codex-delegate') || existsSync(join(agentsSkillsDir, 'codex-delegate'))) {
|
|
153
192
|
lanes.feature = { agent: 'codex', implementer: 'codex' }
|
|
154
193
|
lanes.implement = { agent: 'codex', implementer: 'codex' }
|
|
155
194
|
lanes.fix = { agent: 'codex', implementer: 'codex' }
|
|
156
195
|
}
|
|
157
|
-
if (existsSync(join(agentsSkillsDir, 'agy-delegate'))) {
|
|
196
|
+
if (relays.includes('agy-delegate') || existsSync(join(agentsSkillsDir, 'agy-delegate'))) {
|
|
158
197
|
lanes.plan = { agent: 'agy', implementer: 'agy' }
|
|
159
198
|
lanes.review = { agent: 'agy', implementer: 'agy' }
|
|
160
199
|
lanes.verify = { agent: 'agy', implementer: 'agy' }
|
|
@@ -164,7 +203,9 @@ function discoverDelegate() {
|
|
|
164
203
|
return {
|
|
165
204
|
installed,
|
|
166
205
|
lanes,
|
|
167
|
-
|
|
206
|
+
skills,
|
|
207
|
+
relays,
|
|
208
|
+
source: hasSkillLock ? 'amElnagdy/delegate-skills' : (hasAgentsSkills ? 'local-skills' : (Object.keys(lanes).length > 0 ? 'fleet-config' : (skills.length > 0 ? 'detected-skills' : null)))
|
|
168
209
|
}
|
|
169
210
|
}
|
|
170
211
|
|
package/scripts/doctor.mjs
CHANGED
|
@@ -7,11 +7,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
|
|
10
|
-
function run(script, args = []) {
|
|
10
|
+
function run(script, args = [], env = process.env) {
|
|
11
11
|
try {
|
|
12
12
|
const out = execFileSync(process.execPath, [script, ...args], {
|
|
13
13
|
encoding: 'utf8', timeout: 15000,
|
|
14
14
|
cwd: process.cwd(),
|
|
15
|
+
env,
|
|
15
16
|
});
|
|
16
17
|
return JSON.parse(out.trim());
|
|
17
18
|
} catch {
|
|
@@ -65,9 +66,10 @@ if (check('Registry exists', existsSync(registryPath))) {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
// ── Config ────────────────────────────────────────────────────────────────
|
|
69
|
+
let configObj = null;
|
|
68
70
|
if (check('Config exists', existsSync(configPath), 'adaptive-director setup')) {
|
|
69
71
|
try {
|
|
70
|
-
JSON.parse(readFileSync(configPath, 'utf8'));
|
|
72
|
+
configObj = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
71
73
|
check('Config valid', true);
|
|
72
74
|
} catch {
|
|
73
75
|
allGood &= check('Config valid', false, 'rm ~/.adaptive-director/config.json && adaptive-director setup');
|
|
@@ -99,7 +101,7 @@ allGood &= check('Resume script exists', existsSync(join(skillRoot, 'scripts'
|
|
|
99
101
|
|
|
100
102
|
// ── Host discovery ────────────────────────────────────────────────────────
|
|
101
103
|
console.log('');
|
|
102
|
-
const discovery = run(join(__dirname, 'discover.mjs'));
|
|
104
|
+
const discovery = run(join(__dirname, 'discover.mjs'), [], process.env);
|
|
103
105
|
if (discovery) {
|
|
104
106
|
let anyHost = false;
|
|
105
107
|
for (const [id, info] of Object.entries(discovery.agents ?? {})) {
|
|
@@ -122,11 +124,18 @@ if (discovery) {
|
|
|
122
124
|
if (!anyHost) warn('No supported hosts detected');
|
|
123
125
|
|
|
124
126
|
console.log('');
|
|
125
|
-
const ds = discovery.delegateSkills ?? { installed: false };
|
|
127
|
+
const ds = discovery.delegateSkills ?? { installed: false, skills: [], relays: [], lanes: {} };
|
|
126
128
|
if (ds.installed) {
|
|
127
|
-
|
|
129
|
+
const skillCount = (ds.skills ?? ds.relays ?? []).length;
|
|
130
|
+
const laneCount = Object.keys(ds.lanes ?? {}).length;
|
|
131
|
+
check(`delegate-skills detected (${skillCount} delegate skill(s), ${laneCount} lane(s))`, true);
|
|
128
132
|
} else {
|
|
129
|
-
warn('delegate-skills not detected (optional)');
|
|
133
|
+
warn('delegate-skills not detected (optional — native execution active)');
|
|
134
|
+
if (configObj?.delegate?.lastInstallAttempt === 'failed') {
|
|
135
|
+
warn('Last delegate-skills install attempt failed (run "adaptive-director delegate install" to retry)');
|
|
136
|
+
} else if (configObj?.delegate?.lastInstallAttempt === 'unverified') {
|
|
137
|
+
warn('delegate-skills installation unverified: no relays detected');
|
|
138
|
+
}
|
|
130
139
|
}
|
|
131
140
|
} else {
|
|
132
141
|
allGood &= check('Discovery script works', false, 'Check Node version or reinstall');
|
package/scripts/install.mjs
CHANGED
|
@@ -1,97 +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');
|
|
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');
|
package/scripts/refresh.mjs
CHANGED
|
@@ -7,11 +7,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
|
|
10
|
-
function run(script, args = []) {
|
|
10
|
+
function run(script, args = [], env = process.env) {
|
|
11
11
|
try {
|
|
12
12
|
const out = execFileSync(process.execPath, [script, ...args], {
|
|
13
13
|
encoding: 'utf8', timeout: 15000,
|
|
14
14
|
cwd: process.cwd(),
|
|
15
|
+
env,
|
|
15
16
|
});
|
|
16
17
|
return JSON.parse(out.trim());
|
|
17
18
|
} catch (e) {
|
|
@@ -24,7 +25,7 @@ const configPath = join(configDir, 'config.json');
|
|
|
24
25
|
|
|
25
26
|
console.log('Refreshing Adaptive Director config...\n');
|
|
26
27
|
|
|
27
|
-
const discovery = run(join(__dirname, 'discover.mjs'));
|
|
28
|
+
const discovery = run(join(__dirname, 'discover.mjs'), [], process.env);
|
|
28
29
|
if (!discovery) {
|
|
29
30
|
console.error('✗ Discovery failed.');
|
|
30
31
|
process.exit(1);
|
|
@@ -39,11 +40,20 @@ if (existsSync(configPath)) {
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
const delegateInstalled = Boolean(discovery.delegateSkills?.installed);
|
|
44
|
+
const delegateEnabled = existingConfig.delegate?.enabled ?? existingConfig.delegateEnabled ?? false;
|
|
45
|
+
|
|
42
46
|
const config = {
|
|
43
47
|
version: 1,
|
|
48
|
+
execution: existingConfig.execution || 'native',
|
|
44
49
|
defaultBudget: existingConfig.defaultBudget || 'balanced',
|
|
45
50
|
allowMax: existingConfig.allowMax || false,
|
|
46
|
-
delegateEnabled
|
|
51
|
+
delegateEnabled,
|
|
52
|
+
delegate: {
|
|
53
|
+
installed: delegateInstalled,
|
|
54
|
+
enabled: delegateEnabled,
|
|
55
|
+
...(existingConfig.delegate?.lastInstallAttempt ? { lastInstallAttempt: existingConfig.delegate.lastInstallAttempt } : {})
|
|
56
|
+
},
|
|
47
57
|
hosts: {},
|
|
48
58
|
overrides: existingConfig.overrides || {}
|
|
49
59
|
};
|
|
@@ -51,6 +61,7 @@ const config = {
|
|
|
51
61
|
for (const [id, info] of Object.entries(discovery.agents ?? {})) {
|
|
52
62
|
if (info.installed) {
|
|
53
63
|
config.hosts[id] = {
|
|
64
|
+
...existingConfig.hosts?.[id],
|
|
54
65
|
enabled: existingConfig.hosts?.[id]?.enabled ?? true,
|
|
55
66
|
skillPath: info.skillPath
|
|
56
67
|
};
|