@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/web/service.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Exec } from '../exec.js';
|
|
2
2
|
export declare const WEB_SYSTEMD_UNIT = "ours-fleet-web.service";
|
|
3
3
|
export declare const WEB_LAUNCHD_LABEL = "network.ours.fleet.web";
|
|
4
|
+
type ServiceEnvironment = Partial<Record<'OURS_CONFIG' | 'OURS_FLEET_HOME' | 'PATH', string>>;
|
|
4
5
|
interface ServiceMetadata {
|
|
5
6
|
version: 3;
|
|
6
7
|
platform: 'linux' | 'darwin';
|
|
@@ -10,6 +11,7 @@ interface ServiceMetadata {
|
|
|
10
11
|
configuration?: string;
|
|
11
12
|
bind?: string;
|
|
12
13
|
publicOrigin?: string;
|
|
14
|
+
environment?: ServiceEnvironment;
|
|
13
15
|
}
|
|
14
16
|
export interface WebServiceOptions {
|
|
15
17
|
platform?: NodeJS.Platform;
|
|
@@ -18,6 +20,7 @@ export interface WebServiceOptions {
|
|
|
18
20
|
stateDir?: string;
|
|
19
21
|
uid?: number;
|
|
20
22
|
runtimeExecutable?: string;
|
|
23
|
+
environment?: NodeJS.ProcessEnv;
|
|
21
24
|
}
|
|
22
25
|
export declare class WebServiceManager {
|
|
23
26
|
private readonly platform;
|
|
@@ -26,6 +29,7 @@ export declare class WebServiceManager {
|
|
|
26
29
|
private readonly stateDir;
|
|
27
30
|
private readonly uid;
|
|
28
31
|
private readonly runtimeExecutable;
|
|
32
|
+
private readonly environment;
|
|
29
33
|
constructor(options?: WebServiceOptions);
|
|
30
34
|
get metadataPath(): string;
|
|
31
35
|
get definitionPath(): string;
|
|
@@ -33,6 +37,11 @@ export declare class WebServiceManager {
|
|
|
33
37
|
bind?: string;
|
|
34
38
|
publicOrigin?: string;
|
|
35
39
|
}): Promise<string[]>;
|
|
40
|
+
/** Persist an enrollment bind fallback, reloading launchd's cached definition. */
|
|
41
|
+
retainBoundPort(script: string, port: number, configuration?: string, web?: {
|
|
42
|
+
bind?: string;
|
|
43
|
+
publicOrigin?: string;
|
|
44
|
+
}): Promise<void>;
|
|
36
45
|
start(): Promise<void>;
|
|
37
46
|
stop(): Promise<void>;
|
|
38
47
|
restart(): Promise<void>;
|
|
@@ -45,9 +54,9 @@ export declare class WebServiceManager {
|
|
|
45
54
|
export declare function systemdUnit(runtime: string, script: string, port: number, configuration?: string, web?: {
|
|
46
55
|
bind?: string;
|
|
47
56
|
publicOrigin?: string;
|
|
48
|
-
}): string;
|
|
57
|
+
}, environment?: ServiceEnvironment): string;
|
|
49
58
|
export declare function launchdPlist(runtime: string, script: string, port: number, configuration?: string, web?: {
|
|
50
59
|
bind?: string;
|
|
51
60
|
publicOrigin?: string;
|
|
52
|
-
}): string;
|
|
61
|
+
}, environment?: ServiceEnvironment): string;
|
|
53
62
|
export {};
|
package/dist/web/service.js
CHANGED
|
@@ -15,6 +15,7 @@ export class WebServiceManager {
|
|
|
15
15
|
stateDir;
|
|
16
16
|
uid;
|
|
17
17
|
runtimeExecutable;
|
|
18
|
+
environment;
|
|
18
19
|
constructor(options = {}) {
|
|
19
20
|
const platform = options.platform ?? process.platform;
|
|
20
21
|
if (platform !== 'linux' && platform !== 'darwin')
|
|
@@ -25,6 +26,7 @@ export class WebServiceManager {
|
|
|
25
26
|
this.stateDir = options.stateDir ?? join(stateRoot(), 'web');
|
|
26
27
|
this.uid = options.uid ?? process.getuid?.() ?? 501;
|
|
27
28
|
this.runtimeExecutable = options.runtimeExecutable ?? process.execPath;
|
|
29
|
+
this.environment = serviceEnvironment(options.environment ?? process.env);
|
|
28
30
|
}
|
|
29
31
|
get metadataPath() { return join(this.stateDir, 'service.json'); }
|
|
30
32
|
get definitionPath() {
|
|
@@ -42,13 +44,14 @@ export class WebServiceManager {
|
|
|
42
44
|
const config = configuration ? resolve(configuration) : undefined;
|
|
43
45
|
const metadata = {
|
|
44
46
|
version: VERSION, platform: this.platform, runtime, script: resolvedScript, port,
|
|
47
|
+
environment: this.environment,
|
|
45
48
|
...(config ? { configuration: config } : {}),
|
|
46
49
|
...(web.bind ? { bind: web.bind } : {}),
|
|
47
50
|
...(web.publicOrigin ? { publicOrigin: web.publicOrigin } : {}),
|
|
48
51
|
};
|
|
49
52
|
replaceFileAtomically(this.definitionPath, this.platform === 'linux'
|
|
50
|
-
? systemdUnit(runtime, resolvedScript, port, config, web)
|
|
51
|
-
: launchdPlist(runtime, resolvedScript, port, config, web), 0o600);
|
|
53
|
+
? systemdUnit(runtime, resolvedScript, port, config, web, this.environment)
|
|
54
|
+
: launchdPlist(runtime, resolvedScript, port, config, web, this.environment), 0o600);
|
|
52
55
|
replaceFileAtomically(this.metadataPath, JSON.stringify(metadata, null, 2) + '\n', 0o600);
|
|
53
56
|
if (this.platform === 'linux') {
|
|
54
57
|
await this.must('systemctl', ['--user', 'daemon-reload']);
|
|
@@ -63,6 +66,14 @@ export class WebServiceManager {
|
|
|
63
66
|
}
|
|
64
67
|
return [`installed ${this.definitionPath}`, 'launchd service starts at login'];
|
|
65
68
|
}
|
|
69
|
+
/** Persist an enrollment bind fallback, reloading launchd's cached definition. */
|
|
70
|
+
async retainBoundPort(script, port, configuration, web = {}) {
|
|
71
|
+
await this.install(script, port, configuration, web);
|
|
72
|
+
if (this.platform === 'darwin') {
|
|
73
|
+
await this.stop();
|
|
74
|
+
await this.start();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
66
77
|
async start() {
|
|
67
78
|
this.requireInstalled();
|
|
68
79
|
if (this.platform === 'linux') {
|
|
@@ -159,19 +170,20 @@ function validatePort(port) {
|
|
|
159
170
|
function systemdQuote(value) {
|
|
160
171
|
return `"${value.replace(/[%\\"]/g, char => char === '%' ? '%%' : `\\${char}`)}"`;
|
|
161
172
|
}
|
|
162
|
-
export function systemdUnit(runtime, script, port, configuration, web = {}) {
|
|
173
|
+
export function systemdUnit(runtime, script, port, configuration, web = {}, environment = {}) {
|
|
163
174
|
const config = configuration ? ` --configuration ${systemdQuote(configuration)}` : '';
|
|
164
175
|
const access = `${web.bind ? ` --bind ${systemdQuote(web.bind)}` : ''}`
|
|
165
176
|
+ `${web.publicOrigin ? ` --public-origin ${systemdQuote(web.publicOrigin)}` : ''}`;
|
|
166
177
|
return `[Unit]\nDescription=ours-fleet localhost web console\nAfter=default.target\n\n`
|
|
167
178
|
+ `[Service]\nType=simple\nExecStart=${systemdQuote(runtime)} ${systemdQuote(script)} web serve --port ${port} --no-open${config}${access}\n`
|
|
179
|
+
+ Object.entries(serviceEnvironment(environment)).map(([key, value]) => `Environment=${systemdQuote(`${key}=${value}`)}\n`).join('')
|
|
168
180
|
+ `Restart=on-failure\nRestartSec=5\nTimeoutStopSec=15\n\n`
|
|
169
181
|
+ `[Install]\nWantedBy=default.target\n`;
|
|
170
182
|
}
|
|
171
183
|
const xml = (value) => value.replace(/[&<>"']/g, char => ({
|
|
172
184
|
'&': '&', '<': '<', '>': '>', '"': '"', "'": ''',
|
|
173
185
|
}[char]));
|
|
174
|
-
export function launchdPlist(runtime, script, port, configuration, web = {}) {
|
|
186
|
+
export function launchdPlist(runtime, script, port, configuration, web = {}, environment = {}) {
|
|
175
187
|
const config = configuration
|
|
176
188
|
? `<string>--configuration</string><string>${xml(configuration)}</string>` : '';
|
|
177
189
|
const access = `${web.bind ? `<string>--bind</string><string>${xml(web.bind)}</string>` : ''}`
|
|
@@ -181,6 +193,20 @@ export function launchdPlist(runtime, script, port, configuration, web = {}) {
|
|
|
181
193
|
+ `<plist version="1.0"><dict>\n<key>Label</key><string>${WEB_LAUNCHD_LABEL}</string>\n`
|
|
182
194
|
+ `<key>ProgramArguments</key><array><string>${xml(runtime)}</string><string>${xml(script)}</string><string>web</string>`
|
|
183
195
|
+ `<string>serve</string><string>--port</string><string>${port}</string><string>--no-open</string>${config}${access}</array>\n`
|
|
196
|
+
+ `<key>EnvironmentVariables</key><dict>${Object.entries(serviceEnvironment(environment)).map(([key, value]) => `<key>${key}</key><string>${xml(value)}</string>`).join('')}</dict>\n`
|
|
184
197
|
+ `<key>RunAtLoad</key><true/><key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n`
|
|
185
198
|
+ `<key>ProcessType</key><string>Background</string>\n</dict></plist>\n`;
|
|
186
199
|
}
|
|
200
|
+
// Retain only profile/tool paths, never inherited credentials or arbitrary environment.
|
|
201
|
+
function serviceEnvironment(source) {
|
|
202
|
+
const result = {};
|
|
203
|
+
for (const key of ['OURS_CONFIG', 'OURS_FLEET_HOME', 'PATH']) {
|
|
204
|
+
const value = source[key];
|
|
205
|
+
if (!value)
|
|
206
|
+
continue;
|
|
207
|
+
if (/[\r\n\0]/.test(value))
|
|
208
|
+
throw new FleetError('invalid_request', `invalid service path setting: ${key}`);
|
|
209
|
+
result[key] = key === 'PATH' ? value : resolve(value);
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface WorkspaceDevice {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
createdAt: number;
|
|
5
|
+
lastUsedAt: number;
|
|
6
|
+
expiresAt: number;
|
|
7
|
+
revokedAt: number | null;
|
|
8
|
+
}
|
|
9
|
+
export declare class WorkspaceDeviceStore {
|
|
10
|
+
private readonly now;
|
|
11
|
+
private readonly db;
|
|
12
|
+
readonly workspaceId: string;
|
|
13
|
+
constructor(dir?: string, now?: () => number);
|
|
14
|
+
mint(issuer?: string | null): {
|
|
15
|
+
enrollment: string;
|
|
16
|
+
workspaceId: string;
|
|
17
|
+
expiresAt: number;
|
|
18
|
+
};
|
|
19
|
+
enroll(enrollment: string, workspaceId: string, label: string): {
|
|
20
|
+
token: string;
|
|
21
|
+
device: WorkspaceDevice;
|
|
22
|
+
workspaceId: string;
|
|
23
|
+
};
|
|
24
|
+
authenticate(token: string): WorkspaceDevice;
|
|
25
|
+
valid(id: string): boolean;
|
|
26
|
+
list(): WorkspaceDevice[];
|
|
27
|
+
revoke(id: string): void;
|
|
28
|
+
close(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
3
|
+
import { mkdirSync, chmodSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { stateRoot } from '../paths.js';
|
|
6
|
+
import { FleetError } from '../application/errors.js';
|
|
7
|
+
const opaque = () => randomBytes(32).toString('base64url');
|
|
8
|
+
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
|
9
|
+
export class WorkspaceDeviceStore {
|
|
10
|
+
now;
|
|
11
|
+
db;
|
|
12
|
+
workspaceId;
|
|
13
|
+
constructor(dir = join(stateRoot(), 'web'), now = Date.now) {
|
|
14
|
+
this.now = now;
|
|
15
|
+
const { DatabaseSync } = createRequire(import.meta.url)('node:sqlite');
|
|
16
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
17
|
+
chmodSync(dir, 0o700);
|
|
18
|
+
const path = join(dir, 'workspace-devices.db');
|
|
19
|
+
this.db = new DatabaseSync(path);
|
|
20
|
+
chmodSync(path, 0o600);
|
|
21
|
+
this.db.exec(`PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000;
|
|
22
|
+
CREATE TABLE IF NOT EXISTS metadata(key TEXT PRIMARY KEY,value TEXT NOT NULL);
|
|
23
|
+
CREATE TABLE IF NOT EXISTS devices(id TEXT PRIMARY KEY,hash TEXT NOT NULL,label TEXT NOT NULL,createdAt INTEGER NOT NULL,lastUsedAt INTEGER NOT NULL,expiresAt INTEGER NOT NULL,revokedAt INTEGER);
|
|
24
|
+
CREATE TABLE IF NOT EXISTS enrollments(hash TEXT PRIMARY KEY,expiresAt INTEGER NOT NULL,issuer TEXT);`);
|
|
25
|
+
this.db.prepare('INSERT OR IGNORE INTO metadata VALUES(?,?)').run('workspaceId', opaque());
|
|
26
|
+
this.workspaceId = String(this.db.prepare('SELECT value FROM metadata WHERE key=?').get('workspaceId').value);
|
|
27
|
+
}
|
|
28
|
+
mint(issuer = null) {
|
|
29
|
+
const now = this.now(), enrollment = opaque(), expiresAt = now + 5 * 60000;
|
|
30
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
31
|
+
try {
|
|
32
|
+
this.db.prepare('DELETE FROM enrollments WHERE expiresAt<=?').run(now);
|
|
33
|
+
const count = Number(this.db.prepare('SELECT count(*) AS n FROM enrollments').get().n);
|
|
34
|
+
if (count >= 32)
|
|
35
|
+
throw new FleetError('rate_limited', 'too many pending device links');
|
|
36
|
+
this.db.prepare('INSERT INTO enrollments VALUES(?,?,?)').run(hash(enrollment), expiresAt, issuer);
|
|
37
|
+
this.db.exec('COMMIT');
|
|
38
|
+
return { enrollment, workspaceId: this.workspaceId, expiresAt };
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
this.db.exec('ROLLBACK');
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
enroll(enrollment, workspaceId, label) {
|
|
46
|
+
if (workspaceId !== this.workspaceId || typeof enrollment !== 'string' || !/^[\w-]{43}$/.test(enrollment))
|
|
47
|
+
throw new FleetError('unauthorized', 'invalid device enrollment');
|
|
48
|
+
if (typeof label !== 'string' || !label.trim() || label.length > 100 || /[\x00-\x1f\x7f]/.test(label))
|
|
49
|
+
throw new FleetError('invalid_request', 'device name must contain 1–100 printable characters');
|
|
50
|
+
const now = this.now(), id = opaque(), token = `${id}.${opaque()}`;
|
|
51
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
52
|
+
try {
|
|
53
|
+
const code = this.db.prepare('DELETE FROM enrollments WHERE hash=? AND expiresAt>? RETURNING issuer').get(hash(enrollment), now);
|
|
54
|
+
if (!code)
|
|
55
|
+
throw new FleetError('unauthorized', 'device enrollment is expired or already used');
|
|
56
|
+
if (code.issuer && !this.db.prepare('SELECT id FROM devices WHERE id=? AND revokedAt IS NULL AND expiresAt>?').get(code.issuer, now))
|
|
57
|
+
throw new FleetError('unauthorized', 'issuing device has been revoked');
|
|
58
|
+
const count = Number(this.db.prepare('SELECT count(*) AS n FROM devices WHERE revokedAt IS NULL AND expiresAt>?').get(now).n);
|
|
59
|
+
if (count >= 128)
|
|
60
|
+
throw new FleetError('rate_limited', 'authorized device limit reached');
|
|
61
|
+
const device = { id, label: label.trim(), createdAt: now, lastUsedAt: now, expiresAt: now + 90 * 86400000, revokedAt: null };
|
|
62
|
+
this.db.prepare('INSERT INTO devices VALUES(?,?,?,?,?,?,NULL)').run(id, hash(token), device.label, now, now, device.expiresAt);
|
|
63
|
+
this.db.exec('COMMIT');
|
|
64
|
+
return { token, device, workspaceId };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.db.exec('ROLLBACK');
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
authenticate(token) {
|
|
72
|
+
const id = typeof token === 'string' ? token.split('.')[0] : '', now = this.now();
|
|
73
|
+
const row = this.db.prepare('SELECT * FROM devices WHERE id=? AND revokedAt IS NULL AND expiresAt>?').get(id, now);
|
|
74
|
+
const supplied = Buffer.from(hash(token || '')), expected = Buffer.from(String(row?.hash || '0'.repeat(64)));
|
|
75
|
+
if (!row || !timingSafeEqual(supplied, expected))
|
|
76
|
+
throw new FleetError('unauthorized', 'workspace device is missing, expired, or revoked');
|
|
77
|
+
this.db.prepare('UPDATE devices SET lastUsedAt=? WHERE id=?').run(now, id);
|
|
78
|
+
return { id, label: String(row.label), createdAt: Number(row.createdAt), lastUsedAt: now, expiresAt: Number(row.expiresAt), revokedAt: null };
|
|
79
|
+
}
|
|
80
|
+
valid(id) { return Boolean(this.db.prepare('SELECT id FROM devices WHERE id=? AND revokedAt IS NULL AND expiresAt>?').get(id, this.now())); }
|
|
81
|
+
list() { return this.db.prepare('SELECT id,label,createdAt,lastUsedAt,expiresAt,revokedAt FROM devices ORDER BY createdAt DESC LIMIT 256').all().map(row => ({ id: String(row.id), label: String(row.label), createdAt: Number(row.createdAt), lastUsedAt: Number(row.lastUsedAt), expiresAt: Number(row.expiresAt), revokedAt: row.revokedAt === null ? null : Number(row.revokedAt) })); }
|
|
82
|
+
revoke(id) { this.db.prepare('UPDATE devices SET revokedAt=? WHERE id=? AND revokedAt IS NULL').run(this.now(), id); this.db.prepare('DELETE FROM enrollments WHERE issuer=?').run(id); }
|
|
83
|
+
close() { this.db.close(); }
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startWorkspaceTunnel(origin: string): () => Promise<void>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { stateRoot } from '../paths.js';
|
|
5
|
+
export function startWorkspaceTunnel(origin) {
|
|
6
|
+
const dir = join(stateRoot(), 'workspace'), file = join(dir, 'tunnel.json');
|
|
7
|
+
if (!existsSync(file))
|
|
8
|
+
return async () => { };
|
|
9
|
+
const config = JSON.parse(readFileSync(file, 'utf8'));
|
|
10
|
+
if (config.origin !== origin)
|
|
11
|
+
throw Error('Workspace tunnel requires its configured public origin');
|
|
12
|
+
const tokenFile = join(dir, 'connector');
|
|
13
|
+
if (config.tokenFile !== tokenFile)
|
|
14
|
+
throw Error('Unexpected connector credential path');
|
|
15
|
+
const stat = lstatSync(tokenFile);
|
|
16
|
+
if (!stat.isFile() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0 || stat.uid !== process.getuid?.())
|
|
17
|
+
throw Error('Connector credential must be an owned private file');
|
|
18
|
+
let stopped = false, child, timer, backoff = 1000;
|
|
19
|
+
const launch = () => {
|
|
20
|
+
if (stopped)
|
|
21
|
+
return;
|
|
22
|
+
child = spawn('cloudflared', ['tunnel', '--no-autoupdate', 'run', '--token-file', tokenFile], { stdio: 'ignore' });
|
|
23
|
+
let scheduled = false;
|
|
24
|
+
const retry = () => { if (scheduled || stopped)
|
|
25
|
+
return; scheduled = true; timer = setTimeout(launch, backoff); backoff = Math.min(30000, backoff * 2); };
|
|
26
|
+
child.once('error', retry);
|
|
27
|
+
child.once('exit', retry);
|
|
28
|
+
};
|
|
29
|
+
launch();
|
|
30
|
+
return async () => { stopped = true; clearTimeout(timer); const current = child; if (!current || current.exitCode !== null)
|
|
31
|
+
return; await new Promise(resolve => { const timeout = setTimeout(() => { current.kill('SIGKILL'); resolve(); }, 5000); current.once('exit', () => { clearTimeout(timeout); resolve(); }); current.kill('SIGTERM'); }); };
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.fleet-acp{height:100%;min-height:0;min-width:0;display:flex;flex-direction:column;background:var(--acp-color-bg-primary);color:var(--acp-color-text-primary);font-size:15px}.fleet-acp-header{display:flex;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid var(--acp-color-border)}.fleet-acp-header>div{flex:1;min-width:0;overflow-wrap:anywhere}.fleet-acp-header small{display:block;margin-top:4px;color:var(--acp-color-text-secondary)}.fleet-acp-scroll{flex:1;overflow:auto;min-height:0;overscroll-behavior:contain}.fleet-acp-thread{max-width:820px;margin:auto;padding:24px 24px 16px;min-width:0}.fleet-acp-message>small{display:block;margin-bottom:8px;color:var(--acp-color-text-secondary);font-size:12px}.fleet-acp-message [class*=title],.fleet-acp-message [class*=Title]{white-space:normal!important;overflow-wrap:anywhere}.fleet-acp-message [class*=header]{min-width:0}.fleet-acp-empty{text-align:center;padding:48px 0;color:var(--acp-color-text-secondary)}.fleet-acp-empty h2{font-size:24px;color:var(--acp-color-text-primary)}.fleet-acp-composer{width:100%;max-width:868px;align-self:center;padding:8px 24px 20px;box-sizing:border-box}.fleet-acp-state{display:flex;gap:8px;align-items:center;min-height:32px;color:var(--acp-color-text-secondary);font-size:13px}.fleet-acp-state>button{margin-left:auto}.fleet-acp .fleet-request,.fleet-acp [role=alert]{overflow-wrap:anywhere;min-width:0;max-width:100%}.fleet-acp .fleet-request p,.fleet-acp .fleet-request strong{white-space:pre-wrap;overflow-wrap:anywhere}.fleet-acp .fleet-request{padding:14px;border:1px solid var(--acp-color-border);border-radius:12px;margin:12px 0}.fleet-acp .fleet-request button{margin:4px}@media(max-width:600px){.fleet-acp-header{padding:10px;gap:8px}.fleet-acp-header button{font-size:12px}.fleet-acp-thread{padding:20px 14px 10px}.fleet-acp-composer{padding:8px 10px 12px}.fleet-acp-header strong{font-size:14px}}.fleet-chat-slot:not(.signal-stage){flex:1;min-height:0;overflow:hidden}.fleet-acp{--acp-color-bg-primary:var(--surface);--acp-color-bg-secondary:var(--surface-soft,var(--surface));--acp-color-text-primary:var(--text);--acp-color-accent:var(--accent);--acp-color-border:var(--line)}.fleet-acp .fleet-agent-request{min-width:0;overflow-wrap:anywhere;padding:14px;border:1px solid var(--acp-color-border);border-radius:12px;margin:12px 0}.fleet-acp .fleet-agent-request p{white-space:pre-wrap;overflow-wrap:anywhere}.fleet-acp .fleet-agent-request .fleet-actions{flex-wrap:wrap}.fleet-acp-header strong{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.fleet-acp-header button{flex-shrink:0}.fleet-acp{--acp-color-text-secondary:var(--text-2)}.fleet-acp-header{padding:6px 12px;gap:8px;min-height:56px;box-sizing:border-box}.fleet-acp-header small{margin-top:2px;font-size:12px}.fleet-acp-header .icon-btn{border:0;background:transparent;box-shadow:none}.fleet-acp-message.user>small{color:var(--text);font-weight:600;margin-bottom:4px}.fleet-acp-input .fleet-acp-send{width:44px;height:44px;min-width:44px;padding:0;border-radius:50%;display:grid;place-items:center;flex-shrink:0}.fleet-acp-state{min-height:26px;font-size:12px}.fleet-acp-composer{padding-top:4px;padding-bottom:max(10px,env(safe-area-inset-bottom))}@media(max-width:600px){.fleet-acp-header{padding:4px 6px;gap:4px}.fleet-acp-header strong{font-size:14px}.fleet-acp-thread{padding:14px 12px 8px}.fleet-acp-composer{padding-left:10px;padding-right:10px}.fleet-acp-message>small{font-size:11px;margin-bottom:5px}}.fleet-acp{position:relative;isolation:isolate;--fleet-glass:color-mix(in srgb,var(--surface) 68%,transparent);--fleet-glass-rim:color-mix(in srgb,var(--text) 12%,transparent)}.fleet-acp-scroll{position:absolute;inset:0;scroll-padding-top:var(--fleet-acp-top,80px);scroll-padding-bottom:var(--fleet-acp-bottom,110px)}.fleet-acp-thread{padding-top:calc(var(--fleet-acp-top,80px) + env(safe-area-inset-top));padding-bottom:var(--fleet-acp-bottom,110px)}.fleet-acp-header{position:absolute;z-index:2;top:max(8px,env(safe-area-inset-top));left:12px;right:12px;padding:4px 8px;min-height:52px;border:0;border-radius:28px;background:var(--fleet-glass);backdrop-filter:blur(24px) saturate(180%);-webkit-backdrop-filter:blur(24px) saturate(180%);box-shadow:0 4px 20px #00000012,inset 0 1px 0 var(--fleet-glass-rim),inset 0 0 0 .5px var(--fleet-glass-rim)}.fleet-acp-composer{position:absolute;z-index:2;bottom:max(8px,env(safe-area-inset-bottom));left:50%;transform:translate(-50%);width:calc(100% - 24px);max-width:820px;padding:0;background:transparent}.fleet-acp-state{width:fit-content;max-width:100%;padding:2px 10px;margin:0 0 4px 6px;border-radius:14px;background:var(--fleet-glass);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);font-size:12px;min-height:22px;box-sizing:border-box}.fleet-acp-header:before{content:"";position:absolute;inset:-12px -12px -10px;z-index:-1;pointer-events:none;background:linear-gradient(var(--surface),transparent);opacity:.3;mask-image:linear-gradient(#000,transparent)}.fleet-acp .icon-btn:active,.fleet-acp-send:active{opacity:.8}@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){.fleet-acp{--fleet-glass:var(--surface)}.fleet-acp-header,.fleet-acp-state{backdrop-filter:none;-webkit-backdrop-filter:none}.fleet-acp-header:before{display:none}}@media(prefers-reduced-motion:reduce){.fleet-acp *{scroll-behavior:auto!important;transition:none!important;animation:none!important}}.fleet-command-suggestions{position:absolute;bottom:100%;left:0;right:0;max-height:min(260px,40dvh);overflow-y:auto;margin-bottom:8px;padding:6px;border:1px solid var(--acp-color-border);border-radius:14px;background:var(--acp-color-bg-secondary);box-shadow:0 8px 32px #0003}.fleet-command-suggestions button{display:flex;align-items:center;gap:12px;width:100%;min-height:44px;text-align:left;padding:8px 12px;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer}.fleet-command-suggestions button[aria-selected=true]{background:var(--acp-color-bg-tertiary,#ffffff14)}.fleet-command-suggestions small{color:var(--acp-color-text-secondary)}.fleet-command-suggestions p{padding:8px 12px;margin:0;font-size:13px}.fleet-task-notice{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:16px 18px;margin:16px 0 24px;border:1px solid var(--acp-color-border);border-radius:16px;background:var(--acp-color-bg-secondary)}.fleet-task-notice small{color:var(--acp-color-text-secondary)}.fleet-task-notice strong{overflow-wrap:anywhere}.fleet-task-notice a{display:inline-flex;align-items:center;min-height:44px;color:inherit;text-underline-offset:4px}.fleet-voice-panel{position:absolute;bottom:calc(100% + 8px);left:0;right:0;max-height:45dvh;overflow:auto;padding:14px;border:1px solid var(--line);border-radius:20px;background:var(--surface);box-shadow:0 8px 32px #0002;display:grid;gap:10px}.fleet-voice-panel audio{width:100%;max-height:44px}.fleet-voice-panel .fleet-actions{display:flex;flex-wrap:wrap;gap:8px}.fleet-voice-panel p{margin:0;overflow-wrap:anywhere}.fleet-voice-transcript{white-space:pre-wrap;max-height:120px;overflow:auto}.fleet-live-voice{display:flex;flex-direction:column;align-items:center;text-align:center;padding:24px 12px;gap:16px}.fleet-live-voice h4,.fleet-live-voice p{margin:0}.fleet-live-voice>svg{color:var(--text-2)}.fleet-acp-input .vr-mic{width:44px;height:44px;min-width:44px;border-radius:50%;flex-shrink:0}.fleet-acp-input .voice-rec-overlay{border-radius:28px;padding:8px 12px;gap:8px;min-height:44px}.fleet-acp-input .vr-trash,.fleet-acp-input .vr-stop{min-height:44px;min-width:44px}.fleet-voice-panel .attach-preview{padding:0;display:flex;flex-wrap:wrap;gap:10px}.fleet-voice-panel .attach-audio{flex-basis:100%;max-width:none;width:100%}.fleet-voice-panel .filecard-meta{flex:1;min-width:0}.fleet-voice-panel button{min-height:44px}.fleet-acp-input .vr-hint{font-size:11px}.fleet-acp-scroll{inset:var(--fleet-acp-top,68px) 0 var(--fleet-acp-bottom,80px);scroll-padding:12px 0}.fleet-acp-thread{padding:12px 20px;max-width:820px}.fleet-acp-header{left:10px;right:10px;min-height:48px;border-radius:20px;background:color-mix(in srgb,var(--surface) 92%,transparent);box-shadow:inset 0 0 0 .5px var(--fleet-glass-rim)}.fleet-acp-header:before{display:none}.fleet-acp-header strong{font-size:14px;font-weight:600}.fleet-acp-header small{font-size:11px;margin-top:1px}.fleet-acp-composer{width:calc(100% - 20px);bottom:max(8px,env(safe-area-inset-bottom))}.fleet-acp-input .fleet-live-voice-trigger{background:transparent;border:0;box-shadow:none;color:var(--text-2)}.fleet-acp-input .vr-mic{color:var(--text-2)}.fleet-acp-state[data-idle=true]{position:absolute;width:1px;height:1px;min-height:0;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.fleet-voice-panel{position:static;order:-1;flex:0 0 100%;max-height:none;overflow:visible;padding:0 0 5px;margin:0 0 1px;border:0;border-bottom:1px solid var(--line);border-radius:0;background:transparent;box-shadow:none;gap:4px;box-sizing:border-box}.fleet-voice-panel .attach-preview-compact{display:grid;grid-template-columns:44px minmax(40px,1fr) auto 44px;gap:4px;align-items:center;padding:0;margin:0;background:transparent;border:0;border-radius:0;box-shadow:none;min-height:44px}.attach-preview-compact>audio{display:none}.attach-preview-compact .icon-btn{height:44px;width:44px;padding:0;border:0;background:transparent;box-shadow:none}.voice-preview-timeline{min-width:0;position:relative;height:44px;display:flex;align-items:center}.voice-preview-timeline input{width:100%;height:44px;margin:0;padding:0;accent-color:var(--text-2);cursor:pointer}.voice-preview-timeline span{position:absolute;right:0;bottom:-1px;pointer-events:none;font-size:12px;line-height:14px;font-variant-numeric:tabular-nums;color:var(--text-2);background:var(--surface)}.fleet-voice-panel .voice-preview-add{height:44px;min-width:72px;padding:0 8px;border:0;border-radius:12px;background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--text);font:inherit;font-size:13px;font-weight:600;white-space:nowrap;box-shadow:none}.fleet-voice-panel .voice-preview-add:disabled{opacity:.6}.voice-preview-error{grid-column:1/-1}.fleet-voice-panel p{font-size:12px;padding:4px 8px}@media(max-width:600px){.fleet-acp-thread{padding:10px 14px}.fleet-acp-header{padding:2px 4px}.fleet-acp-input .voice-rec-overlay{border-radius:24px}}.fleet-attachment-previews{display:flex;gap:8px;overflow-x:auto;list-style:none;margin:0;padding:8px 0;max-width:100%}.fleet-attachment-previews li{display:flex;align-items:center;gap:8px;border:1px solid var(--border);border-radius:12px;padding:6px;min-width:0;flex:0 0 200px}.fleet-attachment-previews img{width:44px;height:44px;object-fit:cover;border-radius:6px}.fleet-attachment-previews span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px}.fleet-attachment-previews small{display:block;opacity:.65}.fleet-acp-older{display:block;margin:0 auto 16px;min-height:44px;padding:8px 16px;border:1px solid var(--acp-color-border);border-radius:22px;background:transparent;color:var(--acp-color-text-secondary);font:inherit;font-size:13px;cursor:pointer}.fleet-acp-older:disabled{cursor:default;opacity:.7}.fleet-acp .jump-latest{bottom:calc(var(--fleet-acp-bottom,80px) + 8px);min-height:44px;white-space:nowrap}.fleet-acp-scroll:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}:root,[data-acp-theme=dark]{--acp-color-bg-primary: #0d1117;--acp-color-bg-secondary: #161b22;--acp-color-bg-tertiary: #1c2128;--acp-color-bg-hover: #252b33;--acp-color-bg-glass: rgba(22, 27, 34, .86);--acp-color-bg-input: #0d1117;--acp-color-bg-code: #0d1117;--acp-color-bg-overlay: rgba(0, 0, 0, .55);--acp-color-bg-selected: rgba(97, 175, 239, .12);--acp-color-bg-danger: rgba(248, 81, 73, .12);--acp-color-text-primary: #e6edf3;--acp-color-text-secondary: #8b949e;--acp-color-text-muted: #6e7681;--acp-color-text-inverse: #0d1117;--acp-color-text-danger: #f85149;--acp-color-border: rgba(255, 255, 255, .13);--acp-color-border-subtle: rgba(255, 255, 255, .07);--acp-color-border-accent: rgba(97, 175, 239, .3);--acp-color-accent: #61afef;--acp-color-accent-hover: #75bdf3;--acp-color-accent-muted: rgba(97, 175, 239, .12);--acp-color-accent-text: #82c7ff;--acp-color-success: #3fb950;--acp-color-success-muted: rgba(63, 185, 80, .12);--acp-color-success-bg: rgba(63, 185, 80, .08);--acp-color-warning: #d29922;--acp-color-warning-muted: rgba(210, 153, 34, .12);--acp-color-error: #f85149;--acp-color-error-muted: rgba(248, 81, 73, .12);--acp-color-error-bg: rgba(248, 81, 73, .08);--acp-color-info: #58a6ff;--acp-color-info-muted: rgba(88, 166, 255, .12);--acp-color-user-bubble: #161b22;--acp-color-user-text: #e6edf3;--acp-color-agent-bubble: transparent;--acp-color-agent-text: #e6edf3;--acp-color-knob: #ffffff;--acp-color-knob-shadow: 0 1px 3px rgba(0, 0, 0, .25);--acp-shadow-xs: 0 1px 2px rgba(0, 0, 0, .5);--acp-shadow-sm: 0 2px 8px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .05);--acp-shadow-md: 0 8px 24px rgba(0, 0, 0, .55), 0 0 0 1px rgba(255, 255, 255, .06);--acp-shadow-lg: 0 16px 48px rgba(0, 0, 0, .65), 0 0 0 1px rgba(255, 255, 255, .07);--acp-radius-xs: 4px;--acp-radius-sm: 6px;--acp-radius-md: 10px;--acp-radius-lg: 14px;--acp-radius-xl: 20px;--acp-font-sans: "Geist", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--acp-font-mono: "Geist Mono", "JetBrains Mono", "Fira Code", "Cascadia Code", "Consolas", monospace;--acp-duration-fast: .12s;--acp-duration-normal: .2s;--acp-duration-slow: .35s;--acp-ease-out: cubic-bezier(.16, 1, .3, 1);--acp-ease-in-out: cubic-bezier(.4, 0, .2, 1);--acp-ease-spring: cubic-bezier(.34, 1.56, .64, 1);color-scheme:dark}[data-acp-theme=light]{--acp-color-bg-primary: #ffffff;--acp-color-bg-secondary: #f6f8fa;--acp-color-bg-tertiary: #eaeef2;--acp-color-bg-hover: #dde3e8;--acp-color-bg-glass: rgba(255, 255, 255, .84);--acp-color-bg-input: #ffffff;--acp-color-bg-code: #f6f8fa;--acp-color-bg-overlay: rgba(0, 0, 0, .25);--acp-color-bg-selected: rgba(37, 99, 235, .08);--acp-color-bg-danger: rgba(207, 34, 46, .08);--acp-color-text-primary: #1f2328;--acp-color-text-secondary: #656d76;--acp-color-text-muted: #8b949e;--acp-color-text-inverse: #ffffff;--acp-color-text-danger: #cf222e;--acp-color-border: rgba(0, 0, 0, .12);--acp-color-border-subtle: rgba(0, 0, 0, .07);--acp-color-border-accent: rgba(37, 99, 235, .25);--acp-color-accent: #2563eb;--acp-color-accent-hover: #1d4ed8;--acp-color-accent-muted: rgba(37, 99, 235, .08);--acp-color-accent-text: #1d4ed8;--acp-color-success: #1a7f37;--acp-color-success-muted: rgba(26, 127, 55, .08);--acp-color-success-bg: rgba(26, 127, 55, .06);--acp-color-warning: #9a6700;--acp-color-warning-muted: rgba(154, 103, 0, .08);--acp-color-error: #cf222e;--acp-color-error-muted: rgba(207, 34, 46, .08);--acp-color-error-bg: rgba(207, 34, 46, .06);--acp-color-info: #2563eb;--acp-color-info-muted: rgba(37, 99, 235, .08);--acp-color-user-bubble: #2563eb;--acp-color-user-text: #ffffff;--acp-color-agent-bubble: #f0f0f0;--acp-color-agent-text: #1f2328;--acp-color-knob: #ffffff;--acp-color-knob-shadow: 0 1px 3px rgba(0, 0, 0, .15);--acp-shadow-xs: 0 1px 2px rgba(0, 0, 0, .04);--acp-shadow-sm: 0 2px 8px rgba(0, 0, 0, .06), 0 0 0 1px rgba(0, 0, 0, .03);--acp-shadow-md: 0 8px 24px rgba(0, 0, 0, .08), 0 0 0 1px rgba(0, 0, 0, .04);--acp-shadow-lg: 0 16px 48px rgba(0, 0, 0, .1), 0 0 0 1px rgba(0, 0, 0, .05);--acp-radius-xs: 4px;--acp-radius-sm: 6px;--acp-radius-md: 10px;--acp-radius-lg: 14px;--acp-radius-xl: 20px;--acp-font-sans: "Geist", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--acp-font-mono: "Geist Mono", "JetBrains Mono", "Fira Code", "Cascadia Code", "Consolas", monospace;--acp-duration-fast: .12s;--acp-duration-normal: .2s;--acp-duration-slow: .35s;--acp-ease-out: cubic-bezier(.16, 1, .3, 1);--acp-ease-in-out: cubic-bezier(.4, 0, .2, 1);--acp-ease-spring: cubic-bezier(.34, 1.56, .64, 1);color-scheme:light}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--acp-color-text-muted);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--acp-color-text-secondary)}::selection{background:var(--acp-color-accent-muted);color:var(--acp-color-text-primary)}:focus-visible{outline:2px solid var(--acp-color-accent);outline-offset:2px;border-radius:var(--acp-radius-xs)}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}._acp-loading_1tulc_1{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;gap:18px;color:var(--acp-color-text-secondary);background:var(--acp-color-bg-primary);font-size:14px;font-weight:500}._acp-loading__spinner_1tulc_13{width:36px;height:36px;border:3px solid var(--acp-color-border-subtle);border-top-color:var(--acp-color-accent);border-radius:50%;animation:_acp-spin_1tulc_1 .7s linear infinite}@keyframes _acp-spin_1tulc_1{to{transform:rotate(360deg)}}._acp-workbench_64hok_1{display:grid;grid-template-columns:260px 1fr;grid-template-rows:1fr;height:100vh;background:var(--acp-color-bg-primary);color:var(--acp-color-text-primary);font-family:var(--acp-font-sans);overflow:hidden}._acp-workbench--has-panel_64hok_11{grid-template-columns:260px 1fr 360px}._acp-workbench__sidebar_64hok_14{background:var(--acp-color-bg-glass);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border-right:1px solid var(--acp-color-border-subtle);display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--acp-shadow-sm)}._acp-workbench__main_64hok_24{display:flex;flex-direction:column;overflow:hidden;min-width:0}._acp-workbench__panel_64hok_30{background:var(--acp-color-bg-glass);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border-left:1px solid var(--acp-color-border-subtle);overflow:hidden;box-shadow:var(--acp-shadow-sm)}._acp-project-opener_1fx86_1{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-tertiary);border:1px solid var(--acp-color-border-subtle);margin:0 10px 10px;transition:border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-project-opener_1fx86_1:focus-within{border-color:var(--acp-color-accent)}._acp-project-opener__icon_1fx86_15{flex-shrink:0;font-size:14px;opacity:.6}._acp-project-opener__path_1fx86_20{flex:1;font-size:12px;color:var(--acp-color-text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;padding:3px 6px;border-radius:var(--acp-radius-xs);-webkit-user-select:none;user-select:none;transition:background var(--acp-duration-fast) var(--acp-ease-out)}._acp-project-opener__path_1fx86_20:hover{background:var(--acp-color-bg-hover)}._acp-project-opener__path_1fx86_20:focus-visible{outline:2px solid var(--acp-color-accent);outline-offset:1px}._acp-project-opener__input_1fx86_40{flex:1;font-size:12px;padding:3px 8px;border:1px solid var(--acp-color-accent);border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-input);color:var(--acp-color-text-primary);outline:none;font-family:var(--acp-font-mono);min-width:0}._acp-project-opener__input_1fx86_40::placeholder{color:var(--acp-color-text-muted)}._acp-project-opener__browse_1fx86_55{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:var(--acp-radius-sm);background:transparent;color:var(--acp-color-text-secondary);font-size:16px;cursor:pointer;font-weight:600;transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out)}._acp-project-opener__browse_1fx86_55:hover{background:var(--acp-color-bg-hover);color:var(--acp-color-text-primary)}._acp-project-opener__dropdown_1fx86_75{position:relative;flex:1;min-width:0}._acp-project-opener__chevron_1fx86_80{margin-left:4px;font-size:8px;opacity:.5}._acp-project-opener__menu_1fx86_85{position:absolute;top:100%;left:0;right:0;margin-top:4px;border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-primary);border:1px solid var(--acp-color-border);box-shadow:var(--acp-shadow-md);z-index:100;overflow:hidden}._acp-project-opener__menu-item_1fx86_98{display:flex;align-items:center;padding:8px 12px;cursor:pointer;transition:background var(--acp-duration-fast) var(--acp-ease-out);-webkit-user-select:none;user-select:none}._acp-project-opener__menu-item_1fx86_98:hover{background:var(--acp-color-bg-hover)}._acp-project-opener__menu-item--active_1fx86_109{background:var(--acp-color-bg-selected)}._acp-project-opener__menu-item-label_1fx86_112{font-size:13px;color:var(--acp-color-text-primary);font-weight:500}._acp-project-opener__menu-item-path_1fx86_117{margin-left:8px;font-size:11px;color:var(--acp-color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}._acp-project-opener__menu-item-remove_1fx86_126{flex-shrink:0;margin-left:8px;width:20px;height:20px;border:none;border-radius:var(--acp-radius-xs);background:transparent;color:var(--acp-color-text-muted);font-size:10px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out)}._acp-project-opener__menu-item-remove_1fx86_126:hover{background:var(--acp-color-bg-danger);color:var(--acp-color-text-danger)}._acp-project-opener__menu-divider_1fx86_146{height:1px;margin:4px 8px;background:var(--acp-color-border-subtle)}._acp-session-list_pt51t_1{display:flex;flex-direction:column;height:100%;padding:10px}._acp-session-list__header_pt51t_7{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;margin-bottom:8px}._acp-session-list__title_pt51t_14{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--acp-color-text-muted)}._acp-session-list__new-btn_pt51t_21{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-tertiary);color:var(--acp-color-text-secondary);font-size:16px;cursor:pointer;transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-session-list__new-btn_pt51t_21:hover{background:var(--acp-color-accent);color:var(--acp-color-text-inverse);border-color:var(--acp-color-accent)}._acp-session-list__items_pt51t_40{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:1px}._acp-session-list__empty-state_pt51t_47{padding:16px;text-align:center;color:var(--acp-color-text-muted);font-size:13px}._acp-session-item_pt51t_54{display:flex;align-items:center;padding:9px 12px;border-radius:var(--acp-radius-sm);cursor:pointer;border:none;background:transparent;color:var(--acp-color-text-primary);text-align:left;width:100%;font-size:13px;gap:10px;transition:background var(--acp-duration-fast) var(--acp-ease-out)}._acp-session-item_pt51t_54:hover{background:var(--acp-color-bg-hover)}._acp-session-item_pt51t_54:hover ._acp-session-item__delete_pt51t_72{opacity:1}._acp-session-item--active_pt51t_75{background:var(--acp-color-bg-tertiary)}._acp-session-item__icon_pt51t_78{flex-shrink:0;font-size:14px;opacity:.7}._acp-session-item__content_pt51t_83{flex:1;min-width:0}._acp-session-item__title_pt51t_87{font-size:13px;font-weight:500;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._acp-session-item__meta_pt51t_95{font-size:11px;color:var(--acp-color-text-muted);margin-top:2px}._acp-session-item__delete_pt51t_72{opacity:0;flex-shrink:0;background:none;border:none;color:var(--acp-color-text-muted);cursor:pointer;padding:4px;border-radius:var(--acp-radius-xs);font-size:12px;transition:opacity var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out)}._acp-session-item__delete_pt51t_72:hover{color:var(--acp-color-error)}._acp-agent-info_pt51t_116{padding:10px 14px;border-top:1px solid var(--acp-color-border-subtle);font-size:12px;color:var(--acp-color-text-secondary)}._acp-agent-info__name_pt51t_122{font-weight:600;color:var(--acp-color-text-primary)}._acp-session-load-more_pt51t_127{display:flex;align-items:center;justify-content:center;padding:8px 0;margin-top:4px}._acp-session-load-more__btn_pt51t_134{background:var(--acp-color-bg-tertiary);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-sm);color:var(--acp-color-text-secondary);font-size:12px;padding:6px 16px;cursor:pointer;transition:background var(--acp-duration-fast),color var(--acp-duration-fast),border-color var(--acp-duration-fast)}._acp-session-load-more__btn_pt51t_134:hover{background:var(--acp-color-bg-hover);color:var(--acp-color-text-primary);border-color:var(--acp-color-border)}._acp-session-agent-header_pt51t_150{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--acp-color-text-muted)}._acp-session-agent-header__name_pt51t_161{display:flex;align-items:center;gap:6px}._acp-session-agent-header__dot_pt51t_166{width:6px;height:6px;border-radius:50%}._acp-session-agent-header__dot--connected_pt51t_171{background:var(--acp-color-success)}._acp-session-agent-header__dot--connecting_pt51t_174{background:var(--acp-color-warning)}._acp-session-agent-header__dot--disconnected_pt51t_177{background:var(--acp-color-text-muted)}._acp-session-agent-header__dot--error_pt51t_180{background:var(--acp-color-error)}._acp-session-agent-header__add_pt51t_183{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-xs);background:transparent;color:var(--acp-color-text-muted);font-size:14px;cursor:pointer;transition:color var(--acp-duration-fast),background var(--acp-duration-fast),border-color var(--acp-duration-fast)}._acp-session-agent-header__add_pt51t_183:hover{color:var(--acp-color-text-primary);background:var(--acp-color-bg-hover);border-color:var(--acp-color-border)}._acp-markdown_dbfga_1 p{margin-bottom:10px}._acp-markdown_dbfga_1 p:last-child{margin-bottom:0}._acp-markdown_dbfga_1 ul,._acp-markdown_dbfga_1 ol{padding-left:1.5em;margin-bottom:10px}._acp-markdown_dbfga_1 ul li,._acp-markdown_dbfga_1 ol li{margin-bottom:4px}._acp-markdown_dbfga_1 ul li:last-child,._acp-markdown_dbfga_1 ol li:last-child{margin-bottom:0}._acp-markdown_dbfga_1 pre{font-family:var(--acp-font-mono);font-size:13px;line-height:1.6}._acp-markdown_dbfga_1 code{font-family:var(--acp-font-mono);font-size:.9em;letter-spacing:-.01em}._acp-markdown_dbfga_1 :not(pre)>code{background:var(--acp-color-bg-tertiary);color:var(--acp-color-text-primary);padding:2px 6px;border-radius:var(--acp-radius-xs);border:1px solid var(--acp-color-border-subtle)}._acp-markdown_dbfga_1 h1,._acp-markdown_dbfga_1 h2,._acp-markdown_dbfga_1 h3,._acp-markdown_dbfga_1 h4,._acp-markdown_dbfga_1 h5,._acp-markdown_dbfga_1 h6{margin-top:24px;margin-bottom:12px;font-weight:600;line-height:1.3;color:var(--acp-color-text-primary)}._acp-markdown_dbfga_1 h1:first-child,._acp-markdown_dbfga_1 h2:first-child,._acp-markdown_dbfga_1 h3:first-child,._acp-markdown_dbfga_1 h4:first-child,._acp-markdown_dbfga_1 h5:first-child,._acp-markdown_dbfga_1 h6:first-child{margin-top:0}._acp-markdown_dbfga_1 h1{font-size:1.5em}._acp-markdown_dbfga_1 h2{font-size:1.3em}._acp-markdown_dbfga_1 h3{font-size:1.15em}._acp-markdown_dbfga_1 h4{font-size:1em}._acp-markdown_dbfga_1 blockquote{margin:12px 0;padding:8px 14px;border-left:3px solid var(--acp-color-accent);background:var(--acp-color-bg-tertiary);border-radius:0 var(--acp-radius-sm) var(--acp-radius-sm) 0;color:var(--acp-color-text-secondary)}._acp-markdown_dbfga_1 a{color:var(--acp-color-accent);text-decoration:none}._acp-markdown_dbfga_1 a:hover{text-decoration:underline}._acp-markdown_dbfga_1 table{width:100%;border-collapse:collapse;font-size:13px}._acp-markdown_dbfga_1 th,._acp-markdown_dbfga_1 td{padding:8px 12px;border-right:1px solid var(--acp-color-border);border-bottom:1px solid var(--acp-color-border);text-align:left}._acp-markdown_dbfga_1 th:last-child,._acp-markdown_dbfga_1 td:last-child{border-right:none}._acp-markdown_dbfga_1 th{background:var(--acp-color-bg-tertiary);font-weight:600}._acp-markdown_dbfga_1 tr:last-child td{border-bottom:none}._acp-markdown_dbfga_1 hr{margin:20px 0;border:none;border-top:1px solid var(--acp-color-border-subtle)}._acp-markdown_dbfga_1 img{max-width:100%;border-radius:var(--acp-radius-sm)}._acp-markdown-table_dbfga_105,._acp-markdown-code-block_dbfga_112{margin:12px 0;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-sm);overflow:hidden}._acp-markdown-code-block_dbfga_112 pre{margin:0;padding:14px;overflow-x:auto;background:var(--acp-color-bg-primary);font-family:var(--acp-font-mono);font-size:13px;line-height:1.6}._acp-markdown-code-block_dbfga_112 pre code{padding:0;background:transparent;font-size:inherit;letter-spacing:0}._acp-markdown-code-header_dbfga_134{display:flex;align-items:center;justify-content:space-between;padding:6px 14px;font-size:12px;font-family:var(--acp-font-mono);color:var(--acp-color-text-muted);background:var(--acp-color-bg-tertiary);border-bottom:1px solid var(--acp-color-border-subtle);text-transform:uppercase;letter-spacing:.03em}._acp-diff-view_1cavl_1{height:100%;display:flex;flex-direction:column;overflow:hidden;background:var(--acp-color-bg-primary)}._acp-diff-view__header_1cavl_8{padding:10px 16px;border-bottom:1px solid var(--acp-color-border-subtle);font-size:14px;font-weight:600;letter-spacing:-.01em}._acp-diff-view__empty-state_1cavl_15{flex:1;display:flex;align-items:center;justify-content:center;color:var(--acp-color-text-muted);font-size:13px}._acp-diff-view__content_1cavl_23{flex:1;overflow-y:auto;padding:14px;font-family:var(--acp-font-mono);font-size:13px;line-height:1.6}._acp-diff-view__file_1cavl_31{margin-bottom:16px;border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-md);overflow:hidden}._acp-diff-view__filename_1cavl_37{padding:8px 14px;background:var(--acp-color-bg-secondary);font-weight:600;font-size:12px;color:var(--acp-color-text-secondary);border-bottom:1px solid var(--acp-color-border-subtle)}._acp-diff-view__old_1cavl_45{color:var(--acp-color-error);background:var(--acp-color-error-muted);padding:2px 14px;white-space:pre-wrap}._acp-diff-view__new_1cavl_51{color:var(--acp-color-success);background:var(--acp-color-success-muted);padding:2px 14px;white-space:pre-wrap}._acp-terminal-view_xbaol_1{height:100%;display:flex;flex-direction:column;background:var(--acp-color-bg-code);color:var(--acp-color-text-primary);font-family:var(--acp-font-mono)}._acp-terminal-view__header_xbaol_9{padding:10px 16px;border-bottom:1px solid var(--acp-color-border-subtle);font-size:12px;font-weight:600;color:var(--acp-color-text-muted);text-transform:uppercase;letter-spacing:.04em;display:flex;align-items:center;gap:8px}._acp-terminal-view__count_xbaol_21{background:var(--acp-color-bg-hover);color:var(--acp-color-text-muted);font-size:10px;padding:1px 6px;border-radius:var(--acp-radius-sm)}._acp-terminal-view__empty_xbaol_28{flex:1;display:flex;align-items:center;justify-content:center;font-size:13px;color:var(--acp-color-text-muted);padding:24px}._acp-terminal-view__list_xbaol_37{flex:1;overflow-y:auto}._acp-terminal-view__item_xbaol_41{border-bottom:1px solid var(--acp-color-border-subtle)}._acp-terminal-view__item--running_xbaol_44 ._acp-terminal-view__item--running__item-header_xbaol_44{background:var(--acp-color-bg-hover)}._acp-terminal-view__item-header_xbaol_47{width:100%;display:flex;align-items:center;gap:8px;padding:8px 16px;background:none;border:none;cursor:pointer;font-family:inherit;font-size:12px;color:var(--acp-color-text-primary);text-align:left}._acp-terminal-view__item-header_xbaol_47:hover{background:var(--acp-color-bg-hover)}._acp-terminal-view__item-status_xbaol_64{flex-shrink:0;width:20px;display:flex;align-items:center;justify-content:center}._acp-terminal-view__status-dot_xbaol_71{width:6px;height:6px;border-radius:50%;background:var(--acp-color-accent);animation:_terminalPulse_xbaol_1 1.5s ease-in-out infinite}._acp-terminal-view__exit-badge_xbaol_78{font-size:10px;padding:1px 4px;border-radius:3px;background:var(--acp-color-bg-hover);color:var(--acp-color-text-muted);font-weight:600}._acp-terminal-view__exit-badge--success_xbaol_86{color:var(--acp-color-success);background:var(--acp-color-success-bg)}._acp-terminal-view__exit-badge--error_xbaol_90{color:var(--acp-color-error);background:var(--acp-color-error-bg)}._acp-terminal-view__item-command_xbaol_94{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._acp-terminal-view__item-label_xbaol_100{font-weight:600;color:var(--acp-color-text-muted);margin-right:6px}._acp-terminal-view__chevron_xbaol_105{flex-shrink:0;font-size:8px;color:var(--acp-color-text-muted)}._acp-terminal-view__item-output_xbaol_110{margin:0;padding:12px 16px 8px 44px;font-size:13px;line-height:1.65;white-space:pre-wrap;background:var(--acp-color-bg-primary);color:var(--acp-color-text-secondary)}._acp-terminal-view__truncated-note_xbaol_119{display:block;margin-top:8px;font-size:11px;color:var(--acp-color-text-muted);font-style:italic}@keyframes _terminalPulse_xbaol_1{0%,to{opacity:1}50%{opacity:.4}}._acp-tool-call_u9a95_1{border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-md);margin:8px 0;overflow:hidden;font-size:13px;transition:box-shadow var(--acp-duration-fast) var(--acp-ease-out),border-color var(--acp-duration-fast) var(--acp-ease-out);color:var(--acp-color-text-secondary)}._acp-tool-call_u9a95_1:hover{border-color:var(--acp-color-border);box-shadow:var(--acp-shadow-xs)}._acp-tool-call__header_u9a95_14{display:flex;align-items:center;gap:10px;padding:10px 14px;background:none;cursor:pointer;border:none;width:100%;text-align:left;color:var(--acp-color-text-secondary);font-size:13px;font-family:var(--acp-font-sans)}._acp-tool-call__status_u9a95_28{width:8px;height:8px;border-radius:50%;flex-shrink:0}._acp-tool-call__status--pending_u9a95_34{background:var(--acp-color-text-muted);box-shadow:none}._acp-tool-call__status--in-progress_u9a95_38{background:var(--acp-color-warning);animation:_acp-pulse_u9a95_1 1.5s infinite}._acp-tool-call__status--completed_u9a95_42{background:var(--acp-color-success)}._acp-tool-call__status--failed_u9a95_45{background:var(--acp-color-error)}._acp-tool-call__kind_u9a95_48{flex-shrink:0;font-size:10px;opacity:.7}._acp-tool-call__name_u9a95_53{flex:1;font-weight:600;font-size:12px;letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._acp-tool-call__chevron_u9a95_62{color:var(--acp-color-text-muted);font-size:10px;transition:transform var(--acp-duration-fast) var(--acp-ease-out)}._acp-tool-call__chevron--open_u9a95_67{transform:rotate(90deg)}._acp-tool-call__body_u9a95_70{padding:12px 14px;border-top:1px solid var(--acp-color-border-subtle);max-height:300px;overflow-y:auto}._acp-tool-call__content-text_u9a95_76{white-space:pre-wrap}._acp-tool-call__locations_u9a95_79{display:flex;flex-wrap:wrap;gap:4px;padding:8px 14px;border-top:1px solid var(--acp-color-border-subtle);background:var(--acp-color-bg-primary)}._acp-tool-call__location_u9a95_79{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-tertiary);border:1px solid var(--acp-color-border-subtle);cursor:pointer;font-size:11px;font-family:var(--acp-font-mono);color:var(--acp-color-text-secondary);transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-tool-call__location_u9a95_79:hover{background:var(--acp-color-bg-hover);color:var(--acp-color-text-primary);border-color:var(--acp-color-accent)}._acp-tool-call__location_u9a95_79:focus-visible{outline:2px solid var(--acp-color-accent);outline-offset:1px}._acp-tool-call__location-icon_u9a95_110{font-size:11px;flex-shrink:0}._acp-tool-call__location-path_u9a95_114{white-space:nowrap}._acp-tool-call__location-line_u9a95_117{color:var(--acp-color-accent);font-weight:600}@keyframes _acp-pulse_u9a95_1{0%,to{opacity:1}50%{opacity:.35}}._acp-thought-view_1hsnd_1{margin:4px 0;overflow:hidden;font-size:11px}._acp-thought-view__header_1hsnd_6{display:flex;align-items:center;gap:6px;padding:6px 10px;background:none;cursor:pointer;border:none;width:100%;text-align:left;color:var(--acp-color-text-secondary);font-size:11px;font-weight:600;letter-spacing:.02em;text-transform:uppercase}._acp-thought-view__label_1hsnd_22{font-weight:600}._acp-thought-view__chevron_1hsnd_25{color:var(--acp-color-text-muted);font-size:9px;transition:transform var(--acp-duration-fast) var(--acp-ease-spring);flex-shrink:0}._acp-thought-view__chevron--open_1hsnd_31{transform:rotate(90deg)}._acp-thought-view__spinner_1hsnd_34{width:12px;height:12px;border:1.5px solid var(--acp-color-border-subtle);border-top-color:var(--acp-color-accent);border-radius:50%;animation:_acp-thought-spin_1hsnd_1 .7s linear infinite}._acp-thought-view__body_1hsnd_42{padding:8px 10px;max-height:300px;overflow-y:auto;color:var(--acp-color-text-secondary);line-height:1.5;font-size:12px}._acp-thought-view__body_1hsnd_42 p{margin-bottom:4px}._acp-thought-view__body_1hsnd_42 p:last-child{margin-bottom:0}._acp-thought-view__body_1hsnd_42 pre{font-size:11px;line-height:1.45;margin:4px 0;font-family:var(--acp-font-mono)}._acp-thought-view__body_1hsnd_42 code{font-family:var(--acp-font-mono);font-size:.9em}._acp-thought-view__body_1hsnd_42 :not(pre)>code{background:var(--acp-color-bg-tertiary);padding:1px 4px;border-radius:var(--acp-radius-xs);border:1px solid var(--acp-color-border-subtle)}._acp-thought-view__empty_1hsnd_72{color:var(--acp-color-text-muted);font-style:italic}@keyframes _acp-thought-spin_1hsnd_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}._acp-plan-view_pjklh_1{border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-md);margin:8px 0;overflow:hidden;font-size:13px;transition:box-shadow var(--acp-duration-fast) var(--acp-ease-out),border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-plan-view_pjklh_1:hover{border-color:var(--acp-color-border);box-shadow:var(--acp-shadow-xs)}._acp-plan-view--streaming_pjklh_13{border-left-color:var(--acp-color-success)}._acp-plan-view__header_pjklh_16{display:flex;align-items:center;gap:8px;padding:10px 14px;background:none;cursor:pointer;border:none;width:100%;text-align:left;color:var(--acp-color-text-secondary);font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase}._acp-plan-view__chevron_pjklh_32{color:var(--acp-color-text-muted);font-size:10px;transition:transform var(--acp-duration-fast) var(--acp-ease-spring);flex-shrink:0}._acp-plan-view__chevron--open_pjklh_38{transform:rotate(90deg)}._acp-plan-view__label_pjklh_41{font-weight:600}._acp-plan-view__progress_pjklh_44{color:var(--acp-color-text-muted);font-size:11px;margin-left:auto;font-family:var(--acp-font-mono)}._acp-plan-view__spinner_pjklh_50{width:14px;height:14px;border:2px solid var(--acp-color-border-subtle);border-top-color:var(--acp-color-accent);border-radius:50%;animation:_acp-plan-spin_pjklh_1 .7s linear infinite}._acp-plan-view__body_pjklh_58{border-top:1px solid var(--acp-color-border-subtle);padding:8px 0;max-height:360px;overflow-y:auto}._acp-plan-list_pjklh_65{list-style:none;padding:0 14px;margin:0}._acp-plan-item_pjklh_71{display:flex;align-items:flex-start;gap:10px;padding:7px 6px;color:var(--acp-color-text-secondary);line-height:1.5;position:relative}._acp-plan-item_pjklh_71:after{content:"";position:absolute;left:7.5px;top:26px;bottom:0;width:1px;background:var(--acp-color-border-subtle)}._acp-plan-item_pjklh_71:last-child:after{display:none}._acp-plan-item--high_pjklh_92{color:var(--acp-color-text-primary);font-weight:500}._acp-plan-item--medium_pjklh_96{color:var(--acp-color-text-primary)}._acp-plan-item--low_pjklh_99{color:var(--acp-color-text-secondary)}._acp-plan-item-status_pjklh_103{flex-shrink:0;width:16px;text-align:center;font-size:12px;line-height:1.7}._acp-plan-item-status--pending_pjklh_110{color:var(--acp-color-text-muted)}._acp-plan-item-status--in-progress_pjklh_113{color:var(--acp-color-accent);animation:_acp-plan-pulse_pjklh_1 1.5s ease-in-out infinite}._acp-plan-item-status--completed_pjklh_117{color:var(--acp-color-success)}._acp-plan-item-content_pjklh_121{flex:1}._acp-plan-item-content--done_pjklh_124{text-decoration:line-through;opacity:.5}@keyframes _acp-plan-spin_pjklh_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes _acp-plan-pulse_pjklh_1{0%,to{opacity:1}50%{opacity:.35}}._acp-chat-view_1fe8h_1{display:flex;flex-direction:column;height:100%;overflow:hidden;background:var(--acp-color-bg-primary)}._acp-chat-header_1fe8h_9{display:flex;align-items:center;justify-content:space-between;padding:10px 20px;border-bottom:1px solid var(--acp-color-border-subtle);background:var(--acp-color-bg-glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);min-height:48px}._acp-chat-header__title_1fe8h_20{font-size:13px;font-weight:600;letter-spacing:-.01em;color:var(--acp-color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._acp-message-list_1fe8h_30{flex:1;overflow-y:auto;padding:24px 20px 32px;display:flex;flex-direction:column;gap:36px}._acp-round_1fe8h_39{display:flex;flex-direction:column;gap:24px}._acp-message-bubble_1fe8h_45{display:flex;width:100%;animation:_acp-message-in_1fe8h_1 .25s var(--acp-ease-out)}._acp-message-bubble--agent_1fe8h_50 ._acp-message-bubble__content_1fe8h_50{padding:0}._acp-message-bubble__content_1fe8h_50{flex:1;min-width:0;font-size:14px;word-wrap:break-word}._acp-message-bubble__resource_1fe8h_59{display:inline-flex;align-items:center;gap:6px;background:var(--acp-color-bg-tertiary);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-sm);padding:6px 12px;margin:8px 0;font-size:12px;transition:background .15s var(--acp-ease-out)}._acp-message-bubble__resource_1fe8h_59:hover{background:var(--acp-color-bg-hover)}._acp-message-bubble__resource-name_1fe8h_74{font-family:var(--acp-font-mono);font-size:12px;color:var(--acp-color-text-secondary)}._acp-message-bubble__resource-text_1fe8h_79{margin-top:4px;font-size:12px}._acp-message-bubble__stop-reason_1fe8h_83{font-size:11px;color:var(--acp-color-text-muted);margin-top:8px}._acp-message-bubble__image_1fe8h_88{max-width:100%;max-height:400px;border-radius:var(--acp-radius-sm);margin:8px 0;display:block}@keyframes _acp-message-in_1fe8h_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}._acp-streaming-indicator_1fe8h_106{display:flex;align-items:center;gap:8px;padding:4px 0;color:var(--acp-color-text-muted);font-size:12px;font-weight:500;letter-spacing:.02em;text-transform:uppercase}._acp-streaming-indicator__dots_1fe8h_117{display:flex;gap:3px}._acp-streaming-indicator__dot_1fe8h_117{width:4px;height:4px;border-radius:50%;background:var(--acp-color-accent);animation:_acp-dot-bounce_1fe8h_1 1.4s infinite var(--acp-ease-in-out) both}._acp-streaming-indicator__dot_1fe8h_117:nth-child(1){animation-delay:-.32s}._acp-streaming-indicator__dot_1fe8h_117:nth-child(2){animation-delay:-.16s}@keyframes _acp-dot-bounce_1fe8h_1{0%,80%,to{transform:scale(.3);opacity:.3}40%{transform:scale(1);opacity:1}}._acp-plan-wrapper_1fe8h_145{margin:0 20px}._acp-chat-footer_1fe8h_149{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 20px 20px;background:var(--acp-color-bg-glass)}._acp-chat-empty_1fe8h_158{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;color:var(--acp-color-text-muted);font-size:14px;font-weight:500;letter-spacing:-.01em;opacity:.7}._acp-user-message_4a1s0_1{display:flex;flex-direction:column;align-items:flex-end;width:100%;position:relative}._acp-user-message_4a1s0_1:hover ._acp-user-message__actions_4a1s0_8{opacity:1}._acp-user-message__actions_4a1s0_8{display:flex;justify-content:flex-end;gap:4px;position:absolute;top:100%;left:0;right:0;padding-top:4px;opacity:0;transition:opacity var(--acp-duration-fast) var(--acp-ease-out)}._acp-user-message__action-btn_4a1s0_25{display:flex;align-items:center;justify-content:center;width:20px;height:20px;background:var(--acp-color-bg-glass);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-xs);color:var(--acp-color-text-secondary);cursor:pointer;font-size:13px;padding:0}._acp-user-message__action-btn_4a1s0_25:hover{color:var(--acp-color-text-primary);background:var(--acp-color-bg-hover)}._acp-user-message__action-btn--copied_4a1s0_45{color:var(--acp-color-success)}._acp-user-message__bubble_4a1s0_49{background:var(--acp-color-user-bubble);color:var(--acp-color-user-text);border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-md);padding:12px 18px;max-width:85%;font-size:14px;word-wrap:break-word}._acp-user-message__attachments_4a1s0_60{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid var(--acp-color-border-subtle)}._acp-user-message__attachment_4a1s0_60{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--acp-color-text-secondary);background:var(--acp-color-bg-tertiary);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-sm);padding:4px 10px}._acp-user-message__attachment--image_4a1s0_80{padding:4px;max-width:200px}._acp-user-message__attachment--image_4a1s0_80 img{max-width:100%;max-height:40px;border-radius:var(--acp-radius-xs);display:block}._acp-user-message__stop-reason_4a1s0_91{font-size:11px;color:var(--acp-color-text-muted);margin-top:8px;text-align:right;width:100%}._acp-command-palette_1abam_1{position:relative;display:inline-flex}._acp-command-palette__trigger_1abam_6{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-input);color:var(--acp-color-text-secondary);font-size:14px;font-weight:600;cursor:pointer;transition:border-color var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),box-shadow var(--acp-duration-fast) var(--acp-ease-out)}._acp-command-palette__trigger_1abam_6:hover{border-color:var(--acp-color-accent);color:var(--acp-color-accent);box-shadow:0 0 0 3px var(--acp-color-accent-muted)}._acp-command-palette__trigger_1abam_6:disabled{opacity:.35;cursor:not-allowed;color:var(--acp-color-text-muted)}._acp-command-palette__popover_1abam_32{position:absolute;bottom:calc(100% + 6px);left:0;width:340px;max-height:380px;display:flex;flex-direction:column;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-md);background:var(--acp-color-bg-primary);box-shadow:var(--acp-shadow-lg);z-index:100;overflow:hidden}._acp-command-palette__popover--inline_1abam_47{position:static;width:100%;max-height:240px;box-shadow:var(--acp-shadow-md)}._acp-command-palette__search_1abam_54{padding:10px 12px;border-bottom:1px solid var(--acp-color-border-subtle)}._acp-command-palette__search_1abam_54 input{width:100%;padding:7px 10px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-input);color:var(--acp-color-text-primary);font-size:13px;font-family:var(--acp-font-sans);outline:none;transition:border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-command-palette__search_1abam_54 input::placeholder{color:var(--acp-color-text-muted)}._acp-command-palette__search_1abam_54 input:focus{border-color:var(--acp-color-accent);box-shadow:0 0 0 3px var(--acp-color-accent-muted)}._acp-command-palette__list_1abam_78{flex:1;overflow-y:auto;padding:4px}._acp-command-palette__empty_1abam_84{padding:20px;text-align:center;color:var(--acp-color-text-muted);font-size:13px}._acp-command-palette__item_1abam_91{display:flex;align-items:flex-start;gap:10px;width:100%;padding:9px 12px;border:none;border-radius:var(--acp-radius-sm);background:transparent;color:var(--acp-color-text-primary);font-size:13px;font-family:var(--acp-font-sans);text-align:left;cursor:pointer;transition:background var(--acp-duration-fast) var(--acp-ease-out)}._acp-command-palette__item_1abam_91:hover,._acp-command-palette__item--active_1abam_107{background:var(--acp-color-bg-hover)}._acp-command-palette__item-icon_1abam_111{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:24px;height:24px;border-radius:var(--acp-radius-xs);background:var(--acp-color-accent-muted);color:var(--acp-color-accent);font-size:12px;font-weight:700;font-family:var(--acp-font-mono);margin-top:1px}._acp-command-palette__item-body_1abam_127{flex:1;min-width:0}._acp-command-palette__item-name_1abam_132{font-weight:600;font-size:13px;letter-spacing:-.01em;color:var(--acp-color-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._acp-command-palette__item-desc_1abam_142{margin-top:2px;font-size:12px;color:var(--acp-color-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._acp-command-palette__item-hint_1abam_151{margin-top:1px;font-size:11px;color:var(--acp-color-text-muted);font-family:var(--acp-font-mono)}._acp-chat-composer_5qtly_1{border-top:1px solid var(--acp-color-border-subtle);padding:14px 20px;background:var(--acp-color-bg-glass);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative}._acp-chat-composer__form_5qtly_9{display:flex;flex-direction:column;gap:8px;position:relative}._acp-chat-composer__body_5qtly_15{display:flex;flex-direction:column;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-md);background:var(--acp-color-bg-input);overflow:hidden;transition:border-color var(--acp-duration-fast) var(--acp-ease-out),box-shadow var(--acp-duration-fast) var(--acp-ease-out)}._acp-chat-composer__body_5qtly_15:focus-within{border-color:var(--acp-color-accent);box-shadow:0 0 0 3px var(--acp-color-accent-muted)}._acp-chat-composer__input_5qtly_28{flex:1;resize:none;border:none;padding:10px 14px;background:transparent;color:var(--acp-color-text-primary);font-family:var(--acp-font-sans);font-size:14px;line-height:1.5;min-height:42px;max-height:200px;outline:none}._acp-chat-composer__input_5qtly_28::placeholder{color:var(--acp-color-text-muted)}._acp-chat-composer__input_5qtly_28:disabled{opacity:.5;cursor:not-allowed}._acp-chat-composer__fileList_5qtly_49{display:flex;flex-wrap:wrap;gap:6px;padding:10px 14px 0}._acp-chat-composer__fileChip_5qtly_55{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-sm);padding:2px 4px 2px 6px;background:var(--acp-color-bg-glass);font-size:12px;color:var(--acp-color-text-secondary);max-width:200px}._acp-chat-composer__fileThumb_5qtly_67{width:24px;height:24px;border-radius:2px;object-fit:cover;flex-shrink:0}._acp-chat-composer__fileName_5qtly_74{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}._acp-chat-composer__fileSize_5qtly_81{color:var(--acp-color-text-muted);flex-shrink:0}._acp-chat-composer__fileRemove_5qtly_85{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border:none;border-radius:3px;background:transparent;color:var(--acp-color-text-muted);cursor:pointer;flex-shrink:0;font-size:12px;line-height:1;padding:0;transition:color var(--acp-duration-fast) var(--acp-ease-out),background var(--acp-duration-fast) var(--acp-ease-out)}._acp-chat-composer__fileRemove_5qtly_85:hover{color:var(--acp-color-error);background:var(--acp-color-error-muted)}._acp-chat-composer__actions_5qtly_106{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px}._acp-chat-composer__attachBtn_5qtly_113{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-md);background:transparent;color:var(--acp-color-text-secondary);cursor:pointer;flex-shrink:0;font-size:16px;padding:0;transition:border-color var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),background var(--acp-duration-fast) var(--acp-ease-out)}._acp-chat-composer__attachBtn_5qtly_113:hover{border-color:var(--acp-color-accent);color:var(--acp-color-accent);background:var(--acp-color-accent-muted)}._acp-chat-composer__attachBtn_5qtly_113:disabled{opacity:.35;cursor:not-allowed}._acp-chat-composer__send_5qtly_138{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--acp-radius-md);background:var(--acp-color-accent);color:var(--acp-color-text-inverse);cursor:pointer;flex-shrink:0;font-size:16px;transition:background var(--acp-duration-fast) var(--acp-ease-out),transform var(--acp-duration-fast) var(--acp-ease-out)}._acp-chat-composer__send_5qtly_138:hover{background:var(--acp-color-accent-hover);transform:scale(1.05)}._acp-chat-composer__send_5qtly_138:active{transform:scale(.97)}._acp-chat-composer__send_5qtly_138:disabled{opacity:.35;cursor:not-allowed;transform:none}._acp-chat-composer__cancel_5qtly_165{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-md);background:transparent;color:var(--acp-color-text-secondary);cursor:pointer;flex-shrink:0;font-size:12px;transition:border-color var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out)}._acp-chat-composer__cancel_5qtly_165:hover{border-color:var(--acp-color-error);color:var(--acp-color-error);background:var(--acp-color-error-muted)}._acp-composer-palette_5qtly_186{position:absolute;bottom:calc(100% - 14px);left:20px;right:20px;z-index:100}._acp-usage-bar_1m64v_1{display:flex;align-items:center;gap:8px;padding:4px 10px;font-size:11px;font-family:var(--acp-font-mono);color:var(--acp-color-text-muted);white-space:nowrap}._acp-usage-bar__wrap_1m64v_11{position:relative;width:80px;height:3px;background:var(--acp-color-border-subtle);border-radius:2px;overflow:hidden;flex-shrink:0}._acp-usage-bar__fill_1m64v_20{height:100%;border-radius:2px;transition:width .4s var(--acp-ease-out),background .4s var(--acp-ease-out);background:var(--acp-color-text-muted);position:relative}._acp-usage-bar__fill_1m64v_20:after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.15));border-radius:2px}._acp-usage-bar__fillLow_1m64v_34{background:var(--acp-color-success)}._acp-usage-bar__fillMedium_1m64v_37{background:var(--acp-color-warning)}._acp-usage-bar__fillHigh_1m64v_40{background:var(--acp-color-error)}._acp-usage-bar__text_1m64v_43{flex-shrink:0;font-weight:500}._acp-usage-bar__cost_1m64v_47{flex-shrink:0;color:var(--acp-color-text-secondary)}._acp-session-config-panel_1h52p_1{display:flex;align-items:center;gap:6px}._acp-session-config-item_1h52p_7{display:flex;align-items:center;gap:6px;position:relative}._acp-session-config-label_1h52p_14{font-size:12px;font-weight:500;color:var(--acp-color-text-secondary);white-space:nowrap;letter-spacing:-.01em}._acp-session-config-select_1h52p_22{padding:5px 8px;border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-sm);background:var(--acp-color-bg-input);color:var(--acp-color-text-primary);font-size:12px;font-weight:500;cursor:pointer;outline:none;min-width:100px;transition:border-color var(--acp-duration-fast) var(--acp-ease-out)}._acp-session-config-select_1h52p_22:focus{border-color:var(--acp-color-accent);box-shadow:0 0 0 3px var(--acp-color-accent-muted)}._acp-session-config-select_1h52p_22:hover{border-color:var(--acp-color-text-muted)}._acp-session-config-toggle_1h52p_43{display:flex;align-items:center}._acp-session-config-switch_1h52p_48{position:relative;width:34px;height:20px;border:none;border-radius:10px;background:var(--acp-color-border);cursor:pointer;padding:0;transition:background var(--acp-duration-fast) var(--acp-ease-out);outline:none}._acp-session-config-switch_1h52p_48:focus-visible{box-shadow:0 0 0 3px var(--acp-color-accent-muted)}._acp-session-config-switch--on_1h52p_63{background:var(--acp-color-accent)}._acp-session-config-switch-knob_1h52p_67{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--acp-color-knob);box-shadow:var(--acp-color-knob-shadow);transition:transform var(--acp-duration-fast) var(--acp-ease-spring)}._acp-session-config-switch--on_1h52p_63 ._acp-session-config-switch-knob_1h52p_67{transform:translate(14px)}._acp-session-config-description_1h52p_82{font-size:11px;color:var(--acp-color-text-muted);position:absolute;top:100%;left:0;margin-top:2px;white-space:nowrap}._acp-permission-dialog-overlay_aygh8_1{position:fixed;inset:0;background:var(--acp-color-bg-overlay);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:1000;animation:_acp-overlay-in_aygh8_1 .15s var(--acp-ease-out)}._acp-permission-dialog_aygh8_1{background:var(--acp-color-bg-primary);border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-xl);padding:28px;max-width:480px;width:90%;box-shadow:var(--acp-shadow-lg);animation:_acp-dialog-in_aygh8_1 .25s var(--acp-ease-spring)}._acp-permission-dialog__title_aygh8_24{font-size:17px;font-weight:600;margin-bottom:8px;letter-spacing:-.02em}._acp-permission-dialog__desc_aygh8_30{font-size:13px;color:var(--acp-color-text-secondary);margin-bottom:18px;line-height:1.6}._acp-permission-dialog__tool_aygh8_36{padding:14px;background:var(--acp-color-bg-secondary);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-md);margin-bottom:18px}._acp-permission-dialog__tool-name_aygh8_43{font-family:var(--acp-font-mono);font-size:13px;font-weight:600;color:var(--acp-color-accent)}._acp-permission-dialog__tool-args_aygh8_49{font-family:var(--acp-font-mono);font-size:12px;color:var(--acp-color-text-secondary);margin-top:6px;white-space:pre-wrap;max-height:150px;overflow-y:auto;line-height:1.6}._acp-permission-dialog__actions_aygh8_59{display:flex;gap:10px;justify-content:flex-end}._acp-permission-dialog__btn_aygh8_64{padding:9px 20px;border-radius:var(--acp-radius-sm);font-size:13px;font-weight:600;cursor:pointer;border:none;letter-spacing:-.01em;transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),transform var(--acp-duration-fast) var(--acp-ease-out)}._acp-permission-dialog__btn_aygh8_64:active{transform:scale(.97)}._acp-permission-dialog__btn--deny_aygh8_77{background:transparent;border:1px solid var(--acp-color-border);color:var(--acp-color-text-primary)}._acp-permission-dialog__btn--deny_aygh8_77:hover{background:var(--acp-color-error-muted);color:var(--acp-color-error);border-color:var(--acp-color-error)}._acp-permission-dialog__btn--allow_aygh8_87{background:var(--acp-color-accent);color:var(--acp-color-text-inverse)}._acp-permission-dialog__btn--allow_aygh8_87:hover{background:var(--acp-color-accent-hover)}@keyframes _acp-overlay-in_aygh8_1{0%{opacity:0}to{opacity:1}}@keyframes _acp-dialog-in_aygh8_1{0%{opacity:0;transform:scale(.95) translateY(8px)}to{opacity:1;transform:scale(1) translateY(0)}}._acp-login-dialog-overlay_ienj6_1{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;background:var(--acp-color-bg-overlay);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);animation:_acp-overlay-in_ienj6_1 .15s var(--acp-ease-out)}._acp-login-dialog_ienj6_1{background:var(--acp-color-bg-primary);border:1px solid var(--acp-color-border);border-radius:var(--acp-radius-xl);box-shadow:var(--acp-shadow-lg);padding:28px;max-width:440px;width:90%;animation:_acp-dialog-in_ienj6_1 .25s var(--acp-ease-spring)}._acp-login-dialog-title_ienj6_25{font-size:17px;font-weight:600;margin-bottom:8px;letter-spacing:-.02em}._acp-login-dialog-desc_ienj6_32{font-size:13px;color:var(--acp-color-text-secondary);margin-bottom:18px;line-height:1.6}._acp-login-dialog-error_ienj6_39{font-size:12px;color:var(--acp-color-error);margin-bottom:12px;padding:8px 12px;background:var(--acp-color-error-muted);border-radius:var(--acp-radius-sm)}._acp-login-dialog-methods_ienj6_48{display:flex;flex-direction:column;gap:8px;margin-bottom:18px}._acp-login-dialog-method_ienj6_48{background:var(--acp-color-bg-secondary);border:1px solid var(--acp-color-border-subtle);border-radius:var(--acp-radius-md);padding:14px 16px;cursor:pointer;display:flex;flex-direction:column;gap:4px;transition:background var(--acp-duration-fast) var(--acp-ease-out),border-color var(--acp-duration-fast) var(--acp-ease-out),transform var(--acp-duration-fast) var(--acp-ease-out)}._acp-login-dialog-method_ienj6_48:hover:not(:disabled){background:var(--acp-color-bg-hover);border-color:var(--acp-color-accent)}._acp-login-dialog-method_ienj6_48:active:not(:disabled){transform:scale(.98)}._acp-login-dialog-method_ienj6_48:disabled{cursor:not-allowed;opacity:.6}._acp-login-dialog-method-name_ienj6_78{font-size:14px;font-weight:600;color:var(--acp-color-text-primary)}._acp-login-dialog-method-desc_ienj6_84{font-size:12px;color:var(--acp-color-text-secondary);line-height:1.5}._acp-login-dialog-actions_ienj6_90{display:flex;justify-content:flex-end}._acp-login-dialog-cancel-btn_ienj6_95{padding:9px 20px;border-radius:var(--acp-radius-sm);font-size:13px;font-weight:600;cursor:pointer;background:transparent;border:1px solid var(--acp-color-border);color:var(--acp-color-text-primary);transition:background var(--acp-duration-fast) var(--acp-ease-out),color var(--acp-duration-fast) var(--acp-ease-out),transform var(--acp-duration-fast) var(--acp-ease-out)}._acp-login-dialog-cancel-btn_ienj6_95:hover:not(:disabled){background:var(--acp-color-bg-hover)}._acp-login-dialog-cancel-btn_ienj6_95:active:not(:disabled){transform:scale(.97)}._acp-login-dialog-cancel-btn_ienj6_95:disabled{cursor:not-allowed;opacity:.6}@keyframes _acp-overlay-in_ienj6_1{0%{opacity:0}to{opacity:1}}@keyframes _acp-dialog-in_ienj6_1{0%{opacity:0;transform:scale(.95) translateY(8px)}to{opacity:1;transform:scale(1) translateY(0)}}._acp-connection-status_1avmz_1{display:flex;align-items:center;gap:12px;padding:4px 12px;font-size:12px;font-weight:500;color:var(--acp-color-text-secondary)}._acp-connection-status__item_1avmz_10{display:flex;align-items:center;gap:5px}._acp-connection-status__dot_1avmz_15{width:7px;height:7px;border-radius:50%;flex-shrink:0}._acp-connection-status__dot--connected_1avmz_21{background:var(--acp-color-success);box-shadow:0 0 6px var(--acp-color-success)}._acp-connection-status__dot--connecting_1avmz_25{background:var(--acp-color-warning);box-shadow:0 0 6px var(--acp-color-warning);animation:_acp-pulse_1avmz_1 1.5s infinite}._acp-connection-status__dot--disconnected_1avmz_30{background:var(--acp-color-text-muted)}._acp-connection-status__dot--error_1avmz_33{background:var(--acp-color-error);box-shadow:0 0 6px var(--acp-color-error)}@keyframes _acp-pulse_1avmz_1{0%,to{opacity:1}50%{opacity:.35}}.nav-paint-diagnostic{flex:none;padding:8px 12px;background:var(--surface);color:var(--text);border-block:1px solid var(--line);font:13px/1.4 var(--font)}.nav-paint-diagnostic p{margin:4px 0;font-size:12px}.nav-paint-reference{appearance:none;-webkit-appearance:none;padding:0;border:0;background:transparent;min-height:44px;display:flex;align-items:center;gap:12px;color:var(--text-2);font:500 .8rem/1.2 var(--font)}.nav-paint-options{display:flex;flex-wrap:wrap;gap:4px}.nav-paint-options button{appearance:none;-webkit-appearance:none;font:inherit;color:var(--text);background:var(--surface);border:1px solid var(--line);border-radius:8px;min-height:44px;padding:4px 8px;cursor:pointer}.nav-paint-options button[aria-pressed=true]{border-color:var(--accent)}.nav-paint-options button:focus-visible{outline:2px solid var(--accent)}.fleet-app[data-nav-paint=plain] .fleet-nav button:not(.fleet-brand){appearance:none;-webkit-appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:4px;border:0;background:transparent;box-shadow:none;text-shadow:none;filter:none;backdrop-filter:none;-webkit-backdrop-filter:none;transform:none;transition:none;animation:none;opacity:1;will-change:auto}.fleet-app[data-nav-paint=plain] .fleet-nav .primary{background:var(--accent)}.fleet-app[data-nav-paint=isolated] .fleet-nav{isolation:isolate;contain:paint;transform:translateZ(0);backface-visibility:hidden}.fleet-app[data-nav-paint=no-glass],.fleet-app[data-nav-paint=no-glass] *,.fleet-app[data-nav-paint=no-glass] *:before,.fleet-app[data-nav-paint=no-glass] *:after{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
|