delegation-layer 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/package.json +1 -1
- package/plugins/delegation-layer/.claude-plugin/plugin.json +1 -1
- package/plugins/delegation-layer/.codex-plugin/plugin.json +1 -1
- package/plugins/delegation-layer/skills/agent-integration/SKILL.md +16 -8
- package/plugins/delegation-layer/skills/agent-integration/evals/evals.json +23 -3
- package/plugins/delegation-layer/skills/agent-integration/examples/json-results.md +5 -2
- package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +25 -10
- package/plugins/delegation-layer/skills/agent-integration/examples/read-only-task.md +3 -1
- package/plugins/delegation-layer/skills/agent-integration/references/ccr.md +5 -4
- package/plugins/delegation-layer/skills/agent-integration/references/collaboration.md +2 -2
- package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +69 -33
- package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +7 -4
- package/plugins/delegation-layer/skills/agent-integration/references/interaction.md +6 -5
- package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +7 -4
- package/plugins/delegation-layer/skills/agent-integration/references/routing-rule.json +1 -1
- package/plugins/delegation-layer/skills/agent-integration/references/workspaces.md +18 -14
- package/plugins/delegation-layer/skills/agent-integration/scripts/delegate-routing-context.sh +2 -2
- package/scripts/installer/routing-store.mjs +79 -46
- package/skills/agent-integration/SKILL.md +16 -8
- package/skills/agent-integration/evals/evals.json +23 -3
- package/skills/agent-integration/examples/json-results.md +5 -2
- package/skills/agent-integration/examples/managed-workspace.md +25 -10
- package/skills/agent-integration/examples/read-only-task.md +3 -1
- package/skills/agent-integration/references/ccr.md +5 -4
- package/skills/agent-integration/references/collaboration.md +2 -2
- package/skills/agent-integration/references/command-reference.md +69 -33
- package/skills/agent-integration/references/continuation.md +7 -4
- package/skills/agent-integration/references/interaction.md +6 -5
- package/skills/agent-integration/references/result-handling.md +7 -4
- package/skills/agent-integration/references/routing-rule.json +1 -1
- package/skills/agent-integration/references/workspaces.md +18 -14
- package/skills/agent-integration/scripts/delegate-routing-context.sh +2 -2
|
@@ -7,6 +7,10 @@ or attaches to a managed workspace (`--isolation git-worktree` or
|
|
|
7
7
|
`--workspace ID`), or creates or removes a [Git checkpoint](#git-checkpoints).
|
|
8
8
|
|
|
9
9
|
This reference is self-contained guidance for using managed workspaces.
|
|
10
|
+
Commands use the CLI default under the main skill's
|
|
11
|
+
[root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief). For a workspace
|
|
12
|
+
or checkpoint in an explicit custom or recorded historical root, pass that
|
|
13
|
+
exact `--root` on every related command.
|
|
10
14
|
|
|
11
15
|
Provider-native permissions still apply inside an isolated checkout. A provider
|
|
12
16
|
may edit files but be unable to stage or commit because linked-worktree Git
|
|
@@ -41,7 +45,7 @@ row ending or a provider outcome alone is not closure evidence.
|
|
|
41
45
|
Create a managed workspace from a committed source base:
|
|
42
46
|
|
|
43
47
|
```text
|
|
44
|
-
delegate
|
|
48
|
+
delegate dispatch --isolation git-worktree --cwd ABS \
|
|
45
49
|
[--base REV] [--workspace-budget DURATION] ... --json
|
|
46
50
|
```
|
|
47
51
|
|
|
@@ -55,7 +59,7 @@ removing that source does not block capture, release, or forget. A request that
|
|
|
55
59
|
workspace uses its recorded checkout and source identity:
|
|
56
60
|
|
|
57
61
|
```text
|
|
58
|
-
delegate
|
|
62
|
+
delegate dispatch --workspace WORKSPACE_ID ... --json
|
|
59
63
|
```
|
|
60
64
|
|
|
61
65
|
Public `--workspace` cannot be combined with `--cwd`, `--base`, or
|
|
@@ -80,11 +84,11 @@ made no write outside the promised content scope.
|
|
|
80
84
|
The CLI currently exposes these managed-workspace commands:
|
|
81
85
|
|
|
82
86
|
```text
|
|
83
|
-
delegate
|
|
84
|
-
delegate
|
|
85
|
-
delegate
|
|
86
|
-
delegate
|
|
87
|
-
delegate
|
|
87
|
+
delegate workspace list [--after ID] [--limit 1..50] --json
|
|
88
|
+
delegate workspace status ID [--operation OP] [--watch DURATION] --json
|
|
89
|
+
delegate workspace exec ID --budget DURATION --json -- ARGV...
|
|
90
|
+
delegate workspace release ID [--discard] [--budget DURATION] --json
|
|
91
|
+
delegate workspace forget ID [--budget DURATION] --json
|
|
88
92
|
```
|
|
89
93
|
|
|
90
94
|
`workspace exec` passes `ARGV...` directly to the supervised helper; the
|
|
@@ -110,7 +114,7 @@ must not mutate the predecessor's immutable records. A retained workspace can be
|
|
|
110
114
|
read-only review by attaching its ID, for example:
|
|
111
115
|
|
|
112
116
|
```text
|
|
113
|
-
delegate
|
|
117
|
+
delegate dispatch --provider codex:review \
|
|
114
118
|
--workspace WORKSPACE_ID --review-target TARGET --brief ABS_BRIEF \
|
|
115
119
|
--permission read-only --budget 1h --json
|
|
116
120
|
```
|
|
@@ -183,11 +187,11 @@ fixed Delegate values; trailers carry the checkpoint ID and request digest.
|
|
|
183
187
|
This is unrelated to a provider continuation `mode: "checkpoint"`.
|
|
184
188
|
|
|
185
189
|
```text
|
|
186
|
-
delegate
|
|
187
|
-
delegate
|
|
188
|
-
delegate
|
|
189
|
-
delegate
|
|
190
|
-
delegate
|
|
190
|
+
delegate checkpoint create --cwd ABS [--budget DURATION] --json
|
|
191
|
+
delegate checkpoint create --workspace ID [--budget DURATION] --json
|
|
192
|
+
delegate checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
|
|
193
|
+
delegate checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
|
|
194
|
+
delegate checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
|
|
191
195
|
```
|
|
192
196
|
|
|
193
197
|
- `create` names exactly one target: `--cwd` for an absolute ordinary Git
|
|
@@ -232,7 +236,7 @@ Save every response and exit code once; follow
|
|
|
232
236
|
the same repository as `--cwd`, normally the source the Lead already uses:
|
|
233
237
|
|
|
234
238
|
```text
|
|
235
|
-
delegate
|
|
239
|
+
delegate dispatch --auto --brief ABS_BRIEF --cwd ABS_SOURCE \
|
|
236
240
|
--isolation git-worktree --base COMMIT_OID \
|
|
237
241
|
--permission workspace-write --budget 30m --json
|
|
238
242
|
```
|
package/plugins/delegation-layer/skills/agent-integration/scripts/delegate-routing-context.sh
CHANGED
|
@@ -5,11 +5,11 @@ case "${1:-}" in
|
|
|
5
5
|
SessionStart|SubagentStart) event=$1 ;;
|
|
6
6
|
*) printf '%s\n' 'Expected SessionStart or SubagentStart.' >&2; exit 2 ;;
|
|
7
7
|
esac
|
|
8
|
-
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
8
|
+
script_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
|
|
9
9
|
rule_file="$script_dir/../references/routing-rule.json"
|
|
10
10
|
# Read before emitting anything so a missing asset cannot produce partial JSON.
|
|
11
11
|
rule=$(cat "$rule_file")
|
|
12
|
-
skill_file="$(CDPATH= cd -- "$script_dir/.." && pwd)/SKILL.md"
|
|
12
|
+
skill_file="$(CDPATH='' cd -- "$script_dir/.." && pwd)/SKILL.md"
|
|
13
13
|
DELEGATE_ROUTING_EVENT="$event" DELEGATE_ROUTING_RULE="$rule" DELEGATE_ROUTING_SKILL="$skill_file" awk '
|
|
14
14
|
BEGIN {
|
|
15
15
|
# Paths are task data, not shell code. Escape every JSON control character.
|
|
@@ -5,7 +5,7 @@ import { assertNoSymlinkComponents, existingPath } from "./filesystem.mjs";
|
|
|
5
5
|
import { countRoutingEvents, createRoutingPlan, routingPath, validateHookConfig } from "./routing-rules.mjs";
|
|
6
6
|
import { targetFor } from "./selection.mjs";
|
|
7
7
|
|
|
8
|
-
export async function prepareRouting(selected, action, { environment, platform
|
|
8
|
+
export async function prepareRouting(selected, action, { environment, platform }) {
|
|
9
9
|
const plans = [];
|
|
10
10
|
for (const name of new Set(selected.harnessNames)) {
|
|
11
11
|
const path = routingPath(name, {
|
|
@@ -55,85 +55,118 @@ export async function prepareRouting(selected, action, { environment, platform,
|
|
|
55
55
|
return plans;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const routingFileOperations = Object.freeze({ open, mkdir, readFile, rename, unlink, existingPath, assertNoSymlinkComponents });
|
|
59
|
+
|
|
60
|
+
function errorMessage(error) {
|
|
61
|
+
return error instanceof Error ? error.message : String(error);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function combinedFailure(failures) {
|
|
65
|
+
if (failures.length === 1) return failures[0];
|
|
66
|
+
return new AggregateError(failures, failures.map(errorMessage).join("; "), { cause: failures[0] });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function writeAndClose(file, contents) {
|
|
70
|
+
const failures = [];
|
|
71
|
+
try {
|
|
72
|
+
await file.writeFile(contents);
|
|
73
|
+
await file.sync();
|
|
74
|
+
} catch (error) {
|
|
75
|
+
failures.push(error);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
await file.close();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
failures.push(error);
|
|
81
|
+
}
|
|
82
|
+
if (failures.length) throw combinedFailure(failures);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function cleanupReplacement(lock, temporary, lockPath, operations) {
|
|
86
|
+
const failures = [];
|
|
87
|
+
try {
|
|
88
|
+
await operations.unlink(temporary);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) failures.push(error);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
await lock.close();
|
|
94
|
+
} catch (error) {
|
|
95
|
+
failures.push(error);
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
await operations.unlink(lockPath);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
failures.push(error);
|
|
101
|
+
}
|
|
102
|
+
return failures;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function replaceRoutingConfig(plan, before, after, operations, onCommitted) {
|
|
106
|
+
await operations.assertNoSymlinkComponents(plan.path);
|
|
107
|
+
await operations.mkdir(dirname(plan.path), { recursive: true });
|
|
61
108
|
const lockPath = plan.path + ".delegation-layer.lock";
|
|
62
109
|
let lock;
|
|
63
110
|
try {
|
|
64
|
-
lock = await open(lockPath, "wx", 0o600);
|
|
111
|
+
lock = await operations.open(lockPath, "wx", 0o600);
|
|
65
112
|
} catch (error) {
|
|
66
113
|
if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") {
|
|
67
|
-
throw new Error(`routing configuration is locked: ${lockPath}; verify no other installer is running before removing a stale lock
|
|
114
|
+
throw new Error(`routing configuration is locked: ${lockPath}; verify no other installer is running before removing a stale lock`, { cause: error });
|
|
68
115
|
}
|
|
69
116
|
throw error;
|
|
70
117
|
}
|
|
71
118
|
const suffix = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
72
119
|
const temporary = plan.path + `.delegation-layer-stage-${suffix}`;
|
|
120
|
+
const failures = [];
|
|
73
121
|
try {
|
|
74
|
-
const stat = await existingPath(plan.path);
|
|
122
|
+
const stat = await operations.existingPath(plan.path);
|
|
75
123
|
if (stat && (!stat.isFile() || stat.isSymbolicLink())) {
|
|
76
124
|
throw new Error(`routing configuration changed during installation: ${plan.path}`);
|
|
77
125
|
}
|
|
78
|
-
const current = stat ? await readFile(plan.path, "utf8") : null;
|
|
126
|
+
const current = stat ? await operations.readFile(plan.path, "utf8") : null;
|
|
79
127
|
if (current !== before) throw new Error(`routing configuration changed during installation; retry: ${plan.path}`);
|
|
80
128
|
if (before !== null) {
|
|
81
|
-
const backup = await open(plan.path + `.delegation-layer-backup-${suffix}`, "wx", 0o600);
|
|
82
|
-
|
|
83
|
-
await backup.writeFile(before);
|
|
84
|
-
await backup.sync();
|
|
85
|
-
} finally {
|
|
86
|
-
await backup.close();
|
|
87
|
-
}
|
|
129
|
+
const backup = await operations.open(plan.path + `.delegation-layer-backup-${suffix}`, "wx", 0o600);
|
|
130
|
+
await writeAndClose(backup, before);
|
|
88
131
|
}
|
|
89
132
|
if (after === null) {
|
|
90
|
-
await unlink(plan.path);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
await staged.writeFile(after);
|
|
96
|
-
await staged.sync();
|
|
97
|
-
} finally {
|
|
98
|
-
await staged.close();
|
|
99
|
-
}
|
|
100
|
-
await rename(temporary, plan.path);
|
|
101
|
-
} finally {
|
|
102
|
-
try {
|
|
103
|
-
try {
|
|
104
|
-
await unlink(temporary);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) throw error;
|
|
107
|
-
}
|
|
108
|
-
} finally {
|
|
109
|
-
try {
|
|
110
|
-
await lock.close();
|
|
111
|
-
} finally {
|
|
112
|
-
await unlink(lockPath);
|
|
113
|
-
}
|
|
133
|
+
await operations.unlink(plan.path);
|
|
134
|
+
} else {
|
|
135
|
+
const staged = await operations.open(temporary, "wx", plan.mode);
|
|
136
|
+
await writeAndClose(staged, after);
|
|
137
|
+
await operations.rename(temporary, plan.path);
|
|
114
138
|
}
|
|
139
|
+
onCommitted?.();
|
|
140
|
+
} catch (error) {
|
|
141
|
+
failures.push(error);
|
|
115
142
|
}
|
|
143
|
+
failures.push(...await cleanupReplacement(lock, temporary, lockPath, operations));
|
|
144
|
+
if (failures.length) throw combinedFailure(failures);
|
|
116
145
|
}
|
|
117
146
|
|
|
118
|
-
export async function applyRouting(plans) {
|
|
147
|
+
export async function applyRouting(plans, fileOperations = {}) {
|
|
148
|
+
const operations = { ...routingFileOperations, ...fileOperations };
|
|
149
|
+
// This transaction owns committed mutations, including commits followed by a cleanup failure.
|
|
119
150
|
const applied = [];
|
|
120
151
|
try {
|
|
121
152
|
for (const plan of plans) {
|
|
122
153
|
if (!plan.path || plan.before === plan.after) continue;
|
|
123
|
-
await replaceRoutingConfig(plan, plan.before, plan.after);
|
|
124
|
-
applied.push(plan);
|
|
154
|
+
await replaceRoutingConfig(plan, plan.before, plan.after, operations, () => applied.push(plan));
|
|
125
155
|
}
|
|
126
156
|
} catch (error) {
|
|
127
157
|
const failures = [];
|
|
128
158
|
for (const plan of applied.reverse()) {
|
|
129
159
|
try {
|
|
130
|
-
await replaceRoutingConfig(plan, plan.after, plan.before);
|
|
160
|
+
await replaceRoutingConfig(plan, plan.after, plan.before, operations);
|
|
131
161
|
} catch (rollbackError) {
|
|
132
|
-
failures.push(rollbackError
|
|
162
|
+
failures.push(rollbackError);
|
|
133
163
|
}
|
|
134
164
|
}
|
|
135
|
-
const reason =
|
|
136
|
-
|
|
165
|
+
const reason = errorMessage(error);
|
|
166
|
+
if (failures.length) {
|
|
167
|
+
throw new AggregateError([error, ...failures], `${reason}; rollback needs attention: ${failures.map(errorMessage).join("; ")}`, { cause: error });
|
|
168
|
+
}
|
|
169
|
+
throw new Error(`${reason}; earlier routing changes rolled back`, { cause: error });
|
|
137
170
|
}
|
|
138
171
|
}
|
|
139
172
|
|
|
@@ -87,11 +87,16 @@ Use a supplied brief or write the worker's bounded assignment and acceptance
|
|
|
87
87
|
criteria to a regular file. Do not copy the orchestration request or ask workers
|
|
88
88
|
to recruit others unless recursive delegation was requested.
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
For ordinary task, schedule, observation, interaction, and continuation commands,
|
|
91
|
+
omit `--root`; the CLI owns default-root resolution for the user's configuration
|
|
92
|
+
context, independently of the project cwd. Do not assemble a default path, use a
|
|
93
|
+
sample path or shell fallback, or treat ambient `DELEGATE_ROOT` as authority.
|
|
94
|
+
Only pass `--root` when the user explicitly supplies a root or existing work has
|
|
95
|
+
an already recorded custom or historical root; preserve that exact path for
|
|
96
|
+
every command concerning that work. Never search other roots for an old task.
|
|
97
|
+
Task IDs separate tasks; do not invent per-task or per-project roots. The state
|
|
98
|
+
root must remain outside provider-writable workspaces, provider runtime
|
|
99
|
+
directories, and temporary trees they may write.
|
|
95
100
|
|
|
96
101
|
Prepare paths and dispatch in one tool invocation; shell variables may not
|
|
97
102
|
persist between calls. Use saved absolute paths in later calls. Do not use
|
|
@@ -125,13 +130,16 @@ original command and intent.
|
|
|
125
130
|
### 5. Observe and collect
|
|
126
131
|
|
|
127
132
|
Follow [observation decisions](references/result-handling.md#observe-and-collect)
|
|
128
|
-
with the
|
|
133
|
+
with the created task ID, using the CLI default for ordinary work:
|
|
129
134
|
|
|
130
135
|
```sh
|
|
131
|
-
delegate
|
|
132
|
-
delegate
|
|
136
|
+
delegate status TASK_ID --json
|
|
137
|
+
delegate collect TASK_ID --watch 5s --json
|
|
133
138
|
```
|
|
134
139
|
|
|
140
|
+
For work bound to an explicit custom or historical root, add its exact
|
|
141
|
+
`--root` to both commands under the [root rule](#3-prepare-separate-paths-and-a-finite-brief).
|
|
142
|
+
|
|
135
143
|
Apply the owning decision order before waiting: terminal outcomes and concrete
|
|
136
144
|
errors, cancellation/timeout/interruption, interaction, then pending
|
|
137
145
|
observation. Keep collection in the foreground until completion or a reported
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "normal-dispatch",
|
|
12
12
|
"prompt": "Run one bounded task through the available agent provider.",
|
|
13
|
-
"expected": ["dispatch --auto", "--json", "save task_id", "status", "collect"]
|
|
13
|
+
"expected": ["dispatch --auto", "omit --root on ordinary commands", "--json", "save task_id", "status", "collect"]
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"name": "model-discovery-when-needed",
|
|
@@ -68,9 +68,29 @@
|
|
|
68
68
|
"expected": ["use status with returned task_id", "read saved dispatch response if needed", "do not dispatch again to print an exit code", "exactly one admitted task for the assignment"]
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
"name": "
|
|
71
|
+
"name": "ambient-root-ignored-across-shell-calls",
|
|
72
72
|
"prompt": "DELEGATE_ROOT is already set. Consult a separate external agent and answer its questions; each shell tool call starts a new shell.",
|
|
73
|
-
"expected": ["
|
|
73
|
+
"expected": ["omit --root on dispatch, status, collect, reply, steer, and continue", "ambient DELEGATE_ROOT has no root-selection authority", "CLI resolves its default in the same user/configuration context", "no assembled default, shell fallback, sample path, or per-task root"]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "ordinary-root-from-another-project",
|
|
77
|
+
"prompt": "DELEGATE_ROOT is unset. An admitted task was dispatched without --root in project A. Observe and continue it from project B in the same user/configuration context.",
|
|
78
|
+
"expected": ["omit --root on status, collect, and continue", "use the recorded task ID", "CLI default is independent of project cwd", "no path guessed from project A or B", "no search across roots"]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "explicit-root-across-shell-calls",
|
|
82
|
+
"prompt": "For this isolated test, I explicitly choose the state root /state/custom with spaces. Consult a separate external agent and answer its questions; each shell tool call starts a new shell.",
|
|
83
|
+
"expected": ["pass --root with the exact single argument /state/custom with spaces on dispatch, status, collect, reply, steer, and continue", "quote the root in shell commands", "save and reassign absolute brief and response paths in each needed shell invocation", "no ambient variable or fallback overrides the explicit choice"]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "historical-root-continuation",
|
|
87
|
+
"prompt": "An eligible predecessor task has recorded historical root /state/legacy with spaces. Continue that exact task and collect its successor. The current CLI default is different.",
|
|
88
|
+
"expected": ["pass the exact recorded --root argument /state/legacy with spaces on continue, status, and collect", "use the exact predecessor and returned successor IDs", "no fresh dispatch", "do not move or search for the task in the default root"]
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "ordinary-schedule-root",
|
|
92
|
+
"prompt": "Create a recurring task in this project, then inspect its definition, history, and execution from another project in the same user/configuration context. No custom state root was requested.",
|
|
93
|
+
"expected": ["omit --root on schedule create, list, show, history, and execution", "keep the definition's own project --cwd", "no per-project root", "do not start a persistent scheduler inside the agent task", "forward any returned scheduler.serve_command argv intact"]
|
|
74
94
|
},
|
|
75
95
|
{
|
|
76
96
|
"name": "pending-without-questions",
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# JSON decision sketch
|
|
2
2
|
|
|
3
|
+
Use the created task's exact ID as `TASK_ID` and follow the main skill's
|
|
4
|
+
[root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief).
|
|
5
|
+
|
|
3
6
|
```sh
|
|
4
|
-
delegate
|
|
5
|
-
delegate
|
|
7
|
+
delegate status TASK_ID --json
|
|
8
|
+
delegate collect TASK_ID --watch 5s --json
|
|
6
9
|
```
|
|
7
10
|
|
|
8
11
|
Apply [result handling](../references/result-handling.md) to each response and
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
Use this example for independent write work that should be isolated in a
|
|
4
4
|
retained Git worktree. The source must be a Git checkout and the state root
|
|
5
5
|
must remain outside provider-writable workspaces.
|
|
6
|
+
Commands use the CLI default under the main skill's
|
|
7
|
+
[root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief); preserve any
|
|
8
|
+
explicit custom or recorded historical root on all related commands.
|
|
6
9
|
|
|
7
10
|
```sh
|
|
8
11
|
SOURCE="$PWD"
|
|
9
|
-
BRIEF="$(mktemp)"
|
|
10
|
-
RESPONSE="$(mktemp)"
|
|
12
|
+
BRIEF="$(mktemp)" || exit 1
|
|
13
|
+
RESPONSE="$(mktemp)" || exit 1
|
|
11
14
|
printf '%s\n' 'Implement the requested change and report the files changed.' >"$BRIEF"
|
|
15
|
+
printf 'Saved response: %s\n' "$RESPONSE"
|
|
12
16
|
|
|
13
|
-
if delegate
|
|
17
|
+
if delegate dispatch --auto \
|
|
14
18
|
--brief "$BRIEF" --cwd "$SOURCE" \
|
|
15
19
|
--permission workspace-write --isolation git-worktree \
|
|
16
20
|
--base HEAD --workspace-budget 5m --budget 30m --json >"$RESPONSE"; then
|
|
@@ -26,9 +30,13 @@ Read the saved JSON before running another command. When
|
|
|
26
30
|
`task_record: "created"`, use its `task_id` as `TASK_ID` below. When no task
|
|
27
31
|
was created, follow the [result decisions](../references/result-handling.md#managed-workspace-results);
|
|
28
32
|
do not run task status or collection against that nonexistent record.
|
|
33
|
+
Each later block is a separate shell invocation. Replace `ABS_SAVED_RESPONSE`
|
|
34
|
+
with the printed absolute response path and the ID placeholders with the actual
|
|
35
|
+
returned IDs; reassign the path in each invocation.
|
|
29
36
|
|
|
30
37
|
```sh
|
|
31
|
-
|
|
38
|
+
RESPONSE="ABS_SAVED_RESPONSE"
|
|
39
|
+
if delegate status TASK_ID --json >"$RESPONSE.status"; then
|
|
32
40
|
status_exit=0
|
|
33
41
|
else
|
|
34
42
|
status_exit=$?
|
|
@@ -43,7 +51,8 @@ before running another command. Run the collection below only when that
|
|
|
43
51
|
guidance calls for it.
|
|
44
52
|
|
|
45
53
|
```sh
|
|
46
|
-
|
|
54
|
+
RESPONSE="ABS_SAVED_RESPONSE"
|
|
55
|
+
if delegate collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
|
|
47
56
|
collect_exit=0
|
|
48
57
|
else
|
|
49
58
|
collect_exit=$?
|
|
@@ -64,7 +73,8 @@ Before release, wait for the workspace to return to `state: retained` and inspec
|
|
|
64
73
|
its final capture. Only after the Lead explicitly chooses release, run:
|
|
65
74
|
|
|
66
75
|
```sh
|
|
67
|
-
|
|
76
|
+
RESPONSE="ABS_SAVED_RESPONSE"
|
|
77
|
+
if delegate workspace release WORKSPACE_ID \
|
|
68
78
|
--budget 5m --json >"$RESPONSE.release"; then
|
|
69
79
|
release_exit=0
|
|
70
80
|
else
|
|
@@ -95,8 +105,9 @@ owns every response decision.
|
|
|
95
105
|
|
|
96
106
|
```sh
|
|
97
107
|
SOURCE="$PWD"
|
|
98
|
-
RESPONSE="$(mktemp)"
|
|
99
|
-
|
|
108
|
+
RESPONSE="$(mktemp)" || exit 1
|
|
109
|
+
printf 'Saved response: %s\n' "$RESPONSE"
|
|
110
|
+
if delegate checkpoint create \
|
|
100
111
|
--cwd "$SOURCE" --budget 5m --json >"$RESPONSE.checkpoint"; then
|
|
101
112
|
checkpoint_exit=0
|
|
102
113
|
else
|
|
@@ -109,9 +120,12 @@ cat "$RESPONSE.checkpoint"
|
|
|
109
120
|
Exit `3` with `checkpoint.id` and `next_action: "watch_checkpoint"` means the
|
|
110
121
|
request was accepted, not captured. Use that `checkpoint.id` as
|
|
111
122
|
`CHECKPOINT_ID`. Do not run `create` again.
|
|
123
|
+
For the later checkpoint blocks, replace `ABS_SAVED_RESPONSE` with the absolute
|
|
124
|
+
response path printed by this checkpoint invocation.
|
|
112
125
|
|
|
113
126
|
```sh
|
|
114
|
-
|
|
127
|
+
RESPONSE="ABS_SAVED_RESPONSE"
|
|
128
|
+
if delegate checkpoint status CHECKPOINT_ID \
|
|
115
129
|
--watch 30s --json >"$RESPONSE.checkpoint.status"; then
|
|
116
130
|
checkpoint_status_exit=0
|
|
117
131
|
else
|
|
@@ -130,7 +144,8 @@ dispatch example, replacing `--base HEAD` with `--base COMMIT_OID`. Report a
|
|
|
130
144
|
When the Lead no longer needs the checkpoint, remove it explicitly:
|
|
131
145
|
|
|
132
146
|
```sh
|
|
133
|
-
|
|
147
|
+
RESPONSE="ABS_SAVED_RESPONSE"
|
|
148
|
+
if delegate checkpoint remove CHECKPOINT_ID \
|
|
134
149
|
--budget 5m --json >"$RESPONSE.checkpoint.remove"; then
|
|
135
150
|
checkpoint_remove_exit=0
|
|
136
151
|
else
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Run from the intended workspace, outside Delegate's private state root.
|
|
4
4
|
Use a catalog provider ID in place of `--auto` when a destination was named.
|
|
5
|
+
This example uses the CLI default under the main skill's
|
|
6
|
+
[root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief).
|
|
5
7
|
Prepare paths and dispatch in this same shell invocation:
|
|
6
8
|
|
|
7
9
|
```sh
|
|
@@ -13,7 +15,7 @@ Inspect the workspace and summarize the current test failures. Do not edit files
|
|
|
13
15
|
You are the assigned worker; perform this task without delegating it.
|
|
14
16
|
EOF
|
|
15
17
|
printf 'Saved response: %s\n' "$RESPONSE"
|
|
16
|
-
if delegate
|
|
18
|
+
if delegate dispatch --auto \
|
|
17
19
|
--brief "$BRIEF" --cwd "$WORKSPACE" \
|
|
18
20
|
--permission read-only --budget 30m --json >"$RESPONSE"; then
|
|
19
21
|
dispatch_exit=0
|
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
Use this reference when asked to consult Claude Code Router (CCR), use one of
|
|
4
4
|
its configured model aliases, or compare its models with other harnesses.
|
|
5
5
|
CCR runs Claude Code against a configured third-party or local provider.
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
Use the CLI default under the main skill's
|
|
7
|
+
[root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief); preserve any
|
|
8
|
+
explicit custom or recorded historical root for model discovery and dispatch.
|
|
8
9
|
|
|
9
10
|
1. Resolve CCR through `delegate providers --json`; its profile is `ccr:print`.
|
|
10
11
|
2. Preserve an explicitly requested CCR alias as `--model ALIAS`. Do not replace
|
|
11
12
|
it with an upstream model ID or reject it solely because discovery omitted it.
|
|
12
13
|
3. If no alias was chosen, run
|
|
13
|
-
`delegate
|
|
14
|
+
`delegate models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
|
|
14
15
|
Choose a suitable configured alias from the available metadata and report
|
|
15
16
|
the choice. Clarify when the intended model remains ambiguous. If discovery
|
|
16
17
|
is unavailable and no alias is known, report the blocker; do not guess.
|
|
17
|
-
4. Dispatch through Delegate with
|
|
18
|
+
4. Dispatch through Delegate with
|
|
18
19
|
`--provider ccr:print --model ALIAS`, the brief, workspace, permission, finite
|
|
19
20
|
budget, and `--json`. Use the normal status, collect, and continuation procedure
|
|
20
21
|
from the main skill.
|
|
@@ -45,7 +45,7 @@ RECEIPTS="$(mktemp -d)" || exit 1
|
|
|
45
45
|
# Set these absolute paths and catalog IDs in this same tool invocation.
|
|
46
46
|
# BRIEF_A and BRIEF_B contain the real independent assignments.
|
|
47
47
|
(
|
|
48
|
-
if delegate
|
|
48
|
+
if delegate dispatch --provider "$PROVIDER_A" \
|
|
49
49
|
--brief "$BRIEF_A" --cwd "$WORKSPACE_A" \
|
|
50
50
|
--permission read-only --budget 30m --json \
|
|
51
51
|
>"$RECEIPTS/review-a.json" 2>"$RECEIPTS/review-a.stderr"; then
|
|
@@ -56,7 +56,7 @@ RECEIPTS="$(mktemp -d)" || exit 1
|
|
|
56
56
|
printf '%s\n' "$dispatch_exit" >"$RECEIPTS/review-a.exit"
|
|
57
57
|
) &
|
|
58
58
|
(
|
|
59
|
-
if delegate
|
|
59
|
+
if delegate dispatch --provider "$PROVIDER_B" \
|
|
60
60
|
--brief "$BRIEF_B" --cwd "$WORKSPACE_B" \
|
|
61
61
|
--permission read-only --budget 30m --json \
|
|
62
62
|
>"$RECEIPTS/review-b.json" 2>"$RECEIPTS/review-b.stderr"; then
|