@ours.network/fleet 1.2.0-nightly.9 → 2.0.1
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 +280 -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 +22 -0
- package/dist/agent-ours/mcp-endpoint.js +101 -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 +27 -1
- package/dist/agent-ours/service.js +107 -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 +31 -0
- package/dist/application/conversation-history.js +339 -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 +3 -1
- package/dist/application/role-repository.js +89 -54
- 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 +5 -1
- package/dist/briefing.js +138 -31
- package/dist/build-info.json +10 -5
- package/dist/capabilities.d.ts +9 -1
- package/dist/capabilities.js +13 -0
- package/dist/cli.js +391 -38
- 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 +402 -20
- 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 +13 -0
- package/dist/fleet-command-audit.js +31 -9
- 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 +55 -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 +182 -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 +66 -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-review.d.ts +113 -0
- package/dist/rooms-tasks/task-review.js +561 -0
- 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 -5
- package/dist/rooms-tasks/task-state.js +358 -50
- package/dist/rooms-tasks/task-tools.d.ts +35 -0
- package/dist/rooms-tasks/task-tools.js +134 -0
- package/dist/rooms-tasks/types.d.ts +78 -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 +23 -4
- package/dist/runner.js +409 -61
- 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 +20 -1
- package/dist/startup-readiness.js +66 -3
- 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 +18 -37
- 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 +138 -0
- package/dist/web/resource-views.js +519 -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 +893 -71
- 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-progress-review.md +143 -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 +25 -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 +6 -3
- 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 +21 -13
- package/presets/fleet/roles/Critic.yaml +24 -0
- package/presets/fleet/roles/Developer.yaml +32 -0
- package/presets/fleet/roles/Engineer.yaml +72 -0
- package/presets/fleet/roles/LocalCoordinator.yaml +17 -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
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { assertNativeFleetScope } from './scope.js';
|
|
2
|
+
import { clientConfigPath } from '../client-profile.js';
|
|
1
3
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
4
|
import { delimiter, dirname, join } from 'node:path';
|
|
3
5
|
import { userInfo } from 'node:os';
|
|
4
6
|
import { home } from '../paths.js';
|
|
5
7
|
import { realExec } from '../exec.js';
|
|
6
|
-
export const UNIT_TEMPLATE = 'ours-fleet
|
|
8
|
+
export const UNIT_TEMPLATE = 'ours-fleet.service';
|
|
7
9
|
/**
|
|
8
10
|
* Actionable hint when systemctl cannot reach the user bus. After the cli.ts
|
|
9
11
|
* XDG_RUNTIME_DIR fallback this branch stays reachable only when
|
|
@@ -14,7 +16,7 @@ export const busHint = (stderr) => /user scope bus|XDG_RUNTIME_DIR/.test(stderr)
|
|
|
14
16
|
? `\nhint: no user runtime dir — enable linger: sudo loginctl enable-linger ${userInfo().username}` +
|
|
15
17
|
`\n (if linger is already on: export XDG_RUNTIME_DIR=/run/user/$(id -u))`
|
|
16
18
|
: '';
|
|
17
|
-
export const unitFor = (
|
|
19
|
+
export const unitFor = (_name) => UNIT_TEMPLATE;
|
|
18
20
|
/** Quote a systemd unit argument and escape its specifier marker. */
|
|
19
21
|
const unitArg = (value) => `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/%/g, '%%')}"`;
|
|
20
22
|
/**
|
|
@@ -56,10 +58,11 @@ async function probeLiveness(ctl, name) {
|
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
export function makeSystemdBackend(exec = realExec) {
|
|
59
|
-
const ctl = (...args) => exec('systemctl', ['--user', ...args]);
|
|
61
|
+
const ctl = (...args) => { assertNativeFleetScope(exec); return exec('systemctl', ['--user', ...args]); };
|
|
60
62
|
return {
|
|
61
63
|
id: 'systemd',
|
|
62
64
|
async init(binPath) {
|
|
65
|
+
assertNativeFleetScope(exec);
|
|
63
66
|
const msgs = [];
|
|
64
67
|
const unitDir = join(home(), '.config', 'systemd', 'user');
|
|
65
68
|
// Lingering user units often start before a login shell imports its PATH.
|
|
@@ -69,54 +72,32 @@ export function makeSystemdBackend(exec = realExec) {
|
|
|
69
72
|
dirname(process.execPath),
|
|
70
73
|
...(process.env.PATH ?? '').split(delimiter),
|
|
71
74
|
].filter(Boolean))].join(delimiter);
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
// ours-fleet resolves its daemon from OURS_CONFIG / OURS_PORT / OURS_STATE_DIR
|
|
76
|
-
// and otherwise falls back to ~/.ours and port 3050 (src/monitor.ts). A host
|
|
77
|
-
// set up against a non-default daemon — the installer's multi-daemon profiles
|
|
78
|
-
// do exactly this — passes that selection to `ours-fleet init` in the
|
|
79
|
-
// environment, and it died there: nothing persisted it, so every runner
|
|
80
|
-
// systemd started at boot resolved the default daemon again, and on a host
|
|
81
|
-
// where only the non-default daemon exists that is a daemon that is not there.
|
|
82
|
-
//
|
|
83
|
-
// ONLY OURS_CONFIG is baked, deliberately. It names which daemon, and leaves
|
|
84
|
-
// that daemon's own config file authoritative for port and state directory, so
|
|
85
|
-
// a later edit to it still wins. Baking OURS_PORT/OURS_STATE_DIR would freeze
|
|
86
|
-
// those into a unit file that outranks the config for ever after — the failure
|
|
87
|
-
// mode @ours.network/cli avoids for the same reason (packages/cli/src/
|
|
88
|
-
// service.ts: "The port is deliberately NOT baked").
|
|
89
|
-
//
|
|
90
|
-
// Absent from init's environment ⇒ no line, and the unit is byte-for-byte what
|
|
91
|
-
// it has always been. This teaches fleet nothing about installer profiles; it
|
|
92
|
-
// persists the selection fleet was initialised with.
|
|
75
|
+
// Persist one profile path, never a URL or service port. Profile updates
|
|
76
|
+
// are picked up by every fresh process, including lingering user services.
|
|
93
77
|
const unitEnv = ['PATH=' + servicePath];
|
|
94
|
-
|
|
95
|
-
|
|
78
|
+
unitEnv.push('OURS_CONFIG=' + clientConfigPath(process.env));
|
|
79
|
+
for (const key of ['OURS_FLEET_HOME', 'OURS_FLEET_SOCKET_ROOT', 'CODEX_HOME', 'CODEX_PATH']) {
|
|
80
|
+
if (process.env[key] !== undefined)
|
|
81
|
+
unitEnv.push(key + '=' + process.env[key]);
|
|
82
|
+
}
|
|
96
83
|
const environmentLines = unitEnv
|
|
97
84
|
.map(value => `Environment="${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/%/g, '%%')}"`)
|
|
98
85
|
.join('\n');
|
|
99
86
|
mkdirSync(unitDir, { recursive: true });
|
|
100
87
|
writeFileSync(join(unitDir, UNIT_TEMPLATE), `[Unit]
|
|
101
|
-
Description=ours-fleet
|
|
88
|
+
Description=ours-fleet process manager
|
|
102
89
|
After=default.target
|
|
103
90
|
StartLimitIntervalSec=0
|
|
104
91
|
|
|
105
92
|
[Service]
|
|
106
93
|
Type=simple
|
|
107
94
|
${environmentLines}
|
|
108
|
-
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
TimeoutStartSec=270
|
|
112
|
-
ExecStart=${unitArg(process.execPath)} ${unitArg(binPath)} _run %i
|
|
113
|
-
# The RUNNER owns the child-session restart loop, with a counted, backed-off
|
|
114
|
-
# circuit breaker. systemd must only recover the runner PROCESS crashing —
|
|
115
|
-
# Restart=always here would resume the uncounted two-second relaunch loop, and
|
|
116
|
-
# would also restart a runner that is deliberately holding a failing agent down.
|
|
95
|
+
ExecStart=${unitArg(process.execPath)} ${unitArg(binPath)} _run-fleet
|
|
96
|
+
# Fleet owns agent startup and restart; the OS recovers only the Fleet parent.
|
|
97
|
+
KillMode=control-group
|
|
117
98
|
Restart=on-failure
|
|
118
99
|
RestartSec=5
|
|
119
|
-
TimeoutStopSec=
|
|
100
|
+
TimeoutStopSec=25
|
|
120
101
|
|
|
121
102
|
[Install]
|
|
122
103
|
WantedBy=default.target
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Read-only ownership fence: absence/mismatch never permits a new identity or launch. */
|
|
2
|
+
export declare function taskSupervisorMayRun(name: string): boolean;
|
|
3
|
+
/** Resolve the externally recorded CID/action for explicit terminal retirement.
|
|
4
|
+
* Run only after the same launch passed taskSupervisorMayRun's ownership fence.
|
|
5
|
+
* An unpublished failed launch stays for its seat's retry/retirement saga. */
|
|
6
|
+
export declare function taskMemberRetirementProof(name: string): {
|
|
7
|
+
cid: string;
|
|
8
|
+
action: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readFileSync, lstatSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
|
+
import { agentDir, stateRoot } from './paths.js';
|
|
5
|
+
import { readTempSupervisor } from './temp-lifecycle.js';
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
import { readProvenance } from './creation.js';
|
|
8
|
+
import { getTask } from './rooms-tasks/task-state.js';
|
|
9
|
+
import { getRoomRecord } from './rooms-tasks/room-state.js';
|
|
10
|
+
import { assertWorkspacePresent } from './rooms-tasks/workspace.js';
|
|
11
|
+
import { privateRuntimeRoot } from './agent-ours/service.js';
|
|
12
|
+
import { binderKey, RuntimeJournal } from './agent-ours/state.js';
|
|
13
|
+
import { assertMemberNotPermanent } from './rooms-tasks/member-ownership.js';
|
|
14
|
+
import { readClientProfile } from './client-profile.js';
|
|
15
|
+
import { firstManagedSessionMayStart } from './managed-recovery.js';
|
|
16
|
+
function readProof(path) {
|
|
17
|
+
const stat = lstatSync(path);
|
|
18
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 256 * 1024)
|
|
19
|
+
throw Error('TASK_SUPERVISOR_UNSAFE_PROOF');
|
|
20
|
+
return readFileSync(path, 'utf8');
|
|
21
|
+
}
|
|
22
|
+
/** An admitted task member must resume its retained instance, never allocate a successor. */
|
|
23
|
+
function assertRetainedRuntime(role, action, cid, launch, session) {
|
|
24
|
+
const profile = readClientProfile({ ...process.env, ...role.env });
|
|
25
|
+
if (!profile)
|
|
26
|
+
throw Error('TASK_RUNTIME_PROFILE_MISSING');
|
|
27
|
+
const dir = join(privateRuntimeRoot(), binderKey(profile.expectedInstanceId, role.identity));
|
|
28
|
+
const instance = JSON.parse(readProof(join(dir, 'instance.json')));
|
|
29
|
+
const owner = JSON.parse(readProof(join(dir, 'owner.json')));
|
|
30
|
+
const pin = JSON.parse(readProof(join(dir, 'identity-pin.json')));
|
|
31
|
+
readProof(join(dir, 'state.json'));
|
|
32
|
+
const state = new RuntimeJournal(dir).read();
|
|
33
|
+
const creation = JSON.parse(readProof(join(privateRuntimeRoot(), 'launches', binderKey('temporary', role.name) + '.json')));
|
|
34
|
+
const sessionDir = agentDir(role.name, true);
|
|
35
|
+
let retainedSession = '';
|
|
36
|
+
try {
|
|
37
|
+
retainedSession = readProof(join(sessionDir, role.session === 'codex-app-server' ? '.session-id' : '.acp-session-id')).trim();
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code !== 'ENOENT' || session || !firstManagedSessionMayStart(sessionDir))
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
readProof(join(sessionDir, '.booted')); // presence is the runner's resume marker, including legacy empty files
|
|
44
|
+
if (creation.role !== role.name || creation.identity !== role.identity || creation.action !== action
|
|
45
|
+
|| !state || instance.role !== role.name || instance.temporary !== true || !instance.instance
|
|
46
|
+
|| owner.instance !== instance.instance || typeof owner.token !== 'string' || !owner.token
|
|
47
|
+
|| pin.daemon !== profile.expectedInstanceId || pin.name !== role.identity || pin.cid !== cid
|
|
48
|
+
|| state.daemon !== profile.expectedInstanceId || state.name !== role.identity || state.cid !== cid
|
|
49
|
+
|| state.instance !== instance.instance || state.lifetime !== 'temporary' || state.action !== action
|
|
50
|
+
|| ['QUIESCING', 'TERMINAL_INTENT', 'RELEASED', 'CLEANUP_PENDING', 'FAILED'].includes(state.phase)
|
|
51
|
+
|| (!retainedSession && !firstManagedSessionMayStart(sessionDir)) || (launch && launch !== instance.instance) || (session && session !== retainedSession))
|
|
52
|
+
throw Error('TASK_RETAINED_RUNTIME_MISMATCH');
|
|
53
|
+
}
|
|
54
|
+
/** Read-only ownership fence: absence/mismatch never permits a new identity or launch. */
|
|
55
|
+
export function taskSupervisorMayRun(name) {
|
|
56
|
+
assertMemberNotPermanent(name);
|
|
57
|
+
const dir = agentDir(name, true);
|
|
58
|
+
readProof(join(dir, '.temp-supervisor.json'));
|
|
59
|
+
readProof(join(dir, 'creation.json'));
|
|
60
|
+
const supervisor = readTempSupervisor(dir), owner = supervisor?.taskOwner;
|
|
61
|
+
if (!owner || supervisor.role !== name || !owner.taskId || !owner.creationActionId)
|
|
62
|
+
throw Error('TASK_SUPERVISOR_OWNER_MISSING');
|
|
63
|
+
const role = parse(readProof(join(dir, 'role.yaml')));
|
|
64
|
+
const startup = role.roomMemberStartup, provenance = readProvenance(dir);
|
|
65
|
+
const task = getTask(owner.taskId);
|
|
66
|
+
if (role.name !== name || role.identity !== name || provenance?.role !== name
|
|
67
|
+
|| provenance.creationActionId !== owner.creationActionId)
|
|
68
|
+
throw Error('TASK_SUPERVISOR_OWNERSHIP_MISMATCH');
|
|
69
|
+
if (!task.deletion && !task.terminal_intent && ['provisioning', 'active', 'review'].includes(task.state) && task.workspace) {
|
|
70
|
+
if (role.cwd !== task.workspace.path)
|
|
71
|
+
throw Error('TASK_WORKSPACE_MISMATCH');
|
|
72
|
+
assertWorkspacePresent(task.workspace, 'task', task.task_id);
|
|
73
|
+
}
|
|
74
|
+
if (owner.layout) {
|
|
75
|
+
const { runId, participant } = owner.layout;
|
|
76
|
+
const expectedName = `layout-${createHash('sha256').update(runId + ':' + participant).digest('hex').slice(0, 16)}`;
|
|
77
|
+
if (!task.layout || task.layout.run_id !== runId || runId !== `task-${owner.taskId}`
|
|
78
|
+
|| !/^[A-Za-z0-9_-]+$/.test(runId) || expectedName !== name
|
|
79
|
+
|| owner.creationActionId !== `${runId}:${participant}`)
|
|
80
|
+
throw Error('TASK_LAYOUT_OWNER_MISMATCH');
|
|
81
|
+
const state = JSON.parse(readProof(join(stateRoot(), 'layouts', `${runId}.json`)));
|
|
82
|
+
const member = state.participants[participant];
|
|
83
|
+
if (!member?.owned || member.instance?.remote || (member.instance?.agent && member.instance.agent !== name)
|
|
84
|
+
|| (member.instance && member.instance.temporary !== true))
|
|
85
|
+
throw Error('TASK_LAYOUT_PARTICIPANT_MISMATCH');
|
|
86
|
+
if (task.deletion || task.terminal_intent || state.closed || state.closing || member.retired
|
|
87
|
+
|| !['provisioning', 'active', 'review'].includes(task.state))
|
|
88
|
+
return false;
|
|
89
|
+
if (member.instance)
|
|
90
|
+
assertRetainedRuntime(role, owner.creationActionId, member.instance.cid, member.instance.launch, member.instance.session);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
if (!owner.roomId || !owner.roomIdentityCid)
|
|
94
|
+
throw Error('TASK_SUPERVISOR_OWNER_MISSING');
|
|
95
|
+
const room = getRoomRecord(owner.roomId);
|
|
96
|
+
const seat = room?.member_seats.find(member => member.role_name === name);
|
|
97
|
+
if (!task || !room || room.task_id !== task.task_id || room.room_identity_cid !== owner.roomIdentityCid
|
|
98
|
+
|| (task.room_id !== undefined && task.room_id !== owner.roomId)
|
|
99
|
+
|| (task.room_identity_cid !== undefined && task.room_identity_cid !== owner.roomIdentityCid)
|
|
100
|
+
|| role.name !== name || role.identity !== name || startup?.task_id !== owner.taskId
|
|
101
|
+
|| startup.room_id !== owner.roomId || startup.room_identity_cid !== owner.roomIdentityCid
|
|
102
|
+
|| startup.identity_name !== name || !seat || seat.invite_id !== startup.invite_id
|
|
103
|
+
|| seat.cowork_role !== startup.role || provenance?.role !== name
|
|
104
|
+
|| provenance.creationActionId !== owner.creationActionId
|
|
105
|
+
|| seat.launch?.action_id !== owner.creationActionId
|
|
106
|
+
|| (seat.launch.launch_id !== undefined && seat.launch.launch_id !== supervisor.launchId))
|
|
107
|
+
throw Error('TASK_SUPERVISOR_OWNERSHIP_MISMATCH');
|
|
108
|
+
if (task.deletion || task.terminal_intent || room.close || seat.retirement
|
|
109
|
+
|| !['provisioning', 'active', 'review'].includes(task.state)
|
|
110
|
+
|| !['provisioning', 'active'].includes(room.state))
|
|
111
|
+
return false;
|
|
112
|
+
if (task.workspace && (role.cwd !== task.workspace.path
|
|
113
|
+
|| JSON.stringify(startup.workspace) !== JSON.stringify(task.workspace)
|
|
114
|
+
|| JSON.stringify(room.workspace) !== JSON.stringify(task.workspace)))
|
|
115
|
+
throw Error('TASK_WORKSPACE_MISMATCH');
|
|
116
|
+
if (seat.identity_cid)
|
|
117
|
+
assertRetainedRuntime(role, owner.creationActionId, seat.identity_cid);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
/** Resolve the externally recorded CID/action for explicit terminal retirement.
|
|
121
|
+
* Run only after the same launch passed taskSupervisorMayRun's ownership fence.
|
|
122
|
+
* An unpublished failed launch stays for its seat's retry/retirement saga. */
|
|
123
|
+
export function taskMemberRetirementProof(name) {
|
|
124
|
+
const dir = agentDir(name, true), metadata = readTempSupervisor(dir), owner = metadata?.taskOwner;
|
|
125
|
+
if (!owner || metadata.role !== name)
|
|
126
|
+
throw Error('TASK_SUPERVISOR_OWNER_MISSING');
|
|
127
|
+
let cid;
|
|
128
|
+
if (owner.layout) {
|
|
129
|
+
const state = JSON.parse(readProof(join(stateRoot(), 'layouts', `${owner.layout.runId}.json`)));
|
|
130
|
+
const participant = state.participants[owner.layout.participant];
|
|
131
|
+
if (!participant?.owned || participant.instance?.agent !== name || participant.instance?.remote
|
|
132
|
+
|| participant.instance?.temporary !== true)
|
|
133
|
+
throw Error('TASK_LAYOUT_PARTICIPANT_MISMATCH');
|
|
134
|
+
cid = participant.instance.cid;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const seat = owner.roomId && getRoomRecord(owner.roomId)?.member_seats.find(member => member.role_name === name);
|
|
138
|
+
if (!seat || seat.launch?.action_id !== owner.creationActionId || seat.launch.launch_id !== metadata.launchId)
|
|
139
|
+
throw Error('TASK_SUPERVISOR_OWNERSHIP_MISMATCH');
|
|
140
|
+
cid = seat.identity_cid;
|
|
141
|
+
}
|
|
142
|
+
if (!cid)
|
|
143
|
+
throw Error('TASK_MEMBER_RETIREMENT_CID_MISSING');
|
|
144
|
+
return { cid, action: owner.creationActionId };
|
|
145
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SessionSnapshot } from './session/types.js';
|
|
2
|
+
export declare const TEMP_CHAT_IDLE_MS: number;
|
|
3
|
+
export type ChatIdlePolicy = {
|
|
4
|
+
version: 1;
|
|
5
|
+
timeoutMs: number;
|
|
6
|
+
lastActivityAt: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function readChatIdle(dir: string): ChatIdlePolicy | undefined;
|
|
9
|
+
/** Only a standalone temporary supervisor owns this clock; browser reads never touch it. */
|
|
10
|
+
export declare class TemporaryChatIdle {
|
|
11
|
+
private dir;
|
|
12
|
+
private value;
|
|
13
|
+
private busy;
|
|
14
|
+
constructor(dir: string, now: number);
|
|
15
|
+
private save;
|
|
16
|
+
observe(snapshot: SessionSnapshot, queueDepth: number, now: number): boolean;
|
|
17
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { replaceFileAtomically } from './atomic-file.js';
|
|
4
|
+
export const TEMP_CHAT_IDLE_MS = 24 * 60 * 60_000;
|
|
5
|
+
const FILE = 'chat-idle.json';
|
|
6
|
+
export function readChatIdle(dir) {
|
|
7
|
+
if (!existsSync(join(dir, FILE)))
|
|
8
|
+
return undefined;
|
|
9
|
+
const value = JSON.parse(readFileSync(join(dir, FILE), 'utf8'));
|
|
10
|
+
if (value.version !== 1 || !Number.isSafeInteger(value.lastActivityAt) || value.timeoutMs !== TEMP_CHAT_IDLE_MS)
|
|
11
|
+
throw new Error('Invalid persisted chat idle policy');
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
/** Only a standalone temporary supervisor owns this clock; browser reads never touch it. */
|
|
15
|
+
export class TemporaryChatIdle {
|
|
16
|
+
dir;
|
|
17
|
+
value;
|
|
18
|
+
busy = false;
|
|
19
|
+
constructor(dir, now) {
|
|
20
|
+
this.dir = dir;
|
|
21
|
+
this.value = readChatIdle(dir) ?? { version: 1, timeoutMs: TEMP_CHAT_IDLE_MS, lastActivityAt: now };
|
|
22
|
+
this.save();
|
|
23
|
+
}
|
|
24
|
+
save() { replaceFileAtomically(join(this.dir, FILE), JSON.stringify(this.value) + '\n', 0o600); }
|
|
25
|
+
observe(snapshot, queueDepth, now) {
|
|
26
|
+
// Unknown activity evidence never grants permission to retire a session.
|
|
27
|
+
const idle = snapshot.alive && snapshot.readiness === 'idle' && !snapshot.pendingPermissionId && queueDepth === 0 && snapshot.activity?.activeToolCalls === 0;
|
|
28
|
+
const update = Date.parse(snapshot.activity?.lastUpdateAt ?? '');
|
|
29
|
+
let next = this.value.lastActivityAt;
|
|
30
|
+
if (Number.isFinite(update) && update <= now)
|
|
31
|
+
next = Math.max(next, update);
|
|
32
|
+
if (!idle || this.busy)
|
|
33
|
+
next = Math.max(next, now);
|
|
34
|
+
this.busy = !idle;
|
|
35
|
+
// Active work checkpoints at most once a minute, with an immediate idle boundary write.
|
|
36
|
+
if (next > this.value.lastActivityAt && (idle || next - this.value.lastActivityAt >= 60_000)) {
|
|
37
|
+
this.value.lastActivityAt = next;
|
|
38
|
+
this.save();
|
|
39
|
+
}
|
|
40
|
+
return idle && now >= this.value.lastActivityAt && now - this.value.lastActivityAt >= this.value.timeoutMs;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/dist/temp-lifecycle.d.ts
CHANGED
|
@@ -4,8 +4,18 @@ export declare const TEMP_TERMINATION_FILE = "termination.jsonl";
|
|
|
4
4
|
export declare const TEMP_STOP_REQUEST_FILE = ".temp-stop-request.json";
|
|
5
5
|
export declare const TEMP_RECLAIM_BATCH = 32;
|
|
6
6
|
export declare const TEMP_LAUNCH_GRACE_MS = 60000;
|
|
7
|
-
export type TempSupervisorKind = 'systemd-transient' | 'launchd-transient' | 'detached';
|
|
8
|
-
export type TempTerminationReason = 'identity-closed' | 'session-ended' | 'operator-stop' | 'supervisor-signal' | 'supervisor-recycle' | 'startup-failure' | 'stale-supervisor';
|
|
7
|
+
export type TempSupervisorKind = 'fleet-managed' | 'systemd-transient' | 'launchd-transient' | 'detached';
|
|
8
|
+
export type TempTerminationReason = 'idle-timeout' | 'identity-closed' | 'session-ended' | 'operator-stop' | 'supervisor-signal' | 'supervisor-recycle' | 'startup-failure' | 'stale-supervisor';
|
|
9
|
+
export interface TaskSupervisorOwner {
|
|
10
|
+
taskId: string;
|
|
11
|
+
roomId?: string;
|
|
12
|
+
roomIdentityCid?: string;
|
|
13
|
+
layout?: {
|
|
14
|
+
runId: string;
|
|
15
|
+
participant: string;
|
|
16
|
+
};
|
|
17
|
+
creationActionId: string;
|
|
18
|
+
}
|
|
9
19
|
export interface TempSupervisorRecord {
|
|
10
20
|
version: 1;
|
|
11
21
|
role: string;
|
|
@@ -16,6 +26,7 @@ export interface TempSupervisorRecord {
|
|
|
16
26
|
target?: string;
|
|
17
27
|
pid?: number;
|
|
18
28
|
binPath?: string;
|
|
29
|
+
taskOwner?: TaskSupervisorOwner;
|
|
19
30
|
}
|
|
20
31
|
export interface TempTerminationRecord {
|
|
21
32
|
version: 1;
|
|
@@ -29,13 +40,12 @@ export interface TempTerminationRecord {
|
|
|
29
40
|
export type SupervisorLauncher = (binPath: string, args: string[], dir: string) => void | Promise<void>;
|
|
30
41
|
export declare const tempSystemdUnit: (name: string) => string;
|
|
31
42
|
export declare const tempLaunchdLabel: (name: string) => string;
|
|
32
|
-
export declare function prepareTempSupervisor(dir: string, role: string): TempSupervisorRecord;
|
|
43
|
+
export declare function prepareTempSupervisor(dir: string, role: string, taskOwner?: TaskSupervisorOwner): TempSupervisorRecord;
|
|
33
44
|
export declare function readTempSupervisor(dir: string): TempSupervisorRecord | undefined;
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*/
|
|
45
|
+
/** Broad scans retain unsupported entries instead of blocking other members. */
|
|
46
|
+
export declare function readTempSupervisorForScan(dir: string): TempSupervisorRecord | undefined;
|
|
47
|
+
export declare function updateTempSupervisor(dir: string, update: Partial<Omit<TempSupervisorRecord, 'version' | 'role' | 'launchId' | 'createdAt'>>): Promise<TempSupervisorRecord | undefined>;
|
|
48
|
+
/** Register managed members under Fleet; explicit manual mode uses a detached child. */
|
|
39
49
|
export declare function makeTempSupervisorLauncher(options?: {
|
|
40
50
|
exec?: Exec;
|
|
41
51
|
platform?: NodeJS.Platform;
|
|
@@ -44,6 +54,11 @@ export declare function makeTempSupervisorLauncher(options?: {
|
|
|
44
54
|
}): SupervisorLauncher;
|
|
45
55
|
export declare function markTempSupervisorActive(dir: string, pid?: number): Promise<void>;
|
|
46
56
|
export declare function requestedTempStopReason(dir: string): 'operator-stop' | undefined;
|
|
57
|
+
/** Explicit erasure removes only exact retired role/launch events. */
|
|
58
|
+
export declare function eraseTerminationEvents(launches: ReadonlyArray<{
|
|
59
|
+
role: string;
|
|
60
|
+
launchId: string;
|
|
61
|
+
}>): void;
|
|
47
62
|
/** Move retired state out of the live roster without deleting any evidence. */
|
|
48
63
|
export declare function archiveTempState(role: string, reason: TempTerminationReason, outcome: TempTerminationRecord['outcome'], detail: string, now?: Date): string | undefined;
|
|
49
64
|
/** Resolve only an exact role+launch archive; names and timestamps are never proof. */
|