@ours.network/fleet 1.2.0-nightly.7 → 1.2.0-nightly.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +279 -68
- package/dist/account-origin.d.ts +2 -0
- package/dist/account-origin.js +6 -0
- package/dist/agent-ours/bridge.js +26 -9
- package/dist/agent-ours/correspondence.d.ts +10 -0
- package/dist/agent-ours/correspondence.js +1 -0
- package/dist/agent-ours/file-rpc.d.ts +12 -0
- package/dist/agent-ours/file-rpc.js +18 -4
- package/dist/agent-ours/harness.js +9 -1
- package/dist/agent-ours/mcp-endpoint.d.ts +19 -0
- package/dist/agent-ours/mcp-endpoint.js +98 -25
- package/dist/agent-ours/runtime.d.ts +9 -1
- package/dist/agent-ours/runtime.js +50 -2
- package/dist/agent-ours/service.d.ts +24 -1
- package/dist/agent-ours/service.js +97 -13
- package/dist/application/codex-models.d.ts +15 -0
- package/dist/application/codex-models.js +56 -0
- package/dist/application/conversation-history.d.ts +27 -0
- package/dist/application/conversation-history.js +215 -0
- package/dist/application/conversation-role-observer.d.ts +62 -0
- package/dist/application/conversation-role-observer.js +206 -0
- package/dist/application/fleet-query-service.d.ts +1 -1
- package/dist/application/fleet-query-service.js +2 -2
- package/dist/application/log-service.js +8 -8
- package/dist/application/model-catalog.d.ts +1 -1
- package/dist/application/model-catalog.js +5 -2
- package/dist/application/preset-provenance.d.ts +19 -0
- package/dist/application/preset-provenance.js +59 -0
- package/dist/application/role-creation-service.js +3 -2
- package/dist/application/role-removal-service.js +17 -3
- package/dist/application/role-repository.js +19 -2
- package/dist/application/room-layout-definitions.d.ts +45 -0
- package/dist/application/room-layout-definitions.js +130 -0
- package/dist/application/session-control.d.ts +61 -17
- package/dist/application/session-control.js +207 -23
- package/dist/application/supervisor-ours-tools.js +5 -11
- package/dist/application/task-layouts.d.ts +91 -0
- package/dist/application/task-layouts.js +259 -0
- package/dist/application/task-room-service.d.ts +99 -3
- package/dist/application/task-room-service.js +285 -32
- package/dist/application/types.d.ts +2 -0
- package/dist/atomic-file.d.ts +34 -1
- package/dist/atomic-file.js +161 -18
- package/dist/briefing.d.ts +3 -1
- package/dist/briefing.js +97 -31
- package/dist/build-info.json +9 -4
- package/dist/capabilities.d.ts +9 -1
- package/dist/capabilities.js +13 -0
- package/dist/cli.js +400 -37
- package/dist/client-profile.d.ts +5 -17
- package/dist/client-profile.js +4 -127
- package/dist/config.d.ts +45 -0
- package/dist/config.js +57 -6
- package/dist/creation.d.ts +1 -1
- package/dist/creation.js +4 -4
- package/dist/daemon-recovery.d.ts +1 -8
- package/dist/daemon-recovery.js +8 -113
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +207 -19
- package/dist/doctor.d.ts +4 -1
- package/dist/doctor.js +75 -60
- package/dist/erased-resources.d.ts +9 -0
- package/dist/erased-resources.js +87 -0
- package/dist/file-delivery/reader.d.ts +15 -0
- package/dist/file-delivery/reader.js +63 -0
- package/dist/file-delivery/store.d.ts +15 -0
- package/dist/file-delivery/store.js +124 -0
- package/dist/file-delivery/types.d.ts +19 -0
- package/dist/file-delivery/types.js +1 -0
- package/dist/fleet-command-audit.d.ts +7 -0
- package/dist/fleet-command-audit.js +24 -8
- package/dist/harness/agent-session.d.ts +4 -0
- package/dist/harness/claude-code-session.js +1 -1
- package/dist/harness/claude-code.js +21 -11
- package/dist/harness/claude-runtime.d.ts +12 -0
- package/dist/harness/claude-runtime.js +43 -0
- package/dist/harness/codex-app-server-proxy.d.ts +4 -1
- package/dist/harness/codex-app-server-proxy.js +41 -5
- package/dist/harness/codex-reasoning.d.ts +5 -0
- package/dist/harness/codex-reasoning.js +12 -0
- package/dist/harness/codex-runtime.d.ts +11 -1
- package/dist/harness/codex-runtime.js +31 -4
- package/dist/harness/codex-session.js +2 -2
- package/dist/harness/codex.js +24 -12
- package/dist/init-wizard.d.ts +2 -0
- package/dist/init-wizard.js +38 -19
- package/dist/isolation/policy.js +6 -1
- package/dist/isolation/types.d.ts +5 -0
- package/dist/managed-cli.d.ts +253 -0
- package/dist/managed-cli.js +923 -0
- package/dist/managed-recovery.d.ts +13 -0
- package/dist/managed-recovery.js +31 -0
- package/dist/minimal-setup.d.ts +2 -0
- package/dist/minimal-setup.js +44 -0
- package/dist/monitor.d.ts +8 -34
- package/dist/monitor.js +89 -152
- package/dist/notifications/fleet-producer.d.ts +19 -0
- package/dist/notifications/fleet-producer.js +208 -0
- package/dist/notifications/outbox.d.ts +46 -0
- package/dist/notifications/outbox.js +158 -0
- package/dist/notifications/target-cleanup.d.ts +10 -0
- package/dist/notifications/target-cleanup.js +63 -0
- package/dist/notifications/task-producer.d.ts +18 -0
- package/dist/notifications/task-producer.js +67 -0
- package/dist/ops.d.ts +2 -0
- package/dist/ops.js +20 -3
- package/dist/owner-channel/channel.js +17 -6
- package/dist/owner-channel/commands.d.ts +4 -0
- package/dist/owner-channel/commands.js +8 -0
- package/dist/owner-channel/lifecycle-outbox.js +4 -3
- package/dist/owner-channel/ours-client.js +2 -17
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +2 -0
- package/dist/preset-migration.js +43 -0
- package/dist/process-incarnation.d.ts +23 -0
- package/dist/process-incarnation.js +42 -0
- package/dist/reminders/manager.d.ts +75 -0
- package/dist/reminders/manager.js +278 -0
- package/dist/reminders/runtime.d.ts +27 -0
- package/dist/reminders/runtime.js +32 -0
- package/dist/reminders/schedule.d.ts +37 -0
- package/dist/reminders/schedule.js +104 -0
- package/dist/reminders/store.d.ts +341 -0
- package/dist/reminders/store.js +762 -0
- package/dist/reminders/tools.d.ts +20 -0
- package/dist/reminders/tools.js +114 -0
- package/dist/resolved-plan.js +1 -0
- package/dist/rooms-tasks/add-member.d.ts +48 -0
- package/dist/rooms-tasks/add-member.js +83 -0
- package/dist/rooms-tasks/archived-absence.d.ts +8 -0
- package/dist/rooms-tasks/archived-absence.js +48 -0
- package/dist/rooms-tasks/cli.js +65 -5
- package/dist/rooms-tasks/close.d.ts +6 -2
- package/dist/rooms-tasks/close.js +246 -37
- package/dist/rooms-tasks/config.d.ts +1 -1
- package/dist/rooms-tasks/config.js +11 -4
- package/dist/rooms-tasks/cowork-adapter.d.ts +12 -5
- package/dist/rooms-tasks/cowork-adapter.js +15 -121
- package/dist/rooms-tasks/cowork-http.js +56 -6
- package/dist/rooms-tasks/deletion.d.ts +1 -1
- package/dist/rooms-tasks/deletion.js +84 -5
- package/dist/rooms-tasks/erasure.d.ts +6 -0
- package/dist/rooms-tasks/erasure.js +173 -0
- package/dist/rooms-tasks/external-worker.d.ts +1 -1
- package/dist/rooms-tasks/external-worker.js +3 -4
- package/dist/rooms-tasks/layout-binding-client.d.ts +11 -0
- package/dist/rooms-tasks/layout-binding-client.js +56 -0
- package/dist/rooms-tasks/layout-binding-grants.d.ts +21 -0
- package/dist/rooms-tasks/layout-binding-grants.js +128 -0
- package/dist/rooms-tasks/layout-cli.d.ts +4 -0
- package/dist/rooms-tasks/layout-cli.js +107 -0
- package/dist/rooms-tasks/layout-config.d.ts +11 -0
- package/dist/rooms-tasks/layout-config.js +89 -0
- package/dist/rooms-tasks/layout-control.d.ts +21 -0
- package/dist/rooms-tasks/layout-control.js +52 -0
- package/dist/rooms-tasks/layout-member-retirement.d.ts +10 -0
- package/dist/rooms-tasks/layout-member-retirement.js +90 -0
- package/dist/rooms-tasks/layout-service.d.ts +43 -0
- package/dist/rooms-tasks/layout-service.js +203 -0
- package/dist/rooms-tasks/layout.d.ts +121 -0
- package/dist/rooms-tasks/layout.js +285 -0
- package/dist/rooms-tasks/legacy-task-member.d.ts +19 -0
- package/dist/rooms-tasks/legacy-task-member.js +116 -0
- package/dist/rooms-tasks/live-readiness.d.ts +18 -0
- package/dist/rooms-tasks/live-readiness.js +85 -0
- package/dist/rooms-tasks/member-ownership.d.ts +5 -0
- package/dist/rooms-tasks/member-ownership.js +40 -0
- package/dist/rooms-tasks/member-startup.d.ts +1 -0
- package/dist/rooms-tasks/member-startup.js +2 -0
- package/dist/rooms-tasks/provision.d.ts +3 -0
- package/dist/rooms-tasks/provision.js +101 -49
- package/dist/rooms-tasks/recovery.d.ts +19 -0
- package/dist/rooms-tasks/recovery.js +110 -0
- package/dist/rooms-tasks/room-state.d.ts +4 -2
- package/dist/rooms-tasks/room-state.js +47 -8
- package/dist/rooms-tasks/task-service-retirement.d.ts +11 -0
- package/dist/rooms-tasks/task-service-retirement.js +21 -0
- package/dist/rooms-tasks/task-state.d.ts +51 -8
- package/dist/rooms-tasks/task-state.js +245 -25
- package/dist/rooms-tasks/types.d.ts +40 -0
- package/dist/rooms-tasks/workspace-artifacts.d.ts +6 -0
- package/dist/rooms-tasks/workspace-artifacts.js +93 -0
- package/dist/rooms-tasks/workspace.d.ts +35 -0
- package/dist/rooms-tasks/workspace.js +325 -0
- package/dist/runner.d.ts +33 -4
- package/dist/runner.js +389 -56
- package/dist/session/acp.d.ts +75 -2
- package/dist/session/acp.js +345 -82
- package/dist/session/arbiter.d.ts +98 -0
- package/dist/session/arbiter.js +272 -3
- package/dist/session/codex-app-server.d.ts +45 -1
- package/dist/session/codex-app-server.js +225 -32
- package/dist/session/control.d.ts +17 -3
- package/dist/session/control.js +213 -23
- package/dist/session/conversation-normalizer.d.ts +2 -1
- package/dist/session/conversation-normalizer.js +1 -1
- package/dist/session/conversation-observation.d.ts +25 -0
- package/dist/session/conversation-observation.js +100 -0
- package/dist/session/conversation-replay.d.ts +50 -0
- package/dist/session/conversation-replay.js +203 -0
- package/dist/session/conversation-store.d.ts +15 -1
- package/dist/session/conversation-store.js +206 -26
- package/dist/session/conversation-types.d.ts +57 -4
- package/dist/session/prompt-batch.d.ts +79 -0
- package/dist/session/prompt-batch.js +120 -0
- package/dist/session/task-notice.d.ts +14 -0
- package/dist/session/task-notice.js +13 -0
- package/dist/session/types.d.ts +42 -1
- package/dist/setup-tunnel-preflight.d.ts +34 -0
- package/dist/setup-tunnel-preflight.js +62 -0
- package/dist/socket-path.d.ts +2 -0
- package/dist/socket-path.js +22 -0
- package/dist/spawn.d.ts +5 -1
- package/dist/spawn.js +40 -4
- package/dist/startup-prompt.d.ts +15 -0
- package/dist/startup-prompt.js +71 -0
- package/dist/startup-readiness.d.ts +32 -0
- package/dist/startup-readiness.js +101 -0
- package/dist/startup-telemetry.d.ts +16 -0
- package/dist/startup-telemetry.js +46 -0
- package/dist/subscriptions/cli.d.ts +91 -0
- package/dist/subscriptions/cli.js +223 -0
- package/dist/subscriptions/launch.d.ts +37 -0
- package/dist/subscriptions/launch.js +93 -0
- package/dist/subscriptions/login.d.ts +76 -0
- package/dist/subscriptions/login.js +207 -0
- package/dist/subscriptions/observed.d.ts +7 -0
- package/dist/subscriptions/observed.js +44 -0
- package/dist/subscriptions/probe.d.ts +10 -0
- package/dist/subscriptions/probe.js +73 -0
- package/dist/subscriptions/service.d.ts +102 -0
- package/dist/subscriptions/service.js +364 -0
- package/dist/subscriptions/store.d.ts +71 -0
- package/dist/subscriptions/store.js +140 -0
- package/dist/supervisor/adoption.d.ts +8 -0
- package/dist/supervisor/adoption.js +78 -0
- package/dist/supervisor/catalog.d.ts +62 -0
- package/dist/supervisor/catalog.js +254 -0
- package/dist/supervisor/fleet.d.ts +8 -0
- package/dist/supervisor/fleet.js +89 -0
- package/dist/supervisor/index.js +3 -6
- package/dist/supervisor/launchd.d.ts +1 -1
- package/dist/supervisor/launchd.js +26 -13
- package/dist/supervisor/legacy.d.ts +35 -0
- package/dist/supervisor/legacy.js +524 -0
- package/dist/supervisor/manager.d.ts +15 -0
- package/dist/supervisor/manager.js +270 -0
- package/dist/supervisor/registration-refresh.d.ts +45 -0
- package/dist/supervisor/registration-refresh.js +266 -0
- package/dist/supervisor/scope.d.ts +4 -0
- package/dist/supervisor/scope.js +10 -0
- package/dist/supervisor/systemd.d.ts +2 -2
- package/dist/supervisor/systemd.js +19 -33
- package/dist/task-supervision.d.ts +9 -0
- package/dist/task-supervision.js +145 -0
- package/dist/temp-idle.d.ts +17 -0
- package/dist/temp-idle.js +42 -0
- package/dist/temp-lifecycle.d.ts +23 -8
- package/dist/temp-lifecycle.js +123 -66
- package/dist/temp-supervisor-recovery.d.ts +1 -1
- package/dist/temp-supervisor-recovery.js +2 -2
- package/dist/tunnel-setup-completion.d.ts +7 -0
- package/dist/tunnel-setup-completion.js +13 -0
- package/dist/tunnel-setup-input.d.ts +19 -0
- package/dist/tunnel-setup-input.js +124 -0
- package/dist/web/agent-attachments.d.ts +29 -0
- package/dist/web/agent-attachments.js +162 -0
- package/dist/web/auth.d.ts +65 -2
- package/dist/web/auth.js +201 -11
- package/dist/web/available-port.d.ts +2 -0
- package/dist/web/available-port.js +23 -0
- package/dist/web/control.d.ts +3 -3
- package/dist/web/control.js +10 -8
- package/dist/web/conversation-stream-codec.d.ts +23 -0
- package/dist/web/conversation-stream-codec.js +110 -0
- package/dist/web/conversation-stream.d.ts +25 -0
- package/dist/web/conversation-stream.js +231 -0
- package/dist/web/fleet-config-service.d.ts +4 -1
- package/dist/web/fleet-config-service.js +46 -15
- package/dist/web/prefix-gateway.d.ts +32 -0
- package/dist/web/prefix-gateway.js +238 -0
- package/dist/web/runtime.d.ts +3 -1
- package/dist/web/runtime.js +128 -33
- package/dist/web/server.d.ts +16 -0
- package/dist/web/server.js +639 -55
- package/dist/web/service.d.ts +11 -2
- package/dist/web/service.js +30 -4
- package/dist/web/workspace-devices.d.ts +107 -0
- package/dist/web/workspace-devices.js +277 -0
- package/dist/web/workspace-tunnel.d.ts +1 -0
- package/dist/web/workspace-tunnel.js +34 -0
- package/dist/workspace-enrollment.d.ts +83 -0
- package/dist/workspace-enrollment.js +580 -0
- package/dist/workspace-replacement.d.ts +66 -0
- package/dist/workspace-replacement.js +220 -0
- package/docs/acp-files.md +146 -0
- package/docs/conversation-stream.md +190 -0
- package/docs/fleet-migration.md +54 -0
- package/docs/live-voice.md +13 -0
- package/docs/room-layouts.md +227 -0
- package/docs/self-reminders.md +374 -0
- package/docs/task-workspaces.md +225 -0
- package/docs/validation/managed-cli-permissions.md +421 -0
- package/examples/room-layouts/fresh.yaml +27 -0
- package/examples/room-layouts/scoped.yaml +21 -0
- package/examples/room-layouts/shared.yaml +19 -0
- package/package.json +24 -20
- package/presets/README.md +78 -0
- package/presets/brain-catalog.json +8 -2
- package/presets/fleet/agent_templates/Critic.yaml +1 -1
- package/presets/fleet/agent_templates/Developer.yaml +1 -1
- package/presets/fleet/agent_templates/Engineer.yaml +5 -0
- package/presets/fleet/agent_templates/LocalCoordinator.yaml +4 -2
- package/presets/fleet/agents/FleetCoordinator.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-1-high.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-low.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-max.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-medium.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-1-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-fable-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-fable-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-haiku-4-5-20251001-default.yaml +4 -0
- package/presets/fleet/brains/claude-opus-5-5-high.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-low.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-max.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-medium.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-5-xhigh.yaml +5 -0
- package/presets/fleet/brains/claude-opus-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-opus-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-high.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-low.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-max.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-medium.yaml +1 -1
- package/presets/fleet/brains/claude-sonnet-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-3-codex-spark-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-mini-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-4-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-5-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-luna-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-sol-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-5-6-terra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-1-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-1-sol-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-astra-high.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-low.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-max.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-medium.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-ultra.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-astra-xhigh.yaml +1 -1
- package/presets/fleet/brains/codex-gpt-6-luna-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-luna-xhigh.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-high.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-low.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-max.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-medium.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-ultra.yaml +5 -0
- package/presets/fleet/brains/codex-gpt-6-sol-xhigh.yaml +5 -0
- package/presets/fleet/roles/Coordinator.yaml +12 -11
- package/presets/fleet/roles/Critic.yaml +13 -0
- package/presets/fleet/roles/Developer.yaml +13 -0
- package/presets/fleet/roles/Engineer.yaml +53 -0
- package/presets/fleet/room_layouts/engineering.yaml +25 -0
- package/presets/fleet/room_layouts/pair.yaml +24 -0
- package/presets/fleet/room_layouts/single.yaml +17 -0
- package/presets/fleet/room_layouts/team.yaml +30 -0
- package/presets/fleet/room_templates/engineering.yaml +19 -0
- package/presets/manifest.json +2 -2
- package/dist/web-app/assets/index-59GF-gsZ.css +0 -1
- package/dist/web-app/assets/index-C0h3ALvs.js +0 -10
- package/dist/web-app/icons/ours-fleet-maskable.svg +0 -4
- package/dist/web-app/icons/ours-fleet.svg +0 -4
- package/dist/web-app/index.html +0 -17
- package/dist/web-app/manifest.webmanifest +0 -15
- package/dist/web-app/offline.html +0 -18
- package/dist/web-app/sw.js +0 -51
|
@@ -883,8 +883,15 @@ export class OwnerChannel {
|
|
|
883
883
|
const recovered = [];
|
|
884
884
|
for (const claim of this.messageRecovery.list()) {
|
|
885
885
|
const item = await this.client.getHistoryItem(claim.wireId);
|
|
886
|
-
if (!item)
|
|
887
|
-
|
|
886
|
+
if (!item) {
|
|
887
|
+
// The daemon has definitively lost this body. Retrying the claim would
|
|
888
|
+
// block every later owner message, including after a supervisor restart.
|
|
889
|
+
// Keep transient lookup errors retryable; only an explicit absence skips.
|
|
890
|
+
this.messageRecovery.pruneHandled(wireId => wireId === claim.wireId);
|
|
891
|
+
this.options.log(`[${this.options.role}] skipped journaled owner message ${claim.wireId} `
|
|
892
|
+
+ `(seq=${claim.seq}): missing from persistent history`);
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
888
895
|
recovered.push(this.historyMessage(item, claim));
|
|
889
896
|
}
|
|
890
897
|
const listed = await this.client.listIncomingMessages();
|
|
@@ -1391,6 +1398,7 @@ export class OwnerChannel {
|
|
|
1391
1398
|
await this.fleetOps.provisionTask(task.task_id);
|
|
1392
1399
|
return outcome;
|
|
1393
1400
|
}),
|
|
1401
|
+
observeTaskReadiness: taskId => new TaskRoomApplicationService(this.options.configPath).observeTaskReadiness(taskId),
|
|
1394
1402
|
taskProvisioningOutcome: taskId => new TaskRoomApplicationService(this.options.configPath).taskProvisioningOutcome(taskId),
|
|
1395
1403
|
listTasks: filter => new TaskRoomApplicationService(this.options.configPath).listTasks(filter),
|
|
1396
1404
|
groupedTasks: filter => new TaskRoomApplicationService(this.options.configPath).groupedTasks(filter),
|
|
@@ -1977,6 +1985,9 @@ export class OwnerChannel {
|
|
|
1977
1985
|
const progressMs = this.options.config.progress_interval_ms;
|
|
1978
1986
|
let lastSeq = activityCursor;
|
|
1979
1987
|
let startedAt;
|
|
1988
|
+
// When one turn delivers several waiting prompts, its events carry the turn's
|
|
1989
|
+
// id, not this request's: follow the turn that actually carries this request.
|
|
1990
|
+
const inTurn = (turnId) => turnId === (this.options.session.sharedTurnId?.(queued.promptId) ?? queued.promptId);
|
|
1980
1991
|
let phase = 'starting request';
|
|
1981
1992
|
let timer;
|
|
1982
1993
|
const flushCommentary = () => {
|
|
@@ -2033,7 +2044,7 @@ export class OwnerChannel {
|
|
|
2033
2044
|
};
|
|
2034
2045
|
const acceptCommentary = (event) => {
|
|
2035
2046
|
if (!this.commentsEnabled
|
|
2036
|
-
|| active.commentaryDisabled || active.finalizing || event.turnId
|
|
2047
|
+
|| active.commentaryDisabled || active.finalizing || !inTurn(event.turnId)
|
|
2037
2048
|
|| event.kind !== 'agent_text' || event.messagePhase !== 'commentary'
|
|
2038
2049
|
|| event.replayed || event.origin?.kind !== 'owner'
|
|
2039
2050
|
|| event.origin.requestId !== active.requestId
|
|
@@ -2074,7 +2085,7 @@ export class OwnerChannel {
|
|
|
2074
2085
|
const reportProgress = () => {
|
|
2075
2086
|
const events = this.options.session.eventsSince(lastSeq);
|
|
2076
2087
|
lastSeq = Math.max(lastSeq, this.latestEventSeq(events));
|
|
2077
|
-
const activity = events.filter(event => event.turnId
|
|
2088
|
+
const activity = events.filter(event => inTurn(event.turnId));
|
|
2078
2089
|
if (!activity.length)
|
|
2079
2090
|
return;
|
|
2080
2091
|
startedAt ??= Date.parse(activity[0].at) || Date.now();
|
|
@@ -2099,10 +2110,10 @@ export class OwnerChannel {
|
|
|
2099
2110
|
const startProgress = (event) => {
|
|
2100
2111
|
if (timer || progressMs <= 0)
|
|
2101
2112
|
return;
|
|
2102
|
-
if (event && event.turnId
|
|
2113
|
+
if (event && !inTurn(event.turnId))
|
|
2103
2114
|
return;
|
|
2104
2115
|
const observed = event ? [event] : this.options.session.eventsSince(activityCursor)
|
|
2105
|
-
.filter(item => item.turnId
|
|
2116
|
+
.filter(item => inTurn(item.turnId));
|
|
2106
2117
|
if (!observed.length)
|
|
2107
2118
|
return;
|
|
2108
2119
|
startedAt = Date.parse(observed[0].at) || Date.now();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TaskReadinessIssue } from '../rooms-tasks/live-readiness.js';
|
|
1
2
|
import type { InterruptOutcome, SessionEvent, SessionSnapshot } from '../session/types.js';
|
|
2
3
|
import type { RoomOrchestrationRecord, TaskOutcome, TaskRecord, TaskTerminalIntent, TaskListRecord } from '../rooms-tasks/types.js';
|
|
3
4
|
import { type OwnerCommentsState } from './notices.js';
|
|
@@ -58,6 +59,9 @@ export interface OwnerCommandContext {
|
|
|
58
59
|
terminalTask(taskId: string, kind: TaskTerminalIntent['kind'], outcome?: TaskOutcome): Promise<void>;
|
|
59
60
|
createTask(input: Omit<CreateTaskRequest, 'actor'>): Promise<TaskRecord>;
|
|
60
61
|
startTask(taskId: string): Promise<TaskProvisioningOutcome | TaskRecord>;
|
|
62
|
+
observeTaskReadiness?(taskId: string): Promise<{
|
|
63
|
+
state: 'ready';
|
|
64
|
+
} | TaskReadinessIssue>;
|
|
61
65
|
taskProvisioningOutcome?(taskId: string): TaskProvisioningOutcome;
|
|
62
66
|
listTasks(filter?: {
|
|
63
67
|
state?: TaskState | TaskState[];
|
|
@@ -47,6 +47,11 @@ function isKnownOwnerRoomState(message) {
|
|
|
47
47
|
].some(pattern => pattern.test(message));
|
|
48
48
|
}
|
|
49
49
|
function ownerTaskFailure(error) {
|
|
50
|
+
if (error instanceof TaskRoomApplicationError && error.code === 'task_not_ready')
|
|
51
|
+
return {
|
|
52
|
+
kind: 'state', detail: error.message,
|
|
53
|
+
action: 'Ask Fleet Coordinator to inspect room and member status and choose supported recovery.',
|
|
54
|
+
};
|
|
50
55
|
if (error instanceof TaskListError)
|
|
51
56
|
return {
|
|
52
57
|
kind: error.code === 'list_not_found' ? 'not_found'
|
|
@@ -301,6 +306,7 @@ export const ownerCommands = [
|
|
|
301
306
|
const trailingLines = argLines.slice(1).join('\n').trim() || undefined;
|
|
302
307
|
const showTask = async (id) => {
|
|
303
308
|
const { task: t } = ctx.getTask(id);
|
|
309
|
+
const readiness = t.state === 'active' ? await ctx.observeTaskReadiness?.(id) : undefined;
|
|
304
310
|
await ctx.reply(renderMarkdownResult({
|
|
305
311
|
icon: '📋', title: 'Task details',
|
|
306
312
|
fields: [
|
|
@@ -308,6 +314,8 @@ export const ownerCommands = [
|
|
|
308
314
|
{ label: 'Title', value: t.title },
|
|
309
315
|
{ label: 'Status', value: taskStatus(t.state), kind: 'markdown' },
|
|
310
316
|
{ label: 'List', value: t.list_name ?? 'default', kind: 'code' },
|
|
317
|
+
...(readiness ? [{ label: 'Readiness', value: readiness.state },
|
|
318
|
+
...('reason' in readiness ? [{ label: 'Reason', value: readiness.reason }] : [])] : []),
|
|
311
319
|
...(t.blocked ? [{ label: 'Blocked', value: t.blocked.reason }] : []),
|
|
312
320
|
...(t.template ? [{ label: 'Template', value: `${t.template.name}@${t.template.version}`, kind: 'code' }] : []),
|
|
313
321
|
...(t.room_id ? [{ label: 'Room', value: t.room_id, kind: 'code' }] : []),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { redactErasedContent, writePrivacyFilteredLedger } from '../erased-resources.js';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { chmodSync, existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { replaceFileAtomically } from '../atomic-file.js';
|
|
4
4
|
import { lifecycleEventDigestBasis, validateFleetAuditPresentations, } from '../fleet-command-audit.js';
|
|
5
5
|
const DIGEST = /^[a-f0-9]{64}$/u;
|
|
6
6
|
const LIMIT = 5_000;
|
|
@@ -63,7 +63,7 @@ export class FleetLifecycleOutbox {
|
|
|
63
63
|
}
|
|
64
64
|
pending() {
|
|
65
65
|
this.assertHealthy();
|
|
66
|
-
return this.entries.filter(entry => entry.delivery === 'pending').map(entry => structuredClone(entry));
|
|
66
|
+
return redactErasedContent(this.entries).filter(entry => entry.delivery === 'pending').map(entry => structuredClone(entry));
|
|
67
67
|
}
|
|
68
68
|
finish(digest, delivery) {
|
|
69
69
|
this.assertHealthy();
|
|
@@ -82,6 +82,7 @@ export class FleetLifecycleOutbox {
|
|
|
82
82
|
throw new Error(this.corruptReason);
|
|
83
83
|
}
|
|
84
84
|
persist() {
|
|
85
|
-
|
|
85
|
+
this.entries = redactErasedContent(this.entries);
|
|
86
|
+
writePrivacyFilteredLedger(this.path, { version: 1, entries: this.entries });
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import { extname
|
|
4
|
-
import { readDaemonConfig, resolveEndpoint } from '../monitor.js';
|
|
3
|
+
import { extname } from 'node:path';
|
|
5
4
|
import { readClientProfile } from '../client-profile.js';
|
|
6
5
|
import { OursError, attachOursClient, } from '@ours.network/sdk/client';
|
|
7
6
|
/** Any failure of a daemon operation. Never carries a message body or a token. */
|
|
@@ -131,24 +130,10 @@ export class OursSdkClient {
|
|
|
131
130
|
return;
|
|
132
131
|
const environment = { ...process.env, ...this.env };
|
|
133
132
|
const profile = readClientProfile(environment);
|
|
134
|
-
|
|
135
|
-
// daemon capability before reading the client's protected token delivery file.
|
|
136
|
-
const endpoint = !profile && environment.OURS_DAEMON_ID
|
|
137
|
-
? resolveEndpoint(environment, false) : undefined;
|
|
138
|
-
const token = endpoint ? environment.OURS_API_TOKEN?.trim() || readDaemonConfig(environment).apiToken : undefined;
|
|
139
|
-
const options = profile ? {
|
|
133
|
+
const options = {
|
|
140
134
|
endpoint: profile.endpoint, expectedInstanceId: profile.expectedInstanceId,
|
|
141
135
|
credentialPath: profile.credentialPath,
|
|
142
136
|
sessionMode: 'external', leaseToken: this.leaseToken, env: {},
|
|
143
|
-
} : endpoint ? {
|
|
144
|
-
endpoint: endpoint.origin, expectedInstanceId: environment.OURS_DAEMON_ID,
|
|
145
|
-
sessionMode: 'external', leaseToken: this.leaseToken,
|
|
146
|
-
...(token ? { token } : { credentialPath: join(endpoint.stateDir, 'daemon-token') }),
|
|
147
|
-
} : {
|
|
148
|
-
env: environment,
|
|
149
|
-
leaseToken: this.leaseToken,
|
|
150
|
-
clientPid: process.pid,
|
|
151
|
-
fetch: notificationDeadlineFetch(this.deps.fetch ?? globalThis.fetch, this.deps.notificationRequestDeadlineMs ?? NOTIFICATION_REQUEST_DEADLINE_MS),
|
|
152
137
|
};
|
|
153
138
|
this.client = await (this.deps.attachClient?.(options) ?? attachOursClient(options));
|
|
154
139
|
this.terminalReleasePending = true;
|
package/dist/paths.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare const home: () => string;
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function deriveXdgRuntimeDir(env?: NodeJS.ProcessEnv, uid?: number | undefined, exists?: (p: string) => boolean): string | undefined;
|
|
13
13
|
export declare const stateRoot: () => string;
|
|
14
|
+
/** The Owner invitation file that tunnel setup writes itself after enrollment. */
|
|
15
|
+
export declare const workspaceOwnerInvite: () => string;
|
|
14
16
|
export declare const agentsRoot: () => string;
|
|
15
17
|
export declare const tmpRoot: () => string;
|
|
16
18
|
export declare const logsRoot: () => string;
|
package/dist/paths.js
CHANGED
|
@@ -21,6 +21,8 @@ export function deriveXdgRuntimeDir(env = process.env, uid = process.getuid?.(),
|
|
|
21
21
|
return env.XDG_RUNTIME_DIR;
|
|
22
22
|
}
|
|
23
23
|
export const stateRoot = () => join(home(), '.ours-fleet');
|
|
24
|
+
/** The Owner invitation file that tunnel setup writes itself after enrollment. */
|
|
25
|
+
export const workspaceOwnerInvite = () => join(stateRoot(), 'workspace', 'owner.invite');
|
|
24
26
|
export const agentsRoot = () => join(stateRoot(), 'agents');
|
|
25
27
|
export const tmpRoot = () => join(stateRoot(), 'tmp');
|
|
26
28
|
export const logsRoot = () => join(stateRoot(), 'logs');
|
package/dist/preset-migration.js
CHANGED
|
@@ -67,10 +67,35 @@ const V5_GENERATED_ROLE_DEFAULT_FINGERPRINTS = Object.freeze({
|
|
|
67
67
|
'agent_templates/Developer.yaml': 'fdd953aab72d042e62780dd273598745aae59521b39edf4876d7676bb7189c83',
|
|
68
68
|
'agent_templates/Critic.yaml': '3e98a28f17876061cfadf984351aa59fdbe19629e514eff52c74546545c64a91',
|
|
69
69
|
});
|
|
70
|
+
// The packaged Coordinator role of revisions 8 and 9 addressed a named owner channel that a
|
|
71
|
+
// fresh installation does not have. Untouched copies adopt the current role; edited ones stay.
|
|
72
|
+
const OWNER_CHANNEL_COORDINATOR_FINGERPRINTS = Object.freeze({
|
|
73
|
+
'roles/Coordinator.yaml': [
|
|
74
|
+
'8c8ad28d9bb9ddf9dba8c5c9c7859f25edd8fa10ebf833e2340124a6e49583ec',
|
|
75
|
+
'f0d8b169ad0a18051b57e5280b93cf01e05faa5c12f4e12bdf89973edf2ef58a',
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
// The packaged revision-10 LocalCoordinator continuity loop reread ROUTINES.md and the WORKLOG
|
|
79
|
+
// checkpoint on every 15-minute pass. Untouched copies adopt the current template; edited ones stay.
|
|
80
|
+
const REREADING_CONTINUITY_LOOP_FINGERPRINTS = Object.freeze({
|
|
81
|
+
'agent_templates/LocalCoordinator.yaml': [
|
|
82
|
+
'53889cd3987e25ca42be64ddcfa1cf46a73ab769070db144f5b7d86085734178',
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
// The packaged Developer, Critic and Engineer charters before they described one bounded
|
|
86
|
+
// self-reminder per peer wait. Untouched copies adopt the current text; edited ones stay.
|
|
87
|
+
const PEER_WAIT_REMINDER_FINGERPRINTS = Object.freeze({
|
|
88
|
+
'roles/Developer.yaml': ['2884366ce02760d66d3edbaed2adc83f2959fd7906a7cd3b5a8b90cf601bc3e6'],
|
|
89
|
+
'roles/Critic.yaml': ['998abdbc5159e8e1c26eb1ca09f9707b005ba1930bd5b7a4989c4d6893804c4a'],
|
|
90
|
+
'roles/Engineer.yaml': ['a361453ad32cde08797cf90fff17a35bde1871ccea17389448b44398b45ccfa5'],
|
|
91
|
+
});
|
|
70
92
|
const CURRENT_ROLE_DEFAULTS = new Set([
|
|
71
93
|
'roles/Coordinator.yaml', 'roles/LocalCoordinator.yaml', 'roles/Developer.yaml', 'roles/Critic.yaml',
|
|
94
|
+
'roles/Engineer.yaml',
|
|
72
95
|
'agent_templates/LocalCoordinator.yaml', 'agent_templates/Developer.yaml', 'agent_templates/Critic.yaml',
|
|
96
|
+
'agent_templates/Engineer.yaml',
|
|
73
97
|
'room_templates/single.yaml', 'room_templates/pair.yaml', 'room_templates/team.yaml',
|
|
98
|
+
'room_templates/engineering.yaml',
|
|
74
99
|
'agents/FleetCoordinator.yaml',
|
|
75
100
|
]);
|
|
76
101
|
export const legacyStarterMigrationManifest = Object.freeze({
|
|
@@ -193,6 +218,9 @@ export function migratePackagedRoleDefaults(configuration, options = {}, hooks =
|
|
|
193
218
|
...Object.keys(V3_ROLE_DEFAULT_FINGERPRINTS),
|
|
194
219
|
...Object.keys(V4_ROLE_DEFAULT_FINGERPRINTS),
|
|
195
220
|
...Object.keys(V5_ROLE_DEFAULT_FINGERPRINTS),
|
|
221
|
+
...Object.keys(OWNER_CHANNEL_COORDINATOR_FINGERPRINTS),
|
|
222
|
+
...Object.keys(REREADING_CONTINUITY_LOOP_FINGERPRINTS),
|
|
223
|
+
...Object.keys(PEER_WAIT_REMINDER_FINGERPRINTS),
|
|
196
224
|
]);
|
|
197
225
|
for (const relative of known) {
|
|
198
226
|
const path = join(root, relative);
|
|
@@ -206,6 +234,9 @@ export function migratePackagedRoleDefaults(configuration, options = {}, hooks =
|
|
|
206
234
|
V4_GENERATED_ROLE_DEFAULT_FINGERPRINTS[relative],
|
|
207
235
|
V5_ROLE_DEFAULT_FINGERPRINTS[relative],
|
|
208
236
|
V5_GENERATED_ROLE_DEFAULT_FINGERPRINTS[relative],
|
|
237
|
+
...(OWNER_CHANNEL_COORDINATOR_FINGERPRINTS[relative] ?? []),
|
|
238
|
+
...(REREADING_CONTINUITY_LOOP_FINGERPRINTS[relative] ?? []),
|
|
239
|
+
...(PEER_WAIT_REMINDER_FINGERPRINTS[relative] ?? []),
|
|
209
240
|
].some(expected => expected !== undefined && actual === expected);
|
|
210
241
|
if (recognized)
|
|
211
242
|
(CURRENT_ROLE_DEFAULTS.has(relative) ? replacements : removals).push(path);
|
|
@@ -258,6 +289,18 @@ export function migratePackagedRoleDefaults(configuration, options = {}, hooks =
|
|
|
258
289
|
unlinkSync(target);
|
|
259
290
|
copyFileSync(join(source, relative), target, constants.COPYFILE_EXCL);
|
|
260
291
|
chmodSync(target, 0o600);
|
|
292
|
+
// New Engineer seats use the existing Developer's selected brain. This
|
|
293
|
+
// preserves wizard/custom provider choices without copying permissions.
|
|
294
|
+
if (relative === 'agent_templates/Engineer.yaml' && classified.additions.includes(path)) {
|
|
295
|
+
const developer = join(root, 'agent_templates/Developer.yaml');
|
|
296
|
+
if (existsSync(developer)) {
|
|
297
|
+
const value = parseFleetDocument(developer, readFileSync(developer, 'utf8'), 'strict').value;
|
|
298
|
+
if (value.brain !== undefined && JSON.stringify(value.brain) !== JSON.stringify({ ref: 'claude-default' })) {
|
|
299
|
+
const bytes = readFileSync(target, 'utf8').replace('brain: { ref: claude-default }', () => `brain: ${JSON.stringify(value.brain)}`);
|
|
300
|
+
writeFileSync(target, bytes, { mode: 0o600 });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
261
304
|
fsyncPath(target);
|
|
262
305
|
}
|
|
263
306
|
for (const kind of ['roles', 'agent_templates', 'room_templates', 'agents'])
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which run of a process a PID names. A PID alone is not an identity: after a
|
|
3
|
+
* reboot or wraparound the same number belongs to an unrelated process, and a
|
|
4
|
+
* lock or claim keyed on it would then look held forever. The kernel boot id
|
|
5
|
+
* and the process start time (in clock ticks since boot) pin one incarnation.
|
|
6
|
+
* Both are Linux-only; elsewhere they are absent and callers stay PID-only.
|
|
7
|
+
*/
|
|
8
|
+
export interface ProcessIncarnation {
|
|
9
|
+
boot?: string;
|
|
10
|
+
start?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface IncarnationProbe {
|
|
13
|
+
bootId(): string | undefined;
|
|
14
|
+
startTime(pid: number): string | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare const procIncarnationProbe: IncarnationProbe;
|
|
17
|
+
export declare function processIncarnation(pid: number, probe?: IncarnationProbe): ProcessIncarnation;
|
|
18
|
+
/**
|
|
19
|
+
* True only when a recorded marker positively proves the live PID is a later
|
|
20
|
+
* process: a different boot, or a different start time. A marker that was not
|
|
21
|
+
* recorded, or cannot be read now, proves nothing and keeps the PID check.
|
|
22
|
+
*/
|
|
23
|
+
export declare function incarnationEnded(pid: number, recorded: ProcessIncarnation, probe?: IncarnationProbe): boolean;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
export const procIncarnationProbe = {
|
|
3
|
+
bootId() {
|
|
4
|
+
try {
|
|
5
|
+
return readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim() || undefined;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
startTime(pid) {
|
|
12
|
+
try {
|
|
13
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf8');
|
|
14
|
+
return stat.slice(stat.lastIndexOf(')') + 2).split(/\s+/)[19] || undefined;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export function processIncarnation(pid, probe = procIncarnationProbe) {
|
|
22
|
+
const boot = probe.bootId(), start = probe.startTime(pid);
|
|
23
|
+
return { ...(boot ? { boot } : {}), ...(start ? { start } : {}) };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* True only when a recorded marker positively proves the live PID is a later
|
|
27
|
+
* process: a different boot, or a different start time. A marker that was not
|
|
28
|
+
* recorded, or cannot be read now, proves nothing and keeps the PID check.
|
|
29
|
+
*/
|
|
30
|
+
export function incarnationEnded(pid, recorded, probe = procIncarnationProbe) {
|
|
31
|
+
if (typeof recorded.boot === 'string') {
|
|
32
|
+
const boot = probe.bootId();
|
|
33
|
+
if (boot && boot !== recorded.boot)
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (typeof recorded.start === 'string') {
|
|
37
|
+
const start = probe.startTime(pid);
|
|
38
|
+
if (start && start !== recorded.start)
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ReminderAttempt, UrgentReminderHooks } from '../session/arbiter.js';
|
|
2
|
+
import type { PromptOrigin } from '../session/types.js';
|
|
3
|
+
import type { ReminderEvent, ReminderRecord, ReminderStore } from './store.js';
|
|
4
|
+
/** The admission seam: the role's RoleTurnArbiter in production. */
|
|
5
|
+
export interface ReminderAdmitter {
|
|
6
|
+
tryReminder(text: string, origin: Extract<PromptOrigin, {
|
|
7
|
+
kind: 'self-reminder';
|
|
8
|
+
}>, beforeQueue: () => boolean, releaseGuard: () => boolean): Promise<ReminderAttempt>;
|
|
9
|
+
/** Urgent admission (see `RoleTurnArbiter.tryUrgentReminder`). Absent: urgent reminders are idle-only. */
|
|
10
|
+
tryUrgentReminder?(origin: Extract<PromptOrigin, {
|
|
11
|
+
kind: 'self-reminder';
|
|
12
|
+
}>, hooks: UrgentReminderHooks): Promise<ReminderAttempt>;
|
|
13
|
+
}
|
|
14
|
+
export interface ReminderManagerDeps {
|
|
15
|
+
now(): number;
|
|
16
|
+
setTimer(callback: () => void, ms: number): unknown;
|
|
17
|
+
clearTimer(timer: unknown): void;
|
|
18
|
+
log(line: string): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The dispatcher never sleeps longer than this while reminders are open, so a
|
|
22
|
+
* wall-clock jump (host suspend, NTP step) is noticed within a minute. With
|
|
23
|
+
* nothing open it arms no timer at all: an idle agent costs nothing.
|
|
24
|
+
*/
|
|
25
|
+
export declare const REMINDER_POLL_CEILING_MS = 60000;
|
|
26
|
+
export interface ReminderManagerHandle {
|
|
27
|
+
start(): void;
|
|
28
|
+
stop(): void;
|
|
29
|
+
/** Called after an agent tool changed the schedule so the timer reflects it. */
|
|
30
|
+
changed(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Turns due self-reminders into wakes for the agent that owns them.
|
|
34
|
+
*
|
|
35
|
+
* Runs inside that agent's runner, beside the role's turn arbiter. It starts
|
|
36
|
+
* only after the role's startup turn has succeeded and stops before the runner
|
|
37
|
+
* releases its runtime binding. Admission is idle-only by default: a wake
|
|
38
|
+
* never interrupts or queues behind work, and the session's release guard
|
|
39
|
+
* makes the durable `dispatched` claim at the moment the prompt reaches the
|
|
40
|
+
* model. A reminder created with `interrupt: true` is considered first and may
|
|
41
|
+
* ask an interruptible busy turn to stop once (`tryUrgentReminder`); the
|
|
42
|
+
* release guard is still the only path to the model.
|
|
43
|
+
*/
|
|
44
|
+
export declare class ReminderManager implements ReminderManagerHandle {
|
|
45
|
+
private readonly role;
|
|
46
|
+
private readonly store;
|
|
47
|
+
private readonly admitter;
|
|
48
|
+
private readonly deps;
|
|
49
|
+
private timer?;
|
|
50
|
+
private started;
|
|
51
|
+
private stopping;
|
|
52
|
+
private polling;
|
|
53
|
+
private busyStreak;
|
|
54
|
+
/** Consecutive re-arms with work already overdue; drives the spin backoff. */
|
|
55
|
+
private overdueStreak;
|
|
56
|
+
private readonly inFlight;
|
|
57
|
+
constructor(role: string, store: ReminderStore, admitter: ReminderAdmitter, deps: ReminderManagerDeps);
|
|
58
|
+
start(): void;
|
|
59
|
+
/** Synchronous: after this returns no timer is armed and every release guard refuses. */
|
|
60
|
+
stop(): void;
|
|
61
|
+
get isStopping(): boolean;
|
|
62
|
+
changed(): void;
|
|
63
|
+
/** Public fake-clock seam; the timer calls the same transition. */
|
|
64
|
+
poll(): Promise<void>;
|
|
65
|
+
private admit;
|
|
66
|
+
private guard;
|
|
67
|
+
private retryAt;
|
|
68
|
+
private schedule;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The wake text. It carries the agent's own title so the wake is legible, but
|
|
72
|
+
* the note is only returned by `fleet_reminder_inspect`, which also re-checks
|
|
73
|
+
* eligibility at the moment the agent acts.
|
|
74
|
+
*/
|
|
75
|
+
export declare function wakePrompt(event: ReminderEvent, reminder: ReminderRecord, now: number, retry: boolean): string;
|