@ours.network/fleet 1.1.0-nightly.1 → 1.1.0-nightly.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -73
- package/dist/application/role-creation-service.js +9 -2
- package/dist/application/role-removal-service.js +6 -3
- package/dist/application/types.d.ts +1 -1
- package/dist/briefing.js +2 -2
- package/dist/build-info.json +4 -4
- package/dist/cli.js +8 -5
- package/dist/config.d.ts +28 -2
- package/dist/config.js +307 -23
- package/dist/creation.d.ts +1 -1
- package/dist/creation.js +2 -2
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +31 -69
- package/dist/doctor.js +1 -1
- package/dist/generated-agent-source.d.ts +9 -0
- package/dist/generated-agent-source.js +53 -0
- package/dist/harness/agent-session.d.ts +13 -0
- package/dist/harness/claude-code-session.d.ts +4 -0
- package/dist/harness/claude-code-session.js +4 -0
- package/dist/harness/claude-code.js +10 -0
- package/dist/harness/codex-session.d.ts +4 -0
- package/dist/harness/codex-session.js +4 -0
- package/dist/harness/codex.js +14 -0
- package/dist/harness/registry.js +4 -0
- package/dist/init-guidance.d.ts +1 -0
- package/dist/init-guidance.js +5 -0
- package/dist/model-env.d.ts +0 -1
- package/dist/model-env.js +2 -4
- package/dist/ops.js +4 -2
- package/dist/resolved-plan.d.ts +3 -2
- package/dist/resolved-plan.js +21 -5
- package/dist/sensitive-config.d.ts +2 -0
- package/dist/sensitive-config.js +4 -0
- package/dist/spawn.d.ts +4 -4
- package/dist/spawn.js +52 -23
- package/dist/web/fleet-config-service.d.ts +11 -8
- package/dist/web/fleet-config-service.js +383 -183
- package/dist/web/topology-promote.js +17 -14
- package/dist/web/topology.js +2 -2
- package/dist/web/yaml-document-edit.js +2 -0
- package/dist/web-app/assets/index-BbE9EX6n.js +10 -0
- package/dist/web-app/index.html +1 -1
- package/examples/fleet/agents/Alice.yaml +11 -0
- package/examples/fleet/agents/FleetCoordinator.yaml +7 -0
- package/examples/fleet/brains/claude-default.yaml +5 -0
- package/examples/fleet/roles/coordinator.yaml +5 -0
- package/examples/fleet/roles/developer.yaml +3 -0
- package/examples/fleet.yaml +74 -0
- package/package.json +2 -1
- package/dist/web-app/assets/index-DhMDVRU1.js +0 -10
package/README.md
CHANGED
|
@@ -19,10 +19,10 @@ turns such sessions into **roles**: long-lived agents that
|
|
|
19
19
|
- can **spawn subagents** (permanent or temporary) and **oversee** them: peek into
|
|
20
20
|
a ward's console, answer a stuck prompt, nudge it back to work.
|
|
21
21
|
|
|
22
|
-
The
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
reality match
|
|
22
|
+
The fleet uses a v2 manifest plus typed documents: `~/fleet.yaml` holds
|
|
23
|
+
fleet-wide operational policy and automation, while `~/fleet/agents`,
|
|
24
|
+
`~/fleet/roles`, and `~/fleet/brains` hold bare Agent, Role, and Brain documents.
|
|
25
|
+
`ours-fleet up` makes reality match that trusted split source set.
|
|
26
26
|
|
|
27
27
|
**Harness-agnostic by design.** The core never assumes a specific agent CLI; each
|
|
28
28
|
harness is a small adapter (how to launch, how to resume, how to wire config).
|
|
@@ -31,17 +31,19 @@ public — each additional harness (Gemini CLI, OpenCode, …) is a small adapte
|
|
|
31
31
|
A single fleet can mix harnesses per role:
|
|
32
32
|
|
|
33
33
|
```yaml
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
# ~/fleet/agents/Reviewer.yaml
|
|
35
|
+
role: { ref: reviewer }
|
|
36
|
+
brain: { inline: { harness: claude-code, session: acp } }
|
|
37
|
+
|
|
38
|
+
# ~/fleet/agents/Prototyper.yaml
|
|
39
|
+
role: { inline: { mission: Build prototypes } }
|
|
40
|
+
brain: { inline: { harness: codex, session: acp } }
|
|
39
41
|
```
|
|
40
42
|
|
|
41
43
|
## How it works
|
|
42
44
|
|
|
43
45
|
```
|
|
44
|
-
~/fleet.yaml + ~/fleet
|
|
46
|
+
~/fleet.yaml + ~/fleet/{agents,roles,brains}/*.yaml your declaration
|
|
45
47
|
│ ours-fleet up
|
|
46
48
|
▼
|
|
47
49
|
briefing.md per role ──► agent session adapter ──► ACP client/session ──► ACP agent
|
|
@@ -105,8 +107,9 @@ become that account and repeat.
|
|
|
105
107
|
## Quickstart
|
|
106
108
|
|
|
107
109
|
```sh
|
|
110
|
+
cp -R "$(npm root -g)/@ours.network/fleet/examples/fleet" ~/fleet
|
|
108
111
|
cp "$(npm root -g)/@ours.network/fleet/examples/fleet.yaml" ~/fleet.yaml
|
|
109
|
-
$EDITOR ~/fleet
|
|
112
|
+
$EDITOR ~/fleet/agents/*.yaml # compose Role + Brain and operational settings
|
|
110
113
|
ours-fleet up # boot the fleet (staggered)
|
|
111
114
|
ours-fleet ls # running consoles
|
|
112
115
|
ours-fleet attach Alice # watch one live (Ctrl-b d to leave)
|
|
@@ -252,27 +255,19 @@ Security boundaries:
|
|
|
252
255
|
- tests use temporary fleet homes and fake supervisors/identity providers—never
|
|
253
256
|
active role state.
|
|
254
257
|
|
|
255
|
-
Permanent spawns
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
block sequence — adding or removing an entry under `watch:`, `oversee:`, `roles:`
|
|
269
|
-
or `wake_sources:` — rewrites that one collection as a whole, which drops inline
|
|
270
|
-
comments written on its individual items. The loss is confined to the collection
|
|
271
|
-
you edited, is shown in the diff before anything is written, and can be declined
|
|
272
|
-
by not saving. Each write is revision-guarded, reviewed as a diff of the real
|
|
273
|
-
file, validated with the real loader, and preceded by a timestamped backup.
|
|
274
|
-
Values under `env:` — and the `vars:` entries they interpolate — are masked in
|
|
275
|
-
the diff and never leave the host.
|
|
258
|
+
Permanent spawns write a bare Agent document to
|
|
259
|
+
`~/fleet/agents/<Name>.yaml`; generated-source ownership is recorded so removal
|
|
260
|
+
never deletes an unproven hand-written neighbor. `ours-fleet rm <Name>` unspawns.
|
|
261
|
+
|
|
262
|
+
The web editor reads and writes the split document model explicitly as
|
|
263
|
+
`{manifest, agents}`. Role and Brain presets are visible through Agent refs but
|
|
264
|
+
remain read-only. Saves use one aggregate revision over the manifest and all
|
|
265
|
+
Agent/Role/Brain sources, validate an exact-stem private staging tree, show a
|
|
266
|
+
deterministic redacted diff per document, and hold one manifest-root lock.
|
|
267
|
+
Changed/deleted files are backed up together; any partial failure restores every
|
|
268
|
+
document or reports the private recovery directory. An unchanged save is a
|
|
269
|
+
byte-for-byte no-op and creates no backup. Nested environment, authentication,
|
|
270
|
+
invite, and isolation secrets never leave the host.
|
|
276
271
|
|
|
277
272
|
From inside Claude Code, Codex, or Hermes with the core `ours` plugin installed,
|
|
278
273
|
say **"spawn an ours agent …"**. The core skill checks for `ours-fleet`, installs
|
|
@@ -290,16 +285,16 @@ ours-fleet peek Worker # what is it doing?
|
|
|
290
285
|
ours-fleet send Worker "continue with the tests, then report"
|
|
291
286
|
```
|
|
292
287
|
|
|
293
|
-
Declare standing assignments in
|
|
288
|
+
Declare standing assignments in the overseer's bare Agent document (rendered into its
|
|
294
289
|
briefing) — or just write "keep an eye on Alice and Bob every 5 minutes" in a
|
|
295
290
|
persona; the bundled `oversee-agents` skill defines what that means operationally:
|
|
296
291
|
|
|
297
292
|
```yaml
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
293
|
+
role: { ref: coordinator }
|
|
294
|
+
brain: { ref: claude-default }
|
|
295
|
+
oversee:
|
|
296
|
+
- { agent: Alice, interval: 5m }
|
|
297
|
+
- { agent: Bob, interval: 5m }
|
|
303
298
|
```
|
|
304
299
|
|
|
305
300
|
## Command reference
|
|
@@ -342,28 +337,30 @@ in its state dir) across supervisor-triggered restarts — systemd/launchd re-in
|
|
|
342
337
|
agent process with no arguments, so without this the role would silently fall back to
|
|
343
338
|
the default `~/fleet.yaml` on its very first crash-restart and fail to resolve.
|
|
344
339
|
|
|
345
|
-
##
|
|
340
|
+
## split configuration field reference
|
|
346
341
|
|
|
347
|
-
|
|
342
|
+
The following is a schematic field inventory, not a single YAML document. Host
|
|
343
|
+
settings belong in `~/fleet.yaml`; reusable behavior and harness settings belong
|
|
344
|
+
in `~/fleet/roles/<id>.yaml` and `~/fleet/brains/<id>.yaml`; operational fields
|
|
345
|
+
belong in `~/fleet/agents/<id>.yaml`.
|
|
346
|
+
|
|
347
|
+
```text
|
|
348
348
|
vars: { work_root: /home/me/work } # ${var} substitution anywhere below
|
|
349
|
+
api_version: ours.network/fleet/v2
|
|
349
350
|
start_stagger_ms: 0 # delay between agent LAUNCHES (host-wide, ms); 0 = no stagger
|
|
350
351
|
defaults:
|
|
351
|
-
harness: claude-code # for roles that don't set one
|
|
352
|
-
session: acp # supported Fleet↔agent session path
|
|
353
352
|
permissions: # common intent, translated by each harness/backend
|
|
354
353
|
approval: ask # ask | auto | allow (`deny` is a deprecated alias)
|
|
355
354
|
filesystem: workspace # read-only | workspace | unrestricted
|
|
356
355
|
unattended: deny # deny | wait
|
|
357
|
-
model: claude-fable-5 # default model for roles that don't set one (per-role model / --model wins)
|
|
358
|
-
max_tokens: 500000 # session cap (harness-interpreted)
|
|
359
356
|
monitor:
|
|
360
357
|
mode: fleet # fleet (default) | native
|
|
361
358
|
worklog: # built-ins shown; set false to opt out
|
|
362
359
|
max_kb: 1024 # rotate only above this active-log size
|
|
363
360
|
keep_tail_kb: 256 # UTF-8 tail; line-aligned when one fits
|
|
364
361
|
max_archives: 12 # recent beside log; older preserved cold
|
|
365
|
-
|
|
366
|
-
Name: # [A-Za-z0-9_-]+
|
|
362
|
+
Agent document:
|
|
363
|
+
Name: # filename stem; [A-Za-z0-9_-]+
|
|
367
364
|
harness: claude-code
|
|
368
365
|
session: acp # optional; ACP is the only supported session
|
|
369
366
|
session_options:
|
|
@@ -400,7 +397,7 @@ roles:
|
|
|
400
397
|
bio: | # public card (published as bio)
|
|
401
398
|
briefing_file: curated.md # replaces the generated narrative
|
|
402
399
|
env: { KEY: value } # extra session env
|
|
403
|
-
oversee: [{
|
|
400
|
+
oversee: [{ agent: X, interval: 5m }]
|
|
404
401
|
harness_options: # adapter-owned, adapter-validated
|
|
405
402
|
plugins: { "name@marketplace": false } # claude-code: plugin overrides
|
|
406
403
|
# mem_palace: false # claude-code: disable memory plugin
|
|
@@ -438,13 +435,12 @@ loops: # trusted local scheduled ACP turns
|
|
|
438
435
|
If nothing material changed, complete silently without an owner report.
|
|
439
436
|
```
|
|
440
437
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
and
|
|
447
|
-
overrides `defaults.monitor` key-by-key.
|
|
438
|
+
The v2 loader reads the manifest, then sorted bare Role, Brain, and Agent
|
|
439
|
+
documents from its exact stem directory. Duplicate filename-derived IDs are a
|
|
440
|
+
hard error. Identities and Agents are decoupled—removing an Agent never deletes
|
|
441
|
+
an identity. Role, Brain, and operational ownership are composed explicitly;
|
|
442
|
+
there is no generic cross-kind merge. Manifest operational defaults such as
|
|
443
|
+
`monitor` and `permissions` merge only within their owning Agent fields.
|
|
448
444
|
|
|
449
445
|
Every supervised role is a client of the operator-configured ours daemon. Fleet strips the
|
|
450
446
|
obsolete, presence-sensitive `OURS_AUTOSTART` variable from ACP harness
|
|
@@ -1037,27 +1033,22 @@ the structured CLI watcher, because a detached process cannot wake a Codex turn.
|
|
|
1037
1033
|
wait is re-entered after each handled message; `ours-codex` instead wakes the idle
|
|
1038
1034
|
session through its App Server integration.
|
|
1039
1035
|
|
|
1040
|
-
The main Codex controls
|
|
1036
|
+
The main Codex controls are Brain-owned and also available when spawning:
|
|
1041
1037
|
|
|
1042
1038
|
```yaml
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
roles:
|
|
1058
|
-
Reviewer:
|
|
1059
|
-
harness_options:
|
|
1060
|
-
sandbox: read-only # overrides just this default key
|
|
1039
|
+
# ~/fleet/brains/codex-review.yaml
|
|
1040
|
+
harness: codex
|
|
1041
|
+
session: acp
|
|
1042
|
+
model: gpt-5.4
|
|
1043
|
+
harness_options:
|
|
1044
|
+
launcher: auto
|
|
1045
|
+
profile: fleet
|
|
1046
|
+
sandbox: read-only
|
|
1047
|
+
approval: on-request
|
|
1048
|
+
monitor: true
|
|
1049
|
+
search: true
|
|
1050
|
+
add_dirs: [/data/shared]
|
|
1051
|
+
config: { model_reasoning_effort: high }
|
|
1061
1052
|
```
|
|
1062
1053
|
|
|
1063
1054
|
Equivalent one-off/permanent spawn controls include `--model`, `--permission-mode`,
|
|
@@ -10,6 +10,7 @@ import { FleetError, normalizeError } from './errors.js';
|
|
|
10
10
|
import { inheritCallerSpawnDefaults } from '../fleet-proxy.js';
|
|
11
11
|
import { effectivePermissionMode } from '../permissions.js';
|
|
12
12
|
import { effectiveRoleModel } from '../model-env.js';
|
|
13
|
+
import { getAdapter } from '../harness/registry.js';
|
|
13
14
|
import { claudeModelCatalog, codexModelCatalog, } from './model-catalog.js';
|
|
14
15
|
const canonical = (value) => {
|
|
15
16
|
if (Array.isArray(value))
|
|
@@ -315,8 +316,14 @@ export class RoleCreationService {
|
|
|
315
316
|
throw new FleetError('invalid_request', 'unsupported lifetime');
|
|
316
317
|
bounded(input.model ?? undefined, 'model', 128);
|
|
317
318
|
bounded(input.reasoningEffort ?? undefined, 'reasoning effort', 16);
|
|
318
|
-
if (input.reasoningEffort != null
|
|
319
|
-
|
|
319
|
+
if (input.reasoningEffort != null) {
|
|
320
|
+
try {
|
|
321
|
+
getAdapter(input.harness).agentSession.resolveBrain({ effort: input.reasoningEffort });
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
throw new FleetError('invalid_request', error.message);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
320
327
|
bounded(input.mission, 'mission', 4_096);
|
|
321
328
|
bounded(input.coordinator, 'coordinator', 128);
|
|
322
329
|
bounded(input.bio, 'bio', 8_192);
|
|
@@ -4,6 +4,7 @@ import { loadConfig, ROLE_NAME_RE } from '../config.js';
|
|
|
4
4
|
import { agentDir, stateRoot } from '../paths.js';
|
|
5
5
|
import { rmRole } from '../ops.js';
|
|
6
6
|
import { FleetError } from './errors.js';
|
|
7
|
+
import { provesGeneratedAgentSource } from '../generated-agent-source.js';
|
|
7
8
|
export class RoleRemovalService {
|
|
8
9
|
options;
|
|
9
10
|
constructor(options) {
|
|
@@ -45,8 +46,9 @@ export class RoleRemovalService {
|
|
|
45
46
|
`Stop and uninstall the exact backend registration for '${requested}'.`,
|
|
46
47
|
`Archive then remove ${lifetime === 'temporary' ? temporaryState : permanentState}.`,
|
|
47
48
|
];
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const generatedSource = role && provesGeneratedAgentSource(agentDir(requested), cfg.files[0], role.sourceFile);
|
|
50
|
+
if (generatedSource)
|
|
51
|
+
effects.push(`Remove generated Agent configuration ${role.sourceFile}.`);
|
|
50
52
|
else if (role)
|
|
51
53
|
effects.push(`Keep hand-written configuration ${role.sourceFile}; the role can be recreated from it.`);
|
|
52
54
|
else
|
|
@@ -76,7 +78,8 @@ export class RoleRemovalService {
|
|
|
76
78
|
mkdirSync(recoveryPath, { recursive: true, mode: 0o700 });
|
|
77
79
|
if (existsSync(sourceState))
|
|
78
80
|
cpSync(sourceState, join(recoveryPath, 'state'), { recursive: true });
|
|
79
|
-
if (role
|
|
81
|
+
if (role && provesGeneratedAgentSource(agentDir(preview.role), cfg.files[0], role.sourceFile)
|
|
82
|
+
&& existsSync(role.sourceFile))
|
|
80
83
|
cpSync(role.sourceFile, join(recoveryPath, basename(role.sourceFile)));
|
|
81
84
|
if (role || preview.lifetime === 'temporary')
|
|
82
85
|
await rmRole(cfg, preview.role, this.options.ops);
|
package/dist/briefing.js
CHANGED
|
@@ -196,12 +196,12 @@ export function generateBriefing(role, v, opts) {
|
|
|
196
196
|
L.push('', '## Oversight assignments');
|
|
197
197
|
L.push('These agents are your wards — you keep them unstuck:');
|
|
198
198
|
for (const o of role.oversee)
|
|
199
|
-
L.push(`- **${o.
|
|
199
|
+
L.push(`- **${o.agent}** — check every ${o.interval}`);
|
|
200
200
|
L.push('');
|
|
201
201
|
L.push('Procedure (see also the oversee-agents skill if available). On each tick, for each ward');
|
|
202
202
|
L.push('run BOTH — they answer different questions:');
|
|
203
203
|
for (const o of role.oversee)
|
|
204
|
-
L.push(`\`ours-fleet status ${o.
|
|
204
|
+
L.push(`\`ours-fleet status ${o.agent}\` then \`ours-fleet peek ${o.agent}\``);
|
|
205
205
|
L.push('');
|
|
206
206
|
L.push('**One console command is not a liveness verdict.** A `peek` or `send` that fails tells');
|
|
207
207
|
L.push('you what happened to YOUR REQUEST, and only one of its outcomes says the agent is gone.');
|
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.1.0-nightly.
|
|
3
|
-
"buildId": "
|
|
4
|
-
"commit": "
|
|
2
|
+
"version": "1.1.0-nightly.2",
|
|
3
|
+
"buildId": "da774e6be6b1",
|
|
4
|
+
"commit": "f8890b0449f4142a0c27a195e1351555fe599186",
|
|
5
5
|
"dirty": true,
|
|
6
|
-
"builtAt": "2026-08-
|
|
6
|
+
"builtAt": "2026-08-30T15:08:00.155Z",
|
|
7
7
|
"capabilities": [
|
|
8
8
|
"monitor.interrupt.after_tool"
|
|
9
9
|
]
|
package/dist/cli.js
CHANGED
|
@@ -6,11 +6,12 @@ import { join as joinPath, resolve as resolvePath } from 'node:path';
|
|
|
6
6
|
import { createInterface } from 'node:readline';
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { VERSION } from './version.js';
|
|
9
|
+
import { INIT_COMPLETION_GUIDANCE } from './init-guidance.js';
|
|
9
10
|
import { analyzeInstalls, buildInfo, buildLabel, discoverInstalls, runningLabel, } from './provenance.js';
|
|
10
11
|
import { agentDir, agentsRoot, tmpRoot, logsRoot, deriveXdgRuntimeDir } from './paths.js';
|
|
11
12
|
import { findRole, loadConfig } from './config.js';
|
|
12
13
|
import { formatDuration } from './duration.js';
|
|
13
|
-
import { resolvedPlan } from './resolved-plan.js';
|
|
14
|
+
import { redactSensitive, resolvedPlan } from './resolved-plan.js';
|
|
14
15
|
import { pickBackend } from './supervisor/index.js';
|
|
15
16
|
import { up, down } from './ops.js';
|
|
16
17
|
import { readRestartLedger, runSupervised, runTemp } from './runner.js';
|
|
@@ -76,7 +77,7 @@ const program = new Command()
|
|
|
76
77
|
.description('Fleet of persistent, identity-bound AI agents — selectable harnesses over ACP sessions.')
|
|
77
78
|
.enablePositionalOptions()
|
|
78
79
|
.version(VERSION);
|
|
79
|
-
const cOpt = (cmd) => cmd.option('-c, --configuration <file>', '
|
|
80
|
+
const cOpt = (cmd) => cmd.option('-c, --configuration <file>', 'manifest (default: ~/fleet.yaml; documents under ~/fleet/)');
|
|
80
81
|
const collect = (value, previous) => [...previous, value];
|
|
81
82
|
program.command('docs')
|
|
82
83
|
.alias('man')
|
|
@@ -260,14 +261,16 @@ cOpt(program.command('config').description('validate + print the merged plan (no
|
|
|
260
261
|
console.log(` cwd: ${r.cwd}`);
|
|
261
262
|
if (r.model)
|
|
262
263
|
console.log(` model: ${r.model}`);
|
|
264
|
+
if (r.effort)
|
|
265
|
+
console.log(` effort: ${r.effort}`);
|
|
263
266
|
if (r.harness_options && Object.keys(r.harness_options).length)
|
|
264
|
-
console.log(` options: ${JSON.stringify(r.harness_options)}`);
|
|
267
|
+
console.log(` options: ${JSON.stringify(redactSensitive(r.harness_options))}`);
|
|
265
268
|
if (r.coordinator)
|
|
266
269
|
console.log(` coordinator: ${r.coordinator}`);
|
|
267
270
|
if (r.mission)
|
|
268
271
|
console.log(` mission: ${r.mission.split('\n')[0]}`);
|
|
269
272
|
if (r.oversee?.length)
|
|
270
|
-
console.log(` oversees: ${r.oversee.map(o => `${o.
|
|
273
|
+
console.log(` oversees: ${r.oversee.map(o => `${o.agent}@${o.interval}`).join(', ')}`);
|
|
271
274
|
if (r.isolation) {
|
|
272
275
|
const iso = r.isolation;
|
|
273
276
|
const caps = [
|
|
@@ -1253,7 +1256,7 @@ program.command('init').description('one-time host setup (units, dirs, linger)')
|
|
|
1253
1256
|
mkdirSync(d, { recursive: true });
|
|
1254
1257
|
for (const m of await pickBackend().init(binPath))
|
|
1255
1258
|
console.log(m);
|
|
1256
|
-
console.log(
|
|
1259
|
+
console.log(INIT_COMPLETION_GUIDANCE);
|
|
1257
1260
|
});
|
|
1258
1261
|
const webCommand = cOpt(program.command('web').description('start or open the secure localhost fleet web console'))
|
|
1259
1262
|
.enablePositionalOptions()
|
package/dist/config.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { IsolationConfig, WrapContext } from './isolation/types.js';
|
|
|
3
3
|
import type { ResolvedWatchdog } from './watchdog/config.js';
|
|
4
4
|
import type { ResolvedLoop, ResolvedRoleLoop } from './loops/config.js';
|
|
5
5
|
export interface OverseeEntry {
|
|
6
|
-
|
|
6
|
+
agent: string;
|
|
7
7
|
interval: string;
|
|
8
8
|
}
|
|
9
9
|
export interface WorklogPolicy {
|
|
@@ -123,6 +123,8 @@ export interface RoleConfig {
|
|
|
123
123
|
briefing_file?: string;
|
|
124
124
|
/** Explicit null means use the selected harness's own default, bypassing fleet defaults. */
|
|
125
125
|
model?: string | null;
|
|
126
|
+
/** Neutral Brain reasoning effort, retained for inspection after adapter translation. */
|
|
127
|
+
effort?: string;
|
|
126
128
|
model_chain?: string[];
|
|
127
129
|
max_tokens?: number;
|
|
128
130
|
autocompact_pct?: number;
|
|
@@ -166,14 +168,37 @@ export interface ResolvedRole extends Omit<RoleConfig, 'model' | 'owner_channel'
|
|
|
166
168
|
worklog?: WorklogPolicy;
|
|
167
169
|
auth_proxy?: AuthProxyConfig;
|
|
168
170
|
loops?: ResolvedRoleLoop[];
|
|
171
|
+
provenance?: Record<string, FieldProvenance>;
|
|
169
172
|
/** Internal/transient: never accepted as a user-authored RoleConfig key. */
|
|
170
173
|
roomMemberStartup?: RoomMemberStartup;
|
|
171
174
|
}
|
|
175
|
+
export interface FieldProvenance {
|
|
176
|
+
sourceFile: string;
|
|
177
|
+
sourcePointer: string;
|
|
178
|
+
sourceKind: 'Agent' | 'Role' | 'Brain' | 'Manifest' | 'built-in';
|
|
179
|
+
sourceId?: string;
|
|
180
|
+
origin: 'explicit' | 'typed-default' | 'built-in';
|
|
181
|
+
viaReference?: {
|
|
182
|
+
sourcePointer: string;
|
|
183
|
+
kind: 'Role' | 'Brain';
|
|
184
|
+
id: string;
|
|
185
|
+
};
|
|
186
|
+
transforms: Array<{
|
|
187
|
+
kind: 'substitution' | 'adapter-normalization' | 'validation-default';
|
|
188
|
+
detail: string;
|
|
189
|
+
}>;
|
|
190
|
+
}
|
|
172
191
|
export interface FleetConfig {
|
|
173
192
|
roles: ResolvedRole[];
|
|
174
193
|
vars: Record<string, string>;
|
|
175
194
|
defaults: Record<string, unknown>;
|
|
176
195
|
files: string[];
|
|
196
|
+
configMode?: 'split-v2';
|
|
197
|
+
sourceDocuments?: Array<{
|
|
198
|
+
kind: 'Manifest' | 'Agent' | 'Role' | 'Brain';
|
|
199
|
+
id?: string;
|
|
200
|
+
path: string;
|
|
201
|
+
}>;
|
|
177
202
|
/** Fleet-wide delay (ms) enforced between agent launches to avoid boot bursts (0 = none). */
|
|
178
203
|
startStaggerMs: number;
|
|
179
204
|
/** Warning-first non-plain YAML migration diagnostics, in source order. */
|
|
@@ -204,7 +229,8 @@ export declare function resolveRoleModel(model: string | null | undefined, harne
|
|
|
204
229
|
*/
|
|
205
230
|
export declare function isolationContextFor(role: ResolvedRole): WrapContext;
|
|
206
231
|
export declare const ROLE_NAME_RE: RegExp;
|
|
207
|
-
|
|
232
|
+
export declare function splitRootFor(base: string): string;
|
|
233
|
+
/** Load a v2 manifest and bare Agent/Role/Brain documents from its stem directory. */
|
|
208
234
|
export declare function loadConfig(configPath?: string, options?: {
|
|
209
235
|
yamlMode?: YamlMode;
|
|
210
236
|
}): FleetConfig;
|