@ours.network/fleet-claude-code 0.10.0-nightly.4 → 0.10.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/package.json +5 -22
- package/skills/oversee-agents/SKILL.md +30 -6
- package/skills/spawn-ours-agent/SKILL.md +113 -33
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/fleet-claude-code",
|
|
3
|
-
"version": "0.10.0
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Claude Code plugin for ours-fleet — spawn and oversee fleet agents from inside a session. Bundles the spawn-ours-agent and oversee-agents skills; the ours-fleet CLI (@ours.network/fleet) does the actual work.",
|
|
5
5
|
"license": "FSL-1.1-Apache-2.0",
|
|
6
6
|
"author": "Adapt Framework Solutions Ltd",
|
|
@@ -10,25 +10,8 @@
|
|
|
10
10
|
"url": "git+https://github.com/adapt-toolkit/ours-fleet.git",
|
|
11
11
|
"directory": "integrations/claude-code"
|
|
12
12
|
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"fleet",
|
|
18
|
-
"agents",
|
|
19
|
-
"tmux",
|
|
20
|
-
"spawn",
|
|
21
|
-
"oversight",
|
|
22
|
-
"ours"
|
|
23
|
-
],
|
|
24
|
-
"files": [
|
|
25
|
-
".claude-plugin",
|
|
26
|
-
"skills"
|
|
27
|
-
],
|
|
28
|
-
"publishConfig": {
|
|
29
|
-
"access": "public"
|
|
30
|
-
},
|
|
31
|
-
"engines": {
|
|
32
|
-
"node": ">=20"
|
|
33
|
-
}
|
|
13
|
+
"keywords": ["claude", "claude-code", "plugin", "fleet", "agents", "tmux", "spawn", "oversight", "ours"],
|
|
14
|
+
"files": [".claude-plugin", "skills"],
|
|
15
|
+
"publishConfig": { "access": "public" },
|
|
16
|
+
"engines": { "node": ">=20" }
|
|
34
17
|
}
|
|
@@ -32,26 +32,50 @@ Schedule a repeating check every N minutes using your harness's mechanism
|
|
|
32
32
|
ward once. Keep the loop armed across restarts — re-arm it right after re-binding
|
|
33
33
|
your identity.
|
|
34
34
|
|
|
35
|
-
## 3.
|
|
35
|
+
## 3. One console command is not a liveness verdict
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
This is the mistake that gets busy agents killed. `peek` and `send` tell you what
|
|
38
|
+
happened to YOUR REQUEST. Only one of their outcomes is evidence that the agent
|
|
39
|
+
is gone. Each tick, run BOTH — they answer different questions:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
ours-fleet status <Name> # is the role supervised and alive?
|
|
43
|
+
ours-fleet peek <Name> # what is on its console right now?
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Read the result you actually got:
|
|
47
|
+
|
|
48
|
+
- **queued** — the session accepted the prompt for '<Name>'; a turn already running is not a failure. → Nothing. Do not resend, and do not read the absence of a reply as a stall — check progress with: ours-fleet peek <Name>
|
|
49
|
+
- **timeout** — '<Name>' did not answer in time; a busy agent looks exactly like this. Check: ours-fleet status <Name> → Treat delivery as UNCERTAIN — the request may already have been acted on, so do not resend it blindly.
|
|
50
|
+
- **rejected** — '<Name>' is running and refused the request. → Fix the request, not the agent. A refusal is proof of life.
|
|
51
|
+
- **control-unavailable** — this says nothing about whether '<Name>' is alive — its control plane did not answer; check: ours-fleet status <Name> → Read the role logs as well. The control plane and the agent are separate things, and one being unreachable is not evidence about the other.
|
|
52
|
+
- **backend** — this is a transport failure, not evidence that '<Name>' is gone; check: ours-fleet status <Name> → Investigate the transport, not the agent.
|
|
53
|
+
- **offline** — '<Name>' is confirmed offline. → This is the ONLY result that justifies a restart on its own: ours-fleet restart <Name> for a permanent role. Read the logs first.
|
|
54
|
+
|
|
55
|
+
Never translate any other result into "dead". `ours-fleet` prints the same
|
|
56
|
+
liveness note the CLI derived the result from, so quote what it said rather than
|
|
57
|
+
paraphrasing it as "not running".
|
|
58
|
+
|
|
59
|
+
## 4. Judge the console content
|
|
60
|
+
|
|
61
|
+
Once you know the role is alive, classify what the console actually shows:
|
|
38
62
|
|
|
39
63
|
| Console shows | Action |
|
|
40
64
|
|---|---|
|
|
41
65
|
| Permission prompt or trust dialog | Answer only within already-authorized scope. Use `send --key` for tmux or the `/permit` control shown by ACP `attach`. |
|
|
42
66
|
| A question the agent asked its (absent) user | Answer with what you know of the mission: `ours-fleet send <Name> "<answer>"`. |
|
|
43
|
-
| Crashed to a shell prompt / error text | Investigate (`ours-fleet logs <Name>`);
|
|
67
|
+
| Crashed to a shell prompt / error text | Investigate (`ours-fleet logs <Name>`); restart a permanent role only once `status` confirms it is offline. |
|
|
44
68
|
| Idle with work still assigned | Nudge: `ours-fleet send <Name> "Status? Continue with <task> or declare BLOCKED."` |
|
|
45
|
-
| Actively working / healthy | Nothing. Do not interrupt. |
|
|
69
|
+
| Actively working / healthy | Nothing. Do not interrupt, and do not mistake a long turn for a stall. |
|
|
46
70
|
|
|
47
|
-
##
|
|
71
|
+
## 5. Escalate when unsure
|
|
48
72
|
|
|
49
73
|
If the resolution would make a decision that is not yours (spending, deleting,
|
|
50
74
|
publishing, changing scope), do NOT press through it — message the owner or
|
|
51
75
|
coordinator over ours messaging (`send_message`) with the session snapshot and your
|
|
52
76
|
recommendation.
|
|
53
77
|
|
|
54
|
-
##
|
|
78
|
+
## 6. Log
|
|
55
79
|
|
|
56
80
|
Append notable interventions (ward, what was stuck, what you did) to your
|
|
57
81
|
WORKLOG so the history survives restarts.
|
|
@@ -8,42 +8,84 @@ description: Spawn and configure an ours-fleet agent from Claude Code, using a p
|
|
|
8
8
|
Use the `ours-fleet` CLI to create the role. Do not simulate a subagent inside
|
|
9
9
|
the current conversation.
|
|
10
10
|
|
|
11
|
-
## 1. Read the installed CLI reference
|
|
12
|
-
|
|
13
|
-
Run:
|
|
11
|
+
## 1. Read the installed CLI reference — this step is not optional
|
|
14
12
|
|
|
15
13
|
```sh
|
|
16
14
|
ours-fleet docs
|
|
17
15
|
ours-fleet doctor
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
backends,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
18
|
+
`ours-fleet docs` from the INSTALLED CLI is authoritative for supported
|
|
19
|
+
harnesses, session backends, permissions, and flags. This skill ships with a
|
|
20
|
+
plugin and the CLI is upgraded separately, so where the two differ the installed
|
|
21
|
+
reference wins. Stop at a failed required doctor check.
|
|
22
|
+
|
|
23
|
+
## 2. Understand the two permission traps before you choose anything
|
|
24
|
+
|
|
25
|
+
Both traps produce the same symptom: an agent that does less than its briefing
|
|
26
|
+
told it to and reports no error, because the refusal happened inside the harness
|
|
27
|
+
with no console attached to see it.
|
|
28
|
+
|
|
29
|
+
**Trap 1 — a mode that suppresses the prompt without granting the action.**
|
|
30
|
+
Claude's `dontAsk` hides the permission prompt and still refuses the action. It
|
|
31
|
+
reads like a grant and is not one. This is why neutral `--approval allow` maps
|
|
32
|
+
to `bypassPermissions`, which genuinely permits what the role was authorized to
|
|
33
|
+
do. Nothing else is elevated: `ask` stays on Claude's default mode and `deny`
|
|
34
|
+
maps to `plan`.
|
|
35
|
+
|
|
36
|
+
**Trap 2 — the unattended capability floor.** A role with no console cannot
|
|
37
|
+
answer a permission request, so the request is refused. `ours-fleet` checks each
|
|
38
|
+
role's resolved permissions against a fixed floor before launch:
|
|
39
|
+
|
|
40
|
+
- `read-state` — read its briefing, ROUTINES.md, and WORKLOG.md
|
|
41
|
+
- `write-state` — append its WORKLOG and its own state files
|
|
42
|
+
- `messaging` — bind its identity, send and receive ours mail
|
|
43
|
+
- `monitor` — arm and observe its mail monitor
|
|
44
|
+
- `workspace-edit` — edit and test files in its working directory
|
|
45
|
+
- `status-commands` — run the inspection commands its briefing prescribes
|
|
46
|
+
|
|
47
|
+
`ours-fleet config` and `ours-fleet doctor` report this per role as
|
|
48
|
+
`unattended floor: <Name>`. Under `--unattended deny` a shortfall FAILS doctor,
|
|
49
|
+
because those requests will be denied silently. Under `--unattended wait` it
|
|
50
|
+
warns, because a human can still attach and answer.
|
|
51
|
+
|
|
52
|
+
What this means in practice, on this harness:
|
|
53
|
+
|
|
54
|
+
| Neutral intent | Native mode | Meets the floor? |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| `--approval allow --filesystem workspace` | `bypassPermissions` | yes |
|
|
57
|
+
| `--approval allow --filesystem read-only` | `bypassPermissions` | no — no `write-state`, no `workspace-edit` |
|
|
58
|
+
| `--approval ask` | Claude's default | no — `read-state` only |
|
|
59
|
+
| `--approval deny` | `plan` | no — `read-state` only |
|
|
60
|
+
| `harness_options.permission_mode: dontAsk` | `dontAsk` | no — `read-state`, `status-commands` |
|
|
61
|
+
|
|
62
|
+
## 3. Choose permissions from the job, not from a default
|
|
63
|
+
|
|
64
|
+
There is no safe blanket default. Ask what the role has to do and whether the
|
|
65
|
+
user authorizes it, then pick:
|
|
66
|
+
|
|
67
|
+
- **It must work with nobody watching** (the usual reason to spawn a fleet
|
|
68
|
+
role): it needs `--approval allow --filesystem workspace`. That is a real
|
|
69
|
+
grant, so get the user's explicit authorization for it, and confine the role
|
|
70
|
+
with `--isolation-file` rather than by withholding permissions it needs.
|
|
71
|
+
Use `--unattended deny` so the role never blocks on an unanswerable request.
|
|
72
|
+
- **A human will attach and answer prompts**: `--approval ask --filesystem
|
|
73
|
+
workspace --unattended wait`. Doctor warns that the floor is unmet — that
|
|
74
|
+
warning is correct and expected; the role will block until someone answers.
|
|
75
|
+
- **The user will not authorize `allow`, and nobody will attend it**: say so
|
|
76
|
+
plainly. That role cannot do its job, and doctor will fail it. Reduce the
|
|
77
|
+
job or get the authorization; do not paper over it with `dontAsk`.
|
|
78
|
+
|
|
79
|
+
Never choose `--filesystem unrestricted`, `harness_options.permission_mode:
|
|
80
|
+
bypassPermissions` written directly, or `dontAsk` without the user asking for
|
|
81
|
+
it by name and understanding what it grants.
|
|
82
|
+
|
|
83
|
+
## 4. Pick a name
|
|
42
84
|
|
|
43
85
|
`<Name>` must match `[A-Za-z0-9_-]+` (it becomes the role/service name). Check it
|
|
44
86
|
is free: `ours-fleet config` must not list it and `ours-fleet ls` must not show it.
|
|
45
87
|
|
|
46
|
-
##
|
|
88
|
+
## 5. Co-draft bio and persona
|
|
47
89
|
|
|
48
90
|
Draft WITH the requester, iterating until they approve:
|
|
49
91
|
|
|
@@ -55,45 +97,83 @@ Draft WITH the requester, iterating until they approve:
|
|
|
55
97
|
Write approved text to uniquely named files under `/tmp` without interpolating
|
|
56
98
|
untrusted text into shell commands.
|
|
57
99
|
|
|
58
|
-
##
|
|
100
|
+
## 6. Confine the role at creation, not later
|
|
101
|
+
|
|
102
|
+
`--isolation-file <path>` supplies the role's sandbox policy at creation, so the
|
|
103
|
+
FIRST launch is already confined. A role that only gains `isolation:` on a later
|
|
104
|
+
`up` ran unsandboxed until then. The file holds exactly the `isolation:` mapping
|
|
105
|
+
documented in `ours-fleet docs` and nothing else:
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
network: deny
|
|
109
|
+
fs:
|
|
110
|
+
read: [/opt/reference]
|
|
111
|
+
resources:
|
|
112
|
+
mem: 2G
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
An invalid file is rejected before anything is created — no config, no state
|
|
116
|
+
directory, no identity reservation. This is the right control for a role that
|
|
117
|
+
needs `--approval allow`: isolation is the outer boundary a permission mode
|
|
118
|
+
cannot cross.
|
|
119
|
+
|
|
120
|
+
## 7. Spawn
|
|
59
121
|
|
|
60
|
-
Permanent (announce it to yourself if you are its coordinator):
|
|
122
|
+
Permanent, unattended (announce it to yourself if you are its coordinator):
|
|
61
123
|
|
|
62
124
|
```sh
|
|
63
125
|
ours-fleet spawn <Name> \
|
|
64
126
|
--harness claude-code --session <tmux|acp> \
|
|
65
127
|
--mission "<one-line mission>" \
|
|
66
128
|
--bio-file /tmp/spawn-bio.md --persona-file /tmp/spawn-persona.md \
|
|
67
|
-
--approval
|
|
129
|
+
--approval allow --filesystem workspace --unattended deny \
|
|
130
|
+
--isolation-file /tmp/spawn-isolation.yaml \
|
|
68
131
|
[--cwd <dir>] [--coordinator <YourRoleName>]
|
|
69
132
|
```
|
|
70
133
|
|
|
71
|
-
|
|
134
|
+
Permanent, attended — a human will answer its prompts:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
ours-fleet spawn <Name> \
|
|
138
|
+
--harness claude-code --session <tmux|acp> \
|
|
139
|
+
--mission "<one-line mission>" \
|
|
140
|
+
--bio-file /tmp/spawn-bio.md --persona-file /tmp/spawn-persona.md \
|
|
141
|
+
--approval ask --filesystem workspace --unattended wait
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Temporary — add `--temp`; it supports both session backends:
|
|
72
145
|
|
|
73
146
|
```sh
|
|
74
147
|
ours-fleet spawn --temp <Name> \
|
|
75
148
|
--harness claude-code --session <tmux|acp> \
|
|
76
149
|
--mission "<one-line mission>" \
|
|
77
150
|
--bio-file /tmp/spawn-bio.md --persona-file /tmp/spawn-persona.md \
|
|
78
|
-
--approval
|
|
151
|
+
--approval allow --filesystem workspace --unattended deny
|
|
79
152
|
```
|
|
80
153
|
|
|
81
154
|
Pass model, permission, session, and coordinator choices exactly as approved.
|
|
82
155
|
Do not persist secrets in fleet YAML.
|
|
83
156
|
|
|
84
|
-
##
|
|
157
|
+
## 8. Verify
|
|
85
158
|
|
|
86
159
|
```sh
|
|
160
|
+
ours-fleet doctor
|
|
87
161
|
ours-fleet peek <Name> 60
|
|
88
162
|
ours-fleet status <Name>
|
|
89
163
|
```
|
|
90
164
|
|
|
165
|
+
Read doctor's `permissions: <Name>` and `unattended floor: <Name>` lines for the
|
|
166
|
+
role you just created. `permissions:` shows the neutral intent and the native
|
|
167
|
+
settings it translated to; the floor line lists what the role actually grants,
|
|
168
|
+
or names what is missing. A failure there means the role will silently do less
|
|
169
|
+
than its briefing says — fix the permissions rather than starting it.
|
|
170
|
+
|
|
91
171
|
For ACP, `status` must report `backend: acp`, `alive: true`, and a running/idle
|
|
92
172
|
readiness. For tmux, the pane is authoritative. Confirm the role loaded its
|
|
93
173
|
briefing and reached identity binding. Never answer a permission prompt beyond
|
|
94
174
|
the scope already approved by the user.
|
|
95
175
|
|
|
96
|
-
##
|
|
176
|
+
## 9. Arm oversight
|
|
97
177
|
|
|
98
178
|
The spawner babysits its subagent. Ask the requester for a check interval
|
|
99
179
|
(default **5m**), then follow the **oversee-agents** skill for `<Name>` at that
|