adaptive-director-skill 0.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.
@@ -0,0 +1,92 @@
1
+ # Capability Registry Reference
2
+
3
+ ## Overview
4
+
5
+ The capability registry assigns numeric scores to known models and defines minimum requirements per phase.
6
+
7
+ All scores are 1–5:
8
+
9
+ | Score | Meaning |
10
+ |-------|---------|
11
+ | 1 | Weak — unreliable for this capability |
12
+ | 2 | Limited — acceptable only for simple tasks |
13
+ | 3 | Acceptable — meets baseline requirements |
14
+ | 4 | Strong — reliable for most tasks |
15
+ | 5 | Excellent — best available |
16
+
17
+ ---
18
+
19
+ ## Registry File
20
+
21
+ Location: `data/registry.json`
22
+
23
+ ```json
24
+ {
25
+ "models": {
26
+ "claude-sonnet-4-5": { "planning": 4, "coding": 4, "review": 4 },
27
+ "codex-default": { "planning": 2, "coding": 5, "review": 2 },
28
+ "unknown": { "planning": 1, "coding": 1, "review": 1 }
29
+ },
30
+ "phase_requirements": {
31
+ "plan": { "min_planning": 3 },
32
+ "implement": { "min_coding": 2 },
33
+ "review": { "min_review": 3 },
34
+ "fix": { "min_coding": 2 },
35
+ "verify": { "min_planning": 2 }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Phase Requirements
43
+
44
+ | Phase | Minimum Requirement |
45
+ |-------|-------------------|
46
+ | plan | planning ≥ 3 |
47
+ | implement | coding ≥ 2 |
48
+ | review | review ≥ 3 |
49
+ | fix | coding ≥ 2 |
50
+ | verify | planning ≥ 2 |
51
+
52
+ ---
53
+
54
+ ## Priority Chain
55
+
56
+ The routing script applies this order:
57
+
58
+ ```
59
+ 1. User explicit override (config.yaml agentOverrides.*)
60
+ 2. Delegate lane preference (fleet.yaml, only when --delegate)
61
+ 3. Built-in registry (best available agent by score)
62
+ 4. Fallback (claude)
63
+ ```
64
+
65
+ ---
66
+
67
+ ## User Override (config.yaml)
68
+
69
+ ```yaml
70
+ agentOverrides.plan: claude
71
+ agentOverrides.implement: codex
72
+ agentOverrides.review: claude
73
+ agentOverrides.verify: claude
74
+ ```
75
+
76
+ Uncomment lines in `~/.adaptive-orchestrator/config.yaml` to activate.
77
+
78
+ ---
79
+
80
+ ## Adding a New Model
81
+
82
+ Edit `data/registry.json` and add an entry under `models`:
83
+
84
+ ```json
85
+ "my-custom-model": {
86
+ "planning": 3,
87
+ "coding": 4,
88
+ "review": 3
89
+ }
90
+ ```
91
+
92
+ Then set `ADAPTIVE_CURRENT_MODEL=my-custom-model` in your environment.
@@ -0,0 +1,115 @@
1
+ # Delegate Integration Reference
2
+
3
+ ## Overview
4
+
5
+ Delegate execution is **optional** and **disabled by default**.
6
+
7
+ ```
8
+ Default: native execution
9
+ --delegate flag: delegate execution allowed (not forced)
10
+ ```
11
+
12
+ Adaptive Orchestrator always remains the top-level controller.
13
+ `delegate-skills` is the execution channel — never the orchestrator.
14
+
15
+ ---
16
+
17
+ ## How It Works
18
+
19
+ When `--delegate` is passed:
20
+
21
+ 1. Adaptive Orchestrator reads the `delegate-skills` fleet config
22
+ 2. For each phase, it checks if a matching lane exists
23
+ 3. If yes → dispatches the phase brief to that lane's implementer
24
+ 4. If no → falls back to native execution
25
+
26
+ ```
27
+ Plan → native claude (no planning lane)
28
+ Implement → delegate → codex (feature lane matches)
29
+ Review → native claude (no review lane)
30
+ Verify → native claude (no verify lane)
31
+ ```
32
+
33
+ ---
34
+
35
+ ## delegate-skills Fleet Config
36
+
37
+ Location: `~/.delegate/fleet.yaml` or `./.delegate/fleet.yaml`
38
+
39
+ Example:
40
+ ```yaml
41
+ lanes:
42
+ feature:
43
+ implementer: codex
44
+ model: o4-mini
45
+ effort: medium
46
+ tests:
47
+ implementer: aider
48
+ ui:
49
+ implementer: cursor
50
+ ```
51
+
52
+ Adaptive Orchestrator reads these lanes during routing and maps them to phases by keyword:
53
+
54
+ | Phase | Matching Lane Keywords |
55
+ |-------|----------------------|
56
+ | implement | feature, impl, code, build |
57
+ | fix | fix, repair, feature |
58
+ | plan | plan, planning |
59
+ | review | review, check |
60
+ | verify | test, verify, qa |
61
+
62
+ ---
63
+
64
+ ## Installing delegate-skills
65
+
66
+ ```bash
67
+ npx skills add amElnagdy/delegate-skills
68
+ ```
69
+
70
+ Or specific skills:
71
+ ```bash
72
+ npx skills add amElnagdy/delegate-skills --skill codex-delegate
73
+ npx skills add amElnagdy/delegate-skills --skill claude-delegate
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Relay Location
79
+
80
+ The routing engine looks for relay scripts at:
81
+
82
+ ```
83
+ ./.skills/amElnagdy/delegate-skills/skills/<agent>-delegate/scripts/relay.mjs
84
+ ~/.skills/amElnagdy/delegate-skills/skills/<agent>-delegate/scripts/relay.mjs
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Delegate Rule (MVP)
90
+
91
+ > One delegated executor per phase maximum.
92
+
93
+ The delegate should receive a focused brief and return a structured result.
94
+ It must NOT start its own orchestration loop.
95
+
96
+ ```
97
+ Orchestrator → brief → Delegate → result.json → Orchestrator
98
+ ```
99
+
100
+ The delegate NEVER commits. Committing belongs to the reviewer (you).
101
+
102
+ ---
103
+
104
+ ## Runtime Flags
105
+
106
+ ```bash
107
+ # Enable delegate
108
+ adaptive-orchestrator --delegate "Implement Stripe in Flutter"
109
+
110
+ # Delegate + max reasoning
111
+ adaptive-orchestrator --delegate --allow-max "Refactor payment architecture"
112
+
113
+ # Dry run (shows routing, no execution)
114
+ adaptive-orchestrator --dry-run --delegate "Implement Stripe in Flutter"
115
+ ```
@@ -0,0 +1,137 @@
1
+ # Handoff Schema Reference
2
+
3
+ ## Overview
4
+
5
+ Every run gets an isolated workspace. Agents communicate through files — not shared chat history.
6
+
7
+ ```
8
+ .adaptive-orchestrator/runs/<run-id>/
9
+ ├── metadata.json ← machine-readable run state
10
+ ├── task.md ← original task (human + machine)
11
+ ├── plan.md ← planner output (human readable)
12
+ ├── plan.json ← planner output (machine contract)
13
+ ├── implementation.md ← implementer report (human readable)
14
+ ├── implementation.json ← implementer report (machine contract)
15
+ ├── review.md ← reviewer findings (human readable)
16
+ ├── review.json ← reviewer findings (machine contract)
17
+ └── final.md / final.json ← verification result
18
+ ```
19
+
20
+ ---
21
+
22
+ ## metadata.json
23
+
24
+ ```json
25
+ {
26
+ "runId": "run-abc123",
27
+ "task": "Implement Stripe in Flutter",
28
+ "status": "running",
29
+ "currentPhase": "review",
30
+ "size": "medium",
31
+ "budget": "balanced",
32
+ "allowMax": false,
33
+ "useDelegate": false,
34
+ "routing": [],
35
+ "startedAt": "2026-09-17T01:00:00Z",
36
+ "updatedAt": "2026-09-17T01:15:00Z"
37
+ }
38
+ ```
39
+
40
+ ### RunStatus values
41
+
42
+ | Status | Meaning |
43
+ |--------|---------|
44
+ | pending | initialized, not started |
45
+ | running | currently executing |
46
+ | verified | completed successfully |
47
+ | blocked | review or verify failed after max cycles |
48
+ | failed | agent returned an error |
49
+ | interrupted | stopped mid-run (can resume) |
50
+
51
+ ---
52
+
53
+ ## Phase JSON Contract
54
+
55
+ All phase results follow this schema:
56
+
57
+ ```json
58
+ {
59
+ "phase": "review",
60
+ "status": "completed",
61
+ "summary": "Found 1 critical issue...",
62
+ "findings": [
63
+ {
64
+ "severity": "critical",
65
+ "title": "Duplicate PaymentIntent confirmation",
66
+ "file": "lib/payment_service.dart",
67
+ "description": "PaymentIntent.confirm() is called twice on retry."
68
+ }
69
+ ],
70
+ "touchedFiles": ["lib/payment_service.dart"],
71
+ "sessionId": "sess-xyz"
72
+ }
73
+ ```
74
+
75
+ ### severity values
76
+
77
+ | Value | Behavior |
78
+ |-------|---------|
79
+ | critical | Must fix — triggers fix loop |
80
+ | warning | Report and continue |
81
+ | suggestion | Informational only |
82
+
83
+ ---
84
+
85
+ ## Managing State with run-state.mjs
86
+
87
+ ### Init a run
88
+ ```bash
89
+ node scripts/run-state.mjs init \
90
+ --task "Implement Stripe in Flutter" \
91
+ --size medium \
92
+ --budget balanced
93
+ ```
94
+
95
+ ### Update status
96
+ ```bash
97
+ node scripts/run-state.mjs update --run-id run-abc123 --status running --phase plan
98
+ ```
99
+
100
+ ### Write a phase result
101
+ ```bash
102
+ node scripts/run-state.mjs write-phase \
103
+ --run-id run-abc123 \
104
+ --phase review \
105
+ --status completed \
106
+ --summary "Found 1 critical issue" \
107
+ --findings-json '[{"severity":"critical","title":"...","description":"..."}]'
108
+ ```
109
+
110
+ ### Read a phase result
111
+ ```bash
112
+ node scripts/run-state.mjs read-phase --run-id run-abc123 --phase review
113
+ ```
114
+
115
+ ### Build a brief for a phase
116
+ ```bash
117
+ node scripts/run-state.mjs build-brief --run-id run-abc123 --phase implement
118
+ ```
119
+
120
+ ### List all runs
121
+ ```bash
122
+ node scripts/run-state.mjs list
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Brief Format (what each agent receives)
128
+
129
+ Each agent receives ONLY what it needs — not the full chat history.
130
+
131
+ | Phase | Receives |
132
+ |-------|---------|
133
+ | plan | task.md + instructions |
134
+ | implement | task.md + plan.md + instructions |
135
+ | review | task.md + plan.md + implementation.md + instructions |
136
+ | fix | task.md + review.md + instructions |
137
+ | verify | task.md + plan.md + instructions |
@@ -0,0 +1,99 @@
1
+ # Routing Rules Reference
2
+
3
+ ## Task Classification
4
+
5
+ Initial classification uses keyword heuristics:
6
+
7
+ | Size | Examples |
8
+ |------|---------|
9
+ | small | rename, fix typo, update text, minor fix, change color |
10
+ | medium | Stripe integration, password reset, new API, module refactor |
11
+ | large | architecture refactor, auth system, payment architecture, migration |
12
+
13
+ Default when no keyword matches: **medium**
14
+
15
+ ### Reclassification
16
+
17
+ After the Planner inspects the repository, it appends a JSON block to its plan:
18
+
19
+ ```json
20
+ {"recommended_size": "large", "reason": "discovered webhooks + saved cards + refunds"}
21
+ ```
22
+
23
+ If `recommended_size` differs from initial, Adaptive Orchestrator reclassifies and rebuilds the routing table.
24
+
25
+ ---
26
+
27
+ ## Phase Map
28
+
29
+ | Task Size | Phases |
30
+ |-----------|--------|
31
+ | small | implement → review |
32
+ | medium | plan → implement → review → verify |
33
+ | large | plan → implement → review → [fix] → verify |
34
+
35
+ `fix` only runs if review finds CRITICAL issues.
36
+
37
+ ---
38
+
39
+ ## Effort Table
40
+
41
+ | Phase | conservative | balanced | quality |
42
+ |-------|-------------|---------|---------|
43
+ | plan | medium | high | high |
44
+ | implement | medium | medium | medium |
45
+ | review | high | high | high |
46
+ | fix | medium | medium | medium |
47
+ | verify | medium | medium | high |
48
+
49
+ `max` is never used unless `--allow-max` is passed AND the routing engine selects it.
50
+
51
+ ---
52
+
53
+ ## Agent Priority
54
+
55
+ ### For planning/review/verify phases:
56
+ ```
57
+ claude → agy → gemini → opencode → cursor → cline → copilot → aider → codex
58
+ ```
59
+
60
+ ### For implementation/fix phases:
61
+ ```
62
+ codex → aider → opencode → cursor → cline → claude → agy → copilot → gemini
63
+ ```
64
+
65
+ The first agent in the list whose representative model meets the phase requirement is selected.
66
+
67
+ ---
68
+
69
+ ## Execution Mode
70
+
71
+ | Condition | Execution |
72
+ |-----------|-----------|
73
+ | Default | native |
74
+ | `--delegate` + matching fleet lane | delegate |
75
+ | `--delegate` + no matching lane | native (fallback) |
76
+
77
+ ---
78
+
79
+ ## Using route.mjs
80
+
81
+ ```bash
82
+ echo '{
83
+ "taskSize": "medium",
84
+ "phase": "review",
85
+ "budget": "balanced",
86
+ "allowMax": false,
87
+ "delegateEnabled": false
88
+ }' | node scripts/route.mjs
89
+ ```
90
+
91
+ Returns:
92
+ ```json
93
+ {
94
+ "agent": "claude",
95
+ "model": "claude-sonnet-4-5",
96
+ "effort": "high",
97
+ "execution": "native"
98
+ }
99
+ ```
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * discover.mjs
4
+ * ─────────────
5
+ * Detects installed coding-agent CLIs and delegate-skills fleet.
6
+ * Never guesses. If a capability cannot be verified, it is marked unknown/false.
7
+ *
8
+ * Output: JSON on stdout.
9
+ *
10
+ * Usage:
11
+ * node scripts/discover.mjs
12
+ * node scripts/discover.mjs --json (same, explicit)
13
+ */
14
+
15
+ import { execFileSync, execSync } from 'node:child_process'
16
+ import { existsSync, readFileSync } from 'node:fs'
17
+ import { join } from 'node:path'
18
+ import { homedir } from 'node:os'
19
+
20
+ // ─── Known agents ─────────────────────────────────────────────────────────────
21
+
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'] },
32
+ ]
33
+
34
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
35
+
36
+ function isOnPath(bin) {
37
+ try {
38
+ execSync(
39
+ process.platform === 'win32' ? `where ${bin}` : `which ${bin}`,
40
+ { stdio: 'ignore', timeout: 3000 }
41
+ )
42
+ return true
43
+ } catch {
44
+ return false
45
+ }
46
+ }
47
+
48
+ function findBinary(bins) {
49
+ for (const bin of bins) {
50
+ if (isOnPath(bin)) return bin
51
+ }
52
+ return null
53
+ }
54
+
55
+ function getVersion(bin, args) {
56
+ try {
57
+ const out = execFileSync(bin, args, {
58
+ encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore']
59
+ })
60
+ return out.trim().split('\n')[0].trim()
61
+ } catch {
62
+ return null
63
+ }
64
+ }
65
+
66
+ // ─── Delegate-skills fleet ────────────────────────────────────────────────────
67
+
68
+ function readFleet(path) {
69
+ if (!existsSync(path)) return null
70
+ try {
71
+ const raw = readFileSync(path, 'utf8')
72
+ // Simple YAML lane parser (avoids dependency on js-yaml in scripts)
73
+ const lanes = {}
74
+ let currentLane = null
75
+ for (const line of raw.split('\n')) {
76
+ const laneMatch = line.match(/^ (\w[\w-]*):\s*$/)
77
+ const implementerMatch = line.match(/^\s+implementer:\s*(.+)$/)
78
+ const modelMatch = line.match(/^\s+model:\s*(.+)$/)
79
+ const effortMatch = line.match(/^\s+effort:\s*(.+)$/)
80
+ if (laneMatch) { currentLane = laneMatch[1]; lanes[currentLane] = {} }
81
+ else if (currentLane && implementerMatch) lanes[currentLane].implementer = implementerMatch[1].trim()
82
+ else if (currentLane && modelMatch) lanes[currentLane].model = modelMatch[1].trim()
83
+ else if (currentLane && effortMatch) lanes[currentLane].effort = effortMatch[1].trim()
84
+ }
85
+ return Object.keys(lanes).length > 0 ? lanes : null
86
+ } catch {
87
+ return null
88
+ }
89
+ }
90
+
91
+ function discoverDelegate() {
92
+ const globalPath = join(homedir(), '.delegate', 'fleet.yaml')
93
+ const projectPath = join(process.cwd(), '.delegate', 'fleet.yaml')
94
+
95
+ const globalLanes = readFleet(globalPath)
96
+ const projectLanes = readFleet(projectPath)
97
+
98
+ if (!globalLanes && !projectLanes) {
99
+ return { installed: false, lanes: {} }
100
+ }
101
+
102
+ const merged = { ...(globalLanes ?? {}), ...(projectLanes ?? {}) }
103
+ return { installed: true, lanes: merged }
104
+ }
105
+
106
+ // ─── Main ─────────────────────────────────────────────────────────────────────
107
+
108
+ function discover() {
109
+ const agents = {}
110
+
111
+ for (const desc of KNOWN_AGENTS) {
112
+ const bin = findBinary(desc.bins)
113
+ if (!bin) {
114
+ agents[desc.id] = { installed: false, available: false }
115
+ continue
116
+ }
117
+
118
+ const version = getVersion(bin, desc.versionArgs)
119
+ agents[desc.id] = {
120
+ installed: true,
121
+ available: version !== null,
122
+ version: version ?? 'unknown',
123
+ }
124
+ }
125
+
126
+ const delegateSkills = discoverDelegate()
127
+
128
+ const result = { agents, delegateSkills }
129
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n')
130
+ }
131
+
132
+ discover()
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * resume.mjs
4
+ * ───────────
5
+ * Finds interrupted or running runs and returns state for resumption.
6
+ *
7
+ * Usage:
8
+ * node scripts/resume.mjs → most recent interrupted run
9
+ * node scripts/resume.mjs --run-id run-abc → specific run
10
+ * node scripts/resume.mjs --list → all runs with status
11
+ *
12
+ * Output: JSON metadata of the run, or null if nothing to resume.
13
+ */
14
+
15
+ import { existsSync, readFileSync, readdirSync } from 'node:fs'
16
+ import { join } from 'node:path'
17
+
18
+ const RUNS_ROOT = existsSync(join(process.cwd(), '.adaptive-orchestrator', 'runs'))
19
+ ? join(process.cwd(), '.adaptive-orchestrator', 'runs')
20
+ : join(process.cwd(), '.adaptive-director', 'runs')
21
+ const RESUMABLE = new Set(['interrupted', 'running', 'pending'])
22
+
23
+ function metaPath(runId) {
24
+ return join(RUNS_ROOT, runId, 'metadata.json')
25
+ }
26
+
27
+ function allRuns() {
28
+ if (!existsSync(RUNS_ROOT)) return []
29
+ return readdirSync(RUNS_ROOT, { withFileTypes: true })
30
+ .filter(d => d.isDirectory())
31
+ .map(d => {
32
+ try { return JSON.parse(readFileSync(metaPath(d.name), 'utf8')) }
33
+ catch { return null }
34
+ })
35
+ .filter(Boolean)
36
+ .sort((a, b) => b.startedAt.localeCompare(a.startedAt))
37
+ }
38
+
39
+ // ─── Arg parser ───────────────────────────────────────────────────────────────
40
+
41
+ const args = {}
42
+ const argv = process.argv.slice(2)
43
+ for (let i = 0; i < argv.length; i++) {
44
+ if (argv[i].startsWith('--')) {
45
+ args[argv[i]] = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[++i] : true
46
+ }
47
+ }
48
+
49
+ // ─── Main ─────────────────────────────────────────────────────────────────────
50
+
51
+ function out(data) { process.stdout.write(JSON.stringify(data, null, 2) + '\n') }
52
+
53
+ if (args['--list']) {
54
+ out(allRuns())
55
+ process.exit(0)
56
+ }
57
+
58
+ if (args['--run-id']) {
59
+ const path = metaPath(args['--run-id'])
60
+ if (!existsSync(path)) {
61
+ process.stderr.write(`Run not found: ${args['--run-id']}\n`)
62
+ process.exit(1)
63
+ }
64
+ out(JSON.parse(readFileSync(path, 'utf8')))
65
+ process.exit(0)
66
+ }
67
+
68
+ // Find most recent resumable run
69
+ const resumable = allRuns().find(r => RESUMABLE.has(r.status))
70
+ out(resumable ?? null)