@ours.network/fleet 1.2.0-nightly.3 → 1.2.0-nightly.31
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 +158 -28
- package/dist/account-origin.d.ts +2 -0
- package/dist/account-origin.js +6 -0
- package/dist/agent-ours/bridge.d.ts +3 -0
- package/dist/agent-ours/bridge.js +178 -0
- package/dist/agent-ours/controller.d.ts +14 -0
- package/dist/agent-ours/controller.js +60 -0
- 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 +23 -0
- package/dist/agent-ours/file-rpc.js +123 -0
- package/dist/agent-ours/harness.d.ts +14 -0
- package/dist/agent-ours/harness.js +72 -0
- package/dist/agent-ours/mcp-endpoint.d.ts +15 -0
- package/dist/agent-ours/mcp-endpoint.js +111 -0
- package/dist/agent-ours/runtime.d.ts +59 -0
- package/dist/agent-ours/runtime.js +283 -0
- package/dist/agent-ours/service.d.ts +23 -0
- package/dist/agent-ours/service.js +372 -0
- package/dist/agent-ours/state.d.ts +45 -0
- package/dist/agent-ours/state.js +95 -0
- package/dist/agent-ours/wire.d.ts +14 -0
- package/dist/agent-ours/wire.js +55 -0
- package/dist/application/conversation-history.d.ts +25 -0
- package/dist/application/conversation-history.js +189 -0
- package/dist/application/fleet-query-service.d.ts +1 -1
- package/dist/application/fleet-query-service.js +2 -2
- package/dist/application/legacy-supervisor-identity.d.ts +7 -0
- package/dist/application/legacy-supervisor-identity.js +43 -0
- 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/room-layout-definitions.d.ts +45 -0
- package/dist/application/room-layout-definitions.js +130 -0
- package/dist/application/session-control.d.ts +18 -0
- package/dist/application/session-control.js +54 -3
- package/dist/application/supervisor-ours-tools.d.ts +159 -0
- package/dist/application/supervisor-ours-tools.js +113 -0
- package/dist/application/task-layouts.d.ts +91 -0
- package/dist/application/task-layouts.js +249 -0
- package/dist/application/task-room-service.d.ts +99 -3
- package/dist/application/task-room-service.js +296 -31
- package/dist/atomic-file.d.ts +5 -0
- package/dist/atomic-file.js +62 -1
- package/dist/briefing.js +10 -59
- package/dist/build-info.json +6 -4
- package/dist/capabilities.d.ts +3 -1
- package/dist/capabilities.js +4 -0
- package/dist/cli.js +131 -5
- package/dist/client-profile.d.ts +5 -16
- package/dist/client-profile.js +4 -112
- package/dist/config.d.ts +4 -0
- package/dist/config.js +7 -0
- package/dist/creation.d.ts +1 -1
- package/dist/creation.js +5 -16
- package/dist/daemon-recovery.d.ts +1 -8
- package/dist/daemon-recovery.js +8 -113
- package/dist/docs.d.ts +3 -3
- package/dist/docs.js +43 -23
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +46 -59
- package/dist/erased-resources.d.ts +9 -0
- package/dist/erased-resources.js +87 -0
- package/dist/fleet-command-audit.d.ts +1 -0
- package/dist/fleet-command-audit.js +12 -7
- package/dist/harness/agent-session.d.ts +2 -0
- package/dist/harness/claude-code-session.js +4 -2
- 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-session.js +9 -2
- package/dist/harness/codex.d.ts +3 -2
- package/dist/harness/codex.js +4 -3
- package/dist/harness/hermes-session.js +7 -1
- package/dist/init-wizard.js +20 -9
- package/dist/isolation/policy.js +2 -0
- package/dist/isolation/types.d.ts +5 -0
- package/dist/monitor.d.ts +1 -34
- package/dist/monitor.js +24 -151
- package/dist/notifications/fleet-producer.d.ts +18 -0
- package/dist/notifications/fleet-producer.js +129 -0
- package/dist/notifications/outbox.d.ts +31 -0
- package/dist/notifications/outbox.js +104 -0
- package/dist/owner-channel/channel.d.ts +3 -0
- package/dist/owner-channel/channel.js +34 -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/preset-migration.js +15 -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 +34 -5
- package/dist/rooms-tasks/close.d.ts +5 -2
- package/dist/rooms-tasks/close.js +208 -28
- package/dist/rooms-tasks/config.js +3 -1
- package/dist/rooms-tasks/cowork-adapter.d.ts +6 -4
- package/dist/rooms-tasks/cowork-adapter.js +11 -117
- package/dist/rooms-tasks/cowork-http.d.ts +3 -0
- package/dist/rooms-tasks/cowork-http.js +70 -0
- package/dist/rooms-tasks/deletion.d.ts +1 -1
- package/dist/rooms-tasks/deletion.js +74 -5
- package/dist/rooms-tasks/erasure.d.ts +6 -0
- package/dist/rooms-tasks/erasure.js +169 -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-service.d.ts +42 -0
- package/dist/rooms-tasks/layout-service.js +185 -0
- package/dist/rooms-tasks/layout.d.ts +114 -0
- package/dist/rooms-tasks/layout.js +250 -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-startup.d.ts +1 -0
- package/dist/rooms-tasks/member-startup.js +2 -0
- package/dist/rooms-tasks/provision.d.ts +14 -0
- package/dist/rooms-tasks/provision.js +182 -48
- package/dist/rooms-tasks/room-state.d.ts +4 -2
- package/dist/rooms-tasks/room-state.js +53 -8
- package/dist/rooms-tasks/task-state.d.ts +42 -7
- package/dist/rooms-tasks/task-state.js +153 -23
- package/dist/rooms-tasks/types.d.ts +28 -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 +26 -0
- package/dist/rooms-tasks/workspace.js +195 -0
- package/dist/runner.d.ts +23 -3
- package/dist/runner.js +581 -494
- package/dist/session/acp.d.ts +3 -0
- package/dist/session/acp.js +14 -0
- package/dist/session/arbiter.d.ts +3 -0
- package/dist/session/arbiter.js +20 -2
- package/dist/session/codex-app-server-transport.js +1 -1
- package/dist/session/codex-app-server.d.ts +3 -0
- package/dist/session/codex-app-server.js +25 -1
- package/dist/session/control.d.ts +10 -1
- package/dist/session/control.js +37 -2
- package/dist/session/conversation-normalizer.d.ts +2 -1
- package/dist/session/conversation-normalizer.js +1 -1
- package/dist/session/conversation-types.d.ts +5 -3
- package/dist/session/task-notice.d.ts +14 -0
- package/dist/session/task-notice.js +13 -0
- package/dist/session/types.d.ts +3 -0
- package/dist/socket-path.d.ts +2 -0
- package/dist/socket-path.js +22 -0
- package/dist/spawn.js +19 -16
- package/dist/startup-readiness.d.ts +13 -0
- package/dist/startup-readiness.js +38 -0
- package/dist/subscriptions/cli.d.ts +78 -0
- package/dist/subscriptions/cli.js +186 -0
- package/dist/subscriptions/launch.d.ts +37 -0
- package/dist/subscriptions/launch.js +93 -0
- package/dist/subscriptions/login.d.ts +75 -0
- package/dist/subscriptions/login.js +182 -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/launchd.js +2 -1
- package/dist/supervisor/systemd.js +9 -23
- package/dist/temp-idle.d.ts +17 -0
- package/dist/temp-idle.js +42 -0
- package/dist/temp-lifecycle.d.ts +6 -1
- package/dist/temp-lifecycle.js +29 -13
- package/dist/temp-supervisor-recovery.d.ts +3 -0
- package/dist/temp-supervisor-recovery.js +46 -0
- package/dist/watchdog/briefing.js +3 -16
- package/dist/watchdog/run.js +19 -5
- package/dist/web/agent-attachments.d.ts +29 -0
- package/dist/web/agent-attachments.js +162 -0
- package/dist/web/auth.d.ts +28 -2
- package/dist/web/auth.js +81 -8
- package/dist/web/available-port.d.ts +2 -0
- package/dist/web/available-port.js +23 -0
- package/dist/web/control.d.ts +3 -2
- package/dist/web/control.js +11 -7
- 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 +23 -0
- package/dist/web/prefix-gateway.js +156 -0
- package/dist/web/runtime.d.ts +4 -0
- package/dist/web/runtime.js +106 -20
- package/dist/web/server.d.ts +11 -0
- package/dist/web/server.js +445 -31
- package/dist/web/service.d.ts +11 -2
- package/dist/web/service.js +30 -4
- package/dist/web/workspace-devices.d.ts +29 -0
- package/dist/web/workspace-devices.js +84 -0
- package/dist/web/workspace-tunnel.d.ts +1 -0
- package/dist/web/workspace-tunnel.js +32 -0
- package/dist/web-app/assets/FleetApp-D58F4xje.css +1 -0
- package/dist/web-app/assets/FleetApp-DP5cBY0o.js +302 -0
- package/dist/web-app/assets/FleetApp-DP5cBY0o.js.map +1 -0
- package/dist/web-app/assets/abnfDiagram-VCTEODGH-BvJIz7wN.js +2 -0
- package/dist/web-app/assets/abnfDiagram-VCTEODGH-BvJIz7wN.js.map +1 -0
- package/dist/web-app/assets/arc-AT_BEfpe.js +2 -0
- package/dist/web-app/assets/arc-AT_BEfpe.js.map +1 -0
- package/dist/web-app/assets/architectureDiagram-5GKGNRK7-vSgJa9Xb.js +37 -0
- package/dist/web-app/assets/architectureDiagram-5GKGNRK7-vSgJa9Xb.js.map +1 -0
- package/dist/web-app/assets/blockDiagram-I7D4REHJ-DCFk_4Kv.js +130 -0
- package/dist/web-app/assets/blockDiagram-I7D4REHJ-DCFk_4Kv.js.map +1 -0
- package/dist/web-app/assets/browser-CMIwJ_8L.js +9 -0
- package/dist/web-app/assets/browser-CMIwJ_8L.js.map +1 -0
- package/dist/web-app/assets/c4Diagram-7LVT6UL2-8J_dVUtF.js +39 -0
- package/dist/web-app/assets/c4Diagram-7LVT6UL2-8J_dVUtF.js.map +1 -0
- package/dist/web-app/assets/channel-BHCBlfND.js +2 -0
- package/dist/web-app/assets/channel-BHCBlfND.js.map +1 -0
- package/dist/web-app/assets/chunk-2Q5K7J3B-31RX-jnL.js +2 -0
- package/dist/web-app/assets/chunk-2Q5K7J3B-31RX-jnL.js.map +1 -0
- package/dist/web-app/assets/chunk-5VM5RSS4-CFF8_ZJH.js +16 -0
- package/dist/web-app/assets/chunk-5VM5RSS4-CFF8_ZJH.js.map +1 -0
- package/dist/web-app/assets/chunk-F27PBJKO-Dx1l5wLI.js +2 -0
- package/dist/web-app/assets/chunk-F27PBJKO-Dx1l5wLI.js.map +1 -0
- package/dist/web-app/assets/chunk-IMKFNOWR-Ba2_9bl_.js +232 -0
- package/dist/web-app/assets/chunk-IMKFNOWR-Ba2_9bl_.js.map +1 -0
- package/dist/web-app/assets/chunk-JWPE2WC7-_mnRB2OH.js +2 -0
- package/dist/web-app/assets/chunk-JWPE2WC7-_mnRB2OH.js.map +1 -0
- package/dist/web-app/assets/chunk-POPQ4Y6H-B8jQTxQO.js +2 -0
- package/dist/web-app/assets/chunk-POPQ4Y6H-B8jQTxQO.js.map +1 -0
- package/dist/web-app/assets/chunk-SVP7TREG-BO_Jnb_c.js +89 -0
- package/dist/web-app/assets/chunk-SVP7TREG-BO_Jnb_c.js.map +1 -0
- package/dist/web-app/assets/chunk-TICWLB2K-ZYZ9hFu5.js +207 -0
- package/dist/web-app/assets/chunk-TICWLB2K-ZYZ9hFu5.js.map +1 -0
- package/dist/web-app/assets/chunk-XXDRQBXY-ByUAYXI3.js +2 -0
- package/dist/web-app/assets/chunk-XXDRQBXY-ByUAYXI3.js.map +1 -0
- package/dist/web-app/assets/classDiagram-ZZMXUADV-Ddx7RAuT.js +2 -0
- package/dist/web-app/assets/classDiagram-ZZMXUADV-Ddx7RAuT.js.map +1 -0
- package/dist/web-app/assets/classDiagram-v2-VYDZK3BY-Ddx7RAuT.js +2 -0
- package/dist/web-app/assets/classDiagram-v2-VYDZK3BY-Ddx7RAuT.js.map +1 -0
- package/dist/web-app/assets/cose-bilkent-JH36ORCC-BuOGJgHG.js +2 -0
- package/dist/web-app/assets/cose-bilkent-JH36ORCC-BuOGJgHG.js.map +1 -0
- package/dist/web-app/assets/cynefin-OW5HDTMX-DLksGPh8.js +179 -0
- package/dist/web-app/assets/cynefin-OW5HDTMX-DLksGPh8.js.map +1 -0
- package/dist/web-app/assets/cynefinDiagram-5FMLGOSQ-nJQb5qZR.js +63 -0
- package/dist/web-app/assets/cynefinDiagram-5FMLGOSQ-nJQb5qZR.js.map +1 -0
- package/dist/web-app/assets/cytoscape.esm-CtNdOvlO.js +332 -0
- package/dist/web-app/assets/cytoscape.esm-CtNdOvlO.js.map +1 -0
- package/dist/web-app/assets/dagre-GXQ25YYZ-CCF5O_UD.js +5 -0
- package/dist/web-app/assets/dagre-GXQ25YYZ-CCF5O_UD.js.map +1 -0
- package/dist/web-app/assets/defaultLocale-DX6XiGOO.js +2 -0
- package/dist/web-app/assets/defaultLocale-DX6XiGOO.js.map +1 -0
- package/dist/web-app/assets/diagram-S7CK7UJ4-C88au4NC.js +31 -0
- package/dist/web-app/assets/diagram-S7CK7UJ4-C88au4NC.js.map +1 -0
- package/dist/web-app/assets/diagram-UQ7AKVKN-B4QnPs7U.js +42 -0
- package/dist/web-app/assets/diagram-UQ7AKVKN-B4QnPs7U.js.map +1 -0
- package/dist/web-app/assets/diagram-VSXAHHWV-DeANdVWA.js +4 -0
- package/dist/web-app/assets/diagram-VSXAHHWV-DeANdVWA.js.map +1 -0
- package/dist/web-app/assets/diagram-VX7I27RA-YzlB_2AY.js +25 -0
- package/dist/web-app/assets/diagram-VX7I27RA-YzlB_2AY.js.map +1 -0
- package/dist/web-app/assets/diagram-Z3DM3KII-YY9NFaz_.js +25 -0
- package/dist/web-app/assets/diagram-Z3DM3KII-YY9NFaz_.js.map +1 -0
- package/dist/web-app/assets/ebnfDiagram-PWID7BFC-Cqu9kHUC.js +2 -0
- package/dist/web-app/assets/ebnfDiagram-PWID7BFC-Cqu9kHUC.js.map +1 -0
- package/dist/web-app/assets/erDiagram-RLTQ6QDP-IHi93MdG.js +100 -0
- package/dist/web-app/assets/erDiagram-RLTQ6QDP-IHi93MdG.js.map +1 -0
- package/dist/web-app/assets/flowDiagram-HODETNUW-19bm7W5P.js +169 -0
- package/dist/web-app/assets/flowDiagram-HODETNUW-19bm7W5P.js.map +1 -0
- package/dist/web-app/assets/ganttDiagram-EL5Y4UJY-BvCqvyiB.js +293 -0
- package/dist/web-app/assets/ganttDiagram-EL5Y4UJY-BvCqvyiB.js.map +1 -0
- package/dist/web-app/assets/gitGraphDiagram-WWUBYQGX-G4Ubl8Fs.js +107 -0
- package/dist/web-app/assets/gitGraphDiagram-WWUBYQGX-G4Ubl8Fs.js.map +1 -0
- package/dist/web-app/assets/index-C4BdeFB9.css +1 -0
- package/dist/web-app/assets/index-Dtn3ZY6J.js +430 -0
- package/dist/web-app/assets/index-Dtn3ZY6J.js.map +1 -0
- package/dist/web-app/assets/infoDiagram-27XIBGKW-B6rtfbuC.js +3 -0
- package/dist/web-app/assets/infoDiagram-27XIBGKW-B6rtfbuC.js.map +1 -0
- package/dist/web-app/assets/init-Gi6I4Gst.js +2 -0
- package/dist/web-app/assets/init-Gi6I4Gst.js.map +1 -0
- package/dist/web-app/assets/ishikawaDiagram-5VMMS53U-Lp8q1D21.js +71 -0
- package/dist/web-app/assets/ishikawaDiagram-5VMMS53U-Lp8q1D21.js.map +1 -0
- package/dist/web-app/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/web-app/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/web-app/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/web-app/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/web-app/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/web-app/assets/journeyDiagram-3NMN7TZE-Av03B9l3.js +140 -0
- package/dist/web-app/assets/journeyDiagram-3NMN7TZE-Av03B9l3.js.map +1 -0
- package/dist/web-app/assets/kanban-definition-UXKFOSKX-Ddd3_ejb.js +90 -0
- package/dist/web-app/assets/kanban-definition-UXKFOSKX-Ddd3_ejb.js.map +1 -0
- package/dist/web-app/assets/katex-HP8lGamR.js +258 -0
- package/dist/web-app/assets/katex-HP8lGamR.js.map +1 -0
- package/dist/web-app/assets/layout-CNjBeOlp.js +2 -0
- package/dist/web-app/assets/layout-CNjBeOlp.js.map +1 -0
- package/dist/web-app/assets/linear-DDONU9Ir.js +2 -0
- package/dist/web-app/assets/linear-DDONU9Ir.js.map +1 -0
- package/dist/web-app/assets/mermaid.core-B9X3C61k.js +313 -0
- package/dist/web-app/assets/mermaid.core-B9X3C61k.js.map +1 -0
- package/dist/web-app/assets/mindmap-definition-YA3MSWOX-I2UME2Ce.js +97 -0
- package/dist/web-app/assets/mindmap-definition-YA3MSWOX-I2UME2Ce.js.map +1 -0
- package/dist/web-app/assets/ordinal-Cboi1Yqb.js +2 -0
- package/dist/web-app/assets/ordinal-Cboi1Yqb.js.map +1 -0
- package/dist/web-app/assets/pegDiagram-XKGWAZYB-BER8lNbi.js +2 -0
- package/dist/web-app/assets/pegDiagram-XKGWAZYB-BER8lNbi.js.map +1 -0
- package/dist/web-app/assets/pieDiagram-E7YTZNPT-FVWVg8rH.js +40 -0
- package/dist/web-app/assets/pieDiagram-E7YTZNPT-FVWVg8rH.js.map +1 -0
- package/dist/web-app/assets/quadrantDiagram-AXDQQJYC-YlvT1u77.js +8 -0
- package/dist/web-app/assets/quadrantDiagram-AXDQQJYC-YlvT1u77.js.map +1 -0
- package/dist/web-app/assets/railroadDiagram-O6MQD6OU-CvxT6dMW.js +2 -0
- package/dist/web-app/assets/railroadDiagram-O6MQD6OU-CvxT6dMW.js.map +1 -0
- package/dist/web-app/assets/requirementDiagram-BXWQKSXE-Caav4EkP.js +85 -0
- package/dist/web-app/assets/requirementDiagram-BXWQKSXE-Caav4EkP.js.map +1 -0
- package/dist/web-app/assets/sankeyDiagram-P5KCCOFB-B5Uw70Gn.js +41 -0
- package/dist/web-app/assets/sankeyDiagram-P5KCCOFB-B5Uw70Gn.js.map +1 -0
- package/dist/web-app/assets/sequenceDiagram-WJ2MYXX4-D2SLKVJl.js +163 -0
- package/dist/web-app/assets/sequenceDiagram-WJ2MYXX4-D2SLKVJl.js.map +1 -0
- package/dist/web-app/assets/sizeCapture-INFHLROL-BVaBfbwa.js +2 -0
- package/dist/web-app/assets/sizeCapture-INFHLROL-BVaBfbwa.js.map +1 -0
- package/dist/web-app/assets/stateDiagram-D77RDMKH-BlV9y2tf.js +2 -0
- package/dist/web-app/assets/stateDiagram-D77RDMKH-BlV9y2tf.js.map +1 -0
- package/dist/web-app/assets/stateDiagram-v2-MP3YSRHH-BU4Tu2pp.js +2 -0
- package/dist/web-app/assets/stateDiagram-v2-MP3YSRHH-BU4Tu2pp.js.map +1 -0
- package/dist/web-app/assets/swimlanes-42K2YHIH-Pv3Wv8c7.js +2 -0
- package/dist/web-app/assets/swimlanes-42K2YHIH-Pv3Wv8c7.js.map +1 -0
- package/dist/web-app/assets/swimlanesDiagram-VR7AAH4N-BNKjOvPH.js +9 -0
- package/dist/web-app/assets/swimlanesDiagram-VR7AAH4N-BNKjOvPH.js.map +1 -0
- package/dist/web-app/assets/timeline-definition-24CTP7MA-C9TOilaR.js +121 -0
- package/dist/web-app/assets/timeline-definition-24CTP7MA-C9TOilaR.js.map +1 -0
- package/dist/web-app/assets/vennDiagram-4TSXK5OY-DeSDprN4.js +35 -0
- package/dist/web-app/assets/vennDiagram-4TSXK5OY-DeSDprN4.js.map +1 -0
- package/dist/web-app/assets/wardleyDiagram-VM6X3IG4-SulZn-nm.js +79 -0
- package/dist/web-app/assets/wardleyDiagram-VM6X3IG4-SulZn-nm.js.map +1 -0
- package/dist/web-app/assets/xychartDiagram-S5SC5T6Z-CC6MrQ0h.js +8 -0
- package/dist/web-app/assets/xychartDiagram-S5SC5T6Z-CC6MrQ0h.js.map +1 -0
- package/dist/web-app/fleet-index.html +19 -0
- package/dist/web-app/fleet.webmanifest +37 -0
- package/dist/web-app/icons/apple-touch-icon.png +0 -0
- package/dist/web-app/icons/favicon-16.png +0 -0
- package/dist/web-app/icons/favicon-32.png +0 -0
- package/dist/web-app/icons/icon-192-maskable.png +0 -0
- package/dist/web-app/icons/icon-192.png +0 -0
- package/dist/web-app/icons/icon-512-maskable.png +0 -0
- package/dist/web-app/icons/icon-512.png +0 -0
- package/dist/web-app/index.html +9 -7
- package/dist/web-app/manifest.webmanifest +10 -8
- package/dist/web-app/sw.js +210 -40
- package/dist/web-app/version.json +1 -0
- package/dist/web-app/workspace-install.sh +148 -0
- package/dist/workspace-enrollment.d.ts +28 -0
- package/dist/workspace-enrollment.js +129 -0
- package/docs/room-layouts.md +227 -0
- package/docs/task-workspaces.md +130 -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 +14 -17
- package/presets/README.md +78 -0
- package/presets/brain-catalog.json +8 -2
- package/presets/fleet/agent_templates/Engineer.yaml +5 -0
- 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 +22 -0
- package/presets/fleet/roles/Engineer.yaml +40 -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/offline.html +0 -18
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, symlinkSync } from 'node:fs';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { replaceFileAtomically, withFileLock } from '../atomic-file.js';
|
|
5
|
+
import { FleetError } from '../application/errors.js';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { stateRoot } from '../paths.js';
|
|
8
|
+
export const SUBSCRIPTION_PROVIDERS = ['claude', 'codex'];
|
|
9
|
+
export const DEFAULT_PROFILE_ID = 'default';
|
|
10
|
+
export const PIN_FILE = '.subscription-pin.json';
|
|
11
|
+
export const OBSERVED_USAGE_FILE = '.subscription-usage.json';
|
|
12
|
+
/** Non-history configuration shared from the base home into each new profile. */
|
|
13
|
+
const SHARED_CONFIG = {
|
|
14
|
+
claude: ['settings.json', 'CLAUDE.md', 'plugins', 'skills', 'agents', 'commands'],
|
|
15
|
+
codex: ['config.toml', 'AGENTS.md', 'plugins', 'skills', 'rules'],
|
|
16
|
+
};
|
|
17
|
+
export const PROFILE_ID_RE = /^[a-z0-9][a-z0-9-]{0,40}$/;
|
|
18
|
+
export const subscriptionsRoot = () => join(stateRoot(), 'subscriptions');
|
|
19
|
+
const stateFile = () => join(subscriptionsRoot(), 'state.json');
|
|
20
|
+
const lockPath = () => join(subscriptionsRoot(), '.lock');
|
|
21
|
+
/**
|
|
22
|
+
* The CLI's own default home, adopted as the `default` profile. This follows
|
|
23
|
+
* `$HOME` like the CLIs do, not OURS_FLEET_HOME (which may relocate Fleet state).
|
|
24
|
+
*/
|
|
25
|
+
export const baseHome = (provider) => join(homedir(), provider === 'claude' ? '.claude' : '.codex');
|
|
26
|
+
export function isProvider(value) {
|
|
27
|
+
return value === 'claude' || value === 'codex';
|
|
28
|
+
}
|
|
29
|
+
export function profileHome(provider, profileId) {
|
|
30
|
+
if (profileId === DEFAULT_PROFILE_ID)
|
|
31
|
+
return baseHome(provider);
|
|
32
|
+
if (!PROFILE_ID_RE.test(profileId))
|
|
33
|
+
throw new FleetError('invalid_request', 'invalid profile id');
|
|
34
|
+
return join(subscriptionsRoot(), provider, profileId);
|
|
35
|
+
}
|
|
36
|
+
function initialState() {
|
|
37
|
+
const provider = () => ({
|
|
38
|
+
activeProfileId: DEFAULT_PROFILE_ID,
|
|
39
|
+
profiles: [{ id: DEFAULT_PROFILE_ID, label: 'Default (existing login)', createdAt: new Date(0).toISOString() }],
|
|
40
|
+
});
|
|
41
|
+
return { version: 1, providers: { claude: provider(), codex: provider() } };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Read the state. The file is only ever replaced by an atomic rename, so a
|
|
45
|
+
* reader (including a launching agent) sees either the old or the new active
|
|
46
|
+
* profile, never a torn write.
|
|
47
|
+
*/
|
|
48
|
+
export function readSubscriptionState() {
|
|
49
|
+
let text;
|
|
50
|
+
try {
|
|
51
|
+
text = readFileSync(stateFile(), 'utf8');
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error.code === 'ENOENT')
|
|
55
|
+
return initialState();
|
|
56
|
+
throw unreadable();
|
|
57
|
+
}
|
|
58
|
+
// Fail closed: a damaged state file must not silently move launches to another account.
|
|
59
|
+
let raw;
|
|
60
|
+
try {
|
|
61
|
+
raw = JSON.parse(text);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw unreadable();
|
|
65
|
+
}
|
|
66
|
+
const state = initialState();
|
|
67
|
+
const providers = raw?.providers;
|
|
68
|
+
if (!providers || typeof providers !== 'object')
|
|
69
|
+
throw unreadable();
|
|
70
|
+
for (const provider of SUBSCRIPTION_PROVIDERS) {
|
|
71
|
+
const p = providers[provider];
|
|
72
|
+
if (!p || !Array.isArray(p.profiles) || typeof p.activeProfileId !== 'string')
|
|
73
|
+
throw unreadable();
|
|
74
|
+
const profiles = p.profiles;
|
|
75
|
+
if (profiles.some(x => !x || typeof x.id !== 'string' || (x.id !== DEFAULT_PROFILE_ID && !PROFILE_ID_RE.test(x.id))))
|
|
76
|
+
throw unreadable();
|
|
77
|
+
if (!profiles.some(x => x.id === DEFAULT_PROFILE_ID))
|
|
78
|
+
profiles.unshift(state.providers[provider].profiles[0]);
|
|
79
|
+
if (!profiles.some(x => x.id === p.activeProfileId))
|
|
80
|
+
throw unreadable();
|
|
81
|
+
const active = p.activeProfileId;
|
|
82
|
+
state.providers[provider] = {
|
|
83
|
+
activeProfileId: active,
|
|
84
|
+
profiles: profiles.map(x => ({ id: x.id, label: String(x.label ?? x.id).slice(0, 80), createdAt: String(x.createdAt ?? '') })),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return state;
|
|
88
|
+
}
|
|
89
|
+
const unreadable = () => new FleetError('prerequisite_unavailable', `subscription state ${stateFile()} is unreadable or invalid; fix or remove it before starting agents`);
|
|
90
|
+
/** Serialised read-modify-write of the state under a cross-process lock. */
|
|
91
|
+
export async function updateSubscriptionState(fn) {
|
|
92
|
+
mkdirSync(subscriptionsRoot(), { recursive: true, mode: 0o700 });
|
|
93
|
+
return withFileLock(lockPath(), () => {
|
|
94
|
+
const state = readSubscriptionState();
|
|
95
|
+
const result = fn(state);
|
|
96
|
+
replaceFileAtomically(stateFile(), `${JSON.stringify(state, null, 2)}\n`, 0o600);
|
|
97
|
+
return result;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create an empty profile home (not yet registered). Shared, non-history
|
|
102
|
+
* configuration is symlinked from the base home; credentials and session
|
|
103
|
+
* history stay per profile.
|
|
104
|
+
*/
|
|
105
|
+
export function createProfileHome(provider) {
|
|
106
|
+
const id = `p-${randomBytes(6).toString('hex')}`;
|
|
107
|
+
const dir = profileHome(provider, id);
|
|
108
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
109
|
+
const base = baseHome(provider);
|
|
110
|
+
for (const name of SHARED_CONFIG[provider]) {
|
|
111
|
+
const src = join(base, name);
|
|
112
|
+
if (existsSync(src)) {
|
|
113
|
+
try {
|
|
114
|
+
symlinkSync(src, join(dir, name));
|
|
115
|
+
}
|
|
116
|
+
catch { /* optional convenience */ }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return { id, home: dir };
|
|
120
|
+
}
|
|
121
|
+
/** Remove a non-default profile home. Never touches the adopted default. */
|
|
122
|
+
export function removeProfileHome(provider, profileId) {
|
|
123
|
+
if (profileId === DEFAULT_PROFILE_ID)
|
|
124
|
+
return;
|
|
125
|
+
rmSync(profileHome(provider, profileId), { recursive: true, force: true });
|
|
126
|
+
}
|
|
127
|
+
export function readPin(stateDir, provider) {
|
|
128
|
+
try {
|
|
129
|
+
const pin = JSON.parse(readFileSync(join(stateDir, PIN_FILE), 'utf8'));
|
|
130
|
+
if (provider)
|
|
131
|
+
return pin[provider];
|
|
132
|
+
return Object.values(pin)[0];
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export function writePin(stateDir, pin) {
|
|
139
|
+
replaceFileAtomically(join(stateDir, PIN_FILE), `${JSON.stringify({ [pin.provider]: pin })}\n`, 0o600);
|
|
140
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clientConfigPath } from '../client-profile.js';
|
|
1
2
|
import { existsSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
2
3
|
import { join } from 'node:path';
|
|
3
4
|
import { home, logsRoot } from '../paths.js';
|
|
@@ -22,7 +23,7 @@ const xml = (value) => value
|
|
|
22
23
|
.replaceAll("'", ''');
|
|
23
24
|
function plist(name, binPath) {
|
|
24
25
|
const log = join(logsRoot(), `${name}.log`);
|
|
25
|
-
const config = process.env
|
|
26
|
+
const config = clientConfigPath(process.env);
|
|
26
27
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
27
28
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
28
29
|
<plist version="1.0">
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clientConfigPath } from '../client-profile.js';
|
|
1
2
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
3
|
import { delimiter, dirname, join } from 'node:path';
|
|
3
4
|
import { userInfo } from 'node:os';
|
|
@@ -69,30 +70,10 @@ export function makeSystemdBackend(exec = realExec) {
|
|
|
69
70
|
dirname(process.execPath),
|
|
70
71
|
...(process.env.PATH ?? '').split(delimiter),
|
|
71
72
|
].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.
|
|
73
|
+
// Persist one profile path, never a URL or service port. Profile updates
|
|
74
|
+
// are picked up by every fresh process, including lingering user services.
|
|
93
75
|
const unitEnv = ['PATH=' + servicePath];
|
|
94
|
-
|
|
95
|
-
unitEnv.push('OURS_CONFIG=' + process.env.OURS_CONFIG);
|
|
76
|
+
unitEnv.push('OURS_CONFIG=' + clientConfigPath(process.env));
|
|
96
77
|
const environmentLines = unitEnv
|
|
97
78
|
.map(value => `Environment="${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/%/g, '%%')}"`)
|
|
98
79
|
.join('\n');
|
|
@@ -100,10 +81,15 @@ export function makeSystemdBackend(exec = realExec) {
|
|
|
100
81
|
writeFileSync(join(unitDir, UNIT_TEMPLATE), `[Unit]
|
|
101
82
|
Description=ours-fleet agent %i
|
|
102
83
|
After=default.target
|
|
84
|
+
StartLimitIntervalSec=0
|
|
103
85
|
|
|
104
86
|
[Service]
|
|
105
87
|
Type=simple
|
|
106
88
|
${environmentLines}
|
|
89
|
+
# Wait outside the runner so boot-time daemon unavailability cannot consume
|
|
90
|
+
# the agent crash budget. Selection comes from the same role and profile.
|
|
91
|
+
ExecStartPre=${unitArg(process.execPath)} ${unitArg(binPath)} _wait-daemon %i
|
|
92
|
+
TimeoutStartSec=270
|
|
107
93
|
ExecStart=${unitArg(process.execPath)} ${unitArg(binPath)} _run %i
|
|
108
94
|
# The RUNNER owns the child-session restart loop, with a counted, backed-off
|
|
109
95
|
# circuit breaker. systemd must only recover the runner PROCESS crashing —
|
|
@@ -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
|
@@ -5,7 +5,7 @@ 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
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';
|
|
8
|
+
export type TempTerminationReason = 'idle-timeout' | 'identity-closed' | 'session-ended' | 'operator-stop' | 'supervisor-signal' | 'supervisor-recycle' | 'startup-failure' | 'stale-supervisor';
|
|
9
9
|
export interface TempSupervisorRecord {
|
|
10
10
|
version: 1;
|
|
11
11
|
role: string;
|
|
@@ -44,6 +44,11 @@ export declare function makeTempSupervisorLauncher(options?: {
|
|
|
44
44
|
}): SupervisorLauncher;
|
|
45
45
|
export declare function markTempSupervisorActive(dir: string, pid?: number): Promise<void>;
|
|
46
46
|
export declare function requestedTempStopReason(dir: string): 'operator-stop' | undefined;
|
|
47
|
+
/** Explicit erasure removes only exact retired role/launch events. */
|
|
48
|
+
export declare function eraseTerminationEvents(launches: ReadonlyArray<{
|
|
49
|
+
role: string;
|
|
50
|
+
launchId: string;
|
|
51
|
+
}>): void;
|
|
47
52
|
/** Move retired state out of the live roster without deleting any evidence. */
|
|
48
53
|
export declare function archiveTempState(role: string, reason: TempTerminationReason, outcome: TempTerminationRecord['outcome'], detail: string, now?: Date): string | undefined;
|
|
49
54
|
/** Resolve only an exact role+launch archive; names and timestamps are never proof. */
|
package/dist/temp-lifecycle.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, } from 'node:fs';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { basename, join } from 'node:path';
|
|
4
|
-
import { replaceFileAtomically, withFileLock } from './atomic-file.js';
|
|
4
|
+
import { replaceFileAtomically, withFileLock, withSynchronousFileLock } from './atomic-file.js';
|
|
5
5
|
import { realExec } from './exec.js';
|
|
6
6
|
import { stateRoot, tmpRoot } from './paths.js';
|
|
7
7
|
export const TEMP_SUPERVISOR_FILE = '.temp-supervisor.json';
|
|
@@ -59,7 +59,7 @@ export function makeTempSupervisorLauncher(options = {}) {
|
|
|
59
59
|
const supervisor = options.supervisor ?? process.env.OURS_FLEET_SUPERVISOR;
|
|
60
60
|
return async (binPath, args, dir) => {
|
|
61
61
|
const inherited = [
|
|
62
|
-
'HOME', 'PATH', 'XDG_RUNTIME_DIR', 'OURS_FLEET_HOME', 'CODEX_HOME',
|
|
62
|
+
'HOME', 'PATH', 'XDG_RUNTIME_DIR', 'OURS_FLEET_HOME', 'OURS_FLEET_SOCKET_ROOT', 'CODEX_HOME',
|
|
63
63
|
// Preserve runtime selection across the service-manager boundary, including
|
|
64
64
|
// an explicit empty value which selects the bundle over manager defaults.
|
|
65
65
|
'CODEX_PATH',
|
|
@@ -133,18 +133,34 @@ function appendTermination(dir, record) {
|
|
|
133
133
|
replaceFileAtomically(join(dir, TEMP_GLOBAL_TERMINATION_MARKER), line);
|
|
134
134
|
}
|
|
135
135
|
function appendGlobalTermination(line, checkExisting = false) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
withSynchronousFileLock(join(stateRoot(), 'locks', 'termination-journal'), () => {
|
|
137
|
+
mkdirSync(archiveRoot(), { recursive: true, mode: 0o700 });
|
|
138
|
+
const path = join(archiveRoot(), 'terminations.jsonl');
|
|
139
|
+
// Recovery may revisit a .retiring directory after a crash between the
|
|
140
|
+
// global append and final rename. Avoid duplicating that exact event.
|
|
141
|
+
if (checkExisting) {
|
|
142
|
+
try {
|
|
143
|
+
if (readFileSync(path, 'utf8').split('\n').includes(line.trimEnd()))
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
catch { /* the journal does not exist yet */ }
|
|
144
147
|
}
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
+
appendFileSync(path, line, { mode: 0o600 });
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/** Explicit erasure removes only exact retired role/launch events. */
|
|
152
|
+
export function eraseTerminationEvents(launches) {
|
|
153
|
+
withSynchronousFileLock(join(stateRoot(), 'locks', 'termination-journal'), () => {
|
|
154
|
+
const path = join(archiveRoot(), 'terminations.jsonl');
|
|
155
|
+
if (!existsSync(path))
|
|
156
|
+
return;
|
|
157
|
+
const lines = readFileSync(path, 'utf8').split('\n').filter(Boolean);
|
|
158
|
+
const kept = lines.filter(line => {
|
|
159
|
+
const row = JSON.parse(line);
|
|
160
|
+
return !launches.some(launch => launch.role === row.role && launch.launchId === row.launchId);
|
|
161
|
+
});
|
|
162
|
+
replaceFileAtomically(path, kept.length ? kept.join('\n') + '\n' : '');
|
|
163
|
+
});
|
|
148
164
|
}
|
|
149
165
|
/** Pick a sibling path without overwriting evidence from an earlier attempt. */
|
|
150
166
|
function collisionSafeArchivePaths(targetBase, retiringBase) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { runTemp, SupervisorRecycleRequiredError } from './runner.js';
|
|
3
|
+
export const TEMP_RECYCLE_EXIT = 75;
|
|
4
|
+
/** Keep the service's main process alive while replacing a PID-scoped worker. */
|
|
5
|
+
export async function runTempSupervisor(name, entrypoint, initial = () => runTemp(name)) {
|
|
6
|
+
try {
|
|
7
|
+
await initial();
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
if (!(error instanceof SupervisorRecycleRequiredError))
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
15
|
+
const child = spawn(process.execPath, [entrypoint, '_run-temp-worker', name], {
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
env: process.env,
|
|
18
|
+
});
|
|
19
|
+
let stopping = false;
|
|
20
|
+
const term = () => {
|
|
21
|
+
stopping = true;
|
|
22
|
+
child.kill('SIGTERM');
|
|
23
|
+
}, interrupt = () => {
|
|
24
|
+
stopping = true;
|
|
25
|
+
child.kill('SIGINT');
|
|
26
|
+
};
|
|
27
|
+
process.on('SIGTERM', term);
|
|
28
|
+
process.on('SIGINT', interrupt);
|
|
29
|
+
let code;
|
|
30
|
+
try {
|
|
31
|
+
code = await new Promise((resolve, reject) => {
|
|
32
|
+
child.once('error', reject);
|
|
33
|
+
child.once('exit', resolve);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
process.off('SIGTERM', term);
|
|
38
|
+
process.off('SIGINT', interrupt);
|
|
39
|
+
}
|
|
40
|
+
if (code === 0 || stopping)
|
|
41
|
+
return;
|
|
42
|
+
if (code !== TEMP_RECYCLE_EXIT)
|
|
43
|
+
throw Error(`Temporary supervisor replacement exited with ${code}`);
|
|
44
|
+
}
|
|
45
|
+
throw Error('Temporary supervisor recycle limit reached; identity retained for explicit recovery');
|
|
46
|
+
}
|
|
@@ -5,22 +5,9 @@ import { formatDuration } from '../duration.js';
|
|
|
5
5
|
* wasn't verified when configured, fall back to createTool on first run.
|
|
6
6
|
*/
|
|
7
7
|
function bindSection(heading, wd, v, guarantee) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (guarantee === 'unverified') {
|
|
12
|
-
L.push(`- This identity was NOT verified when this watchdog was configured, so it may not`);
|
|
13
|
-
L.push(` exist yet. If binding reports no such identity, call **${v.createTool}** name`);
|
|
14
|
-
L.push(` "${wd.identity}" once to mint it on this first run, then you are bound. Re-binding`);
|
|
15
|
-
L.push(' your OWN identity is always allowed.');
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
L.push(`- It was ${guarantee === 'created' ? 'created' : 'verified to exist'} when this`);
|
|
19
|
-
L.push(' watchdog was configured, so binding should succeed. If it unexpectedly reports no');
|
|
20
|
-
L.push(` such identity, call **${v.createTool}** name "${wd.identity}" once and report the`);
|
|
21
|
-
L.push(' discrepancy — something removed it since.');
|
|
22
|
-
}
|
|
23
|
-
return L;
|
|
8
|
+
return ['', '## Assigned identity',
|
|
9
|
+
`Your supervisor has bound your identity **${wd.identity}**. The ours tools are ready.`,
|
|
10
|
+
'No identity setup or skill reading is required.'];
|
|
24
11
|
}
|
|
25
12
|
/**
|
|
26
13
|
* Render a watchdog run's fixed contract (briefing.md-equivalent for a one-shot clean-context
|
package/dist/watchdog/run.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { preparePermanentAssignment, releaseManagedAgent } from '../agent-ours/service.js';
|
|
1
2
|
import { closeSync, existsSync, openSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
2
3
|
import { spawn as spawnChild } from 'node:child_process';
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -7,8 +8,7 @@ import { acquireRunLock, formatRunId, pruneReports, releaseRunLock, writeReport
|
|
|
7
8
|
import { generateNotifierBriefing, generateWatchdogBriefing } from './briefing.js';
|
|
8
9
|
import { computeDigest, reconcileLedger, readLedger, writeLedger } from './alerts.js';
|
|
9
10
|
import { applyRole } from '../ops.js';
|
|
10
|
-
import {
|
|
11
|
-
import { runOnce, START_STAGGER_FILE } from '../runner.js';
|
|
11
|
+
import { runOnce, loadTempRole, START_STAGGER_FILE } from '../runner.js';
|
|
12
12
|
import { agentDir, tmpRoot } from '../paths.js';
|
|
13
13
|
import { loadConfig, ROLE_NAME_RE, } from '../config.js';
|
|
14
14
|
import { getAdapter } from '../harness/registry.js';
|
|
@@ -53,6 +53,7 @@ async function killIfNeeded(reason, child, roleName, sleep) {
|
|
|
53
53
|
if (reason === 'stable')
|
|
54
54
|
await sleep(HARVEST_GRACE_MS);
|
|
55
55
|
child.kill();
|
|
56
|
+
await child.exited;
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
function defaultLaunchChild(binPath, roleName, runDir) {
|
|
@@ -139,7 +140,7 @@ export async function executeWatchdogRun(wd, deps) {
|
|
|
139
140
|
rmSync(runDir, { recursive: true, force: true });
|
|
140
141
|
let report;
|
|
141
142
|
try {
|
|
142
|
-
const guarantee =
|
|
143
|
+
const guarantee = { state: 'unverified' }; // The child supervisor provisions before its harness starts.
|
|
143
144
|
const cfg = deps.cfg ?? loadConfig();
|
|
144
145
|
const discovered = wd.watchExplicit
|
|
145
146
|
? []
|
|
@@ -272,7 +273,7 @@ export async function executeNotifierRun(wd, text, deps) {
|
|
|
272
273
|
// A crashed previous run can leave the temp dir behind; start clean.
|
|
273
274
|
if (existsSync(runDir))
|
|
274
275
|
rmSync(runDir, { recursive: true, force: true });
|
|
275
|
-
const guarantee =
|
|
276
|
+
const guarantee = { state: 'unverified' }; // The child supervisor provisions before its harness starts.
|
|
276
277
|
const cfg = deps.cfg ?? loadConfig();
|
|
277
278
|
const role = buildWatchdogRole(wd, cfg);
|
|
278
279
|
const dir = applyRole(role, { temp: true, identityGuarantee: guarantee.state });
|
|
@@ -317,5 +318,18 @@ export async function executeNotifierRun(wd, text, deps) {
|
|
|
317
318
|
}
|
|
318
319
|
/** What `_run-watchdog` calls: one supervised session, no cleanup — the parent harvests. */
|
|
319
320
|
export async function runWatchdogAgent(name) {
|
|
320
|
-
|
|
321
|
+
const role = loadTempRole(name);
|
|
322
|
+
await preparePermanentAssignment(role);
|
|
323
|
+
let stopping = false;
|
|
324
|
+
const stop = () => { stopping = true; };
|
|
325
|
+
process.on('SIGTERM', stop);
|
|
326
|
+
process.on('SIGINT', stop);
|
|
327
|
+
try {
|
|
328
|
+
await runOnce(name, { temp: true, identityLifetime: 'permanent' }, { shouldStop: () => stopping });
|
|
329
|
+
}
|
|
330
|
+
finally {
|
|
331
|
+
process.off('SIGTERM', stop);
|
|
332
|
+
process.off('SIGINT', stop);
|
|
333
|
+
await releaseManagedAgent(role);
|
|
334
|
+
}
|
|
321
335
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const MAX_ATTACHMENT_BYTES: number;
|
|
2
|
+
export declare const MAX_ATTACHMENT_BODY: number;
|
|
3
|
+
export interface AgentAttachment {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
sha256: string;
|
|
9
|
+
generation: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function storeAgentAttachment(stateDir: string, generation: string, input: unknown): AgentAttachment;
|
|
12
|
+
export declare function attachmentPrompt(stateDir: string, generation: string, ids: unknown, text: string): string;
|
|
13
|
+
export declare function readAgentAttachment(stateDir: string, id: string): {
|
|
14
|
+
record: AgentAttachment;
|
|
15
|
+
bytes: Buffer;
|
|
16
|
+
};
|
|
17
|
+
interface AttachmentPresentation {
|
|
18
|
+
generation: string;
|
|
19
|
+
commandId: string;
|
|
20
|
+
text: string;
|
|
21
|
+
transportDigest: string;
|
|
22
|
+
ids: string[];
|
|
23
|
+
}
|
|
24
|
+
/** Written before admission so a lost HTTP response cannot lose the visible message. */
|
|
25
|
+
export declare function storeAttachmentPresentation(stateDir: string, value: AttachmentPresentation): void;
|
|
26
|
+
export declare function prepareAttachmentPresentation(stateDir: string, generation: string, commandId: string, ids: string[], text: string, transport: string): void;
|
|
27
|
+
/** Never infer attachments by stripping user text or interpreting a marker. */
|
|
28
|
+
export declare function presentAttachmentEvent<T>(stateDir: string | undefined, roleId: string, event: T): T;
|
|
29
|
+
export {};
|