@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,250 @@
|
|
|
1
|
+
/** Durable local room-layout controller.
|
|
2
|
+
* Uses native Cowork operations and a supervising Fleet's exact-instance port.
|
|
3
|
+
* Unknown mutation outcomes stop for reconciliation; they are never replayed.
|
|
4
|
+
*/
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { canonicalJson } from '../canonical-json.js';
|
|
8
|
+
import { replaceFileAtomically, withFileLock } from '../atomic-file.js';
|
|
9
|
+
const ownerReference = (owner) => ({ cid: owner.cid, role: owner.role, fingerprint: createHash('sha256').update(owner.invite).digest('hex') });
|
|
10
|
+
const own = (o, key) => Object.hasOwn(o, key);
|
|
11
|
+
function need(ok, message) { if (!ok)
|
|
12
|
+
throw Error(message); }
|
|
13
|
+
/** Room/participant keys cannot contain ':', so scoped instance keys cannot collide. */
|
|
14
|
+
function instanceKey(definition, participant, room) {
|
|
15
|
+
return definition.participants[participant].instance_scope === 'room' ? `${room}:${participant}` : participant;
|
|
16
|
+
}
|
|
17
|
+
export function validateLayout(def) {
|
|
18
|
+
need(Object.keys(def.rooms).length && Object.keys(def.participants).length, 'rooms and participants required');
|
|
19
|
+
for (const [key, participant] of Object.entries(def.participants)) {
|
|
20
|
+
need(participant.instance_scope === undefined || ['layout', 'room'].includes(participant.instance_scope), `invalid instance_scope for ${key}`);
|
|
21
|
+
if (participant.instance_scope === 'room')
|
|
22
|
+
need(typeof participant.agent_template === 'string' && participant.agent_template.trim(), `room-scoped participant ${key} requires agent_template`);
|
|
23
|
+
}
|
|
24
|
+
for (const [key, room] of Object.entries(def.rooms)) {
|
|
25
|
+
need(key.length && room.goal.trim() && room.members.length, 'room goal and members required');
|
|
26
|
+
need(new Set(room.members).size === room.members.length, 'duplicate participant in room');
|
|
27
|
+
for (const member of room.members)
|
|
28
|
+
need(own(def.participants, member), `unknown participant ${member}`);
|
|
29
|
+
}
|
|
30
|
+
for (const key of [...Object.keys(def.rooms), ...Object.keys(def.participants)])
|
|
31
|
+
need(/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(key) && !['constructor', 'prototype', '__proto__'].includes(key), 'invalid layout key');
|
|
32
|
+
}
|
|
33
|
+
export class RoomLayout {
|
|
34
|
+
file;
|
|
35
|
+
supervisor;
|
|
36
|
+
owner;
|
|
37
|
+
coworkAdapter;
|
|
38
|
+
coworkFactory;
|
|
39
|
+
constructor(file, cowork, supervisor, owner) {
|
|
40
|
+
this.file = file;
|
|
41
|
+
this.supervisor = supervisor;
|
|
42
|
+
this.owner = owner;
|
|
43
|
+
this.coworkFactory = typeof cowork === 'function' ? cowork : () => cowork;
|
|
44
|
+
}
|
|
45
|
+
get cowork() { return this.coworkAdapter ??= this.coworkFactory(); }
|
|
46
|
+
snapshot() { return JSON.parse(readFileSync(this.file, 'utf8')); }
|
|
47
|
+
save(s) { replaceFileAtomically(this.file, JSON.stringify(s, null, 2)); }
|
|
48
|
+
async verify(i) {
|
|
49
|
+
need(i.supervisor === this.supervisor.id || i.remote, 'remote binding unsupported');
|
|
50
|
+
need(i.launch && i.cid && i.session, 'incomplete instance reference');
|
|
51
|
+
await this.supervisor.verify(i);
|
|
52
|
+
}
|
|
53
|
+
async create(definition, controller, bindings = {}, agentTemplates) {
|
|
54
|
+
validateLayout(definition);
|
|
55
|
+
need(controller, 'controller required');
|
|
56
|
+
this.checkOwnerRoles(definition);
|
|
57
|
+
await withFileLock(this.file + '.lock', async () => {
|
|
58
|
+
need(!existsSync(this.file), 'layout instance already exists');
|
|
59
|
+
for (const key of Object.keys(bindings)) {
|
|
60
|
+
need(own(definition.participants, key), 'unknown binding');
|
|
61
|
+
need(definition.participants[key].instance_scope !== 'room', `binding unsupported for room-scoped participant ${key}`);
|
|
62
|
+
}
|
|
63
|
+
// Validate every supplied binding before any external mutation.
|
|
64
|
+
for (const [key, p] of Object.entries(definition.participants)) {
|
|
65
|
+
need(bindings[key] || p.agent_template, `binding required for ${key}`);
|
|
66
|
+
if (bindings[key])
|
|
67
|
+
await this.verify(bindings[key]);
|
|
68
|
+
}
|
|
69
|
+
for (const room of Object.values(definition.rooms)) {
|
|
70
|
+
const cids = room.members.flatMap(key => bindings[key] ? [bindings[key].cid] : []);
|
|
71
|
+
need(new Set(cids).size === cids.length, 'same instance cannot occupy two seats in one room');
|
|
72
|
+
}
|
|
73
|
+
const participants = {};
|
|
74
|
+
for (const [key, participant] of Object.entries(definition.participants)) {
|
|
75
|
+
if (participant.instance_scope === 'room') {
|
|
76
|
+
for (const [room, spec] of Object.entries(definition.rooms))
|
|
77
|
+
if (spec.members.includes(key))
|
|
78
|
+
participants[instanceKey(definition, key, room)] = { owned: true, participant: key, room };
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
participants[key] = { owned: !bindings[key], ...(bindings[key] ? { instance: bindings[key] } : {}) };
|
|
82
|
+
}
|
|
83
|
+
this.save({ version: 1, definition, controller, ...(this.owner ? { owner: ownerReference(this.owner) } : {}),
|
|
84
|
+
agent_templates: agentTemplates, participants, rooms: {}, order: [], closed: false });
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
checkOwnerRoles(definition) {
|
|
88
|
+
if (!this.owner)
|
|
89
|
+
return;
|
|
90
|
+
for (const room of Object.values(definition.rooms))
|
|
91
|
+
need(room.members.every(member => (room.roles?.[member] ?? member) !== this.owner.role), 'participant cannot use the owner role');
|
|
92
|
+
}
|
|
93
|
+
async operation(actor, work, cleanup = false) {
|
|
94
|
+
return withFileLock(this.file + '.lock', async () => {
|
|
95
|
+
const s = this.snapshot();
|
|
96
|
+
need(actor === s.controller, 'controller authorization required');
|
|
97
|
+
if (!cleanup) {
|
|
98
|
+
need(!s.closed && !s.closing, 'layout instance closing or closed');
|
|
99
|
+
need(!s.uncertain, `reconciliation required: ${s.uncertain}`);
|
|
100
|
+
}
|
|
101
|
+
return work(s);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async mutation(s, id, work, commit) {
|
|
105
|
+
s.uncertain = id;
|
|
106
|
+
this.save(s);
|
|
107
|
+
// On any error keep the cursor, even if the operation may have succeeded.
|
|
108
|
+
const result = await work();
|
|
109
|
+
commit(result);
|
|
110
|
+
delete s.uncertain;
|
|
111
|
+
this.save(s);
|
|
112
|
+
}
|
|
113
|
+
async activateRoom(s, key, spec) {
|
|
114
|
+
if (s.owner)
|
|
115
|
+
need(this.owner && canonicalJson(s.owner) === canonicalJson(ownerReference(this.owner)), 'room owner configuration changed');
|
|
116
|
+
this.checkOwnerRoles(s.definition);
|
|
117
|
+
need(s.rooms[key]?.state !== 'closed', 'room closed');
|
|
118
|
+
for (const member of spec.members) {
|
|
119
|
+
const p = s.participants[instanceKey(s.definition, member, key)];
|
|
120
|
+
const i = p?.instance;
|
|
121
|
+
if (i)
|
|
122
|
+
await this.verify(i);
|
|
123
|
+
need(!p?.retired, 'participant retired');
|
|
124
|
+
}
|
|
125
|
+
if (s.rooms[key]?.state === 'active') {
|
|
126
|
+
await this.assertRoomActive(s, key);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const room = s.rooms[key] ??= { spec, state: 'provisioning', ready: [] };
|
|
130
|
+
this.save(s);
|
|
131
|
+
for (const member of spec.members) {
|
|
132
|
+
const resolvedKey = instanceKey(s.definition, member, key), p = s.participants[resolvedKey];
|
|
133
|
+
if (!p.instance) {
|
|
134
|
+
const template = s.definition.participants[member]?.agent_template;
|
|
135
|
+
need(template, `no factory for ${member}`);
|
|
136
|
+
await this.mutation(s, `spawn:${resolvedKey}`, () => this.supervisor.spawn(resolvedKey, template), i => { p.instance = i; });
|
|
137
|
+
await this.verify(p.instance);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const roleFor = (member) => spec.roles?.[member] ?? member;
|
|
141
|
+
if (!room.native)
|
|
142
|
+
await this.mutation(s, `create:${key}`, () => this.cowork.createRoom({
|
|
143
|
+
room_name: `${key.slice(0, 24)}-${createHash('sha256').update(this.file + '\0' + key).digest('hex').slice(0, 24)}`,
|
|
144
|
+
goal: spec.goal, briefing: JSON.stringify({ goal: spec.goal, contract: spec.contract }),
|
|
145
|
+
quiet_membership: spec.quiet_membership ?? true, anonymous: spec.anonymous ?? false,
|
|
146
|
+
activation_requirements: [...new Set(spec.members.map(roleFor))].map(role => ({ role, count: spec.members.filter(m => roleFor(m) === role).length })),
|
|
147
|
+
}), native => { room.native = native; s.order.push(key); });
|
|
148
|
+
if (s.owner && !room.owner_ready)
|
|
149
|
+
await this.mutation(s, `owner:${key}`, async () => {
|
|
150
|
+
await this.cowork.acceptInvite(room.native.room_id, this.owner.invite, { role: s.owner.role, expected_cid: s.owner.cid });
|
|
151
|
+
await this.cowork.setRoleCommands(room.native.room_id, { role: s.owner.role, commands: ['*'] });
|
|
152
|
+
}, () => { room.owner_ready = true; });
|
|
153
|
+
for (const member of spec.members) {
|
|
154
|
+
if (room.ready.includes(member))
|
|
155
|
+
continue;
|
|
156
|
+
const i = s.participants[instanceKey(s.definition, member, key)].instance;
|
|
157
|
+
await this.verify(i);
|
|
158
|
+
const seats = await this.cowork.getSeats(room.native.room_id);
|
|
159
|
+
if (!seats.some(seat => seat.identity_cid === i.cid && seat.role === roleFor(member) && seat.seat_state !== 'removed')) {
|
|
160
|
+
await this.mutation(s, `admit:${key}:${member}`, async () => {
|
|
161
|
+
const invite = i.remote ? '' : (await this.cowork.issueInvite(room.native.room_id, { mode: 'one_time', role: roleFor(member), min_accepts: 1 })).invite;
|
|
162
|
+
await this.supervisor.join(i, invite, room.native.identity_cid, { roomId: room.native.room_id, role: roleFor(member) });
|
|
163
|
+
}, () => { });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
await this.assertRoomActive(s, key);
|
|
167
|
+
// Admission of all required seats precedes any participant work.
|
|
168
|
+
for (const member of spec.members) {
|
|
169
|
+
if (room.ready.includes(member))
|
|
170
|
+
continue;
|
|
171
|
+
const i = s.participants[instanceKey(s.definition, member, key)].instance;
|
|
172
|
+
await this.verify(i);
|
|
173
|
+
await this.mutation(s, `assignment:${key}:${member}`, () => this.supervisor.assign(i, {
|
|
174
|
+
id: `${key}:${member}`, room_id: room.native.room_id, room_cid: room.native.identity_cid,
|
|
175
|
+
participant: member, room_role: roleFor(member), goal: spec.goal, contract: spec.contract,
|
|
176
|
+
}), () => { room.ready.push(member); });
|
|
177
|
+
}
|
|
178
|
+
room.state = 'active';
|
|
179
|
+
this.save(s);
|
|
180
|
+
}
|
|
181
|
+
activate(actor, key) {
|
|
182
|
+
return this.operation(actor, async (s) => {
|
|
183
|
+
need(own(s.definition.rooms, key), 'unknown room');
|
|
184
|
+
await this.activateRoom(s, key, s.definition.rooms[key]);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async assertRoomActive(s, key) {
|
|
188
|
+
const room = s.rooms[key], native = await this.cowork.getRoom(room.native.room_id);
|
|
189
|
+
need(native?.identity_cid === room.native.identity_cid && native.state === 'active', 'native room missing, changed or inactive');
|
|
190
|
+
if (s.owner)
|
|
191
|
+
need(native.seats.some(seat => seat.identity_cid.toLowerCase() === s.owner.cid.toLowerCase()
|
|
192
|
+
&& seat.role === s.owner.role && seat.seat_state === 'active'), 'owner membership not active');
|
|
193
|
+
need(room.spec.members.every(member => native.seats.some(seat => seat.identity_cid === s.participants[instanceKey(s.definition, member, key)].instance.cid
|
|
194
|
+
&& seat.role === (room.spec.roles?.[member] ?? member) && seat.seat_state === 'active')), 'membership not active');
|
|
195
|
+
}
|
|
196
|
+
async archiveRoom(s, key) {
|
|
197
|
+
const room = s.rooms[key];
|
|
198
|
+
need(room?.native, 'room not created');
|
|
199
|
+
if (room.state === 'closed')
|
|
200
|
+
return;
|
|
201
|
+
const native = await this.cowork.getRoom(room.native.room_id);
|
|
202
|
+
if (native) {
|
|
203
|
+
need(native.identity_cid === room.native.identity_cid, 'native room identity changed');
|
|
204
|
+
if (native.state !== 'closed')
|
|
205
|
+
await this.cowork.closeRoom(room.native.room_id);
|
|
206
|
+
}
|
|
207
|
+
room.state = 'closed';
|
|
208
|
+
this.save(s);
|
|
209
|
+
}
|
|
210
|
+
closeRoom(actor, key) {
|
|
211
|
+
return this.operation(actor, s => this.archiveRoom(s, key), true);
|
|
212
|
+
}
|
|
213
|
+
close(actor) {
|
|
214
|
+
return this.operation(actor, async (s) => {
|
|
215
|
+
if (s.closed)
|
|
216
|
+
return;
|
|
217
|
+
s.closing = true;
|
|
218
|
+
this.save(s);
|
|
219
|
+
const errors = [];
|
|
220
|
+
for (const key of [...s.order].reverse()) {
|
|
221
|
+
try {
|
|
222
|
+
await this.archiveRoom(s, key);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
errors.push(`room ${key}: ${String(error)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
for (const [key, p] of Object.entries(s.participants))
|
|
229
|
+
if (p.owned && p.instance && !p.retired) {
|
|
230
|
+
try {
|
|
231
|
+
need(p.instance.supervisor === this.supervisor.id, 'remote binding unsupported');
|
|
232
|
+
await this.supervisor.retire(p.instance);
|
|
233
|
+
p.retired = true;
|
|
234
|
+
this.save(s);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
errors.push(`participant ${key}: ${String(error)}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Clean known resources without erasing evidence of an unknown creation outcome.
|
|
241
|
+
if (s.uncertain)
|
|
242
|
+
errors.push(`known resources cleaned where possible; inspection still required: ${s.uncertain}`);
|
|
243
|
+
if (errors.length)
|
|
244
|
+
throw Error(`layout cleanup incomplete: ${errors.join('; ')}`);
|
|
245
|
+
s.closed = true;
|
|
246
|
+
delete s.closing;
|
|
247
|
+
this.save(s);
|
|
248
|
+
}, true);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readRoomReadiness } from '../agent-ours/service.js';
|
|
2
|
+
import { controlRequest } from '../session/control.js';
|
|
3
|
+
import { readTempSupervisor, tempSupervisorLiveness } from '../temp-lifecycle.js';
|
|
4
|
+
import type { CoworkAdapter } from './cowork-adapter.js';
|
|
5
|
+
import type { RoomOrchestrationRecord, TaskRecord } from './types.js';
|
|
6
|
+
export type TaskReadinessIssue = {
|
|
7
|
+
state: 'degraded' | 'unknown';
|
|
8
|
+
reason: string;
|
|
9
|
+
member?: string;
|
|
10
|
+
};
|
|
11
|
+
export interface LiveReadinessDeps {
|
|
12
|
+
supervisor?: typeof readTempSupervisor;
|
|
13
|
+
liveness?: typeof tempSupervisorLiveness;
|
|
14
|
+
readiness?: typeof readRoomReadiness;
|
|
15
|
+
control?: typeof controlRequest;
|
|
16
|
+
}
|
|
17
|
+
/** Read-only observation. A failed probe never grants authority to replace a seat. */
|
|
18
|
+
export declare function taskLiveReadiness(task: TaskRecord, room: RoomOrchestrationRecord | undefined, cowork: Pick<CoworkAdapter, 'getRoom'>, deps?: LiveReadinessDeps): Promise<TaskReadinessIssue | undefined>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { realExec } from '../exec.js';
|
|
2
|
+
import { agentDir } from '../paths.js';
|
|
3
|
+
import { readRoomReadiness } from '../agent-ours/service.js';
|
|
4
|
+
import { controlRequest } from '../session/control.js';
|
|
5
|
+
import { readTempSupervisor, tempSupervisorLiveness } from '../temp-lifecycle.js';
|
|
6
|
+
/** Read-only observation. A failed probe never grants authority to replace a seat. */
|
|
7
|
+
export async function taskLiveReadiness(task, room, cowork, deps = {}) {
|
|
8
|
+
const degraded = (reason, member) => ({ state: 'degraded', reason, member });
|
|
9
|
+
const unknown = (reason, member) => ({ state: 'unknown', reason, member });
|
|
10
|
+
if (!room || task.state !== 'active' || task.room_id !== room.room_id || room.state !== 'active' || room.close || task.terminal_intent
|
|
11
|
+
|| room.task_id !== task.task_id || !room.room_identity_cid
|
|
12
|
+
|| task.room_identity_cid !== room.room_identity_cid)
|
|
13
|
+
return degraded('room_record_mismatch');
|
|
14
|
+
const baseExpected = room.template_snapshot?.members.reduce((n, member) => n + member.count, 0);
|
|
15
|
+
const expected = baseExpected === undefined ? undefined : baseExpected + (room.additional_member_templates ?? []).reduce((n, t) => n + t.members.reduce((m, s) => m + s.count, 0), 0);
|
|
16
|
+
if (expected === undefined || room.member_seats.length !== expected
|
|
17
|
+
|| new Set(room.member_seats.map(seat => seat.role_name)).size !== expected
|
|
18
|
+
|| new Set(room.member_seats.map(seat => seat.identity_cid)).size !== expected)
|
|
19
|
+
return degraded('member_roster_mismatch');
|
|
20
|
+
let remote;
|
|
21
|
+
try {
|
|
22
|
+
remote = await cowork.getRoom(room.room_id);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return unknown('room_probe_unavailable');
|
|
26
|
+
}
|
|
27
|
+
if (!remote || remote.room_id !== room.room_id || remote.identity_cid !== room.room_identity_cid
|
|
28
|
+
|| remote.state !== 'active')
|
|
29
|
+
return degraded('room_identity_or_state_mismatch');
|
|
30
|
+
if (room.owner_seat_cid && remote.seats.filter(seat => seat.identity_cid.toLowerCase() === room.owner_seat_cid.toLowerCase() && seat.seat_state === 'active').length !== 1)
|
|
31
|
+
return degraded('owner_seat_missing');
|
|
32
|
+
for (const seat of room.member_seats) {
|
|
33
|
+
const member = seat.role_name;
|
|
34
|
+
if (!/^[A-Za-z0-9_-]+$/.test(member) || seat.seat_state !== 'active' || !seat.identity_cid || !seat.invite_id
|
|
35
|
+
|| seat.launch?.state !== 'launched' || !seat.launch.launch_id || seat.retirement)
|
|
36
|
+
return degraded('member_record_incomplete', member);
|
|
37
|
+
const matches = remote.seats.filter(item => item.display_name === member && item.seat_state !== 'removed');
|
|
38
|
+
if (matches.length !== 1 || matches[0].identity_cid !== seat.identity_cid
|
|
39
|
+
|| matches[0].invite_id !== seat.invite_id || matches[0].role !== seat.cowork_role
|
|
40
|
+
|| matches[0].seat_state !== 'active')
|
|
41
|
+
return degraded('member_seat_mismatch', member);
|
|
42
|
+
const dir = agentDir(member, true);
|
|
43
|
+
try {
|
|
44
|
+
const supervisor = (deps.supervisor ?? readTempSupervisor)(dir);
|
|
45
|
+
if (!supervisor)
|
|
46
|
+
return unknown('supervisor_record_missing', member);
|
|
47
|
+
if (supervisor.role !== member || supervisor.launchId !== seat.launch.launch_id)
|
|
48
|
+
return degraded('supervisor_launch_mismatch', member);
|
|
49
|
+
const live = await (deps.liveness ?? tempSupervisorLiveness)(dir, {
|
|
50
|
+
exec: (cmd, args, opts) => realExec(cmd, args, { ...opts, timeout: 2_000 }),
|
|
51
|
+
});
|
|
52
|
+
if (live === 'stopped')
|
|
53
|
+
return degraded('supervisor_stopped', member);
|
|
54
|
+
if (live !== 'running')
|
|
55
|
+
return unknown('supervisor_liveness_unknown', member);
|
|
56
|
+
const ready = (deps.readiness ?? readRoomReadiness)(room.room_identity_cid, member);
|
|
57
|
+
if (!ready || ready.room !== room.room_id || ready.invite !== seat.invite_id || ready.cid !== seat.identity_cid)
|
|
58
|
+
return degraded('member_readiness_mismatch', member);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return unknown('supervisor_probe_unavailable', member);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const response = await (deps.control ?? controlRequest)(dir, { command: 'status', controller: false }, 2_000);
|
|
65
|
+
if (!response.ok)
|
|
66
|
+
return unknown('control_unavailable', member);
|
|
67
|
+
const status = response.result;
|
|
68
|
+
if (status?.alive === false || status?.readiness === 'failed')
|
|
69
|
+
return degraded('agent_not_ready', member);
|
|
70
|
+
if (status?.alive !== true || !['idle', 'running', 'awaiting_permission'].includes(status.readiness ?? ''))
|
|
71
|
+
return unknown('agent_readiness_unknown', member);
|
|
72
|
+
const after = (deps.supervisor ?? readTempSupervisor)(dir);
|
|
73
|
+
if (!after || after.role !== member || after.launchId !== seat.launch.launch_id)
|
|
74
|
+
return degraded('supervisor_launch_changed', member);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return unknown('control_unavailable', member);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const memberCids = new Set(room.member_seats.map(seat => seat.identity_cid));
|
|
81
|
+
const memberRoles = new Set(room.member_seats.map(seat => seat.cowork_role));
|
|
82
|
+
if (remote.seats.some(seat => seat.seat_state === 'active' && memberRoles.has(seat.role)
|
|
83
|
+
&& !memberCids.has(seat.identity_cid) && seat.identity_cid.toLowerCase() !== room.owner_seat_cid?.toLowerCase()))
|
|
84
|
+
return degraded('untracked_member_seats');
|
|
85
|
+
}
|
|
@@ -6,6 +6,7 @@ export interface RoomTaskMember {
|
|
|
6
6
|
}
|
|
7
7
|
/** Build the complete task text Fleet places directly in a temporary member's briefing. */
|
|
8
8
|
export declare function buildRoomMemberTask(input: {
|
|
9
|
+
workspace?: string;
|
|
9
10
|
taskId?: string;
|
|
10
11
|
roomId: string;
|
|
11
12
|
roomIdentityCid: string;
|
|
@@ -7,6 +7,8 @@ export function buildRoomMemberTask(input) {
|
|
|
7
7
|
`Fleet Task ${input.taskId ?? '(standalone)'} — ${member.cowork_role} in room ${input.roomId}`,
|
|
8
8
|
'',
|
|
9
9
|
];
|
|
10
|
+
if (input.workspace)
|
|
11
|
+
lines.push(`Task-owned workspace: ${input.workspace}`, 'Start and keep all execution artifacts, dependency checkouts, and Git worktrees inside this workspace.', 'Clone repositories inside this workspace before adding worktrees; never attach to an external Git common directory.', 'Use distinct per-agent branches/directories for concurrent edits. Configured cwd is source context, not artifact ownership.', 'Completion, cancellation and room retirement retain artifacts. Only explicit owner deletion removes them.', 'Do not delete the workspace or its ownership marker yourself.', '');
|
|
10
12
|
if (input.goal)
|
|
11
13
|
lines.push(`Goal: ${input.goal}`);
|
|
12
14
|
if (input.brief)
|
|
@@ -3,6 +3,7 @@ import type { RoomOrchestrationRecord, TemplateSnapshot } from './types.js';
|
|
|
3
3
|
import { type FleetConfig } from '../config.js';
|
|
4
4
|
export declare function getBinPath(): string;
|
|
5
5
|
export interface ProvisionMembersInput {
|
|
6
|
+
configPath?: string;
|
|
6
7
|
cfg: FleetConfig;
|
|
7
8
|
cowork: CoworkAdapter;
|
|
8
9
|
roomId: string;
|
|
@@ -12,6 +13,8 @@ export interface ProvisionMembersInput {
|
|
|
12
13
|
brief?: string;
|
|
13
14
|
goal?: string;
|
|
14
15
|
startupWait?: Partial<StartupWaitPolicy>;
|
|
16
|
+
/** Append only the supplied new slots to an already active room. */
|
|
17
|
+
append?: boolean;
|
|
15
18
|
}
|
|
16
19
|
export interface StartupWaitPolicy {
|
|
17
20
|
timeoutMs: number;
|
|
@@ -21,6 +24,17 @@ export interface StartupWaitPolicy {
|
|
|
21
24
|
sleep(ms: number): Promise<void>;
|
|
22
25
|
}
|
|
23
26
|
export declare function provisionMembers(input: ProvisionMembersInput): Promise<RoomOrchestrationRecord>;
|
|
27
|
+
/** Reconcile proven, admitted launches without any spawn, archive, invite or recovery path. */
|
|
28
|
+
export declare function reconcileExistingTaskMembers(input: {
|
|
29
|
+
taskId: string;
|
|
30
|
+
checkOnly?: boolean;
|
|
31
|
+
cowork: Pick<CoworkAdapter, 'getRoom'>;
|
|
32
|
+
expectedLaunches: ReadonlyArray<{
|
|
33
|
+
role_name: string;
|
|
34
|
+
launch_id: string;
|
|
35
|
+
identity_cid: string;
|
|
36
|
+
}>;
|
|
37
|
+
}): Promise<RoomOrchestrationRecord>;
|
|
24
38
|
export declare function cleanupMembers(input: {
|
|
25
39
|
roomId: string;
|
|
26
40
|
taskId?: string;
|