@ours.network/fleet 1.2.0-nightly.7 → 1.2.0-nightly.70
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 +279 -68
- package/dist/account-origin.d.ts +2 -0
- package/dist/account-origin.js +6 -0
- package/dist/agent-ours/bridge.js +26 -9
- package/dist/agent-ours/correspondence.d.ts +10 -0
- package/dist/agent-ours/correspondence.js +1 -0
- package/dist/agent-ours/file-rpc.d.ts +12 -0
- package/dist/agent-ours/file-rpc.js +18 -4
- package/dist/agent-ours/harness.js +9 -1
- package/dist/agent-ours/mcp-endpoint.d.ts +19 -0
- package/dist/agent-ours/mcp-endpoint.js +98 -25
- package/dist/agent-ours/runtime.d.ts +9 -1
- package/dist/agent-ours/runtime.js +50 -2
- package/dist/agent-ours/service.d.ts +24 -1
- package/dist/agent-ours/service.js +97 -13
- package/dist/application/codex-models.d.ts +15 -0
- package/dist/application/codex-models.js +56 -0
- package/dist/application/conversation-history.d.ts +27 -0
- package/dist/application/conversation-history.js +215 -0
- package/dist/application/conversation-role-observer.d.ts +62 -0
- package/dist/application/conversation-role-observer.js +206 -0
- package/dist/application/fleet-query-service.d.ts +1 -1
- package/dist/application/fleet-query-service.js +2 -2
- package/dist/application/log-service.js +8 -8
- package/dist/application/model-catalog.d.ts +1 -1
- package/dist/application/model-catalog.js +5 -2
- package/dist/application/preset-provenance.d.ts +19 -0
- package/dist/application/preset-provenance.js +59 -0
- package/dist/application/role-creation-service.js +3 -2
- package/dist/application/role-removal-service.js +17 -3
- package/dist/application/role-repository.js +19 -2
- package/dist/application/room-layout-definitions.d.ts +45 -0
- package/dist/application/room-layout-definitions.js +130 -0
- package/dist/application/session-control.d.ts +61 -17
- package/dist/application/session-control.js +207 -23
- package/dist/application/supervisor-ours-tools.js +5 -11
- package/dist/application/task-layouts.d.ts +91 -0
- package/dist/application/task-layouts.js +259 -0
- package/dist/application/task-room-service.d.ts +99 -3
- package/dist/application/task-room-service.js +285 -32
- package/dist/application/types.d.ts +2 -0
- package/dist/atomic-file.d.ts +34 -1
- package/dist/atomic-file.js +161 -18
- package/dist/briefing.d.ts +3 -1
- package/dist/briefing.js +97 -31
- package/dist/build-info.json +9 -4
- package/dist/capabilities.d.ts +9 -1
- package/dist/capabilities.js +13 -0
- package/dist/cli.js +400 -37
- package/dist/client-profile.d.ts +5 -17
- package/dist/client-profile.js +4 -127
- package/dist/config.d.ts +45 -0
- package/dist/config.js +57 -6
- package/dist/creation.d.ts +1 -1
- package/dist/creation.js +4 -4
- package/dist/daemon-recovery.d.ts +1 -8
- package/dist/daemon-recovery.js +8 -113
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +207 -19
- package/dist/doctor.d.ts +4 -1
- package/dist/doctor.js +75 -60
- package/dist/erased-resources.d.ts +9 -0
- package/dist/erased-resources.js +87 -0
- package/dist/file-delivery/reader.d.ts +15 -0
- package/dist/file-delivery/reader.js +63 -0
- package/dist/file-delivery/store.d.ts +15 -0
- package/dist/file-delivery/store.js +124 -0
- package/dist/file-delivery/types.d.ts +19 -0
- package/dist/file-delivery/types.js +1 -0
- package/dist/fleet-command-audit.d.ts +7 -0
- package/dist/fleet-command-audit.js +24 -8
- package/dist/harness/agent-session.d.ts +4 -0
- package/dist/harness/claude-code-session.js +1 -1
- package/dist/harness/claude-code.js +21 -11
- package/dist/harness/claude-runtime.d.ts +12 -0
- package/dist/harness/claude-runtime.js +43 -0
- package/dist/harness/codex-app-server-proxy.d.ts +4 -1
- package/dist/harness/codex-app-server-proxy.js +41 -5
- package/dist/harness/codex-reasoning.d.ts +5 -0
- package/dist/harness/codex-reasoning.js +12 -0
- package/dist/harness/codex-runtime.d.ts +11 -1
- package/dist/harness/codex-runtime.js +31 -4
- package/dist/harness/codex-session.js +2 -2
- package/dist/harness/codex.js +24 -12
- package/dist/init-wizard.d.ts +2 -0
- package/dist/init-wizard.js +38 -19
- package/dist/isolation/policy.js +6 -1
- package/dist/isolation/types.d.ts +5 -0
- package/dist/managed-cli.d.ts +253 -0
- package/dist/managed-cli.js +923 -0
- package/dist/managed-recovery.d.ts +13 -0
- package/dist/managed-recovery.js +31 -0
- package/dist/minimal-setup.d.ts +2 -0
- package/dist/minimal-setup.js +44 -0
- package/dist/monitor.d.ts +8 -34
- package/dist/monitor.js +89 -152
- package/dist/notifications/fleet-producer.d.ts +19 -0
- package/dist/notifications/fleet-producer.js +208 -0
- package/dist/notifications/outbox.d.ts +46 -0
- package/dist/notifications/outbox.js +158 -0
- package/dist/notifications/target-cleanup.d.ts +10 -0
- package/dist/notifications/target-cleanup.js +63 -0
- package/dist/notifications/task-producer.d.ts +18 -0
- package/dist/notifications/task-producer.js +67 -0
- package/dist/ops.d.ts +2 -0
- package/dist/ops.js +20 -3
- package/dist/owner-channel/channel.js +17 -6
- package/dist/owner-channel/commands.d.ts +4 -0
- package/dist/owner-channel/commands.js +8 -0
- package/dist/owner-channel/lifecycle-outbox.js +4 -3
- package/dist/owner-channel/ours-client.js +2 -17
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +2 -0
- package/dist/preset-migration.js +43 -0
- package/dist/process-incarnation.d.ts +23 -0
- package/dist/process-incarnation.js +42 -0
- package/dist/reminders/manager.d.ts +75 -0
- package/dist/reminders/manager.js +278 -0
- package/dist/reminders/runtime.d.ts +27 -0
- package/dist/reminders/runtime.js +32 -0
- package/dist/reminders/schedule.d.ts +37 -0
- package/dist/reminders/schedule.js +104 -0
- package/dist/reminders/store.d.ts +341 -0
- package/dist/reminders/store.js +762 -0
- package/dist/reminders/tools.d.ts +20 -0
- package/dist/reminders/tools.js +114 -0
- package/dist/resolved-plan.js +1 -0
- package/dist/rooms-tasks/add-member.d.ts +48 -0
- package/dist/rooms-tasks/add-member.js +83 -0
- package/dist/rooms-tasks/archived-absence.d.ts +8 -0
- package/dist/rooms-tasks/archived-absence.js +48 -0
- package/dist/rooms-tasks/cli.js +65 -5
- package/dist/rooms-tasks/close.d.ts +6 -2
- package/dist/rooms-tasks/close.js +246 -37
- package/dist/rooms-tasks/config.d.ts +1 -1
- package/dist/rooms-tasks/config.js +11 -4
- package/dist/rooms-tasks/cowork-adapter.d.ts +12 -5
- package/dist/rooms-tasks/cowork-adapter.js +15 -121
- package/dist/rooms-tasks/cowork-http.js +56 -6
- package/dist/rooms-tasks/deletion.d.ts +1 -1
- package/dist/rooms-tasks/deletion.js +84 -5
- package/dist/rooms-tasks/erasure.d.ts +6 -0
- package/dist/rooms-tasks/erasure.js +173 -0
- package/dist/rooms-tasks/external-worker.d.ts +1 -1
- package/dist/rooms-tasks/external-worker.js +3 -4
- package/dist/rooms-tasks/layout-binding-client.d.ts +11 -0
- package/dist/rooms-tasks/layout-binding-client.js +56 -0
- package/dist/rooms-tasks/layout-binding-grants.d.ts +21 -0
- package/dist/rooms-tasks/layout-binding-grants.js +128 -0
- package/dist/rooms-tasks/layout-cli.d.ts +4 -0
- package/dist/rooms-tasks/layout-cli.js +107 -0
- package/dist/rooms-tasks/layout-config.d.ts +11 -0
- package/dist/rooms-tasks/layout-config.js +89 -0
- package/dist/rooms-tasks/layout-control.d.ts +21 -0
- package/dist/rooms-tasks/layout-control.js +52 -0
- package/dist/rooms-tasks/layout-member-retirement.d.ts +10 -0
- package/dist/rooms-tasks/layout-member-retirement.js +90 -0
- package/dist/rooms-tasks/layout-service.d.ts +43 -0
- package/dist/rooms-tasks/layout-service.js +203 -0
- package/dist/rooms-tasks/layout.d.ts +121 -0
- package/dist/rooms-tasks/layout.js +285 -0
- package/dist/rooms-tasks/legacy-task-member.d.ts +19 -0
- package/dist/rooms-tasks/legacy-task-member.js +116 -0
- package/dist/rooms-tasks/live-readiness.d.ts +18 -0
- package/dist/rooms-tasks/live-readiness.js +85 -0
- package/dist/rooms-tasks/member-ownership.d.ts +5 -0
- package/dist/rooms-tasks/member-ownership.js +40 -0
- package/dist/rooms-tasks/member-startup.d.ts +1 -0
- package/dist/rooms-tasks/member-startup.js +2 -0
- package/dist/rooms-tasks/provision.d.ts +3 -0
- package/dist/rooms-tasks/provision.js +101 -49
- package/dist/rooms-tasks/recovery.d.ts +19 -0
- package/dist/rooms-tasks/recovery.js +110 -0
- package/dist/rooms-tasks/room-state.d.ts +4 -2
- package/dist/rooms-tasks/room-state.js +47 -8
- package/dist/rooms-tasks/task-service-retirement.d.ts +11 -0
- package/dist/rooms-tasks/task-service-retirement.js +21 -0
- package/dist/rooms-tasks/task-state.d.ts +51 -8
- package/dist/rooms-tasks/task-state.js +245 -25
- package/dist/rooms-tasks/types.d.ts +40 -0
- package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
- package/dist/rooms-tasks/workspace-artifacts.js +93 -0
- package/dist/rooms-tasks/workspace.d.ts +35 -0
- package/dist/rooms-tasks/workspace.js +325 -0
- package/dist/runner.d.ts +33 -4
- package/dist/runner.js +389 -56
- package/dist/session/acp.d.ts +75 -2
- package/dist/session/acp.js +345 -82
- package/dist/session/arbiter.d.ts +98 -0
- package/dist/session/arbiter.js +272 -3
- package/dist/session/codex-app-server.d.ts +45 -1
- package/dist/session/codex-app-server.js +225 -32
- package/dist/session/control.d.ts +17 -3
- package/dist/session/control.js +213 -23
- package/dist/session/conversation-normalizer.d.ts +2 -1
- package/dist/session/conversation-normalizer.js +1 -1
- package/dist/session/conversation-observation.d.ts +25 -0
- package/dist/session/conversation-observation.js +100 -0
- package/dist/session/conversation-replay.d.ts +50 -0
- package/dist/session/conversation-replay.js +203 -0
- package/dist/session/conversation-store.d.ts +15 -1
- package/dist/session/conversation-store.js +206 -26
- package/dist/session/conversation-types.d.ts +57 -4
- package/dist/session/prompt-batch.d.ts +79 -0
- package/dist/session/prompt-batch.js +120 -0
- package/dist/session/task-notice.d.ts +14 -0
- package/dist/session/task-notice.js +13 -0
- package/dist/session/types.d.ts +42 -1
- package/dist/setup-tunnel-preflight.d.ts +34 -0
- package/dist/setup-tunnel-preflight.js +62 -0
- package/dist/socket-path.d.ts +2 -0
- package/dist/socket-path.js +22 -0
- package/dist/spawn.d.ts +5 -1
- package/dist/spawn.js +40 -4
- package/dist/startup-prompt.d.ts +15 -0
- package/dist/startup-prompt.js +71 -0
- package/dist/startup-readiness.d.ts +32 -0
- package/dist/startup-readiness.js +101 -0
- package/dist/startup-telemetry.d.ts +16 -0
- package/dist/startup-telemetry.js +46 -0
- package/dist/subscriptions/cli.d.ts +91 -0
- package/dist/subscriptions/cli.js +223 -0
- package/dist/subscriptions/launch.d.ts +37 -0
- package/dist/subscriptions/launch.js +93 -0
- package/dist/subscriptions/login.d.ts +76 -0
- package/dist/subscriptions/login.js +207 -0
- package/dist/subscriptions/observed.d.ts +7 -0
- package/dist/subscriptions/observed.js +44 -0
- package/dist/subscriptions/probe.d.ts +10 -0
- package/dist/subscriptions/probe.js +73 -0
- package/dist/subscriptions/service.d.ts +102 -0
- package/dist/subscriptions/service.js +364 -0
- package/dist/subscriptions/store.d.ts +71 -0
- package/dist/subscriptions/store.js +140 -0
- package/dist/supervisor/adoption.d.ts +8 -0
- package/dist/supervisor/adoption.js +78 -0
- package/dist/supervisor/catalog.d.ts +62 -0
- package/dist/supervisor/catalog.js +254 -0
- package/dist/supervisor/fleet.d.ts +8 -0
- package/dist/supervisor/fleet.js +89 -0
- package/dist/supervisor/index.js +3 -6
- package/dist/supervisor/launchd.d.ts +1 -1
- package/dist/supervisor/launchd.js +26 -13
- package/dist/supervisor/legacy.d.ts +35 -0
- package/dist/supervisor/legacy.js +524 -0
- package/dist/supervisor/manager.d.ts +15 -0
- package/dist/supervisor/manager.js +270 -0
- package/dist/supervisor/registration-refresh.d.ts +45 -0
- package/dist/supervisor/registration-refresh.js +266 -0
- package/dist/supervisor/scope.d.ts +4 -0
- package/dist/supervisor/scope.js +10 -0
- package/dist/supervisor/systemd.d.ts +2 -2
- package/dist/supervisor/systemd.js +19 -33
- package/dist/task-supervision.d.ts +9 -0
- package/dist/task-supervision.js +145 -0
- package/dist/temp-idle.d.ts +17 -0
- package/dist/temp-idle.js +42 -0
- package/dist/temp-lifecycle.d.ts +23 -8
- package/dist/temp-lifecycle.js +123 -66
- package/dist/temp-supervisor-recovery.d.ts +1 -1
- package/dist/temp-supervisor-recovery.js +2 -2
- package/dist/tunnel-setup-completion.d.ts +7 -0
- package/dist/tunnel-setup-completion.js +13 -0
- package/dist/tunnel-setup-input.d.ts +19 -0
- package/dist/tunnel-setup-input.js +124 -0
- package/dist/web/agent-attachments.d.ts +29 -0
- package/dist/web/agent-attachments.js +162 -0
- package/dist/web/auth.d.ts +65 -2
- package/dist/web/auth.js +201 -11
- package/dist/web/available-port.d.ts +2 -0
- package/dist/web/available-port.js +23 -0
- package/dist/web/control.d.ts +3 -3
- package/dist/web/control.js +10 -8
- package/dist/web/conversation-stream-codec.d.ts +23 -0
- package/dist/web/conversation-stream-codec.js +110 -0
- package/dist/web/conversation-stream.d.ts +25 -0
- package/dist/web/conversation-stream.js +231 -0
- package/dist/web/fleet-config-service.d.ts +4 -1
- package/dist/web/fleet-config-service.js +46 -15
- package/dist/web/prefix-gateway.d.ts +32 -0
- package/dist/web/prefix-gateway.js +238 -0
- package/dist/web/runtime.d.ts +3 -1
- package/dist/web/runtime.js +128 -33
- package/dist/web/server.d.ts +16 -0
- package/dist/web/server.js +639 -55
- package/dist/web/service.d.ts +11 -2
- package/dist/web/service.js +30 -4
- package/dist/web/workspace-devices.d.ts +107 -0
- package/dist/web/workspace-devices.js +277 -0
- package/dist/web/workspace-tunnel.d.ts +1 -0
- package/dist/web/workspace-tunnel.js +34 -0
- package/dist/workspace-enrollment.d.ts +83 -0
- package/dist/workspace-enrollment.js +580 -0
- package/dist/workspace-replacement.d.ts +66 -0
- package/dist/workspace-replacement.js +220 -0
- package/docs/acp-files.md +146 -0
- package/docs/conversation-stream.md +190 -0
- package/docs/fleet-migration.md +54 -0
- package/docs/live-voice.md +13 -0
- package/docs/room-layouts.md +227 -0
- package/docs/self-reminders.md +374 -0
- package/docs/task-workspaces.md +225 -0
- package/docs/validation/managed-cli-permissions.md +421 -0
- package/examples/room-layouts/fresh.yaml +27 -0
- package/examples/room-layouts/scoped.yaml +21 -0
- package/examples/room-layouts/shared.yaml +19 -0
- package/package.json +24 -20
- package/presets/README.md +78 -0
- package/presets/brain-catalog.json +8 -2
- package/presets/fleet/agent_templates/Critic.yaml +1 -1
- package/presets/fleet/agent_templates/Developer.yaml +1 -1
- package/presets/fleet/agent_templates/Engineer.yaml +5 -0
- package/presets/fleet/agent_templates/LocalCoordinator.yaml +4 -2
- package/presets/fleet/agents/FleetCoordinator.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
- package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
- package/presets/fleet/roles/Coordinator.yaml +12 -11
- package/presets/fleet/roles/Critic.yaml +13 -0
- package/presets/fleet/roles/Developer.yaml +13 -0
- package/presets/fleet/roles/Engineer.yaml +53 -0
- package/presets/fleet/room_layouts/engineering.yaml +25 -0
- package/presets/fleet/room_layouts/pair.yaml +24 -0
- package/presets/fleet/room_layouts/single.yaml +17 -0
- package/presets/fleet/room_layouts/team.yaml +30 -0
- package/presets/fleet/room_templates/engineering.yaml +19 -0
- package/presets/manifest.json +2 -2
- package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
- package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
- package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
- package/dist/web-app/icons/ours-fleet.svg +0 -4
- package/dist/web-app/index.html +0 -17
- package/dist/web-app/manifest.webmanifest +0 -15
- package/dist/web-app/offline.html +0 -18
- package/dist/web-app/sw.js +0 -51
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const PROVENANCE_KINDS: {
|
|
2
|
+
readonly role: "roles";
|
|
3
|
+
readonly brain: "brains";
|
|
4
|
+
readonly template: "agent_templates";
|
|
5
|
+
readonly layout: "room_layouts";
|
|
6
|
+
};
|
|
7
|
+
export type ProvenanceKind = keyof typeof PROVENANCE_KINDS;
|
|
8
|
+
export type ProvenanceStatus = 'predefined' | 'changed' | 'custom';
|
|
9
|
+
export interface ProvenanceEntry {
|
|
10
|
+
status: ProvenanceStatus;
|
|
11
|
+
preset?: string;
|
|
12
|
+
}
|
|
13
|
+
export type Provenance = Record<ProvenanceKind, Record<string, ProvenanceEntry>>;
|
|
14
|
+
export declare class PresetProvenance {
|
|
15
|
+
private configPath?;
|
|
16
|
+
private presetRoot;
|
|
17
|
+
constructor(configPath?: string | undefined, presetRoot?: string);
|
|
18
|
+
read(): Provenance;
|
|
19
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Where each configured definition came from, compared with the packaged presets.
|
|
2
|
+
* A definition is `predefined` when it has the same value as the shipped preset of
|
|
3
|
+
* the same name, `changed` when a preset of that name exists but the value differs,
|
|
4
|
+
* and `custom` otherwise. Values are compared after parsing, so the formatting the
|
|
5
|
+
* configuration editor writes does not count as a change. Preset text is returned
|
|
6
|
+
* so users can see exactly what ships; it contains no host data.
|
|
7
|
+
*/
|
|
8
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
9
|
+
import { existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';
|
|
10
|
+
import { basename, extname, join } from 'node:path';
|
|
11
|
+
import { parse } from 'yaml';
|
|
12
|
+
import { defaultConfigPath } from '../paths.js';
|
|
13
|
+
import { splitRootFor } from '../config.js';
|
|
14
|
+
import { packagedPresetRoot } from '../preset-bootstrap.js';
|
|
15
|
+
export const PROVENANCE_KINDS = { role: 'roles', brain: 'brains', template: 'agent_templates', layout: 'room_layouts' };
|
|
16
|
+
const MAX_BYTES = 256 * 1024;
|
|
17
|
+
/** Regular, bounded YAML files of one directory, by definition name. Anything else is skipped. */
|
|
18
|
+
function yamlFiles(dir) {
|
|
19
|
+
const files = new Map();
|
|
20
|
+
if (!existsSync(dir) || !lstatSync(dir).isDirectory())
|
|
21
|
+
return files;
|
|
22
|
+
for (const file of readdirSync(dir).sort()) {
|
|
23
|
+
if (!/\.ya?ml$/.test(file))
|
|
24
|
+
continue;
|
|
25
|
+
const path = join(dir, file), stat = lstatSync(path);
|
|
26
|
+
if (!stat.isFile() || stat.size > MAX_BYTES)
|
|
27
|
+
continue;
|
|
28
|
+
files.set(basename(file, extname(file)), readFileSync(path, 'utf8'));
|
|
29
|
+
}
|
|
30
|
+
return files;
|
|
31
|
+
}
|
|
32
|
+
const parsed = (text) => { try {
|
|
33
|
+
return parse(text);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return Symbol('unparseable');
|
|
37
|
+
} };
|
|
38
|
+
export class PresetProvenance {
|
|
39
|
+
configPath;
|
|
40
|
+
presetRoot;
|
|
41
|
+
constructor(configPath, presetRoot = join(packagedPresetRoot(), 'fleet')) {
|
|
42
|
+
this.configPath = configPath;
|
|
43
|
+
this.presetRoot = presetRoot;
|
|
44
|
+
}
|
|
45
|
+
read() {
|
|
46
|
+
const split = splitRootFor(this.configPath ?? defaultConfigPath());
|
|
47
|
+
const result = {};
|
|
48
|
+
for (const [kind, dir] of Object.entries(PROVENANCE_KINDS)) {
|
|
49
|
+
const presets = yamlFiles(join(this.presetRoot, dir)), installed = yamlFiles(join(split, dir));
|
|
50
|
+
result[kind] = Object.fromEntries([...installed].map(([name, text]) => {
|
|
51
|
+
const preset = presets.get(name);
|
|
52
|
+
if (preset === undefined)
|
|
53
|
+
return [name, { status: 'custom' }];
|
|
54
|
+
return [name, { status: isDeepStrictEqual(parsed(text), parsed(preset)) ? 'predefined' : 'changed', preset }];
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -59,7 +59,8 @@ export class RoleCreationService {
|
|
|
59
59
|
}
|
|
60
60
|
async createManaged(caller, requested) {
|
|
61
61
|
const plan = this.previewSpawn({ origin: 'managed', caller, options: requested });
|
|
62
|
-
const creationActionId =
|
|
62
|
+
const creationActionId = requested.roomMemberStartup?.task_id
|
|
63
|
+
? requested.creationActionId ?? randomUUID() : randomUUID();
|
|
63
64
|
plan.options.creationActionId = creationActionId;
|
|
64
65
|
const statePath = await this.launchSync(plan.options);
|
|
65
66
|
const selectionSummary = (kind) => {
|
|
@@ -138,7 +139,7 @@ export class RoleCreationService {
|
|
|
138
139
|
reasoningEffort: resolved.effort,
|
|
139
140
|
cwd, lifetime: request.lifetime,
|
|
140
141
|
permissions: resolvePermissions(defaults.permissions, request.permissions),
|
|
141
|
-
monitor: resolveMonitorConfig(defaults.monitor, request.monitor),
|
|
142
|
+
monitor: resolveMonitorConfig(defaults.monitor, request.monitor, { harness: resolved.harness }),
|
|
142
143
|
};
|
|
143
144
|
const warnings = [];
|
|
144
145
|
if (request.permissions.approval === 'allow')
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { retireNotificationTarget } from '../notifications/target-cleanup.js';
|
|
1
2
|
import { cpSync, existsSync, mkdirSync, readdirSync, renameSync } from 'node:fs';
|
|
2
3
|
import { basename, dirname, join } from 'node:path';
|
|
3
4
|
import { loadConfig, ROLE_NAME_RE } from '../config.js';
|
|
4
5
|
import { agentDir, stateRoot } from '../paths.js';
|
|
5
|
-
import { rmRole } from '../ops.js';
|
|
6
|
+
import { assertStandaloneRoleRemoval, rmRole } from '../ops.js';
|
|
6
7
|
import { FleetError } from './errors.js';
|
|
8
|
+
import { removeReminderState } from '../reminders/store.js';
|
|
7
9
|
import { provesGeneratedAgentSource } from '../generated-agent-source.js';
|
|
8
10
|
export class RoleRemovalService {
|
|
9
11
|
options;
|
|
@@ -18,6 +20,12 @@ export class RoleRemovalService {
|
|
|
18
20
|
if (!ROLE_NAME_RE.test(requested))
|
|
19
21
|
throw new FleetError('invalid_request', 'invalid role name');
|
|
20
22
|
const cfg = loadConfig(this.options.configPath);
|
|
23
|
+
try {
|
|
24
|
+
assertStandaloneRoleRemoval(cfg, requested);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new FleetError('conflict', error instanceof Error ? error.message : String(error));
|
|
28
|
+
}
|
|
21
29
|
const names = new Set(cfg.roles.map(role => role.name));
|
|
22
30
|
for (const root of [dirname(agentDir('_')), dirname(agentDir('_', true))]) {
|
|
23
31
|
try {
|
|
@@ -76,8 +84,11 @@ export class RoleRemovalService {
|
|
|
76
84
|
const stamp = new Date().toISOString().replaceAll(/[:.]/g, '-');
|
|
77
85
|
const recoveryPath = join(stateRoot(), 'recovery', 'removed', `${stamp}-${preview.role}`);
|
|
78
86
|
mkdirSync(recoveryPath, { recursive: true, mode: 0o700 });
|
|
79
|
-
if (existsSync(sourceState))
|
|
87
|
+
if (existsSync(sourceState)) {
|
|
80
88
|
cpSync(sourceState, join(recoveryPath, 'state'), { recursive: true });
|
|
89
|
+
// Recovery evidence is not a schedule: a removed agent's reminders end here.
|
|
90
|
+
removeReminderState(join(recoveryPath, 'state'));
|
|
91
|
+
}
|
|
81
92
|
if (role && provesGeneratedAgentSource(agentDir(preview.role), cfg.files[0], role.sourceFile)
|
|
82
93
|
&& existsSync(role.sourceFile))
|
|
83
94
|
cpSync(role.sourceFile, join(recoveryPath, basename(role.sourceFile)));
|
|
@@ -85,8 +96,11 @@ export class RoleRemovalService {
|
|
|
85
96
|
await rmRole(cfg, preview.role, this.options.ops);
|
|
86
97
|
else {
|
|
87
98
|
await this.options.ops.backend.uninstall(preview.role);
|
|
88
|
-
if (existsSync(sourceState))
|
|
99
|
+
if (existsSync(sourceState)) {
|
|
89
100
|
renameSync(sourceState, join(recoveryPath, 'orphan-state'));
|
|
101
|
+
removeReminderState(join(recoveryPath, 'orphan-state'));
|
|
102
|
+
}
|
|
103
|
+
await retireNotificationTarget(`/fleet/chats/agents/${encodeURIComponent(preview.role)}`).catch(() => { });
|
|
90
104
|
this.options.ops.log(`removed orphaned backend/state '${preview.role}'`);
|
|
91
105
|
}
|
|
92
106
|
return { ...preview, removed: true, recoveryPath };
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { lstatSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
|
|
2
2
|
import { join, relative } from 'node:path';
|
|
3
3
|
import { parse } from 'yaml';
|
|
4
|
-
import { loadConfig,
|
|
4
|
+
import { loadConfig, resolveSnapshotMonitor, resolvePermissions, ROLE_NAME_RE, } from '../config.js';
|
|
5
5
|
import { agentsRoot, tmpRoot } from '../paths.js';
|
|
6
6
|
import { readSpawnLineage } from '../web/topology.js';
|
|
7
7
|
const MAX_SNAPSHOT_BYTES = 256 * 1024;
|
|
8
|
+
function retainedTaskId(dir, name) {
|
|
9
|
+
try {
|
|
10
|
+
const path = join(dir, '.temp-supervisor.json');
|
|
11
|
+
const stat = lstatSync(path);
|
|
12
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 16 * 1024)
|
|
13
|
+
return undefined;
|
|
14
|
+
const record = JSON.parse(readFileSync(path, 'utf8'));
|
|
15
|
+
const id = record?.taskOwner?.taskId;
|
|
16
|
+
return record?.version === 1 && record?.role === name && typeof id === 'string'
|
|
17
|
+
&& /^[0-9a-z]{9}[0-9a-f]{8}$/.test(id) ? id : undefined;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
8
23
|
function safeDirs(root) {
|
|
9
24
|
try {
|
|
10
25
|
return readdirSync(root, { withFileTypes: true })
|
|
@@ -54,7 +69,7 @@ function snapshot(path, name) {
|
|
|
54
69
|
session, identity: typeof raw.identity === 'string' ? raw.identity : name,
|
|
55
70
|
permissions: resolvePermissions(undefined, raw.permissions),
|
|
56
71
|
permissionsDeclared: raw.permissions !== undefined,
|
|
57
|
-
monitor:
|
|
72
|
+
monitor: resolveSnapshotMonitor(raw.monitor),
|
|
58
73
|
sourceFile: '(temp)',
|
|
59
74
|
},
|
|
60
75
|
};
|
|
@@ -128,10 +143,12 @@ export class RoleRepository {
|
|
|
128
143
|
const stateRef = inTemporary ? { lifetime: 'temporary' }
|
|
129
144
|
: inPermanent ? { lifetime: 'permanent' } : undefined;
|
|
130
145
|
const tempStateDir = inTemporary ? join(temporaryRoot, name) : undefined;
|
|
146
|
+
const taskId = !config && tempStateDir ? retainedTaskId(tempStateDir, name) : undefined;
|
|
131
147
|
return {
|
|
132
148
|
id: name,
|
|
133
149
|
lifetime: config ? 'permanent' : inTemporary ? 'temporary' : 'orphan',
|
|
134
150
|
configured: Boolean(config),
|
|
151
|
+
...(taskId ? { taskId } : {}),
|
|
135
152
|
config: config ? view(config) : tempRole ? view(tempRole) : undefined,
|
|
136
153
|
stateRef,
|
|
137
154
|
stateHealth,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { loadConfig } from '../config.js';
|
|
2
|
+
import { type RoomLayoutDefinition } from '../rooms-tasks/layout-config.js';
|
|
3
|
+
export declare const ABSENT_REVISION = "absent";
|
|
4
|
+
export type LayoutDefinitionBody = Omit<RoomLayoutDefinition, 'sourceFile'>;
|
|
5
|
+
export type LayoutListEntry = {
|
|
6
|
+
name: string;
|
|
7
|
+
revision: string;
|
|
8
|
+
file: string;
|
|
9
|
+
definition: LayoutDefinitionBody;
|
|
10
|
+
issues: string[];
|
|
11
|
+
definition_hash: string;
|
|
12
|
+
} | {
|
|
13
|
+
name: string;
|
|
14
|
+
revision: string;
|
|
15
|
+
file: string;
|
|
16
|
+
error: string;
|
|
17
|
+
};
|
|
18
|
+
export declare class RoomLayoutDefinitions {
|
|
19
|
+
private configPath?;
|
|
20
|
+
private deps;
|
|
21
|
+
constructor(configPath?: string | undefined, deps?: {
|
|
22
|
+
loadConfiguration?: typeof loadConfig;
|
|
23
|
+
});
|
|
24
|
+
private root;
|
|
25
|
+
private pathFor;
|
|
26
|
+
private currentRevision;
|
|
27
|
+
/** Agent-template references that do not resolve in the current Fleet configuration. */
|
|
28
|
+
private templateIssues;
|
|
29
|
+
/** The configured default (`rooms.defaults.template`, else `tasks.default_room_template`) when it names a usable layout. */
|
|
30
|
+
defaultLayout(entries?: LayoutListEntry[]): string | undefined;
|
|
31
|
+
list(): LayoutListEntry[];
|
|
32
|
+
validate(raw: unknown): {
|
|
33
|
+
definition?: LayoutDefinitionBody;
|
|
34
|
+
issues: string[];
|
|
35
|
+
};
|
|
36
|
+
save(name: string, expectedRevision: string, raw: unknown): Promise<{
|
|
37
|
+
name: string;
|
|
38
|
+
revision: string;
|
|
39
|
+
definition: LayoutDefinitionBody;
|
|
40
|
+
}>;
|
|
41
|
+
remove(name: string, expectedRevision: string): Promise<{
|
|
42
|
+
name: string;
|
|
43
|
+
deleted: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** Web authoring of `fleet/room_layouts/<name>.yaml`.
|
|
2
|
+
* Writes are revision-guarded (sha256 of the file bytes) and validated with the
|
|
3
|
+
* same parser the CLI uses. Retained layout runs keep their own snapshots, so
|
|
4
|
+
* editing or deleting a definition never changes an existing run.
|
|
5
|
+
*/
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync } from 'node:fs';
|
|
8
|
+
import { basename, extname, join } from 'node:path';
|
|
9
|
+
import { stringify } from 'yaml';
|
|
10
|
+
import { replaceFileAtomically, withFileLock } from '../atomic-file.js';
|
|
11
|
+
import { parseFleetDocument } from '../config-yaml.js';
|
|
12
|
+
import { defaultConfigPath } from '../paths.js';
|
|
13
|
+
import { loadConfig, splitRootFor } from '../config.js';
|
|
14
|
+
import { assertLayoutFile, validLayoutKey, validateRoomLayout } from '../rooms-tasks/layout-config.js';
|
|
15
|
+
import { FleetError } from './errors.js';
|
|
16
|
+
import { layoutDefinitionHash } from './task-layouts.js';
|
|
17
|
+
export const ABSENT_REVISION = 'absent';
|
|
18
|
+
const revisionOf = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
19
|
+
export class RoomLayoutDefinitions {
|
|
20
|
+
configPath;
|
|
21
|
+
deps;
|
|
22
|
+
constructor(configPath, deps = {}) {
|
|
23
|
+
this.configPath = configPath;
|
|
24
|
+
this.deps = deps;
|
|
25
|
+
}
|
|
26
|
+
root() { return join(splitRootFor(this.configPath ?? defaultConfigPath()), 'room_layouts'); }
|
|
27
|
+
pathFor(name) {
|
|
28
|
+
if (!validLayoutKey(name))
|
|
29
|
+
throw new FleetError('invalid_request', 'layout name must start with a letter and use letters, digits, - or _');
|
|
30
|
+
return join(this.root(), `${name}.yaml`);
|
|
31
|
+
}
|
|
32
|
+
currentRevision(path) {
|
|
33
|
+
if (!existsSync(path))
|
|
34
|
+
return ABSENT_REVISION;
|
|
35
|
+
assertLayoutFile(path);
|
|
36
|
+
return revisionOf(readFileSync(path));
|
|
37
|
+
}
|
|
38
|
+
/** Agent-template references that do not resolve in the current Fleet configuration. */
|
|
39
|
+
templateIssues(definition) {
|
|
40
|
+
let templates = {};
|
|
41
|
+
try {
|
|
42
|
+
templates = (this.deps.loadConfiguration ?? loadConfig)(this.configPath).agentTemplates ?? {};
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return [`fleet configuration unavailable: ${error.message}`];
|
|
46
|
+
}
|
|
47
|
+
return Object.entries(definition.participants).flatMap(([key, participant]) => participant.agent_template && !Object.hasOwn(templates, participant.agent_template)
|
|
48
|
+
? [`participant ${key}: agent template not found: ${participant.agent_template}`] : []);
|
|
49
|
+
}
|
|
50
|
+
/** The configured default (`rooms.defaults.template`, else `tasks.default_room_template`) when it names a usable layout. */
|
|
51
|
+
defaultLayout(entries = this.list()) {
|
|
52
|
+
let name;
|
|
53
|
+
try {
|
|
54
|
+
const config = (this.deps.loadConfiguration ?? loadConfig)(this.configPath);
|
|
55
|
+
name = config.rooms?.defaults?.template ?? config.tasks?.default_room_template;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const entry = entries.find(e => e.name === name);
|
|
61
|
+
return entry && !('error' in entry) && !entry.issues.length ? entry.name : undefined;
|
|
62
|
+
}
|
|
63
|
+
list() {
|
|
64
|
+
const root = this.root();
|
|
65
|
+
if (!existsSync(root))
|
|
66
|
+
return [];
|
|
67
|
+
assertLayoutFile(root, true);
|
|
68
|
+
return readdirSync(root).filter(file => /\.ya?ml$/.test(file)).sort().map(file => {
|
|
69
|
+
const name = basename(file, extname(file)), path = join(root, file);
|
|
70
|
+
try {
|
|
71
|
+
if (!validLayoutKey(name))
|
|
72
|
+
throw Error(`invalid room layout id: ${name}`);
|
|
73
|
+
assertLayoutFile(path);
|
|
74
|
+
const bytes = readFileSync(path);
|
|
75
|
+
const definition = validateRoomLayout(parseFleetDocument(path, bytes.toString('utf8'), 'strict').value, file);
|
|
76
|
+
return { name, file, revision: revisionOf(bytes), definition, issues: this.templateIssues(definition), definition_hash: layoutDefinitionHash(definition) };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Only a trusted regular file may be read to offer an overwrite revision.
|
|
80
|
+
let revision = ABSENT_REVISION;
|
|
81
|
+
try {
|
|
82
|
+
assertLayoutFile(path);
|
|
83
|
+
revision = revisionOf(readFileSync(path));
|
|
84
|
+
}
|
|
85
|
+
catch { /* not trusted: never read */ }
|
|
86
|
+
return { name, file, revision, error: error.message };
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
validate(raw) {
|
|
91
|
+
let definition;
|
|
92
|
+
try {
|
|
93
|
+
definition = validateRoomLayout(raw, 'room layout');
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return { issues: [error.message] };
|
|
97
|
+
}
|
|
98
|
+
return { definition, issues: this.templateIssues(definition) };
|
|
99
|
+
}
|
|
100
|
+
async save(name, expectedRevision, raw) {
|
|
101
|
+
const path = this.pathFor(name);
|
|
102
|
+
const { definition, issues } = this.validate(raw);
|
|
103
|
+
if (!definition || issues.length)
|
|
104
|
+
throw new FleetError('invalid_request', issues.join('; '));
|
|
105
|
+
const root = this.root();
|
|
106
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
107
|
+
assertLayoutFile(root, true);
|
|
108
|
+
return withFileLock(`${path}.lock`, async () => {
|
|
109
|
+
const current = this.currentRevision(path);
|
|
110
|
+
if (current !== expectedRevision)
|
|
111
|
+
throw new FleetError('stale_state', 'room layout changed since it was loaded; reload before saving');
|
|
112
|
+
const { description, participants, rooms } = definition;
|
|
113
|
+
const text = stringify({ version: 1, ...(description ? { description } : {}), participants, rooms });
|
|
114
|
+
replaceFileAtomically(path, text, 0o600);
|
|
115
|
+
return { name, revision: revisionOf(text), definition };
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async remove(name, expectedRevision) {
|
|
119
|
+
const path = this.pathFor(name);
|
|
120
|
+
return withFileLock(`${path}.lock`, async () => {
|
|
121
|
+
const current = this.currentRevision(path);
|
|
122
|
+
if (current === ABSENT_REVISION)
|
|
123
|
+
return { name, deleted: false };
|
|
124
|
+
if (current !== expectedRevision)
|
|
125
|
+
throw new FleetError('stale_state', 'room layout changed since it was loaded; reload before deleting');
|
|
126
|
+
unlinkSync(path);
|
|
127
|
+
return { name, deleted: true };
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { ConversationRoleObservation, ConversationRoleState, ObserveConversationRole } from './conversation-role-observer.js';
|
|
2
|
+
import { type ConversationTailPage } from './conversation-history.js';
|
|
3
|
+
import type { AgentHistoryQuery } from '../agent-ours/correspondence.js';
|
|
4
|
+
import { controlRequest, followConversation } from '../session/control.js';
|
|
5
|
+
import type { ConversationEventV1, ConversationSnapshot, ConversationObservationState, PromptReceipt } from '../session/conversation-types.js';
|
|
3
6
|
import type { SessionSnapshot } from '../session/types.js';
|
|
7
|
+
import type { PassiveConversationFollowRequest, ConversationReplayPage, ConversationReplayReady } from '../session/conversation-replay.js';
|
|
4
8
|
import type { OutputPage, SendReceipt, SessionDescriptor } from './types.js';
|
|
5
9
|
export interface ConversationPageView {
|
|
6
10
|
events: ConversationEventV1[];
|
|
@@ -12,6 +16,23 @@ export interface ConversationPageView {
|
|
|
12
16
|
export interface ConversationFollowHandle {
|
|
13
17
|
close(): void;
|
|
14
18
|
}
|
|
19
|
+
export interface LegacyConversationFollowRequest {
|
|
20
|
+
after?: string;
|
|
21
|
+
onPage(page: ConversationPageView): void;
|
|
22
|
+
onEvent(event: ConversationEventV1): void;
|
|
23
|
+
onClose(reason?: string): void;
|
|
24
|
+
}
|
|
25
|
+
export interface PassiveConversationFollow extends PassiveConversationFollowRequest {
|
|
26
|
+
/** Reports role updates from the owned or borrowed observer; never attaches a controller. */
|
|
27
|
+
onRole?(state: ConversationRoleState): void;
|
|
28
|
+
/** Application-only borrowed owner; never sent over the private wire. */
|
|
29
|
+
roleObservation?: ConversationRoleObservation;
|
|
30
|
+
onReplay(page: ConversationReplayPage): void;
|
|
31
|
+
onReady(ready: ConversationReplayReady): void;
|
|
32
|
+
onEvent(event: ConversationEventV1): void;
|
|
33
|
+
onState(state: ConversationObservationState): void;
|
|
34
|
+
onClose(reason?: string): void;
|
|
35
|
+
}
|
|
15
36
|
/**
|
|
16
37
|
* An interrupt that reached the session. `state` says whether the turn stopped
|
|
17
38
|
* cooperatively or through bounded forced recovery — both are accepted, so no
|
|
@@ -23,7 +44,11 @@ export interface InterruptReceipt {
|
|
|
23
44
|
reasonCode?: string;
|
|
24
45
|
}
|
|
25
46
|
export interface RoleSessionControl {
|
|
26
|
-
|
|
47
|
+
/** Standalone owner for role-only observation; dispose with that connection. */
|
|
48
|
+
observeRole?: ObserveConversationRole;
|
|
49
|
+
agentContacts?(): Promise<unknown>;
|
|
50
|
+
agentHistory?(request: AgentHistoryQuery): Promise<unknown>;
|
|
51
|
+
describe(roleObservation?: ConversationRoleObservation): Promise<SessionDescriptor>;
|
|
27
52
|
snapshot(): Promise<SessionSnapshot>;
|
|
28
53
|
recentOutput(request?: {
|
|
29
54
|
since?: number;
|
|
@@ -41,12 +66,24 @@ export interface RoleSessionControl {
|
|
|
41
66
|
after?: string;
|
|
42
67
|
limit?: number;
|
|
43
68
|
}): Promise<ConversationPageView>;
|
|
69
|
+
/** The newest visible events (or those before `before`), read backwards from the ledger. */
|
|
70
|
+
conversationTail?(request: {
|
|
71
|
+
before?: string;
|
|
72
|
+
limit?: number;
|
|
73
|
+
}): Promise<ConversationTailPage>;
|
|
44
74
|
submitPromptV2?(request: {
|
|
45
75
|
commandId: string;
|
|
46
76
|
text: string;
|
|
47
77
|
actorBrowserSession: string;
|
|
78
|
+
expectedSessionGeneration?: string;
|
|
79
|
+
requireIdle?: boolean;
|
|
48
80
|
source: 'owner_admin_console';
|
|
49
81
|
}): Promise<PromptReceipt>;
|
|
82
|
+
interruptPromptV2?(request: {
|
|
83
|
+
commandId: string;
|
|
84
|
+
expectedSessionGeneration: string;
|
|
85
|
+
promptId: string;
|
|
86
|
+
}): Promise<InterruptReceipt>;
|
|
50
87
|
interruptV2?(commandId: string): Promise<InterruptReceipt & {
|
|
51
88
|
commandId: string;
|
|
52
89
|
}>;
|
|
@@ -64,18 +101,19 @@ export interface RoleSessionControl {
|
|
|
64
101
|
* replay page; `onEvent` every subsequent durable event; `onClose` fires
|
|
65
102
|
* exactly once when the underlying control stream ends.
|
|
66
103
|
*/
|
|
67
|
-
followConversation?(request:
|
|
68
|
-
after?: string;
|
|
69
|
-
onPage(page: ConversationPageView): void;
|
|
70
|
-
onEvent(event: ConversationEventV1): void;
|
|
71
|
-
onClose(reason?: string): void;
|
|
72
|
-
}): Promise<ConversationFollowHandle>;
|
|
104
|
+
followConversation?(request: LegacyConversationFollowRequest | PassiveConversationFollow): Promise<ConversationFollowHandle>;
|
|
73
105
|
}
|
|
74
106
|
export declare class RoleSessionControlAdapter implements RoleSessionControl {
|
|
75
107
|
private readonly stateDir;
|
|
76
108
|
private readonly request;
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
private readonly openFollow;
|
|
110
|
+
readonly observeRole?: ObserveConversationRole | undefined;
|
|
111
|
+
private controlHealthy;
|
|
112
|
+
constructor(stateDir: string, request?: typeof controlRequest, openFollow?: typeof followConversation, observeRole?: ObserveConversationRole | undefined);
|
|
113
|
+
agentContacts(): Promise<unknown>;
|
|
114
|
+
agentHistory(request: AgentHistoryQuery): Promise<unknown>;
|
|
115
|
+
private requireCorrespondence;
|
|
116
|
+
describe(roleObservation?: ConversationRoleObservation): Promise<SessionDescriptor>;
|
|
79
117
|
snapshot(): Promise<SessionSnapshot>;
|
|
80
118
|
recentOutput(request?: {
|
|
81
119
|
since?: number;
|
|
@@ -87,12 +125,23 @@ export declare class RoleSessionControlAdapter implements RoleSessionControl {
|
|
|
87
125
|
after?: string;
|
|
88
126
|
limit?: number;
|
|
89
127
|
}): Promise<ConversationPageView>;
|
|
128
|
+
conversationTail(request?: {
|
|
129
|
+
before?: string;
|
|
130
|
+
limit?: number;
|
|
131
|
+
}): Promise<ConversationTailPage>;
|
|
90
132
|
submitPromptV2(request: {
|
|
91
133
|
commandId: string;
|
|
92
134
|
text: string;
|
|
93
135
|
actorBrowserSession: string;
|
|
136
|
+
expectedSessionGeneration?: string;
|
|
137
|
+
requireIdle?: boolean;
|
|
94
138
|
source: 'owner_admin_console';
|
|
95
139
|
}): Promise<PromptReceipt>;
|
|
140
|
+
interruptPromptV2(request: {
|
|
141
|
+
commandId: string;
|
|
142
|
+
expectedSessionGeneration: string;
|
|
143
|
+
promptId: string;
|
|
144
|
+
}): Promise<InterruptReceipt>;
|
|
96
145
|
interruptV2(commandId: string): Promise<InterruptReceipt & {
|
|
97
146
|
commandId: string;
|
|
98
147
|
}>;
|
|
@@ -105,12 +154,7 @@ export declare class RoleSessionControlAdapter implements RoleSessionControl {
|
|
|
105
154
|
accepted: true;
|
|
106
155
|
commandId: string;
|
|
107
156
|
}>;
|
|
108
|
-
followConversation(request:
|
|
109
|
-
after?: string;
|
|
110
|
-
onPage(page: ConversationPageView): void;
|
|
111
|
-
onEvent(event: ConversationEventV1): void;
|
|
112
|
-
onClose(reason?: string): void;
|
|
113
|
-
}): Promise<ConversationFollowHandle>;
|
|
157
|
+
followConversation(request: LegacyConversationFollowRequest | PassiveConversationFollow): Promise<ConversationFollowHandle>;
|
|
114
158
|
respondPermission(request: {
|
|
115
159
|
permissionId: string;
|
|
116
160
|
optionId: string;
|