delegation-layer 0.1.15 → 0.1.17
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 +32 -4
- package/install.sh +37 -6
- package/package.json +2 -1
- package/plugins/delegation-layer/.claude-plugin/plugin.json +22 -0
- package/plugins/delegation-layer/.codex-plugin/plugin.json +33 -0
- package/plugins/delegation-layer/hooks/hooks.json +14 -0
- package/plugins/delegation-layer/scripts/ensure-delegate.sh +123 -0
- package/plugins/delegation-layer/scripts/install-cli.sh +108 -0
- package/plugins/delegation-layer/skills/agent-integration/SKILL.md +301 -0
- package/plugins/delegation-layer/skills/agent-integration/evals/evals.json +61 -0
- package/plugins/delegation-layer/skills/agent-integration/examples/json-results.md +14 -0
- package/plugins/delegation-layer/skills/agent-integration/examples/read-only-task.md +12 -0
- package/plugins/delegation-layer/skills/agent-integration/examples/workspace-write-task.md +14 -0
- package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +50 -0
- package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +46 -0
- package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +37 -0
- package/skills/agent-integration/SKILL.md +12 -6
package/README.md
CHANGED
|
@@ -31,14 +31,41 @@ already use instead of replacing them.
|
|
|
31
31
|
|
|
32
32
|
## How it works
|
|
33
33
|
|
|
34
|
-
1. Install the
|
|
34
|
+
1. Install the plugin so the skill and self-contained CLI are available together.
|
|
35
35
|
2. The lead agent discovers the available provider capabilities.
|
|
36
36
|
3. Delegation Layer admits one bounded provider turn through the supervisor.
|
|
37
37
|
4. The lead agent collects the sealed result and evidence.
|
|
38
38
|
|
|
39
39
|
## Install
|
|
40
40
|
|
|
41
|
-
###
|
|
41
|
+
### Recommended for Codex and Claude Code
|
|
42
|
+
|
|
43
|
+
Install the plugin from this repository. It installs the provider-neutral skill
|
|
44
|
+
and runs a trusted session-start bootstrap that reuses the checksum-verified
|
|
45
|
+
Delegation Layer release installer when `delegate` is missing. The bootstrap
|
|
46
|
+
installs the CLI and its bundled supervisor; it does not install provider CLIs,
|
|
47
|
+
change provider authentication, or change provider configuration.
|
|
48
|
+
|
|
49
|
+
For Codex:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
codex plugin marketplace add hishamkaram/delegation-layer
|
|
53
|
+
codex plugin add delegation-layer@delegation-layer
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For Claude Code:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
claude plugin marketplace add hishamkaram/delegation-layer
|
|
60
|
+
claude plugin install delegation-layer@delegation-layer
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Start a new harness session after installation. Plugin hooks require the
|
|
64
|
+
harness trust review before they run. If the bootstrap reports that the
|
|
65
|
+
install directory is not on `PATH`, add the reported directory to `PATH` and
|
|
66
|
+
start a new session; the skill never falls back to a provider-native CLI.
|
|
67
|
+
|
|
68
|
+
### Install the Agent Skill only
|
|
42
69
|
|
|
43
70
|
The standard Agent Skills installer works across popular coding agents. From
|
|
44
71
|
the project where you want the skill available, run:
|
|
@@ -68,8 +95,9 @@ npx --yes delegation-layer install \
|
|
|
68
95
|
--yes
|
|
69
96
|
```
|
|
70
97
|
|
|
71
|
-
|
|
72
|
-
|
|
98
|
+
This path installs guidance only. It does not install the CLI, change provider
|
|
99
|
+
logins, or run a task. Use the plugin path above when you want the skill and
|
|
100
|
+
CLI bootstrap together.
|
|
73
101
|
|
|
74
102
|
### Install the CLI
|
|
75
103
|
|
package/install.sh
CHANGED
|
@@ -10,13 +10,18 @@ fail() {
|
|
|
10
10
|
exit 1
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
for command_name in awk curl grep install mktemp tar uname; do
|
|
13
|
+
for command_name in awk curl grep install mkdir mktemp mv rm tar uname; do
|
|
14
14
|
command -v "$command_name" >/dev/null 2>&1 || fail "required command not found: $command_name"
|
|
15
15
|
done
|
|
16
16
|
|
|
17
|
+
case "$INSTALL_DIR" in
|
|
18
|
+
/*) ;;
|
|
19
|
+
*) fail "install directory must be an absolute path: $INSTALL_DIR" ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
17
22
|
if [ "$REQUESTED_VERSION" = "latest" ]; then
|
|
18
23
|
latest_url="https://github.com/${REPOSITORY}/releases/latest"
|
|
19
|
-
resolved_url="$(curl -fsSL -o /dev/null -w '%{url_effective}' "$latest_url")" || fail "could not resolve the latest release"
|
|
24
|
+
resolved_url="$(curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o /dev/null -w '%{url_effective}' "$latest_url")" || fail "could not resolve the latest release"
|
|
20
25
|
VERSION="${resolved_url##*/}"
|
|
21
26
|
else
|
|
22
27
|
VERSION="$REQUESTED_VERSION"
|
|
@@ -44,11 +49,21 @@ esac
|
|
|
44
49
|
ARCHIVE="delegation-layer_${VERSION#v}_${OS}_${ARCH}.tar.gz"
|
|
45
50
|
RELEASE_URL="https://github.com/${REPOSITORY}/releases/download/${VERSION}"
|
|
46
51
|
TEMP_DIR="$(mktemp -d)"
|
|
47
|
-
|
|
52
|
+
STAGE_DIR=""
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
cleanup() {
|
|
55
|
+
status=$?
|
|
56
|
+
trap - EXIT HUP INT TERM
|
|
57
|
+
set +e
|
|
58
|
+
[ -z "$STAGE_DIR" ] || rm -rf "$STAGE_DIR"
|
|
59
|
+
rm -rf "$TEMP_DIR"
|
|
60
|
+
exit "$status"
|
|
61
|
+
}
|
|
62
|
+
trap cleanup EXIT HUP INT TERM
|
|
63
|
+
|
|
64
|
+
curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o "$TEMP_DIR/$ARCHIVE" "$RELEASE_URL/$ARCHIVE" || \
|
|
50
65
|
fail "could not download $ARCHIVE"
|
|
51
|
-
curl -fsSL --retry
|
|
66
|
+
curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o "$TEMP_DIR/checksums.txt" "$RELEASE_URL/checksums.txt" || \
|
|
52
67
|
fail "could not download checksums.txt"
|
|
53
68
|
|
|
54
69
|
CHECKSUM_LINE="$(awk -v archive="$ARCHIVE" '$2 == archive { print; exit }' "$TEMP_DIR/checksums.txt")"
|
|
@@ -65,10 +80,26 @@ fi
|
|
|
65
80
|
|
|
66
81
|
tar -xzf "$ARCHIVE" -C "$TEMP_DIR" || fail "could not extract $ARCHIVE"
|
|
67
82
|
mkdir -p "$INSTALL_DIR"
|
|
83
|
+
STAGE_DIR="$(mktemp -d "$INSTALL_DIR/.delegation-layer-stage.XXXXXX")" || \
|
|
84
|
+
fail "could not create an installation staging directory"
|
|
68
85
|
for binary in delegate delegate-run pueue pueued; do
|
|
69
86
|
[ -f "$TEMP_DIR/$binary" ] || fail "release archive does not contain $binary"
|
|
70
|
-
install -m 0755 "$TEMP_DIR/$binary" "$
|
|
87
|
+
install -m 0755 "$TEMP_DIR/$binary" "$STAGE_DIR/$binary" || \
|
|
88
|
+
fail "could not stage $binary"
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
for binary in delegate delegate-run pueue pueued; do
|
|
92
|
+
[ -x "$STAGE_DIR/$binary" ] || fail "staged release bundle does not contain executable $binary"
|
|
93
|
+
done
|
|
94
|
+
|
|
95
|
+
# Rename staged files only after the complete bundle has been downloaded,
|
|
96
|
+
# verified, extracted, and checked. Keep delegate last so a fresh install never
|
|
97
|
+
# exposes the control command before its runner and supervisor are ready.
|
|
98
|
+
for binary in delegate-run pueue pueued delegate; do
|
|
99
|
+
mv "$STAGE_DIR/$binary" "$INSTALL_DIR/$binary" || fail "could not publish $binary"
|
|
71
100
|
done
|
|
101
|
+
rm -rf "$STAGE_DIR"
|
|
102
|
+
STAGE_DIR=""
|
|
72
103
|
|
|
73
104
|
printf 'Installed delegation-layer CLI and bundled supervisor %s in %s\n' "$VERSION" "$INSTALL_DIR"
|
|
74
105
|
case ":${PATH:-}:" in
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delegation-layer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Multi-provider AI agent delegation CLI and Agent Skill for running bounded coding tasks across provider CLIs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"docs/assets/delegation-layer-hero.jpg",
|
|
26
26
|
"install.sh",
|
|
27
27
|
"skills/agent-integration/",
|
|
28
|
+
"plugins/delegation-layer/",
|
|
28
29
|
"scripts/install-agent-integration.mjs",
|
|
29
30
|
"scripts/install-cli.mjs"
|
|
30
31
|
],
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "delegation-layer",
|
|
3
|
+
"displayName": "Delegation Layer",
|
|
4
|
+
"version": "0.1.17",
|
|
5
|
+
"description": "Route every delegated agent task through a bounded, resumable Delegation Layer CLI.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Hesham Karam",
|
|
8
|
+
"url": "https://github.com/hishamkaram"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/hishamkaram/delegation-layer",
|
|
11
|
+
"repository": "https://github.com/hishamkaram/delegation-layer",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"agent-delegation",
|
|
15
|
+
"agent-skills",
|
|
16
|
+
"coding-agents",
|
|
17
|
+
"orchestration",
|
|
18
|
+
"task-lifecycle"
|
|
19
|
+
],
|
|
20
|
+
"defaultEnabled": true,
|
|
21
|
+
"skills": "./skills/"
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "delegation-layer",
|
|
3
|
+
"version": "0.1.17",
|
|
4
|
+
"description": "Route every delegated agent task through a bounded, resumable Delegation Layer CLI.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Hesham Karam",
|
|
7
|
+
"url": "https://github.com/hishamkaram"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/hishamkaram/delegation-layer",
|
|
10
|
+
"repository": "https://github.com/hishamkaram/delegation-layer",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"agent-delegation",
|
|
14
|
+
"agent-skills",
|
|
15
|
+
"coding-agents",
|
|
16
|
+
"orchestration",
|
|
17
|
+
"task-lifecycle"
|
|
18
|
+
],
|
|
19
|
+
"skills": "./skills/",
|
|
20
|
+
"interface": {
|
|
21
|
+
"displayName": "Delegation Layer",
|
|
22
|
+
"shortDescription": "Delegate agent work reliably",
|
|
23
|
+
"longDescription": "Routes external agent work through a bounded, resumable CLI with durable evidence and provider-neutral capability handling.",
|
|
24
|
+
"developerName": "Hesham Karam",
|
|
25
|
+
"category": "Productivity",
|
|
26
|
+
"capabilities": [
|
|
27
|
+
"Agent delegation",
|
|
28
|
+
"Bounded execution",
|
|
29
|
+
"Resumable tasks"
|
|
30
|
+
],
|
|
31
|
+
"defaultPrompt": "Use $agent-integration whenever another agent, harness, model, or provider should perform work."
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "/bin/sh -c 'plugin_root=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:?plugin root environment variable is missing}}\"; exec \"$plugin_root/scripts/ensure-delegate.sh\"'"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
fail() {
|
|
5
|
+
printf 'delegation-layer plugin: %s\n' "$1" >&2
|
|
6
|
+
exit 1
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
plugin_root="${PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-}}"
|
|
10
|
+
[ -n "$plugin_root" ] || fail 'the plugin root environment variable is missing'
|
|
11
|
+
|
|
12
|
+
installer="$plugin_root/scripts/install-cli.sh"
|
|
13
|
+
[ -x "$installer" ] || fail "the bundled CLI installer is missing: $installer"
|
|
14
|
+
|
|
15
|
+
resolve_command_path() {
|
|
16
|
+
path="$1"
|
|
17
|
+
case "$path" in
|
|
18
|
+
/*) ;;
|
|
19
|
+
*) path="$(cd -P "$(dirname "$path")" 2>/dev/null && pwd)/$(basename "$path")" || return 1 ;;
|
|
20
|
+
esac
|
|
21
|
+
while [ -L "$path" ]; do
|
|
22
|
+
link="$(readlink "$path")" || return 1
|
|
23
|
+
case "$link" in
|
|
24
|
+
/*) path="$link" ;;
|
|
25
|
+
*) path="$(dirname "$path")/$link" ;;
|
|
26
|
+
esac
|
|
27
|
+
done
|
|
28
|
+
path="$(cd -P "$(dirname "$path")" 2>/dev/null && pwd)/$(basename "$path")" || return 1
|
|
29
|
+
printf '%s\n' "$path"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
valid_delegate() {
|
|
33
|
+
candidate="$1"
|
|
34
|
+
[ -f "$candidate" ] && [ -x "$candidate" ] || return 1
|
|
35
|
+
resolved_candidate="$(resolve_command_path "$candidate")" || return 1
|
|
36
|
+
resolved_bin_dir="$(dirname "$resolved_candidate")"
|
|
37
|
+
supervisor_dir="$resolved_bin_dir"
|
|
38
|
+
if [ ! -x "$supervisor_dir/pueue" ] || [ ! -x "$supervisor_dir/pueued" ]; then
|
|
39
|
+
supervisor_dir="$resolved_bin_dir/../libexec"
|
|
40
|
+
fi
|
|
41
|
+
delegate_run="$resolved_bin_dir/delegate-run"
|
|
42
|
+
pueue="$supervisor_dir/pueue"
|
|
43
|
+
pueued="$supervisor_dir/pueued"
|
|
44
|
+
[ -f "$delegate_run" ] && [ -x "$delegate_run" ] || return 1
|
|
45
|
+
[ -f "$pueue" ] && [ -x "$pueue" ] || return 1
|
|
46
|
+
[ -f "$pueued" ] && [ -x "$pueued" ] || return 1
|
|
47
|
+
|
|
48
|
+
delegate_version="$("$candidate" --version 2>/dev/null)" || return 1
|
|
49
|
+
case "$delegate_version" in
|
|
50
|
+
delegate\ *) ;;
|
|
51
|
+
*) return 1 ;;
|
|
52
|
+
esac
|
|
53
|
+
pueue_version="$("$pueue" --version 2>/dev/null)" || return 1
|
|
54
|
+
pueued_version="$("$pueued" --version 2>/dev/null)" || return 1
|
|
55
|
+
case "$pueue_version" in
|
|
56
|
+
pueue\ *) ;;
|
|
57
|
+
*) return 1 ;;
|
|
58
|
+
esac
|
|
59
|
+
case "$pueued_version" in
|
|
60
|
+
pueued\ *) ;;
|
|
61
|
+
*) return 1 ;;
|
|
62
|
+
esac
|
|
63
|
+
pueue_release="$(printf '%s\n' "$pueue_version" | awk 'NF { print $NF; exit }')"
|
|
64
|
+
pueued_release="$(printf '%s\n' "$pueued_version" | awk 'NF { print $NF; exit }')"
|
|
65
|
+
[ -n "$pueue_release" ] && [ "$pueue_release" = "$pueued_release" ]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
path_points_to() {
|
|
69
|
+
expected="$1"
|
|
70
|
+
actual="$(command -v delegate 2>/dev/null || true)"
|
|
71
|
+
[ -n "$actual" ] || return 1
|
|
72
|
+
actual="$(resolve_command_path "$actual")" || return 1
|
|
73
|
+
expected="$(resolve_command_path "$expected")" || return 1
|
|
74
|
+
[ "$actual" = "$expected" ]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
path_delegate="$(command -v delegate 2>/dev/null || true)"
|
|
78
|
+
if [ -n "$path_delegate" ] && valid_delegate "$path_delegate"; then
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
existing_install_dir="${DELEGATION_LAYER_INSTALL_DIR:-$HOME/.local/bin}"
|
|
83
|
+
existing_delegate="$existing_install_dir/delegate"
|
|
84
|
+
if valid_delegate "$existing_delegate"; then
|
|
85
|
+
case ":${PATH:-}:" in
|
|
86
|
+
*:"$existing_install_dir":*)
|
|
87
|
+
path_points_to "$existing_delegate" && exit 0
|
|
88
|
+
shadowed_delegate="$(command -v delegate 2>/dev/null || true)"
|
|
89
|
+
fail "delegate is installed at $existing_install_dir but PATH resolves delegate to ${shadowed_delegate:-an unavailable command}; put $existing_install_dir before the shadowing entry and start a new harness session"
|
|
90
|
+
;;
|
|
91
|
+
*)
|
|
92
|
+
fail "delegate is installed at $existing_install_dir but that directory is not on PATH; add it to PATH and start a new harness session"
|
|
93
|
+
;;
|
|
94
|
+
esac
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
install_dir="$existing_install_dir"
|
|
98
|
+
case "$install_dir" in
|
|
99
|
+
/*) ;;
|
|
100
|
+
*) fail "the CLI install directory must be an absolute path: $install_dir" ;;
|
|
101
|
+
esac
|
|
102
|
+
|
|
103
|
+
if [ -e "$install_dir/delegate" ] || [ -L "$install_dir/delegate" ]; then
|
|
104
|
+
fail "refusing to overwrite an existing delegate at $install_dir/delegate; put a clean directory first in PATH or set DELEGATION_LAYER_INSTALL_DIR to a dedicated directory"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
DELEGATION_LAYER_INSTALL_DIR="$install_dir" sh "$installer" ||
|
|
108
|
+
fail 'the checksum-verified CLI installation failed'
|
|
109
|
+
|
|
110
|
+
installed_delegate="$install_dir/delegate"
|
|
111
|
+
valid_delegate "$installed_delegate" ||
|
|
112
|
+
fail "the installer completed but delegate is not usable at $installed_delegate"
|
|
113
|
+
|
|
114
|
+
if path_points_to "$installed_delegate"; then
|
|
115
|
+
printf 'Delegation Layer CLI is ready at %s\n' "$installed_delegate"
|
|
116
|
+
exit 0
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
path_delegate="$(command -v delegate 2>/dev/null || true)"
|
|
120
|
+
if [ -n "$path_delegate" ]; then
|
|
121
|
+
fail "delegate was installed at $install_dir but PATH resolves delegate to $path_delegate; put $install_dir before the shadowing entry and start a new harness session"
|
|
122
|
+
fi
|
|
123
|
+
fail "delegate was installed at $install_dir but that directory is not on PATH; add it to PATH and start a new harness session"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
REPOSITORY="hishamkaram/delegation-layer"
|
|
5
|
+
REQUESTED_VERSION="${DELEGATION_LAYER_VERSION:-latest}"
|
|
6
|
+
INSTALL_DIR="${DELEGATION_LAYER_INSTALL_DIR:-$HOME/.local/bin}"
|
|
7
|
+
|
|
8
|
+
fail() {
|
|
9
|
+
printf 'delegation-layer: %s\n' "$1" >&2
|
|
10
|
+
exit 1
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for command_name in awk curl grep install mkdir mktemp mv rm tar uname; do
|
|
14
|
+
command -v "$command_name" >/dev/null 2>&1 || fail "required command not found: $command_name"
|
|
15
|
+
done
|
|
16
|
+
|
|
17
|
+
case "$INSTALL_DIR" in
|
|
18
|
+
/*) ;;
|
|
19
|
+
*) fail "install directory must be an absolute path: $INSTALL_DIR" ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
if [ "$REQUESTED_VERSION" = "latest" ]; then
|
|
23
|
+
latest_url="https://github.com/${REPOSITORY}/releases/latest"
|
|
24
|
+
resolved_url="$(curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o /dev/null -w '%{url_effective}' "$latest_url")" || fail "could not resolve the latest release"
|
|
25
|
+
VERSION="${resolved_url##*/}"
|
|
26
|
+
else
|
|
27
|
+
VERSION="$REQUESTED_VERSION"
|
|
28
|
+
case "$VERSION" in
|
|
29
|
+
v*) ;;
|
|
30
|
+
*) VERSION="v${VERSION}" ;;
|
|
31
|
+
esac
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
printf '%s\n' "$VERSION" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$' || \
|
|
35
|
+
fail "invalid version: $VERSION"
|
|
36
|
+
|
|
37
|
+
case "$(uname -s)" in
|
|
38
|
+
Linux) OS=Linux ;;
|
|
39
|
+
Darwin) OS=Darwin ;;
|
|
40
|
+
*) fail "unsupported operating system: $(uname -s)" ;;
|
|
41
|
+
esac
|
|
42
|
+
|
|
43
|
+
case "$(uname -m)" in
|
|
44
|
+
x86_64|amd64) ARCH=amd64 ;;
|
|
45
|
+
arm64|aarch64) ARCH=arm64 ;;
|
|
46
|
+
*) fail "unsupported architecture: $(uname -m)" ;;
|
|
47
|
+
esac
|
|
48
|
+
|
|
49
|
+
ARCHIVE="delegation-layer_${VERSION#v}_${OS}_${ARCH}.tar.gz"
|
|
50
|
+
RELEASE_URL="https://github.com/${REPOSITORY}/releases/download/${VERSION}"
|
|
51
|
+
TEMP_DIR="$(mktemp -d)"
|
|
52
|
+
STAGE_DIR=""
|
|
53
|
+
|
|
54
|
+
cleanup() {
|
|
55
|
+
status=$?
|
|
56
|
+
trap - EXIT HUP INT TERM
|
|
57
|
+
set +e
|
|
58
|
+
[ -z "$STAGE_DIR" ] || rm -rf "$STAGE_DIR"
|
|
59
|
+
rm -rf "$TEMP_DIR"
|
|
60
|
+
exit "$status"
|
|
61
|
+
}
|
|
62
|
+
trap cleanup EXIT HUP INT TERM
|
|
63
|
+
|
|
64
|
+
curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o "$TEMP_DIR/$ARCHIVE" "$RELEASE_URL/$ARCHIVE" || \
|
|
65
|
+
fail "could not download $ARCHIVE"
|
|
66
|
+
curl -fsSL --connect-timeout 5 --max-time 20 --retry 2 --retry-delay 1 --retry-max-time 30 -o "$TEMP_DIR/checksums.txt" "$RELEASE_URL/checksums.txt" || \
|
|
67
|
+
fail "could not download checksums.txt"
|
|
68
|
+
|
|
69
|
+
CHECKSUM_LINE="$(awk -v archive="$ARCHIVE" '$2 == archive { print; exit }' "$TEMP_DIR/checksums.txt")"
|
|
70
|
+
[ -n "$CHECKSUM_LINE" ] || fail "checksums.txt does not contain $ARCHIVE"
|
|
71
|
+
|
|
72
|
+
cd "$TEMP_DIR"
|
|
73
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
74
|
+
printf '%s\n' "$CHECKSUM_LINE" | sha256sum -c - || fail "checksum verification failed"
|
|
75
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
76
|
+
printf '%s\n' "$CHECKSUM_LINE" | shasum -a 256 -c - || fail "checksum verification failed"
|
|
77
|
+
else
|
|
78
|
+
fail "sha256sum or shasum is required for checksum verification"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
tar -xzf "$ARCHIVE" -C "$TEMP_DIR" || fail "could not extract $ARCHIVE"
|
|
82
|
+
mkdir -p "$INSTALL_DIR"
|
|
83
|
+
STAGE_DIR="$(mktemp -d "$INSTALL_DIR/.delegation-layer-stage.XXXXXX")" || \
|
|
84
|
+
fail "could not create an installation staging directory"
|
|
85
|
+
for binary in delegate delegate-run pueue pueued; do
|
|
86
|
+
[ -f "$TEMP_DIR/$binary" ] || fail "release archive does not contain $binary"
|
|
87
|
+
install -m 0755 "$TEMP_DIR/$binary" "$STAGE_DIR/$binary" || \
|
|
88
|
+
fail "could not stage $binary"
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
for binary in delegate delegate-run pueue pueued; do
|
|
92
|
+
[ -x "$STAGE_DIR/$binary" ] || fail "staged release bundle does not contain executable $binary"
|
|
93
|
+
done
|
|
94
|
+
|
|
95
|
+
# Rename staged files only after the complete bundle has been downloaded,
|
|
96
|
+
# verified, extracted, and checked. Keep delegate last so a fresh install never
|
|
97
|
+
# exposes the control command before its runner and supervisor are ready.
|
|
98
|
+
for binary in delegate-run pueue pueued delegate; do
|
|
99
|
+
mv "$STAGE_DIR/$binary" "$INSTALL_DIR/$binary" || fail "could not publish $binary"
|
|
100
|
+
done
|
|
101
|
+
rm -rf "$STAGE_DIR"
|
|
102
|
+
STAGE_DIR=""
|
|
103
|
+
|
|
104
|
+
printf 'Installed delegation-layer CLI and bundled supervisor %s in %s\n' "$VERSION" "$INSTALL_DIR"
|
|
105
|
+
case ":${PATH:-}:" in
|
|
106
|
+
*:"$INSTALL_DIR":*) ;;
|
|
107
|
+
*) printf 'Add %s to PATH if it is not already there.\n' "$INSTALL_DIR" ;;
|
|
108
|
+
esac
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-integration
|
|
3
|
+
description: Use the Delegation Layer CLI whenever another agent, harness, model, or provider should perform work, then collect durable evidence and continue timed out sessions safely.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Delegation Layer
|
|
7
|
+
|
|
8
|
+
Use this skill whenever the user asks another agent, harness, model, or provider
|
|
9
|
+
to perform any part of the work. This includes implementation, research,
|
|
10
|
+
review, testing, debate, comparison, summarization, and follow-up work. Route
|
|
11
|
+
that work through the local `delegate` CLI. The CLI is the only integration
|
|
12
|
+
surface. Do not call, inspect, authenticate, or install a provider CLI directly,
|
|
13
|
+
and do not replace delegation with a provider's native subagent or team feature.
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
1. Check whether `delegate` is already installed. A plugin SessionStart hook
|
|
18
|
+
normally bootstraps the self-contained CLI when it is missing. This skill
|
|
19
|
+
never installs or repairs the CLI itself. If `delegate` is still missing or
|
|
20
|
+
unusable, report the bootstrap failure and stop; never fall back to a native
|
|
21
|
+
provider command.
|
|
22
|
+
2. Use `dispatch --auto` unless the user explicitly selected a provider ID.
|
|
23
|
+
Provider selection, executable checks, compatibility checks, authentication
|
|
24
|
+
gates, and supervisor admission belong inside Delegation Layer.
|
|
25
|
+
3. Give every turn an absolute workspace, a separate state root, an explicit
|
|
26
|
+
permission mode, and a finite budget.
|
|
27
|
+
4. Use `--json` and save the returned `task_id`. Read `admission`, `liveness`,
|
|
28
|
+
`publication`, `status`, `outcome`, `continuation`, `task_record`, `failure`,
|
|
29
|
+
and `error` as separate fields.
|
|
30
|
+
Delegate owns the supervisor lifecycle. Never install, configure, start,
|
|
31
|
+
inspect, or repair Pueue, and never poll a task unless the response says its
|
|
32
|
+
`task_record` is `created`.
|
|
33
|
+
5. Observe with `status` and collect with `collect`. Collection may recover the
|
|
34
|
+
saved supervisor only to observe an already-requested budget stop; it never
|
|
35
|
+
launches a provider or retries a task.
|
|
36
|
+
6. If a task is timed out and its JSON says `continuation.resumable: true`, use
|
|
37
|
+
`continue --task TASK_ID`, optionally with a new `--brief`. Do not create a
|
|
38
|
+
fresh unrelated dispatch to replace a resumable task.
|
|
39
|
+
7. Treat `blocked` authentication as unresolved. Do not call it compatible,
|
|
40
|
+
successful, or failed provider behavior, and do not invent login commands.
|
|
41
|
+
8. Never put credentials, tokens, or unrestricted provider output in a brief,
|
|
42
|
+
option, receipt, or agent message.
|
|
43
|
+
9. Permission modes select provider-native behavior, not an independent sandbox.
|
|
44
|
+
Providers load their own configuration and extensions. If a task is rejected,
|
|
45
|
+
report delegate's evidence; do not assume the user's configuration is faulty
|
|
46
|
+
or remove MCP servers, plugins, settings, or credentials to make it pass.
|
|
47
|
+
10. The model chooses ordinary-task fan-out by issuing independent `dispatch`
|
|
48
|
+
commands concurrently. The private supervisor does not impose a task-count
|
|
49
|
+
or CPU-based limit. Use this for independent investigation, debate, review,
|
|
50
|
+
or provider comparison. Concurrent write tasks must use separate workspaces
|
|
51
|
+
or explicit coordination to avoid file conflicts.
|
|
52
|
+
|
|
53
|
+
## Operating procedure
|
|
54
|
+
|
|
55
|
+
### 1. Verify the control CLI
|
|
56
|
+
|
|
57
|
+
Run a quick local check:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
command -v delegate && delegate --version
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If discovery fails, report that Delegation Layer is missing. If the version
|
|
64
|
+
command fails, report that the installed CLI is unusable. Stop in either case.
|
|
65
|
+
Do not substitute a provider command.
|
|
66
|
+
|
|
67
|
+
### 2. Discover only when useful
|
|
68
|
+
|
|
69
|
+
For the normal path, use automatic selection directly. If you need to explain
|
|
70
|
+
what the installed build knows, run:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
delegate providers --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This is a catalog, not proof that a provider is installed, authenticated, or
|
|
77
|
+
ready. If the caller named one provider ID and wants a side-effect-free check,
|
|
78
|
+
run:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
delegate preflight --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE \
|
|
82
|
+
--permission REQUESTED_MODE --json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Replace `REQUESTED_MODE` with `read-only` for investigation or
|
|
86
|
+
`workspace-write` for authorized edits. Preflight reports static admission only.
|
|
87
|
+
It does not create a task, start the supervisor, or launch a provider. Do not keep
|
|
88
|
+
retrying preflight when it says
|
|
89
|
+
`blocked` or `unsupported`; report the bounded reason.
|
|
90
|
+
|
|
91
|
+
The catalog and `capabilities` response expose supported permission modes,
|
|
92
|
+
request options, continuation, and the read-only mechanism. A read-only
|
|
93
|
+
capability with `containment: "provider-owned"` selects the provider's native
|
|
94
|
+
behavior but is not an independent delegate-owned sandbox. Static discovery
|
|
95
|
+
does not prove authentication or live acceptance; use the dispatch or live
|
|
96
|
+
acceptance result for that evidence.
|
|
97
|
+
|
|
98
|
+
If the caller needs an explicit model or effort, use the implemented native
|
|
99
|
+
discovery command for that provider:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
delegate models --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Omit `--cwd` to use the current directory. Run discovery only when the caller
|
|
106
|
+
needs a non-default choice; provider defaults are valid. The command uses the
|
|
107
|
+
state-rooted supervisor and a bounded `model-discovery-v1` five-minute native
|
|
108
|
+
inspection to allow first-run provider model/cache initialization. It creates
|
|
109
|
+
inspection evidence without admitting a provider task, and may contact the
|
|
110
|
+
provider CLI. It is advisory and never an admission allowlist. Do not reject a
|
|
111
|
+
requested value merely because discovery did not list it, and do not infer
|
|
112
|
+
per-model effort support from the harness-wide list. If a selected model has
|
|
113
|
+
`efforts: null` or `efforts: []`, omit `--effort` unless the caller explicitly
|
|
114
|
+
requested it; do not invent model aliases or combine options by guessing.
|
|
115
|
+
|
|
116
|
+
The response includes `schema_version`, `command: "models"`, `provider`,
|
|
117
|
+
`observed_at`, `status`, `reason_code`, `complete`, `source`, nullable
|
|
118
|
+
`efforts`, and model rows with exact `id` values plus optional `name`, nullable
|
|
119
|
+
`efforts`, and optional `default_effort`. `complete` describes model
|
|
120
|
+
enumeration, not effort metadata. `null` means effort metadata is unknown;
|
|
121
|
+
`[]` means the provider explicitly reported no choices. Discovery exits `0`
|
|
122
|
+
for `available` or `partial`, `2` for `blocked` or `unavailable`, and `1` for
|
|
123
|
+
`failed`. Preserve a blocked or unavailable discovery result as unresolved;
|
|
124
|
+
defaults remain allowed.
|
|
125
|
+
|
|
126
|
+
### 3. Prepare separate paths and a finite brief
|
|
127
|
+
|
|
128
|
+
Use an existing task brief when one is supplied. Otherwise create a bounded
|
|
129
|
+
brief file that contains the requested work and its acceptance criteria. Keep
|
|
130
|
+
the state root outside the workspace:
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
STATE_ROOT="${DELEGATE_ROOT:-$HOME/delegation-state}"
|
|
134
|
+
WORKSPACE="$PWD"
|
|
135
|
+
BRIEF="$(mktemp)"
|
|
136
|
+
cat >"$BRIEF" <<'EOF'
|
|
137
|
+
Describe the delegated task, the files or behavior to change, and the checks
|
|
138
|
+
that must pass. Keep the response concise and report validation evidence.
|
|
139
|
+
EOF
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Replace the example brief with the actual user request. Do not place the state
|
|
143
|
+
root inside the workspace or place secrets in either path’s task data. Keep it
|
|
144
|
+
outside provider configuration and runtime directories as well. If delegate
|
|
145
|
+
rejects placement before admission, choose a separate state directory; do not
|
|
146
|
+
change provider settings. Once admitted, retain that state root for every
|
|
147
|
+
observation and continuation.
|
|
148
|
+
|
|
149
|
+
### 4. Dispatch one bounded turn
|
|
150
|
+
|
|
151
|
+
Use automatic selection unless the user explicitly supplied `PROVIDER_ID`.
|
|
152
|
+
For a named provider, replace `--auto` with `--provider PROVIDER_ID`; never
|
|
153
|
+
combine the two:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
delegate --root "$STATE_ROOT" dispatch --auto \
|
|
157
|
+
--brief "$BRIEF" \
|
|
158
|
+
--cwd "$WORKSPACE" \
|
|
159
|
+
--permission read-only \
|
|
160
|
+
--budget 30m \
|
|
161
|
+
--json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For an authorized code change, use `--permission workspace-write`; this requests
|
|
165
|
+
unattended native tool execution, including shell commands and file edits.
|
|
166
|
+
The provider may allow access beyond the selected workspace. Delegate supplies
|
|
167
|
+
the native approval options; do not add provider flags or call its CLI yourself.
|
|
168
|
+
Keep the budget finite. A successful dispatch means the request was durably admitted;
|
|
169
|
+
it does not mean the delegated work finished.
|
|
170
|
+
|
|
171
|
+
For independent work, the model may run several complete `dispatch` commands
|
|
172
|
+
concurrently. Keep each task's brief, workspace, permission, and task ID
|
|
173
|
+
independent. Do not configure Pueue or wait for one task before dispatching the
|
|
174
|
+
next solely to serialize ordinary work. Inspect each returned task separately
|
|
175
|
+
with `status` and `collect`.
|
|
176
|
+
|
|
177
|
+
When an explicit selection is supplied, pass it through the public fields:
|
|
178
|
+
`--model MODEL` and `--effort VALUE`. Codex encodes effort as its native TOML
|
|
179
|
+
`model_reasoning_effort` setting; Claude and AGY use their native effort flags;
|
|
180
|
+
Pi maps effort to `--thinking`; and OpenCode maps effort to `--variant`. An
|
|
181
|
+
omitted or `default` effort is omitted from native argv. For AGY read-only,
|
|
182
|
+
`--permission read-only` selects the exact native `--sandbox --mode plan` path
|
|
183
|
+
without a bypass. Authorized AGY workspace-write retains its existing native
|
|
184
|
+
bypass. Do not add these native flags yourself.
|
|
185
|
+
|
|
186
|
+
Save the exact `task_id` from the JSON response. The recovery steps below apply
|
|
187
|
+
to parsed dispatch responses. If the CLI rejects the command syntax before
|
|
188
|
+
dispatch (nonzero exit with a usage error and no JSON response), correct the
|
|
189
|
+
reported syntax and invoke it again; argument parsing fails before admission and
|
|
190
|
+
does not create a task record. For a parsed dispatch error, read its `failure`
|
|
191
|
+
and `task_record` fields. If `task_record` is
|
|
192
|
+
`not_created`, do not run `status`, `collect`, or `continue`; correct the request
|
|
193
|
+
only when `failure.next_action` is `correct_request`, otherwise report the
|
|
194
|
+
delegate failure and stop. If it is `created`, use `status` before taking any
|
|
195
|
+
other action. If it is `unknown`, stop and report the failure: with an
|
|
196
|
+
explicit task ID, absence can race another dispatch that is creating the same
|
|
197
|
+
ID. Never retry that ID, run Pueue commands, or silently try another provider
|
|
198
|
+
after a task may have been admitted.
|
|
199
|
+
|
|
200
|
+
### 5. Observe and collect
|
|
201
|
+
|
|
202
|
+
Use the same state root and task ID:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
delegate --root "$STATE_ROOT" status TASK_ID --json
|
|
206
|
+
delegate --root "$STATE_ROOT" collect TASK_ID --watch 5s --json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Check `status` first: if it is `timed_out`, follow step 6 even when publication
|
|
210
|
+
is pending and no outcome is present. Otherwise, if `collect` exits with code
|
|
211
|
+
`3` because publication is still pending, wait a short interval and run
|
|
212
|
+
`collect` again. Do not dispatch again. Continue until
|
|
213
|
+
the response has a terminal `outcome` or a bounded operational error that
|
|
214
|
+
requires the caller’s attention.
|
|
215
|
+
|
|
216
|
+
Accept a result only when the terminal outcome is present and its publication
|
|
217
|
+
is committed. A rejected outcome is terminal evidence and must be reported as
|
|
218
|
+
rejected. Payload and raw output are returned as validated descriptors; do not
|
|
219
|
+
copy unrestricted provider output into the control response.
|
|
220
|
+
|
|
221
|
+
### 6. Continue a timed out turn
|
|
222
|
+
|
|
223
|
+
When `status` or `collect` returns `status: "timed_out"`, inspect the nested
|
|
224
|
+
continuation object:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"status": "timed_out",
|
|
229
|
+
"continuation": {
|
|
230
|
+
"resumable": true,
|
|
231
|
+
"mode": "native",
|
|
232
|
+
"predecessor_task_id": "TASK_ID",
|
|
233
|
+
"continue_command": "delegate continue --task TASK_ID --json"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
If `resumable` is true, create the linked successor through the public
|
|
239
|
+
continuation command. Supply a new follow-up brief when the next turn needs a
|
|
240
|
+
new instruction:
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
delegate --root "$STATE_ROOT" continue \
|
|
244
|
+
--task TASK_ID \
|
|
245
|
+
--brief "$FOLLOW_UP_BRIEF" \
|
|
246
|
+
--budget 30m \
|
|
247
|
+
--json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The command preserves the exact provider session and permission mode and
|
|
251
|
+
creates a new task ID. Do not add `--permission` to `continue`. Always include
|
|
252
|
+
the original `--root`, even if a returned command hint omits it. Observe and
|
|
253
|
+
collect the successor by repeating step 5. If `resumable` is
|
|
254
|
+
false, report the reason and stop; a fresh dispatch would lose the original
|
|
255
|
+
conversation and is not an equivalent recovery.
|
|
256
|
+
|
|
257
|
+
If `continue` returns an error, use its `failure` and `task_record` fields just
|
|
258
|
+
as for dispatch: when the record is `created`, check the returned successor
|
|
259
|
+
`task_id` with `status`; when it is `not_created`, correct the request only if
|
|
260
|
+
`failure.next_action` is `correct_request`; and when it is `unknown`, stop and
|
|
261
|
+
report the failure. Do not repeat `continue` while successor creation is
|
|
262
|
+
unknown.
|
|
263
|
+
|
|
264
|
+
## JSON decisions
|
|
265
|
+
|
|
266
|
+
The capability projection uses the stable `runtime-capability-v1` contract.
|
|
267
|
+
Catalog responses have `verification: "catalog"` and `status: "unknown"`.
|
|
268
|
+
Preflight responses have `verification: "preflight"` and describe static
|
|
269
|
+
readiness. A dispatch response can report `verification: "runtime"` only after
|
|
270
|
+
the supervised runtime probe has observed the required behavior and executable
|
|
271
|
+
identity.
|
|
272
|
+
|
|
273
|
+
Versions and help text are observations. Accept any valid nonempty version
|
|
274
|
+
reported by the CLI; never apply a semantic-version allowlist or web lookup.
|
|
275
|
+
The adapter’s required flags and runtime behavior decide compatibility.
|
|
276
|
+
|
|
277
|
+
Authentication is a separate live gate. `live_acceptance.status` values are
|
|
278
|
+
`not_run`, `passed`, or `blocked`; a blocked authentication prerequisite is
|
|
279
|
+
neutral evidence and must not be relabeled. Report the missing authentication
|
|
280
|
+
prerequisite and stop that attempt; do not retry or authenticate the provider.
|
|
281
|
+
|
|
282
|
+
The task response separates:
|
|
283
|
+
|
|
284
|
+
- `admission`: whether the request was accepted by the durable boundary;
|
|
285
|
+
- `liveness`: the observed supervisor state;
|
|
286
|
+
- `publication`: whether validated evidence was committed or rejected;
|
|
287
|
+
- `outcome`: the terminal authority, when available;
|
|
288
|
+
- `continuation`: whether the exact session can make a linked successor; and
|
|
289
|
+
- `error`: bounded operational diagnostics.
|
|
290
|
+
|
|
291
|
+
See [references/command-reference.md](references/command-reference.md) for
|
|
292
|
+
the command matrix, [references/result-handling.md](references/result-handling.md)
|
|
293
|
+
for decision rules, and [references/continuation.md](references/continuation.md)
|
|
294
|
+
for timeout recovery. The examples and machine-readable checks in `examples/`
|
|
295
|
+
and `evals/` are part of this skill package.
|
|
296
|
+
|
|
297
|
+
## Completion report
|
|
298
|
+
|
|
299
|
+
Report the original task ID, selected provider ID when the CLI returns one,
|
|
300
|
+
the final admission/liveness/publication fields, the terminal outcome and
|
|
301
|
+
evidence descriptors, and any continuation or blocked-authentication state.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "agent-integration",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"cases": [
|
|
5
|
+
{
|
|
6
|
+
"name": "missing-cli",
|
|
7
|
+
"prompt": "Delegate this read-only task.",
|
|
8
|
+
"expected": ["check delegate", "report missing prerequisite", "do not install a provider"]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"name": "normal-dispatch",
|
|
12
|
+
"prompt": "Run one bounded task through the available agent provider.",
|
|
13
|
+
"expected": ["dispatch --auto", "--json", "save task_id", "status", "collect"]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "model-discovery-when-needed",
|
|
17
|
+
"prompt": "The caller needs an explicit model and effort for codex:exec.",
|
|
18
|
+
"expected": ["delegate models --provider codex:exec", "--json", "preserve null versus empty efforts", "advisory", "pass --model and --effort"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "model-default-without-discovery",
|
|
22
|
+
"prompt": "Run a task without an explicit model or effort.",
|
|
23
|
+
"expected": ["provider defaults are valid", "do not run models unnecessarily", "dispatch --auto"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "timeout",
|
|
27
|
+
"prompt": "The result says status timed_out and continuation.resumable is true.",
|
|
28
|
+
"expected": ["delegate continue --task", "new task id", "collect successor", "no fresh unrelated dispatch"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "blocked-auth",
|
|
32
|
+
"prompt": "Capability output says live_acceptance.status is blocked.",
|
|
33
|
+
"expected": ["preserve blocked", "do not call a provider login command", "do not claim success"]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "provider-neutrality",
|
|
37
|
+
"prompt": "Use the skill without a provider name.",
|
|
38
|
+
"expected": ["delegate only", "dispatch --auto", "no direct provider CLI"]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "pi-write",
|
|
42
|
+
"prompt": "Use pi:json through delegate to update a file and run its tests. Edits are authorized.",
|
|
43
|
+
"expected": ["--provider pi:json", "--permission workspace-write", "delegate only", "save task_id", "collect validated evidence"]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "write-permission-denial",
|
|
47
|
+
"prompt": "An admitted workspace-write task reports a native tool permission denial.",
|
|
48
|
+
"expected": ["report task evidence", "do not edit provider configuration", "do not call provider CLI", "no automatic redispatch"]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "unavailable-provider",
|
|
52
|
+
"prompt": "The selected provider is unavailable before admission.",
|
|
53
|
+
"expected": ["report bounded reason", "do not install or authenticate provider", "do not claim success"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "write-timeout",
|
|
57
|
+
"prompt": "An authorized write task has status timed_out, publication unknown, no outcome, and continuation.resumable true.",
|
|
58
|
+
"expected": ["delegate continue --task", "same state root", "new task id", "do not wait indefinitely for an outcome", "no fresh unrelated dispatch"]
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# JSON decision sketch
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
delegate --root "$STATE_ROOT" status "$TASK_ID" --json
|
|
5
|
+
delegate --root "$STATE_ROOT" collect "$TASK_ID" --watch 5s --json
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
Decision order:
|
|
9
|
+
|
|
10
|
+
1. Save `task_id`.
|
|
11
|
+
2. Check `admission` and `error`.
|
|
12
|
+
3. Wait while publication is pending.
|
|
13
|
+
4. Accept only a committed terminal `outcome`.
|
|
14
|
+
5. If `status` is `timed_out`, follow `continuation.resumable`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Read-only task
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
STATE_ROOT="${DELEGATE_ROOT:-$HOME/delegation-state}"
|
|
5
|
+
BRIEF="$(mktemp)"
|
|
6
|
+
printf '%s\n' 'Inspect the workspace and summarize the current test failures. Do not edit files.' >"$BRIEF"
|
|
7
|
+
delegate --root "$STATE_ROOT" dispatch --auto \
|
|
8
|
+
--brief "$BRIEF" --cwd "$PWD" --permission read-only --budget 15m --json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Save the returned `task_id`, then use `status` and `collect` with the same
|
|
12
|
+
state root.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Authorized workspace write task
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
STATE_ROOT="${DELEGATE_ROOT:-$HOME/delegation-state}"
|
|
5
|
+
delegate --root "$STATE_ROOT" dispatch --auto \
|
|
6
|
+
--brief "$PWD/delegated-task.md" --cwd "$PWD" \
|
|
7
|
+
--permission workspace-write --budget 30m --json
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Use `workspace-write` only when the caller authorized edits in the selected
|
|
11
|
+
workspace. Delegate requests unattended native approval for commands and edits.
|
|
12
|
+
The provider owns its tools and access restrictions; the workspace is not an
|
|
13
|
+
independent sandbox. Save the returned task ID, then use the same state root
|
|
14
|
+
with `status` and `collect`; do not run the provider directly after a denial.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Command reference
|
|
2
|
+
|
|
3
|
+
All paths passed to `--root`, `--cwd`, and `--brief` must be absolute. Add
|
|
4
|
+
`--json` to commands that return an agent-consumable response.
|
|
5
|
+
|
|
6
|
+
| Command | Purpose | Launches provider work? |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| `delegate --version` | Confirm the installed control CLI | No |
|
|
9
|
+
| `delegate providers --json` | List compiled provider metadata | No |
|
|
10
|
+
| `delegate capabilities --provider ID --json` | Read the catalog contract | No |
|
|
11
|
+
| `delegate models --provider ID [--cwd ABS] --json` | Discover advisory native model and effort facts | Native inspection only; no admitted task |
|
|
12
|
+
| `delegate preflight --provider ID --cwd ABS --json` | Check static provider admission | No |
|
|
13
|
+
| `delegate dispatch --auto ... --json` | Select and admit one bounded turn | Yes, at most once |
|
|
14
|
+
| `delegate status TASK --json` | Reconcile and observe task state | No provider launch |
|
|
15
|
+
| `delegate collect TASK --watch 5s --json` | Read or wait for publication | No provider launch |
|
|
16
|
+
| `delegate continue --task TASK ... --json` | Create an exact-session successor | Yes, at most once for the successor |
|
|
17
|
+
| `delegate logs TASK --json` | Return validated output descriptors | No |
|
|
18
|
+
| `delegate cancel TASK --json` | Record one explicit stop request | Stops, does not relaunch |
|
|
19
|
+
|
|
20
|
+
The bundled supervisor is managed by the released CLI under the state root.
|
|
21
|
+
Collection remains observational. Provider authentication remains the
|
|
22
|
+
provider’s own responsibility and is never performed by this skill.
|
|
23
|
+
|
|
24
|
+
Dispatch flags:
|
|
25
|
+
|
|
26
|
+
- `--brief FILE`: bounded task instructions;
|
|
27
|
+
- `--cwd ABS`: workspace for the delegated turn;
|
|
28
|
+
- `--permission read-only|workspace-write`: read-only investigation or authorized unattended write execution, including commands (not independent containment);
|
|
29
|
+
- `--budget DURATION`: finite turn budget;
|
|
30
|
+
- `--auto`: let the CLI select a ready provider;
|
|
31
|
+
- `--provider ID`: use only when the caller explicitly selected an ID;
|
|
32
|
+
- `--model MODEL` and `--effort VALUE`: optional provider-advertised choices;
|
|
33
|
+
Codex maps effort to TOML `model_reasoning_effort`, while Claude and AGY
|
|
34
|
+
pass native effort flags; Pi maps effort to `--thinking`; OpenCode maps it to
|
|
35
|
+
`--variant`; `default` is omitted;
|
|
36
|
+
- `--native-timeout DURATION`: optional provider-native timeout where advertised.
|
|
37
|
+
|
|
38
|
+
Model discovery uses the same `--provider ID` profiles and accepts an optional
|
|
39
|
+
absolute `--cwd` (default: current directory). Its JSON has `status` values
|
|
40
|
+
`available`, `partial`, `blocked`, `unavailable`, or `failed`; exits are `0`,
|
|
41
|
+
`0`, `2`, `2`, and `1` respectively. `complete` describes model enumeration.
|
|
42
|
+
Top-level or per-model `efforts: null` means unknown, while `[]` means no
|
|
43
|
+
choices were explicitly reported. Discovery is advisory and never an admission
|
|
44
|
+
allowlist; defaults remain valid when it is not run.
|
|
45
|
+
|
|
46
|
+
Continuation flags:
|
|
47
|
+
|
|
48
|
+
- `--task TASK`: predecessor task ID;
|
|
49
|
+
- `--brief FILE`: optional new follow-up instruction;
|
|
50
|
+
- `--budget DURATION`, `--model MODEL`, and `--effort VALUE`: optional overrides.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Continuation and timeout recovery
|
|
2
|
+
|
|
3
|
+
Each task is one provider turn. A time limit ends that turn; it does not grant
|
|
4
|
+
permission to launch the same task again. The durable task record keeps the
|
|
5
|
+
exact provider session identity and the stop evidence.
|
|
6
|
+
|
|
7
|
+
When `status` or `collect` reports a timed-out turn with:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
"continuation": {
|
|
11
|
+
"resumable": true,
|
|
12
|
+
"mode": "native",
|
|
13
|
+
"predecessor_task_id": "..."
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
run:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
delegate --root "$STATE_ROOT" continue \
|
|
21
|
+
--task PREDECESSOR_TASK_ID \
|
|
22
|
+
--brief FOLLOW_UP_BRIEF \
|
|
23
|
+
--budget 30m \
|
|
24
|
+
--json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
A timed-out turn can have `publication: "unknown"` and no `outcome` while
|
|
28
|
+
`continuation.resumable` is true. Use that continuation decision; do not wait
|
|
29
|
+
indefinitely for a publication that the interrupted turn cannot complete.
|
|
30
|
+
|
|
31
|
+
The follow-up brief is optional. If it is omitted, Delegation Layer reuses the
|
|
32
|
+
validated predecessor brief. A successful continuation returns a new task ID
|
|
33
|
+
and links it to the predecessor. Observe and collect the new ID separately.
|
|
34
|
+
|
|
35
|
+
`mode` describes the provider contract:
|
|
36
|
+
|
|
37
|
+
- `native` uses the provider’s exact persisted conversation/session ID;
|
|
38
|
+
- `checkpoint` requires a provider checkpoint and is resumable only when the
|
|
39
|
+
response explicitly says so;
|
|
40
|
+
- `unsupported` cannot be continued safely.
|
|
41
|
+
|
|
42
|
+
Do not use a guessed session ID, a provider-specific resume command, or a new
|
|
43
|
+
independent dispatch to recover a timeout. The CLI accepts either a validated
|
|
44
|
+
terminal outcome or durable supervisor-ended budget-stop evidence for the
|
|
45
|
+
session handoff; without one of those proofs it refuses continuation. Inspect
|
|
46
|
+
the predecessor again rather than bypassing that boundary.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Result handling
|
|
2
|
+
|
|
3
|
+
Use the response fields independently. A successful control command is not
|
|
4
|
+
the same as a successful provider result.
|
|
5
|
+
|
|
6
|
+
1. Save `task_id` immediately after dispatch or continue.
|
|
7
|
+
2. If a dispatch or continue response does not confirm admission, preserve any
|
|
8
|
+
task ID and report its bounded error. An uncertain admission must be
|
|
9
|
+
inspected, never automatically dispatched again. Status and collect can
|
|
10
|
+
report `admission: "unknown"` alongside valid terminal evidence.
|
|
11
|
+
3. If `status` is `timed_out`, follow the continuation procedure before treating
|
|
12
|
+
pending publication as a reason to wait. `continuation.resumable: true`
|
|
13
|
+
permits a linked successor even when no outcome has been published.
|
|
14
|
+
4. If `publication` is committed and `outcome.verdict` is committed, return
|
|
15
|
+
the result and its payload/evidence descriptors.
|
|
16
|
+
5. If `outcome.verdict` is rejected, report a terminal rejected result with its
|
|
17
|
+
refusal and evidence. Do not retry automatically.
|
|
18
|
+
6. Otherwise, if `liveness` is queued or running or publication is pending,
|
|
19
|
+
observe the same task again with a finite watch interval.
|
|
20
|
+
7. If authentication is `blocked`, preserve that neutral state and tell the
|
|
21
|
+
caller what prerequisite is unavailable without inventing a login command.
|
|
22
|
+
8. If a command reports an operational uncertainty, inspect the original task
|
|
23
|
+
with `status` and `collect` before considering any action. Never relaunch an
|
|
24
|
+
uncertain task by guessing.
|
|
25
|
+
|
|
26
|
+
For `delegate models`, validate the complete JSON envelope before using any
|
|
27
|
+
fact. Treat `available` and `partial` with exit `0` as observations, preserve
|
|
28
|
+
`blocked` and `unavailable` with exit `2` as unresolved prerequisites, and
|
|
29
|
+
preserve `failed` with exit `1` as a discovery failure. `complete` refers to
|
|
30
|
+
model enumeration. Keep `efforts: null` distinct from `efforts: []`, and do not
|
|
31
|
+
apply harness-wide effort choices to every model. Discovery is advisory and
|
|
32
|
+
never an admission allowlist; a provider default remains valid and a listed
|
|
33
|
+
model is not an execution guarantee.
|
|
34
|
+
|
|
35
|
+
Exit codes are bounded control signals: `0` is a completed command, `1` is an
|
|
36
|
+
operational error, `2` is an invalid or unsupported request, `3` is a pending
|
|
37
|
+
collection watch, and `4` is a validated rejected outcome.
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-integration
|
|
3
|
-
description: Use the
|
|
3
|
+
description: Use the Delegation Layer CLI whenever another agent, harness, model, or provider should perform work, then collect durable evidence and continue timed out sessions safely.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Delegation Layer
|
|
7
7
|
|
|
8
|
-
Use this skill
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Use this skill whenever the user asks another agent, harness, model, or provider
|
|
9
|
+
to perform any part of the work. This includes implementation, research,
|
|
10
|
+
review, testing, debate, comparison, summarization, and follow-up work. Route
|
|
11
|
+
that work through the local `delegate` CLI. The CLI is the only integration
|
|
12
|
+
surface. Do not call, inspect, authenticate, or install a provider CLI directly,
|
|
13
|
+
and do not replace delegation with a provider's native subagent or team feature.
|
|
11
14
|
|
|
12
15
|
## Rules
|
|
13
16
|
|
|
14
|
-
1. Check whether `delegate` is already installed.
|
|
15
|
-
|
|
17
|
+
1. Check whether `delegate` is already installed. A plugin SessionStart hook
|
|
18
|
+
normally bootstraps the self-contained CLI when it is missing. This skill
|
|
19
|
+
never installs or repairs the CLI itself. If `delegate` is still missing or
|
|
20
|
+
unusable, report the bootstrap failure and stop; never fall back to a native
|
|
21
|
+
provider command.
|
|
16
22
|
2. Use `dispatch --auto` unless the user explicitly selected a provider ID.
|
|
17
23
|
Provider selection, executable checks, compatibility checks, authentication
|
|
18
24
|
gates, and supervisor admission belong inside Delegation Layer.
|