@ours.network/fleet 1.2.0-nightly.8 → 1.2.0-nightly.80
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 +5 -0
- package/dist/account-origin.js +31 -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 +34 -0
- package/dist/application/conversation-history.js +294 -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 +3 -3
- 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/resource-observer.d.ts +43 -0
- package/dist/application/resource-observer.js +323 -0
- package/dist/application/role-creation-service.js +3 -2
- package/dist/application/role-removal-service.js +17 -3
- package/dist/application/role-repository.d.ts +1 -1
- package/dist/application/role-repository.js +30 -7
- 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 +63 -17
- package/dist/application/session-control.js +221 -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 +261 -0
- package/dist/application/task-room-service.d.ts +101 -3
- package/dist/application/task-room-service.js +286 -33
- 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 +14 -9
- package/dist/daemon-recovery.js +124 -115
- 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 +9 -34
- package/dist/monitor.js +90 -153
- package/dist/notifications/fleet-producer.d.ts +31 -0
- package/dist/notifications/fleet-producer.js +351 -0
- package/dist/notifications/outbox.d.ts +59 -0
- package/dist/notifications/outbox.js +199 -0
- package/dist/notifications/target-cleanup.d.ts +16 -0
- package/dist/notifications/target-cleanup.js +75 -0
- package/dist/notifications/task-producer.d.ts +20 -0
- package/dist/notifications/task-producer.js +100 -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 +5 -0
- package/dist/paths.js +5 -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 +84 -0
- package/dist/rooms-tasks/archived-absence.d.ts +4 -0
- package/dist/rooms-tasks/archived-absence.js +11 -0
- package/dist/rooms-tasks/cli.js +65 -5
- package/dist/rooms-tasks/close.d.ts +5 -2
- package/dist/rooms-tasks/close.js +224 -36
- 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 +63 -10
- 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 +286 -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 +43 -5
- package/dist/rooms-tasks/task-state.js +244 -22
- package/dist/rooms-tasks/types.d.ts +35 -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 +410 -62
- 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 +219 -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 +213 -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 +77 -0
- package/dist/subscriptions/login.js +215 -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 +143 -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 +130 -0
- package/dist/watchdog/query.d.ts +3 -1
- package/dist/watchdog/query.js +2 -1
- 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 +26 -0
- package/dist/web/conversation-stream.js +239 -0
- package/dist/web/events.d.ts +2 -0
- package/dist/web/events.js +9 -0
- package/dist/web/fleet-config-service.d.ts +7 -1
- package/dist/web/fleet-config-service.js +61 -16
- package/dist/web/prefix-gateway.d.ts +32 -0
- package/dist/web/prefix-gateway.js +248 -0
- package/dist/web/resource-views.d.ts +135 -0
- package/dist/web/resource-views.js +486 -0
- package/dist/web/runtime.d.ts +3 -1
- package/dist/web/runtime.js +132 -34
- package/dist/web/server.d.ts +19 -0
- package/dist/web/server.js +821 -68
- 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 +605 -0
- package/dist/workspace-replacement.d.ts +66 -0
- package/dist/workspace-replacement.js +238 -0
- package/docs/acp-files.md +146 -0
- package/docs/conversation-stream.md +216 -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,20 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type ReminderStore } from './store.js';
|
|
3
|
+
/**
|
|
4
|
+
* What the agent's managed MCP endpoint needs from its runner. Absent until
|
|
5
|
+
* the runner has bound the store to this exact runtime instance and identity.
|
|
6
|
+
*/
|
|
7
|
+
export interface ReminderToolBackend {
|
|
8
|
+
store: ReminderStore;
|
|
9
|
+
/** Re-arm the dispatcher after a schedule change. */
|
|
10
|
+
changed(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare const REMINDER_TOOL_NAMES: readonly ["fleet_reminder_create", "fleet_reminder_list", "fleet_reminder_update", "fleet_reminder_cancel", "fleet_reminder_inspect", "fleet_reminder_ack"];
|
|
13
|
+
/**
|
|
14
|
+
* Register the self-reminder tools on the agent's own fixed-identity MCP
|
|
15
|
+
* server. No argument names an agent, identity or recipient: the server is the
|
|
16
|
+
* caller's own supervisor, so every operation is implicitly self-scoped.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerReminderTools(server: McpServer, backend: () => ReminderToolBackend | undefined,
|
|
19
|
+
/** The endpoint's runtime admission; nothing is read or changed unless it admits. */
|
|
20
|
+
admit: () => Promise<() => void>): void;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ReminderError } from './store.js';
|
|
3
|
+
export const REMINDER_TOOL_NAMES = Object.freeze([
|
|
4
|
+
'fleet_reminder_create', 'fleet_reminder_list', 'fleet_reminder_update',
|
|
5
|
+
'fleet_reminder_cancel', 'fleet_reminder_inspect', 'fleet_reminder_ack',
|
|
6
|
+
]);
|
|
7
|
+
const schedule = {
|
|
8
|
+
local_time: z.string().describe('Calendar date and wall-clock time WITHOUT an offset, e.g. "2027-01-20T16:00". Always a real date: resolve "tomorrow" yourself.'),
|
|
9
|
+
time_zone: z.string().describe('IANA zone the time is meant in, e.g. "Europe/London", "America/New_York" or "UTC". Use the zone of the person or task, not a guess.'),
|
|
10
|
+
fold: z.union([z.literal(0), z.literal(1)]).optional().describe('Only for a wall time that occurs twice when clocks go back: 0 = first occurrence, 1 = second.'),
|
|
11
|
+
late_window_seconds: z.number().int().optional().describe('How late the wake may still be delivered if this agent or the host was offline or busy at the due time (60..604800, default 3600). After it the reminder expires without a wake.'),
|
|
12
|
+
interrupt: z.boolean().optional().describe('Default false: the wake waits until you are idle. true only for a return that is genuinely time-bound: '
|
|
13
|
+
+ 'when due and you are busy with interruptible work, Fleet asks your current turn to stop (session and context are kept) and wakes you with this reminder instead of waiting. '
|
|
14
|
+
+ 'At most one interruption per reminder revision. It never pre-empts owner requests, the owner console, startup, a pending permission, queued work or another reminder; '
|
|
15
|
+
+ 'then it waits like an ordinary reminder. Not a hard real-time alarm: no wake while the host or agent is down, and model start-up still takes time.'),
|
|
16
|
+
};
|
|
17
|
+
function result(value) {
|
|
18
|
+
return {
|
|
19
|
+
content: [{ type: 'text', text: JSON.stringify(value, null, 2) }],
|
|
20
|
+
structuredContent: value,
|
|
21
|
+
isError: false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function failure(code, message) {
|
|
25
|
+
const value = { error: code, message };
|
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(value) }], isError: true };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register the self-reminder tools on the agent's own fixed-identity MCP
|
|
30
|
+
* server. No argument names an agent, identity or recipient: the server is the
|
|
31
|
+
* caller's own supervisor, so every operation is implicitly self-scoped.
|
|
32
|
+
*/
|
|
33
|
+
export function registerReminderTools(server, backend,
|
|
34
|
+
/** The endpoint's runtime admission; nothing is read or changed unless it admits. */
|
|
35
|
+
admit) {
|
|
36
|
+
const run = async (operation, mutates) => {
|
|
37
|
+
let release;
|
|
38
|
+
try {
|
|
39
|
+
release = await admit();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return failure('runtime_not_ready', 'the managed runtime is not admitting tool calls right now; nothing was read or changed');
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const target = backend();
|
|
46
|
+
if (!target)
|
|
47
|
+
return failure('reminders_unavailable', 'self-reminders are not available in this session (the supervisor has not bound them, or this session cannot take scheduled prompts)');
|
|
48
|
+
try {
|
|
49
|
+
const value = operation(target);
|
|
50
|
+
if (mutates)
|
|
51
|
+
target.changed();
|
|
52
|
+
return result(value);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof ReminderError)
|
|
56
|
+
return failure(error.code, error.message);
|
|
57
|
+
return failure('reminder_store_failed', 'the reminder could not be recorded; nothing was changed');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
release();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
server.registerTool('fleet_reminder_create', {
|
|
65
|
+
description: 'Schedule a one-time reminder that wakes YOU (this agent) at a future date and time. '
|
|
66
|
+
+ 'It sends nothing to anyone: when due, Fleet starts a turn for you with the reminder, and you decide what to do. '
|
|
67
|
+
+ 'Use it to come back to something later instead of polling or waiting. Repeating a call with the same request_key '
|
|
68
|
+
+ 'and input returns the existing reminder instead of creating another.',
|
|
69
|
+
inputSchema: {
|
|
70
|
+
request_key: z.string().describe('Stable key for this scheduling decision, so a retried call cannot create a duplicate (e.g. "release-check-2027-01-20").'),
|
|
71
|
+
title: z.string().describe('Short label shown in the wake (max 200 characters).'),
|
|
72
|
+
note: z.string().optional().describe('Private context for your future self: what to check and why (max 4000 characters). Returned by inspect, not in the wake text.'),
|
|
73
|
+
...schedule,
|
|
74
|
+
},
|
|
75
|
+
}, async (args) => run(({ store }) => store.create(args.request_key, args), true));
|
|
76
|
+
server.registerTool('fleet_reminder_list', {
|
|
77
|
+
description: 'List your own reminders. state: "open" (default: scheduled or delivered but not acknowledged), "closed", or "all". '
|
|
78
|
+
+ 'Pages with limit (1..100, default 50) and after (the id from the previous page).',
|
|
79
|
+
inputSchema: {
|
|
80
|
+
state: z.enum(['open', 'closed', 'all']).optional(),
|
|
81
|
+
limit: z.number().int().optional(),
|
|
82
|
+
after: z.string().optional(),
|
|
83
|
+
},
|
|
84
|
+
}, async (args) => run(({ store }) => store.list(args), false));
|
|
85
|
+
server.registerTool('fleet_reminder_update', {
|
|
86
|
+
description: 'Change one of your reminders, e.g. to postpone it. Pass the id and the revision you last saw '
|
|
87
|
+
+ '(expected_revision) plus only the fields to change. Any wake already issued for the old revision becomes void.',
|
|
88
|
+
inputSchema: {
|
|
89
|
+
id: z.string(),
|
|
90
|
+
expected_revision: z.number().int(),
|
|
91
|
+
title: z.string().optional(),
|
|
92
|
+
note: z.string().optional(),
|
|
93
|
+
local_time: schedule.local_time.optional(),
|
|
94
|
+
time_zone: schedule.time_zone.optional(),
|
|
95
|
+
fold: schedule.fold,
|
|
96
|
+
late_window_seconds: schedule.late_window_seconds,
|
|
97
|
+
interrupt: schedule.interrupt,
|
|
98
|
+
},
|
|
99
|
+
}, async ({ id, expected_revision, ...changes }) => run(({ store }) => store.update(id, expected_revision, changes), true));
|
|
100
|
+
server.registerTool('fleet_reminder_cancel', {
|
|
101
|
+
description: 'Cancel one of your reminders (id + expected_revision). A wake already waiting for it will not be delivered.',
|
|
102
|
+
inputSchema: { id: z.string(), expected_revision: z.number().int() },
|
|
103
|
+
}, async ({ id, expected_revision }) => run(({ store }) => store.cancel(id, expected_revision), true));
|
|
104
|
+
server.registerTool('fleet_reminder_inspect', {
|
|
105
|
+
description: 'Read the reminder behind a [fleet-reminder] wake, including its note, whether the wake is still current and eligible, '
|
|
106
|
+
+ 'and for an urgent reminder what its interruption request did (interrupt.state).',
|
|
107
|
+
inputSchema: { event_id: z.string() },
|
|
108
|
+
}, async ({ event_id }) => run(({ store }) => store.inspect(event_id), false));
|
|
109
|
+
server.registerTool('fleet_reminder_ack', {
|
|
110
|
+
description: 'Record that you handled a [fleet-reminder] wake (event_id + revision from the wake). '
|
|
111
|
+
+ 'It closes the reminder and sends nothing; it does not claim any external action happened. Safe to repeat.',
|
|
112
|
+
inputSchema: { event_id: z.string(), expected_revision: z.number().int() },
|
|
113
|
+
}, async ({ event_id, expected_revision }) => run(({ store }) => store.ack(event_id, expected_revision), true));
|
|
114
|
+
}
|
package/dist/resolved-plan.js
CHANGED
|
@@ -103,6 +103,7 @@ export function resolvedRolePlan(role, manifestDir = dirname(role.sourceFile)) {
|
|
|
103
103
|
isolation: role.isolation ?? null,
|
|
104
104
|
worklog: role.worklog ?? null,
|
|
105
105
|
authProxy: role.auth_proxy ?? null,
|
|
106
|
+
managedCli: role.managed_cli ?? [],
|
|
106
107
|
oversee: role.oversee ?? [],
|
|
107
108
|
harnessOptions: redactSensitive(role.harness_options ?? null),
|
|
108
109
|
env: {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FleetConfig } from '../config.js';
|
|
2
|
+
import { TaskStateError } from './task-state.js';
|
|
3
|
+
import { provisionMembers } from './provision.js';
|
|
4
|
+
import type { CoworkAdapter } from './cowork-adapter.js';
|
|
5
|
+
export declare class MemberAdditionRejected extends TaskStateError {
|
|
6
|
+
readonly accepted = false;
|
|
7
|
+
}
|
|
8
|
+
export interface AddMemberRequest {
|
|
9
|
+
requestId: string;
|
|
10
|
+
slot: string;
|
|
11
|
+
role: string;
|
|
12
|
+
brain: string;
|
|
13
|
+
agentTemplate: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function memberAddition(taskId: string, requestId: string): {
|
|
16
|
+
requestId: string;
|
|
17
|
+
taskId: string;
|
|
18
|
+
roleId: string;
|
|
19
|
+
state: "running" | "succeeded" | "attention" | "failed";
|
|
20
|
+
error?: string;
|
|
21
|
+
} | {
|
|
22
|
+
state: string;
|
|
23
|
+
error: string;
|
|
24
|
+
requestId: string;
|
|
25
|
+
taskId: string;
|
|
26
|
+
roleId: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function requestMemberAddition(input: {
|
|
29
|
+
taskId: string;
|
|
30
|
+
request: AddMemberRequest;
|
|
31
|
+
cfg: FleetConfig;
|
|
32
|
+
cowork: CoworkAdapter;
|
|
33
|
+
configPath?: string;
|
|
34
|
+
binPath: string;
|
|
35
|
+
provision?: typeof provisionMembers;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
requestId: string;
|
|
38
|
+
taskId: string;
|
|
39
|
+
roleId: string;
|
|
40
|
+
state: "running" | "succeeded" | "attention" | "failed";
|
|
41
|
+
error?: string;
|
|
42
|
+
} | {
|
|
43
|
+
state: string;
|
|
44
|
+
error: string;
|
|
45
|
+
requestId: string;
|
|
46
|
+
taskId: string;
|
|
47
|
+
roleId: string;
|
|
48
|
+
}>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { publishFleetResourceCommit } from '../application/resource-observer.js';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { replaceFileAtomically, withFileLock } from '../atomic-file.js';
|
|
6
|
+
import { canonicalJson } from '../canonical-json.js';
|
|
7
|
+
import { stateRoot } from '../paths.js';
|
|
8
|
+
import { getTask, TaskStateError } from './task-state.js';
|
|
9
|
+
import { getRoomRecord } from './room-state.js';
|
|
10
|
+
import { prepareExecutionPlan } from './member-overrides.js';
|
|
11
|
+
import { sealTemplateSnapshot } from './templates.js';
|
|
12
|
+
import { provisionMembers } from './provision.js';
|
|
13
|
+
export class MemberAdditionRejected extends TaskStateError {
|
|
14
|
+
accepted = false;
|
|
15
|
+
}
|
|
16
|
+
const running = new Set();
|
|
17
|
+
function pathFor(taskId, requestId) {
|
|
18
|
+
if (!/^[a-z0-9]{10,40}$/.test(taskId) || !/^[a-zA-Z0-9_-]{8,80}$/.test(requestId))
|
|
19
|
+
throw new TaskStateError('Invalid task or request ID');
|
|
20
|
+
return join(stateRoot(), 'member-additions', taskId, requestId + '.json');
|
|
21
|
+
}
|
|
22
|
+
export function memberAddition(taskId, requestId) {
|
|
23
|
+
getTask(taskId);
|
|
24
|
+
const path = pathFor(taskId, requestId);
|
|
25
|
+
if (!existsSync(path))
|
|
26
|
+
throw new TaskStateError('Member request not found');
|
|
27
|
+
const receipt = JSON.parse(readFileSync(path, 'utf8'));
|
|
28
|
+
const { hash, ...view } = receipt;
|
|
29
|
+
return receipt.state === 'running' && !running.has(path) ? { ...view, state: 'attention', error: 'The server stopped observing this launch. Inspect the existing agent before any recovery.' } : view;
|
|
30
|
+
}
|
|
31
|
+
export async function requestMemberAddition(input) {
|
|
32
|
+
const { request: r, taskId } = input;
|
|
33
|
+
if (!r || typeof r.slot !== 'string' || !/^[A-Za-z][A-Za-z0-9_-]{0,31}$/.test(r.slot)
|
|
34
|
+
|| ![r.role, r.brain, r.agentTemplate].every(v => typeof v === 'string' && v.length > 0 && v.length <= 128))
|
|
35
|
+
// No receipt lookup has happened yet: this request ID may already be accepted.
|
|
36
|
+
throw new TaskStateError('Slot, Role, Brain and Agent Template are required');
|
|
37
|
+
const path = pathFor(taskId, r.requestId);
|
|
38
|
+
const hash = createHash('sha256').update(canonicalJson(r)).digest('hex');
|
|
39
|
+
mkdirSync(join(stateRoot(), 'member-additions', taskId), { recursive: true, mode: 0o700 });
|
|
40
|
+
return withFileLock(path + '.lock', async () => {
|
|
41
|
+
if (existsSync(path)) {
|
|
42
|
+
const old = JSON.parse(readFileSync(path, 'utf8'));
|
|
43
|
+
if (old.hash !== hash)
|
|
44
|
+
throw new TaskStateError('Request ID was already used with different settings');
|
|
45
|
+
return memberAddition(taskId, r.requestId);
|
|
46
|
+
}
|
|
47
|
+
const task = getTask(taskId);
|
|
48
|
+
const room = task.room_id && getRoomRecord(task.room_id);
|
|
49
|
+
if (!room || !['active', 'review'].includes(task.state) || task.terminal_intent || room.state !== 'active'
|
|
50
|
+
|| room.task_id !== taskId || room.room_identity_cid !== task.room_identity_cid)
|
|
51
|
+
throw new MemberAdditionRejected('Adding an agent requires an active task room');
|
|
52
|
+
const roleId = `${taskId.slice(0, 8)}-${r.slot}-1`;
|
|
53
|
+
if (room.member_seats.some(s => s.role_name === roleId))
|
|
54
|
+
throw new MemberAdditionRejected('This member slot already exists');
|
|
55
|
+
const plan = (() => {
|
|
56
|
+
try {
|
|
57
|
+
return prepareExecutionPlan({ name: 'additional-member', version: 1, description: 'Additional task participant',
|
|
58
|
+
contract: room.template_snapshot?.contract, members: [{ slot: r.slot, role: r.role, count: 1, agent_template: r.agentTemplate }] }, input.cfg, { [r.slot]: { role: r.role, brain: r.brain } });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new MemberAdditionRejected(error instanceof Error ? error.message : 'Invalid member configuration');
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
const template = sealTemplateSnapshot(plan.snapshot, input.cfg.agentTemplates ?? {}, plan.launchDefinitions);
|
|
65
|
+
const receipt = { taskId, requestId: r.requestId, roleId, hash, state: 'running' };
|
|
66
|
+
const save = () => { replaceFileAtomically(path, JSON.stringify(receipt) + '\n', 0o600); publishFleetResourceCommit(path); };
|
|
67
|
+
save();
|
|
68
|
+
running.add(path);
|
|
69
|
+
void (input.provision ?? provisionMembers)({ cfg: input.cfg, cowork: input.cowork, configPath: input.configPath, binPath: input.binPath,
|
|
70
|
+
taskId, roomId: room.room_id, template, goal: task.title, brief: task.brief, append: true }).then(result => {
|
|
71
|
+
const seat = result.member_seats.find(s => s.role_name === roleId);
|
|
72
|
+
receipt.state = seat?.seat_state === 'active' && getTask(taskId).member_roles.some(m => m.name === roleId) ? 'succeeded' : 'attention';
|
|
73
|
+
if (receipt.state === 'attention')
|
|
74
|
+
receipt.error = 'Admission is not confirmed. Inspect the existing launch; no automatic retry was made.';
|
|
75
|
+
}).catch(() => { receipt.state = 'failed'; receipt.error = 'Member launch failed. Inspect the task and agent logs before recovery.'; })
|
|
76
|
+
.finally(() => { try {
|
|
77
|
+
save();
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
running.delete(path);
|
|
81
|
+
} }).catch(() => { running.delete(path); });
|
|
82
|
+
return memberAddition(taskId, r.requestId);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ArchivedMemberAbsence, RoomMemberSeat } from './types.js';
|
|
2
2
|
/** Revalidate live facts; a persisted timestamp is never cleanup authority. */
|
|
3
3
|
export declare function verifyArchivedAbsence(proof: ArchivedMemberAbsence): Promise<void>;
|
|
4
|
+
/** After the verified archive has been consumed by explicit workspace deletion,
|
|
5
|
+
* still fence replacement live state and a recreated daemon identity on every retry.
|
|
6
|
+
*/
|
|
7
|
+
export declare function verifyArchivedMemberStillAbsent(proof: ArchivedMemberAbsence): Promise<void>;
|
|
4
8
|
export declare function proveArchivedAbsence(seat: RoomMemberSeat): Promise<ArchivedMemberAbsence>;
|
|
@@ -18,6 +18,17 @@ export async function verifyArchivedAbsence(proof) {
|
|
|
18
18
|
throw new Error('Archived member absence ownership proof mismatch');
|
|
19
19
|
if (await tempSupervisorLiveness(archive) !== 'stopped')
|
|
20
20
|
throw new Error('Archived member supervisor absence is not proven');
|
|
21
|
+
await verifyArchivedMemberStillAbsent(proof);
|
|
22
|
+
}
|
|
23
|
+
/** After the verified archive has been consumed by explicit workspace deletion,
|
|
24
|
+
* still fence replacement live state and a recreated daemon identity on every retry.
|
|
25
|
+
*/
|
|
26
|
+
export async function verifyArchivedMemberStillAbsent(proof) {
|
|
27
|
+
const absent = () => {
|
|
28
|
+
if (existsSync(agentDir(proof.name, true)))
|
|
29
|
+
throw new Error('Archived member has replacement live state');
|
|
30
|
+
};
|
|
31
|
+
absent();
|
|
21
32
|
await assertMemberIdentityAbsent({
|
|
22
33
|
role_name: proof.name, slot: 'archived', cowork_role: 'archived', seat_state: 'removed',
|
|
23
34
|
});
|
package/dist/rooms-tasks/cli.js
CHANGED
|
@@ -75,6 +75,11 @@ async function presentDetachedProvisioningOutcome(outcome) {
|
|
|
75
75
|
function taskRoomPublicFailure(error) {
|
|
76
76
|
const f = error.fields;
|
|
77
77
|
switch (error.code) {
|
|
78
|
+
case 'task_not_ready': return {
|
|
79
|
+
legacy: `task readiness ${f.readiness}: ${f.reason}`, kind: 'state',
|
|
80
|
+
detail: `Task ${f.task} readiness is ${f.readiness}: ${f.reason}${f.member ? ` (${f.member})` : ''}.`,
|
|
81
|
+
action: 'Ask Fleet Coordinator to inspect room and member status and choose supported recovery. Do not blindly relaunch agents or reuse invites.',
|
|
82
|
+
};
|
|
78
83
|
case 'task_confirmation_mismatch': return {
|
|
79
84
|
legacy: 'confirmation ID must match task ID', kind: 'usage',
|
|
80
85
|
detail: 'The two task IDs must match.', action: 'Repeat the same task ID twice.',
|
|
@@ -242,6 +247,8 @@ const taskListMarkdown = (tasks, title = 'Tasks') => renderMarkdownList({
|
|
|
242
247
|
icon: '📋', title, empty: 'No tasks found.',
|
|
243
248
|
records: tasks.map(t => `${taskStatus(t.state)} ${markdownCode(t.task_id)} — ${markdownProse(t.title)}`
|
|
244
249
|
+ ` — List ${markdownCode(t.list_name ?? 'default')}`
|
|
250
|
+
+ (t.deletion?.status === 'pending' ? ' — Deletion pending'
|
|
251
|
+
+ (t.deletion.error ? `: ${markdownProse(t.deletion.error)}` : '') : '')
|
|
245
252
|
+ (t.blocked ? ` — 🚧 Blocked: ${markdownProse(t.blocked.reason)}` : '')),
|
|
246
253
|
});
|
|
247
254
|
const taskActionMarkdown = (title, task, fields = []) => {
|
|
@@ -515,10 +522,10 @@ function taskRoomService(configuration) {
|
|
|
515
522
|
function allTemplates(cfg) {
|
|
516
523
|
return cfg.roomTemplates ?? {};
|
|
517
524
|
}
|
|
518
|
-
function coworkFor(cfg) {
|
|
525
|
+
function coworkFor(cfg, options) {
|
|
519
526
|
if (!cfg.rooms)
|
|
520
527
|
throw new ConfigError('rooms: configuration is required before creating or querying rooms');
|
|
521
|
-
return createCoworkAdapter({ configPath: cfg.rooms.cowork?.config });
|
|
528
|
+
return createCoworkAdapter({ configPath: cfg.rooms.cowork?.config, ...options });
|
|
522
529
|
}
|
|
523
530
|
function resolveRoomTemplate(cfg, name) {
|
|
524
531
|
if (!name)
|
|
@@ -709,6 +716,7 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
709
716
|
.option('--state <state>', 'filter by state (backlog|active|provisioning|review|done|cancelled|failed|all)')
|
|
710
717
|
.option('--list <name>', 'filter by task list')
|
|
711
718
|
.option('--group-by-list', 'group deterministic results by list (JSON)')
|
|
719
|
+
.option('--include-deleting', 'include tasks whose accepted deletion is still pending')
|
|
712
720
|
.option('--json', 'JSON output')
|
|
713
721
|
.action(async (opts) => {
|
|
714
722
|
try {
|
|
@@ -717,7 +725,8 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
717
725
|
stateFilter = opts.state;
|
|
718
726
|
}
|
|
719
727
|
const service = taskRoomService(opts.configuration);
|
|
720
|
-
const filter = { ...(stateFilter ? { state: stateFilter } : {}), ...(opts.list ? { list: opts.list } : {})
|
|
728
|
+
const filter = { ...(stateFilter ? { state: stateFilter } : {}), ...(opts.list ? { list: opts.list } : {}),
|
|
729
|
+
...(opts.includeDeleting ? { includeDeleting: true } : {}) };
|
|
721
730
|
const tasks = service.listTasks(filter);
|
|
722
731
|
if (opts.json) {
|
|
723
732
|
console.log(JSON.stringify(opts.groupByList
|
|
@@ -827,16 +836,19 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
827
836
|
dieTaskRoom(e);
|
|
828
837
|
}
|
|
829
838
|
});
|
|
830
|
-
taskCmd.command('show <id>')
|
|
839
|
+
cOpt(taskCmd.command('show <id>'))
|
|
831
840
|
.description('show task details')
|
|
832
841
|
.option('--json', 'JSON output')
|
|
833
842
|
.action(async (id, opts) => {
|
|
834
843
|
try {
|
|
835
|
-
const service = taskRoomService();
|
|
844
|
+
const service = taskRoomService(opts.configuration);
|
|
836
845
|
const { task: t, orchestration: room } = service.getTask(id);
|
|
846
|
+
const readiness = t.state === 'active' && t.deletion?.status !== 'pending'
|
|
847
|
+
? await service.observeTaskReadiness(id) : undefined;
|
|
837
848
|
if (opts.json) {
|
|
838
849
|
console.log(JSON.stringify({
|
|
839
850
|
schema_version: 1, task: t, orchestration: room ?? null,
|
|
851
|
+
...(readiness ? { readiness } : {}),
|
|
840
852
|
}, null, 2));
|
|
841
853
|
return;
|
|
842
854
|
}
|
|
@@ -846,6 +858,13 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
846
858
|
{ label: 'ID', value: t.task_id, kind: 'code' },
|
|
847
859
|
{ label: 'Title', value: t.title },
|
|
848
860
|
{ label: 'Status', value: taskStatus(t.state), kind: 'markdown' },
|
|
861
|
+
...(t.deletion?.status === 'pending' ? [
|
|
862
|
+
{ label: 'Deletion', value: 'Pending — cleanup is not complete' },
|
|
863
|
+
...(t.deletion.error ? [{ label: 'Cleanup error', value: t.deletion.error }] : []),
|
|
864
|
+
{ label: 'Retry', value: `ours-fleet task delete ${t.task_id} ${t.task_id}`, kind: 'code' },
|
|
865
|
+
] : []),
|
|
866
|
+
...(readiness ? [{ label: 'Readiness', value: readiness.state },
|
|
867
|
+
...('reason' in readiness ? [{ label: 'Reason', value: readiness.reason }] : [])] : []),
|
|
849
868
|
...(t.blocked ? [{ label: 'Blocked', value: t.blocked.reason }] : []),
|
|
850
869
|
...(t.template ? [{ label: 'Template', value: `${t.template.name}@${t.template.version}`, kind: 'code' }] : []),
|
|
851
870
|
...(t.room_id ? [{ label: 'Room', value: t.room_id, kind: 'code' }] : []),
|
|
@@ -872,6 +891,27 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
872
891
|
dieTaskRoom(e);
|
|
873
892
|
}
|
|
874
893
|
});
|
|
894
|
+
cOpt(taskCmd.command('recover-members <id>'))
|
|
895
|
+
.description('resume proven stopped task members in-place; never create identities or replay invites')
|
|
896
|
+
.option('--json', 'JSON output')
|
|
897
|
+
.action(async (id, opts) => {
|
|
898
|
+
try {
|
|
899
|
+
const { recoverTaskMembers } = await import('./recovery.js');
|
|
900
|
+
const task = getTask(id), cfg = loadConfig(opts.configuration);
|
|
901
|
+
const members = await recoverTaskMembers({ taskId: id, binPath: getBinPath(),
|
|
902
|
+
cowork: task.layout ? undefined : createCoworkAdapter({ configPath: cfg.rooms?.cowork?.config }) });
|
|
903
|
+
if (opts.json)
|
|
904
|
+
console.log(JSON.stringify({ schema_version: 1, task_id: id, members }, null, 2));
|
|
905
|
+
else
|
|
906
|
+
for (const member of members)
|
|
907
|
+
console.log(`${member.name}: ${member.status}`);
|
|
908
|
+
}
|
|
909
|
+
catch (e) {
|
|
910
|
+
if (opts.json)
|
|
911
|
+
die(e);
|
|
912
|
+
dieTaskRoom(e);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
875
915
|
cOpt(taskCmd.command('start <id>'))
|
|
876
916
|
.description('idempotently select a plan, provision, and start a task')
|
|
877
917
|
.option('--template <name>', 'room template')
|
|
@@ -1176,6 +1216,26 @@ export function registerTaskCommands(parent, cOpt) {
|
|
|
1176
1216
|
dieTaskRoom(e);
|
|
1177
1217
|
}
|
|
1178
1218
|
});
|
|
1219
|
+
cOpt(taskCmd.command('_layout <id> <operation> [room]', { hidden: true }))
|
|
1220
|
+
.description('internal: run an accepted layout room operation (open, close-room, close)')
|
|
1221
|
+
.option('--json', 'JSON output')
|
|
1222
|
+
.option('--operation-id <id>', 'accepted operation ID; status updates apply only while it is current')
|
|
1223
|
+
.action(async (id, operation, room, opts) => {
|
|
1224
|
+
try {
|
|
1225
|
+
if (!['open', 'close-room', 'close'].includes(operation))
|
|
1226
|
+
throw new Error(`unknown layout operation: ${operation}`);
|
|
1227
|
+
const view = await taskRoomService(opts.configuration).runTaskLayoutOperation({
|
|
1228
|
+
actor: { kind: 'internal_worker', surface: 'cli' }, taskId: id,
|
|
1229
|
+
operation: operation, room, operationId: opts.operationId,
|
|
1230
|
+
});
|
|
1231
|
+
console.log(JSON.stringify({ schema_version: 1, layout: view }, null, 2));
|
|
1232
|
+
}
|
|
1233
|
+
catch (e) {
|
|
1234
|
+
if (opts.json)
|
|
1235
|
+
die(e);
|
|
1236
|
+
dieTaskRoom(e);
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1179
1239
|
cOpt(taskCmd.command('_settle_delete <id>', { hidden: true }))
|
|
1180
1240
|
.description('internal: settle a previously accepted task deletion')
|
|
1181
1241
|
.option('--json', 'JSON output')
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { retireTaskMemberService } from './task-service-retirement.js';
|
|
1
2
|
import { withFileLock } from '../atomic-file.js';
|
|
2
3
|
import { type TempLifecycleDeps } from '../temp-lifecycle.js';
|
|
3
4
|
import { type CoworkAdapter } from './cowork-adapter.js';
|
|
4
5
|
import type { RoomMemberSeat, RoomOrchestrationRecord } from './types.js';
|
|
6
|
+
export declare const CLOSE_LOCK_STALE_MS: number;
|
|
5
7
|
export declare function roomCloseLockPath(roomId: string): string;
|
|
6
8
|
export interface RoomCloseDeps {
|
|
9
|
+
retireTaskService?: typeof retireTaskMemberService;
|
|
7
10
|
inspectMember?(seat: RoomMemberSeat): Promise<{
|
|
8
11
|
launchId: string;
|
|
9
12
|
}>;
|
|
@@ -26,7 +29,7 @@ export declare function acceptManagedRoomClose(roomId: string): Promise<RoomOrch
|
|
|
26
29
|
export declare function recordManagedRoomCloseError(roomId: string, error: string, recoveryHint: string): Promise<RoomOrchestrationRecord>;
|
|
27
30
|
export declare function closeManagedRoom(input: {
|
|
28
31
|
roomId: string;
|
|
29
|
-
cowork: Pick<CoworkAdapter, 'closeRoom'
|
|
32
|
+
cowork: Pick<CoworkAdapter, 'closeRoom'> & Partial<Pick<CoworkAdapter, 'getRoom'>>;
|
|
30
33
|
deps?: RoomCloseDeps;
|
|
31
34
|
}): Promise<RoomOrchestrationRecord>;
|
|
32
35
|
export interface ManagedRoomDeleteResult {
|
|
@@ -40,6 +43,6 @@ export declare function deleteLegacyClosedRooms(input: {
|
|
|
40
43
|
/** Retire live resources through the existing cursor, then delete retained state. */
|
|
41
44
|
export declare function deleteManagedRoom(input: {
|
|
42
45
|
roomId: string;
|
|
43
|
-
cowork: Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'
|
|
46
|
+
cowork: Pick<CoworkAdapter, 'closeRoom' | 'deleteRoom'> & Partial<Pick<CoworkAdapter, 'getRoom'>>;
|
|
44
47
|
deps?: RoomCloseDeps;
|
|
45
48
|
}): Promise<ManagedRoomDeleteResult>;
|