@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
package/dist/doctor.js
CHANGED
|
@@ -10,7 +10,6 @@ import { agentDir, deriveXdgRuntimeDir } from './paths.js';
|
|
|
10
10
|
import { resolveIsolation, harnessRuntimeDir } from './isolation/policy.js';
|
|
11
11
|
import { hermesConfiguredProvider } from './harness/hermes-startup.js';
|
|
12
12
|
import { makeBubblewrapBackend } from './isolation/bubblewrap.js';
|
|
13
|
-
import { authResolutionHint, resolveEndpoint, } from './monitor.js';
|
|
14
13
|
import { readClientProfile } from './client-profile.js';
|
|
15
14
|
import { readScheduledLoops, storedLoopHealth } from './loops/state.js';
|
|
16
15
|
import { controlSocketPath } from './session/control.js';
|
|
@@ -36,25 +35,21 @@ function resolveMonitorProfiles(roles) {
|
|
|
36
35
|
const profiles = [];
|
|
37
36
|
for (const role of roles.filter(r => r.monitor?.mode === 'fleet')) {
|
|
38
37
|
const env = { ...process.env, ...(role.env ?? {}) };
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
existing.roles.push(role.name);
|
|
46
|
-
else
|
|
47
|
-
profiles.push({ client, roles: [role.name] });
|
|
38
|
+
let client;
|
|
39
|
+
try {
|
|
40
|
+
client = readClientProfile(env);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
profiles.push({ roles: [role.name], error: error instanceof Error ? error.message : 'Invalid gateway profile' });
|
|
48
44
|
continue;
|
|
49
45
|
}
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
&& p.endpoint.headers['x-ours-api-token'] === token);
|
|
46
|
+
const existing = profiles.find(p => p.client?.endpoint === client.endpoint
|
|
47
|
+
&& p.client.expectedInstanceId === client.expectedInstanceId
|
|
48
|
+
&& p.client.credentialPath === client.credentialPath);
|
|
54
49
|
if (existing)
|
|
55
50
|
existing.roles.push(role.name);
|
|
56
51
|
else
|
|
57
|
-
profiles.push({
|
|
52
|
+
profiles.push({ client, roles: [role.name] });
|
|
58
53
|
}
|
|
59
54
|
return profiles;
|
|
60
55
|
}
|
|
@@ -155,7 +150,7 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
155
150
|
// ── Rooms/tasks checks ────────────────────────────────────────
|
|
156
151
|
if (loaded.ok && loaded.rooms) {
|
|
157
152
|
const rooms = loaded.rooms;
|
|
158
|
-
// Cowork
|
|
153
|
+
// Cowork gateway reachability
|
|
159
154
|
const coworkConfig = rooms.cowork?.config;
|
|
160
155
|
try {
|
|
161
156
|
const { createCoworkAdapter } = await import('./rooms-tasks/cowork-adapter.js');
|
|
@@ -164,14 +159,14 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
164
159
|
checks.push({
|
|
165
160
|
name: 'cowork', ok: reachable,
|
|
166
161
|
detail: reachable
|
|
167
|
-
? 'management
|
|
168
|
-
: `management
|
|
162
|
+
? 'gateway management reachable'
|
|
163
|
+
: `gateway management unreachable${coworkConfig ? ` (config: ${coworkConfig})` : ''}`,
|
|
169
164
|
});
|
|
170
165
|
}
|
|
171
166
|
catch (e) {
|
|
172
167
|
checks.push({
|
|
173
168
|
name: 'cowork', ok: false,
|
|
174
|
-
detail: `management
|
|
169
|
+
detail: `gateway management error${coworkConfig ? ` (config: ${coworkConfig})` : ''}: ${e?.message ?? e}`,
|
|
175
170
|
});
|
|
176
171
|
}
|
|
177
172
|
// Owner CID shape
|
|
@@ -218,17 +213,6 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
218
213
|
: `template '${defaultTemplate}' not found`,
|
|
219
214
|
});
|
|
220
215
|
}
|
|
221
|
-
// Shared-daemon selection coherence
|
|
222
|
-
if (rooms.cowork?.config) {
|
|
223
|
-
const { existsSync: exists } = await import('node:fs');
|
|
224
|
-
const configOk = exists(rooms.cowork.config);
|
|
225
|
-
checks.push({
|
|
226
|
-
name: 'rooms: cowork config', ok: configOk,
|
|
227
|
-
detail: configOk
|
|
228
|
-
? `cowork config at ${rooms.cowork.config}`
|
|
229
|
-
: `cowork config not found: ${rooms.cowork.config}`,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
216
|
// Hard room-management capability check
|
|
233
217
|
try {
|
|
234
218
|
const { createCoworkAdapter } = await import('./rooms-tasks/cowork-adapter.js');
|
|
@@ -272,21 +256,36 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
272
256
|
}
|
|
273
257
|
catch { /* state dir may not exist yet */ }
|
|
274
258
|
}
|
|
259
|
+
let managedSelection = true;
|
|
275
260
|
try {
|
|
261
|
+
// Mark explicit selection before validation so a damaged managed profile does
|
|
262
|
+
// not produce advice to start an unrelated local daemon.
|
|
263
|
+
managedSelection = true;
|
|
264
|
+
const selected = readClientProfile(process.env);
|
|
265
|
+
managedSelection = selected !== undefined;
|
|
276
266
|
const client = await attachDaemon({
|
|
277
|
-
|
|
267
|
+
endpoint: selected.endpoint, expectedInstanceId: selected.expectedInstanceId,
|
|
268
|
+
credentialPath: selected.credentialPath, env: {}, sessionMode: 'external',
|
|
278
269
|
leaseToken: `ours-fleet-doctor-${process.pid}`,
|
|
279
|
-
clientPid: process.pid,
|
|
280
270
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
271
|
+
let daemonVersion;
|
|
272
|
+
try {
|
|
273
|
+
const info = await client.version();
|
|
274
|
+
if (info.name !== 'ours' || typeof info.version !== 'string')
|
|
275
|
+
throw new Error('the selected endpoint did not return a valid ours daemon identity');
|
|
276
|
+
daemonVersion = info.version;
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
await client.close();
|
|
280
|
+
}
|
|
281
|
+
checks.push({ name: 'ours daemon', ok: true, detail: `running (${daemonVersion})` });
|
|
285
282
|
}
|
|
286
283
|
catch (error) {
|
|
287
284
|
checks.push({
|
|
288
285
|
name: 'ours daemon', ok: false,
|
|
289
|
-
detail:
|
|
286
|
+
detail: (managedSelection
|
|
287
|
+
? 'selected client profile failed — check its endpoint, instance and issued credential '
|
|
288
|
+
: 'not reachable through the SDK — start it with: ours-daemon start ')
|
|
290
289
|
+ `[${error?.message ?? String(error)}]`,
|
|
291
290
|
});
|
|
292
291
|
}
|
|
@@ -429,14 +428,18 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
429
428
|
// shared-mode misconfig (401) surfaces here rather than as a silent deaf monitor.
|
|
430
429
|
const monitorProfiles = resolveMonitorProfiles(roles);
|
|
431
430
|
for (const profile of monitorProfiles) {
|
|
432
|
-
const
|
|
431
|
+
const selected = profile.client;
|
|
433
432
|
const checkName = monitorProfiles.length === 1
|
|
434
433
|
? 'monitor: daemon API'
|
|
435
434
|
: `monitor: daemon API (${profile.roles.join(', ')})`;
|
|
436
|
-
let ok = false, detail;
|
|
435
|
+
let ok = false, detail = 'gateway profile unavailable';
|
|
436
|
+
if (profile.error) {
|
|
437
|
+
checks.push({ name: checkName, ok: false, detail: profile.error });
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
437
440
|
try {
|
|
438
441
|
if (selected) {
|
|
439
|
-
const daemon = await
|
|
442
|
+
const daemon = await attachDaemon({
|
|
440
443
|
endpoint: selected.endpoint,
|
|
441
444
|
expectedInstanceId: selected.expectedInstanceId,
|
|
442
445
|
credentialPath: selected.credentialPath,
|
|
@@ -445,7 +448,7 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
445
448
|
});
|
|
446
449
|
try {
|
|
447
450
|
const [info, identities] = await Promise.all([
|
|
448
|
-
daemon.version(), daemon.identities(),
|
|
451
|
+
daemon.version(), daemon.identities?.(),
|
|
449
452
|
]);
|
|
450
453
|
if (info.name !== 'ours' || !Array.isArray(identities))
|
|
451
454
|
throw new Error('selected daemon metadata is invalid');
|
|
@@ -458,27 +461,11 @@ export async function doctor(opts = {}, exec = realExec, platform = process.plat
|
|
|
458
461
|
checks.push({ name: checkName, ok, detail });
|
|
459
462
|
continue;
|
|
460
463
|
}
|
|
461
|
-
const live = await fetchImpl(`${endpoint.origin}/state-dir`, {});
|
|
462
|
-
if (!live.ok) {
|
|
463
|
-
detail = `daemon on :${endpoint.port} answered /state-dir with HTTP ${live.status} — not the ours daemon?`;
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
const auth = await fetchImpl(`${endpoint.origin}/identities`, { headers: endpoint.headers });
|
|
467
|
-
if (auth.status === 401)
|
|
468
|
-
detail = `reachable on :${endpoint.port} but the API token was rejected (401) — ` +
|
|
469
|
-
authResolutionHint(endpoint);
|
|
470
|
-
else if (!auth.ok)
|
|
471
|
-
detail = `reachable on :${endpoint.port} but /identities returned HTTP ${auth.status}`;
|
|
472
|
-
else {
|
|
473
|
-
ok = true;
|
|
474
|
-
detail = `reachable on :${endpoint.port}, authorized — supervisor wake stream available`;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
464
|
}
|
|
478
465
|
catch (e) {
|
|
479
|
-
const target = selected
|
|
466
|
+
const target = selected.endpoint;
|
|
480
467
|
detail = `unreachable on ${target} — monitored roles run degraded until it is up ` +
|
|
481
|
-
`(
|
|
468
|
+
`(check the configured gateway and issued credential) [${e?.message ?? e}]`;
|
|
482
469
|
}
|
|
483
470
|
checks.push({ name: checkName, ok, detail });
|
|
484
471
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const erasedArg: (value: string) => string;
|
|
2
|
+
export declare function redactErasedContent<T>(value: T): T;
|
|
3
|
+
/** Every cooperative writer filters stale in-memory snapshots under the same lock as erasure. */
|
|
4
|
+
export declare function writePrivacyFilteredLedger(path: string, value: unknown): void;
|
|
5
|
+
/** Content-free resource IDs persist to prevent active writers resurrecting erased labels. */
|
|
6
|
+
export declare function eraseResourcePresentations(resources: ReadonlyArray<{
|
|
7
|
+
kind: 'task' | 'room' | 'agent';
|
|
8
|
+
id: string;
|
|
9
|
+
}>): void;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { replaceFileAtomically, withSynchronousFileLock } from './atomic-file.js';
|
|
5
|
+
import { stateRoot } from './paths.js';
|
|
6
|
+
const registryPath = () => join(stateRoot(), 'erased-resources.json');
|
|
7
|
+
const lockPath = () => join(stateRoot(), 'locks', 'audit-erasure');
|
|
8
|
+
const ledgerNames = ['.fleet-command-audit.json', '.owner-channel-command-audit.json', '.owner-channel-lifecycle-outbox.json'];
|
|
9
|
+
export const erasedArg = (value) => `[erased:${createHash('sha256').update(value).digest('hex')}]`;
|
|
10
|
+
function registry() {
|
|
11
|
+
if (!existsSync(registryPath()))
|
|
12
|
+
return new Set();
|
|
13
|
+
const value = JSON.parse(readFileSync(registryPath(), 'utf8'));
|
|
14
|
+
if (!Array.isArray(value) || value.some(v => typeof v !== 'string'))
|
|
15
|
+
throw new Error('Invalid erasure registry');
|
|
16
|
+
return new Set(value);
|
|
17
|
+
}
|
|
18
|
+
/** Preserve delivery/deduplication metadata while removing owned presentation content. */
|
|
19
|
+
function redact(value, erased) {
|
|
20
|
+
if (Array.isArray(value))
|
|
21
|
+
return value.map(item => redact(item, erased));
|
|
22
|
+
if (!value || typeof value !== 'object')
|
|
23
|
+
return value;
|
|
24
|
+
const next = { ...value };
|
|
25
|
+
const kind = value.kind === 'lifecycle_failure' ? value.resource?.toLowerCase() : value.kind === 'agent_started' ? 'agent' : value.kind;
|
|
26
|
+
if (typeof value.id === 'string' && erased.has(`${kind}:${value.id}`)) {
|
|
27
|
+
for (const key of ['title', 'reason', 'roomName', 'label', 'template', 'configuration', 'model', 'permissions'])
|
|
28
|
+
delete next[key];
|
|
29
|
+
if (kind === 'task')
|
|
30
|
+
next.agents = [];
|
|
31
|
+
if (kind === 'room') {
|
|
32
|
+
delete next.name;
|
|
33
|
+
next.participants = [];
|
|
34
|
+
}
|
|
35
|
+
if (kind === 'agent') {
|
|
36
|
+
next.name = 'erased';
|
|
37
|
+
next.brain = '[erased]';
|
|
38
|
+
next.role = '[erased]';
|
|
39
|
+
next.inherited = [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (typeof value.roomId === 'string' && erased.has(`room:${value.roomId}`)) {
|
|
43
|
+
delete next.roomName;
|
|
44
|
+
if (kind === 'task')
|
|
45
|
+
next.agents = [];
|
|
46
|
+
}
|
|
47
|
+
const resources = value.outcome?.resourceIds;
|
|
48
|
+
const ownsAttempt = resources && Object.entries(resources).some(([key, id]) => erased.has(`${key}:${id}`));
|
|
49
|
+
const ownsPresentation = value.outcome?.presentations?.some((p) => erased.has(`${p.kind === 'agent_started' ? 'agent' : p.kind}:${p.id}`));
|
|
50
|
+
if ((ownsAttempt || ownsPresentation) && Array.isArray(value.argv) && !value.erased) {
|
|
51
|
+
next.argv = value.argv.map(erasedArg);
|
|
52
|
+
next.erased = true;
|
|
53
|
+
}
|
|
54
|
+
for (const key of Object.keys(next))
|
|
55
|
+
if (typeof next[key] === 'object')
|
|
56
|
+
next[key] = redact(next[key], erased);
|
|
57
|
+
return next;
|
|
58
|
+
}
|
|
59
|
+
export function redactErasedContent(value) { return redact(value, registry()); }
|
|
60
|
+
/** Every cooperative writer filters stale in-memory snapshots under the same lock as erasure. */
|
|
61
|
+
export function writePrivacyFilteredLedger(path, value) {
|
|
62
|
+
withSynchronousFileLock(lockPath(), () => replaceFileAtomically(path, JSON.stringify(redact(value, registry())) + '\n'));
|
|
63
|
+
}
|
|
64
|
+
/** Content-free resource IDs persist to prevent active writers resurrecting erased labels. */
|
|
65
|
+
export function eraseResourcePresentations(resources) {
|
|
66
|
+
withSynchronousFileLock(lockPath(), () => {
|
|
67
|
+
const erased = registry();
|
|
68
|
+
for (const resource of resources)
|
|
69
|
+
erased.add(`${resource.kind}:${resource.id}`);
|
|
70
|
+
replaceFileAtomically(registryPath(), JSON.stringify([...erased]));
|
|
71
|
+
for (const root of [join(stateRoot(), 'agents'), join(stateRoot(), 'tmp'), join(stateRoot(), 'recovery', 'temporary')]) {
|
|
72
|
+
if (!existsSync(root))
|
|
73
|
+
continue;
|
|
74
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
75
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
76
|
+
continue;
|
|
77
|
+
for (const name of ledgerNames) {
|
|
78
|
+
const path = join(root, entry.name, name);
|
|
79
|
+
if (!existsSync(path) || !lstatSync(path).isFile() || lstatSync(path).isSymbolicLink())
|
|
80
|
+
continue;
|
|
81
|
+
const old = JSON.parse(readFileSync(path, 'utf8'));
|
|
82
|
+
replaceFileAtomically(path, JSON.stringify(redact(old, erased)) + '\n');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { erasedArg, redactErasedContent, writePrivacyFilteredLedger } from './erased-resources.js';
|
|
1
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
3
|
import { randomUUID } from 'node:crypto';
|
|
3
4
|
import { Buffer } from 'node:buffer';
|
|
4
|
-
import { replaceFileAtomically } from './atomic-file.js';
|
|
5
5
|
import { isSensitiveConfigKey } from './sensitive-config.js';
|
|
6
6
|
import { mandatoryConfigurationFits } from './lifecycle-summary.js';
|
|
7
7
|
import { MARKDOWN_MAX_BYTES, MARKDOWN_MAX_CODE_POINTS, markdownCode, markdownProse, } from './rooms-tasks/markdown.js';
|
|
@@ -91,7 +91,7 @@ export function recordFleetAuditPresentation(value) {
|
|
|
91
91
|
: value.kind === 'lifecycle_failure'
|
|
92
92
|
? { label: fleetPresentationLabel(value.label) }
|
|
93
93
|
: {};
|
|
94
|
-
const presentation = structuredClone({ ...value, ...labels, eventId: basis });
|
|
94
|
+
const presentation = redactErasedContent(structuredClone({ ...value, ...labels, eventId: basis }));
|
|
95
95
|
const digest = lifecycleEventDigestBasis(presentation);
|
|
96
96
|
if (!collection.presentations.some(existing => lifecycleEventDigestBasis(existing) === digest))
|
|
97
97
|
collection.presentations.push(presentation);
|
|
@@ -117,6 +117,7 @@ export function consumeFleetAuditCollection() {
|
|
|
117
117
|
const SAFE_READ = new Set(['docs', 'version', 'config', 'ls', 'peek', 'logs', 'status', 'doctor']);
|
|
118
118
|
const AGENT_SURFACES = {
|
|
119
119
|
spawn: new Set(['<none>']),
|
|
120
|
+
ours: new Set(['tools', 'call']),
|
|
120
121
|
template: new Set(['list', 'show', 'validate']),
|
|
121
122
|
task: new Set(['create', 'list', 'lists', 'list-create', 'list-rename', 'list-delete', 'move',
|
|
122
123
|
'show', 'start', 'block', 'unblock', 'review', 'done', 'cancel', 'delete', 'work', 'finish']),
|
|
@@ -132,7 +133,7 @@ export const fleetProxyTopLevelInventory = Object.freeze({
|
|
|
132
133
|
'up', 'down', 'restart', 'force-restart', 'attach', 'send', 'loops', 'owner-channel',
|
|
133
134
|
'watchdog-run', 'watchdog-report', 'rm', 'init', 'web',
|
|
134
135
|
], denied: [...DENIED],
|
|
135
|
-
hidden: ['_run', '_run-temp', '_run-watchdog', '_run-watchdogs'], aliases: ['man'],
|
|
136
|
+
hidden: ['_run', '_run-temp', '_run-temp-worker', '_run-watchdog', '_run-watchdogs'], aliases: ['man'],
|
|
136
137
|
});
|
|
137
138
|
const globalValueOptions = new Set(['-c', '--configuration']);
|
|
138
139
|
/** Classify before Commander parsing. Unknown and internal paths fail closed. */
|
|
@@ -189,7 +190,7 @@ const sensitiveValueFlags = new Set([
|
|
|
189
190
|
'--identity', '--invite', '--token', '--api-token', '--password', '--password-file',
|
|
190
191
|
'--env', '--brief', '--brief-file', '--bio-file', '--persona-file', '--isolation-file', '--loops-file',
|
|
191
192
|
'--configuration', '-c', '--public-invite', '--public-invite-file', '--invite-file',
|
|
192
|
-
'--summary-file', '--text', '--message', '--summary', '--reason', '--goal', '--cwd',
|
|
193
|
+
'--args-file', '--summary-file', '--text', '--message', '--summary', '--reason', '--goal', '--cwd',
|
|
193
194
|
'--identity-cid', '--owner-cid', '--contact-cid', '--codex-config', '--add-dir',
|
|
194
195
|
]);
|
|
195
196
|
function redactUrl(value) {
|
|
@@ -304,11 +305,12 @@ export class FleetCommandAuditStore {
|
|
|
304
305
|
if (recovered)
|
|
305
306
|
this.persist();
|
|
306
307
|
}
|
|
307
|
-
list() { return this.attempts.map(item => structuredClone(item)); }
|
|
308
|
+
list() { return redactErasedContent(this.attempts).map(item => structuredClone(item)); }
|
|
308
309
|
begin(requestId, caller, argv) {
|
|
310
|
+
this.attempts = redactErasedContent(this.attempts);
|
|
309
311
|
const existing = this.attempts.find(item => item.caller === caller && item.requestId === requestId);
|
|
310
312
|
if (existing) {
|
|
311
|
-
if (JSON.stringify(existing.argv) !== JSON.stringify(redactFleetArgv(argv)))
|
|
313
|
+
if (JSON.stringify(existing.argv) !== JSON.stringify(existing.erased ? redactFleetArgv(argv).map(erasedArg) : redactFleetArgv(argv)))
|
|
312
314
|
throw new Error('fleet command request ID was reused with different argv');
|
|
313
315
|
return structuredClone(existing);
|
|
314
316
|
}
|
|
@@ -328,6 +330,8 @@ export class FleetCommandAuditStore {
|
|
|
328
330
|
return structuredClone(attempt);
|
|
329
331
|
}
|
|
330
332
|
finish(correlationId, caller, outcome) {
|
|
333
|
+
this.attempts = redactErasedContent(this.attempts);
|
|
334
|
+
outcome = redactErasedContent({ outcome }).outcome;
|
|
331
335
|
const attempt = this.owned(correlationId, caller);
|
|
332
336
|
if (!attempt.outcome)
|
|
333
337
|
attempt.outcome = { ...outcome, completedAt: this.deps.now().toISOString(), delivery: 'sending' };
|
|
@@ -359,7 +363,8 @@ export class FleetCommandAuditStore {
|
|
|
359
363
|
return attempt;
|
|
360
364
|
}
|
|
361
365
|
persist() {
|
|
362
|
-
|
|
366
|
+
this.attempts = redactErasedContent(this.attempts);
|
|
367
|
+
writePrivacyFilteredLedger(this.path, { version: 1, attempts: this.attempts });
|
|
363
368
|
}
|
|
364
369
|
}
|
|
365
370
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ManagedHarnessOurs } from '../agent-ours/harness.js';
|
|
1
2
|
import type { CommonPermissions, FleetPermissionMode, ResolvedRole } from '../config.js';
|
|
2
3
|
import type { AgentSession } from '../session/types.js';
|
|
3
4
|
import type { Launch, SessionPrep } from './types.js';
|
|
@@ -22,6 +23,7 @@ export interface AgentSessionConfigSelection {
|
|
|
22
23
|
value: string;
|
|
23
24
|
}
|
|
24
25
|
export interface AgentSessionStartOptions {
|
|
26
|
+
managedOurs?: ManagedHarnessOurs;
|
|
25
27
|
role: ResolvedRole;
|
|
26
28
|
prep: SessionPrep;
|
|
27
29
|
launch: PreparedAgentSessionLaunch;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { managedClaudeMeta } from '../agent-ours/harness.js';
|
|
1
2
|
import { AcpSession } from '../session/acp.js';
|
|
2
3
|
import { acpAdapterState, } from './acp-session-transport.js';
|
|
3
4
|
/** Explicit Claude Code implementation of Fleet's shared agent-session factory. */
|
|
@@ -25,8 +26,9 @@ export class ClaudeCodeAgentSessionAdapter {
|
|
|
25
26
|
argv: launch.argv, cwd: options.cwd, env: launch.env,
|
|
26
27
|
stateDir: options.stateDir, mode: options.mode, permissions: options.permissions,
|
|
27
28
|
modeId: this.strategy.permissionModeId(role),
|
|
28
|
-
mcpServers: this.strategy.mcpServers(role),
|
|
29
|
-
|
|
29
|
+
mcpServers: options.managedOurs ? [...(this.strategy.mcpServers(role) ?? []).filter(s => s.name !== 'ours'), options.managedOurs.server] : this.strategy.mcpServers(role),
|
|
30
|
+
inheritEnvironment: options.managedOurs ? false : undefined,
|
|
31
|
+
sessionMeta: options.managedOurs ? managedClaudeMeta(this.strategy.sessionMeta(role, prep)) : this.strategy.sessionMeta(role, prep),
|
|
30
32
|
configSelections: this.strategy.sessionConfigSelections(role),
|
|
31
33
|
permissionMode: options.permissionMode,
|
|
32
34
|
permissionMetadataSource: acpAdapterState(launch.adapterState).permissionMetadataSource,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
type JsonObject = Record<string, unknown>;
|
|
2
3
|
interface TerminalRecoveryOptions {
|
|
3
4
|
sendToCodex(line: string): void;
|
|
4
5
|
emitToClient(line: string): void;
|
|
@@ -39,6 +40,8 @@ export declare class CodexTerminalRecovery {
|
|
|
39
40
|
private finishTurn;
|
|
40
41
|
}
|
|
41
42
|
/** Transform one app-server NDJSON request; malformed input passes through. */
|
|
42
|
-
export declare function rewriteCodexAppServerRequest(line: string, approval: string, expectedSandbox: string, disableInheritedMcp?: boolean): string;
|
|
43
|
+
export declare function rewriteCodexAppServerRequest(line: string, approval: string, expectedSandbox: string, disableInheritedMcp?: boolean, managedOursTools?: JsonObject): string;
|
|
44
|
+
/** ACP only carries transport fields; read policy from Fleet's complete config. */
|
|
45
|
+
export declare function managedCodexToolPolicy(env: NodeJS.ProcessEnv): JsonObject | undefined;
|
|
43
46
|
export declare function runCodexAppServerProxy(): void;
|
|
44
47
|
export {};
|
|
@@ -300,9 +300,9 @@ function sandboxMode(policy) {
|
|
|
300
300
|
* Fleet keeps the preset's sandbox policy, but restores the independently
|
|
301
301
|
* configured approval policy on the request Codex actually executes.
|
|
302
302
|
*/
|
|
303
|
-
function rewriteMessage(value, approval, expectedSandbox, disableInheritedMcp) {
|
|
303
|
+
function rewriteMessage(value, approval, expectedSandbox, disableInheritedMcp, managedOursTools) {
|
|
304
304
|
if (Array.isArray(value))
|
|
305
|
-
return value.map(candidate => rewriteMessage(candidate, approval, expectedSandbox, disableInheritedMcp));
|
|
305
|
+
return value.map(candidate => rewriteMessage(candidate, approval, expectedSandbox, disableInheritedMcp, managedOursTools));
|
|
306
306
|
if (!isObject(value) || !isObject(value.params))
|
|
307
307
|
return value;
|
|
308
308
|
if (value.method === 'turn/start') {
|
|
@@ -318,17 +318,52 @@ function rewriteMessage(value, approval, expectedSandbox, disableInheritedMcp) {
|
|
|
318
318
|
params: { ...value.params, config: { ...config, mcp_servers: {} } },
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
|
+
if (managedOursTools
|
|
322
|
+
&& (value.method === 'thread/start' || value.method === 'thread/resume')) {
|
|
323
|
+
const config = isObject(value.params.config) ? value.params.config : {};
|
|
324
|
+
const servers = isObject(config.mcp_servers) ? config.mcp_servers : {};
|
|
325
|
+
const ours = servers.ours;
|
|
326
|
+
// Policy cannot create or re-enable a connector that ACP did not inject.
|
|
327
|
+
if (!isObject(ours) || ours.enabled === false)
|
|
328
|
+
return value;
|
|
329
|
+
const tools = isObject(ours.tools) ? { ...ours.tools } : {};
|
|
330
|
+
for (const [name, policy] of Object.entries(managedOursTools)) {
|
|
331
|
+
if (isObject(policy))
|
|
332
|
+
tools[name] = {
|
|
333
|
+
...(isObject(tools[name]) ? tools[name] : {}), ...policy,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
return { ...value, params: { ...value.params, config: { ...config,
|
|
337
|
+
mcp_servers: { ...servers, ours: { ...ours, tools } },
|
|
338
|
+
} } };
|
|
339
|
+
}
|
|
321
340
|
return value;
|
|
322
341
|
}
|
|
323
342
|
/** Transform one app-server NDJSON request; malformed input passes through. */
|
|
324
|
-
export function rewriteCodexAppServerRequest(line, approval, expectedSandbox, disableInheritedMcp = false) {
|
|
343
|
+
export function rewriteCodexAppServerRequest(line, approval, expectedSandbox, disableInheritedMcp = false, managedOursTools) {
|
|
325
344
|
try {
|
|
326
|
-
return JSON.stringify(rewriteMessage(JSON.parse(line), approval, expectedSandbox, disableInheritedMcp));
|
|
345
|
+
return JSON.stringify(rewriteMessage(JSON.parse(line), approval, expectedSandbox, disableInheritedMcp, managedOursTools));
|
|
327
346
|
}
|
|
328
347
|
catch {
|
|
329
348
|
return line;
|
|
330
349
|
}
|
|
331
350
|
}
|
|
351
|
+
/** ACP only carries transport fields; read policy from Fleet's complete config. */
|
|
352
|
+
export function managedCodexToolPolicy(env) {
|
|
353
|
+
if (env.FLEET_OURS_MANAGED !== '1')
|
|
354
|
+
return undefined;
|
|
355
|
+
try {
|
|
356
|
+
const config = JSON.parse(env.CODEX_CONFIG ?? '{}');
|
|
357
|
+
const servers = isObject(config) ? config.mcp_servers : undefined;
|
|
358
|
+
const ours = isObject(servers) ? servers.ours : undefined;
|
|
359
|
+
return isObject(ours) && ours.enabled !== false && isObject(ours.tools)
|
|
360
|
+
? ours.tools : undefined;
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
// Invalid config never grants tool approval. ACP owns config diagnostics.
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
332
367
|
function requiredChoice(name, allowed) {
|
|
333
368
|
const value = process.env[name];
|
|
334
369
|
if (value && allowed.has(value))
|
|
@@ -355,6 +390,7 @@ export function runCodexAppServerProxy() {
|
|
|
355
390
|
const approval = requiredChoice(APPROVAL_ENV, APPROVAL_POLICIES);
|
|
356
391
|
const expectedSandbox = requiredChoice(SANDBOX_ENV, SANDBOX_MODES);
|
|
357
392
|
const disableInheritedMcp = process.env[DISABLE_INHERITED_MCP_ENV] === '1';
|
|
393
|
+
const managedOursTools = managedCodexToolPolicy(process.env);
|
|
358
394
|
const launch = realCodexLaunch();
|
|
359
395
|
const env = { ...process.env };
|
|
360
396
|
delete env.CODEX_PATH;
|
|
@@ -450,7 +486,7 @@ export function runCodexAppServerProxy() {
|
|
|
450
486
|
input.on('line', line => {
|
|
451
487
|
if (finished)
|
|
452
488
|
return;
|
|
453
|
-
const rewritten = rewriteCodexAppServerRequest(line, approval, expectedSandbox, disableInheritedMcp);
|
|
489
|
+
const rewritten = rewriteCodexAppServerRequest(line, approval, expectedSandbox, disableInheritedMcp, managedOursTools);
|
|
454
490
|
recovery.observeClientLine(rewritten);
|
|
455
491
|
writeToChild(rewritten);
|
|
456
492
|
});
|
|
@@ -23,6 +23,12 @@ export class CodexAgentSessionAdapter {
|
|
|
23
23
|
}
|
|
24
24
|
start(options) {
|
|
25
25
|
const { role, prep, launch } = options;
|
|
26
|
+
const original = this.strategy.nativeConfig(role) ?? {};
|
|
27
|
+
const managed = options.managedOurs?.native;
|
|
28
|
+
const config = managed ? { ...original, ...managed,
|
|
29
|
+
mcp_servers: { ...(original.mcp_servers ?? {}), ...(managed.mcp_servers ?? {}) },
|
|
30
|
+
plugins: { ...(original.plugins ?? {}), ...(managed.plugins ?? {}) },
|
|
31
|
+
} : original;
|
|
26
32
|
if (role.session === 'codex-app-server')
|
|
27
33
|
return this.nativeTransport({
|
|
28
34
|
name: role.name, argv: launch.argv, cwd: options.cwd, env: launch.env,
|
|
@@ -31,7 +37,7 @@ export class CodexAgentSessionAdapter {
|
|
|
31
37
|
model: role.model, effort: role.effort,
|
|
32
38
|
approvalPolicy: this.strategy.approvalPolicy(role),
|
|
33
39
|
sandbox: this.strategy.sandbox(role),
|
|
34
|
-
config
|
|
40
|
+
config,
|
|
35
41
|
addDirs: this.strategy.addDirs(role),
|
|
36
42
|
log: options.log,
|
|
37
43
|
});
|
|
@@ -40,7 +46,8 @@ export class CodexAgentSessionAdapter {
|
|
|
40
46
|
argv: launch.argv, cwd: options.cwd, env: launch.env,
|
|
41
47
|
stateDir: options.stateDir, mode: options.mode, permissions: options.permissions,
|
|
42
48
|
modeId: this.strategy.permissionModeId(role),
|
|
43
|
-
mcpServers: this.strategy.mcpServers(role),
|
|
49
|
+
mcpServers: options.managedOurs ? [...(this.strategy.mcpServers(role) ?? []).filter(s => s.name !== 'ours'), options.managedOurs.server] : this.strategy.mcpServers(role),
|
|
50
|
+
inheritEnvironment: options.managedOurs ? false : undefined,
|
|
44
51
|
sessionMeta: this.strategy.sessionMeta(role, prep),
|
|
45
52
|
configSelections: this.strategy.sessionConfigSelections(role),
|
|
46
53
|
permissionMode: options.permissionMode,
|
package/dist/harness/codex.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ import type { AcpSessionTransport } from './acp-session-transport.js';
|
|
|
6
6
|
import type { CodexAppServerSessionTransport } from './codex-session.js';
|
|
7
7
|
/**
|
|
8
8
|
* What an unattended role can actually do under Codex's native settings.
|
|
9
|
-
* `on-request` and `untrusted`
|
|
10
|
-
*
|
|
9
|
+
* `on-request` and `untrusted` can ask even for startup file reads (for example,
|
|
10
|
+
* shell reads or files outside the sandbox). Without a controller the request
|
|
11
|
+
* waits or is denied according to policy. Neither guarantees `read-state`.
|
|
11
12
|
*/
|
|
12
13
|
export declare function codexCapabilities(approval: string, sandbox: string): UnattendedCapability[];
|
|
13
14
|
/** Defense in depth for callers which launch a role after validation was bypassed. */
|
package/dist/harness/codex.js
CHANGED
|
@@ -25,12 +25,13 @@ const CODEX_PROXY_REAL_PATH_ENV = 'OURS_FLEET_REAL_CODEX_PATH';
|
|
|
25
25
|
const CODEX_PROXY_MANIFEST_ENV = 'OURS_FLEET_CODEX_ACP_MANIFEST';
|
|
26
26
|
/**
|
|
27
27
|
* What an unattended role can actually do under Codex's native settings.
|
|
28
|
-
* `on-request` and `untrusted`
|
|
29
|
-
*
|
|
28
|
+
* `on-request` and `untrusted` can ask even for startup file reads (for example,
|
|
29
|
+
* shell reads or files outside the sandbox). Without a controller the request
|
|
30
|
+
* waits or is denied according to policy. Neither guarantees `read-state`.
|
|
30
31
|
*/
|
|
31
32
|
export function codexCapabilities(approval, sandbox) {
|
|
32
33
|
if (approval !== 'never')
|
|
33
|
-
return [
|
|
34
|
+
return [];
|
|
34
35
|
const caps = ['read-state', 'messaging', 'monitor', 'status-commands'];
|
|
35
36
|
if (sandbox !== 'read-only')
|
|
36
37
|
caps.push('write-state', 'workspace-edit');
|
|
@@ -53,6 +53,12 @@ export class HermesAgentSessionAdapter {
|
|
|
53
53
|
// composition; no second ambient merge may reintroduce provider secrets.
|
|
54
54
|
const env = hermesChildEnvironment(role, preparedHome(prep), launch.env, launch.env);
|
|
55
55
|
delete env.OURS_AUTOSTART;
|
|
56
|
+
if (options.managedOurs) {
|
|
57
|
+
for (const key of Object.keys(env))
|
|
58
|
+
if (key.startsWith('OURS_') && !key.startsWith('OURS_FLEET_'))
|
|
59
|
+
delete env[key];
|
|
60
|
+
Object.assign(env, { FLEET_OURS_MANAGED: '1' });
|
|
61
|
+
}
|
|
56
62
|
await this.checks.preflight?.(options, env);
|
|
57
63
|
const nativeProvider = await this.checks.expectedProvider(role, prep);
|
|
58
64
|
if (typeof nativeProvider !== 'string' || !nativeProvider.trim())
|
|
@@ -68,7 +74,7 @@ export class HermesAgentSessionAdapter {
|
|
|
68
74
|
permissions: options.permissions, modeId, requireMode: true,
|
|
69
75
|
permissionMode: { fleetMode: options.permissionMode.fleetMode, nativeMode: modeId },
|
|
70
76
|
permissionTimeoutMs: 50_000,
|
|
71
|
-
mcpServers: hermesMcpServers(role, env),
|
|
77
|
+
mcpServers: options.managedOurs ? [...hermesMcpServers(role, env).filter(s => s.name !== 'ours'), options.managedOurs.server] : hermesMcpServers(role, env),
|
|
72
78
|
scrubObsoleteOursAutostart: true,
|
|
73
79
|
validateStartupResponse: async (initialized, created) => {
|
|
74
80
|
await this.checks.validateArtifact(initialized);
|