@mecha.im/cli 0.3.4
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/Dockerfile +103 -0
- package/README.md +173 -0
- package/agent/activity.ts +31 -0
- package/agent/costs.ts +93 -0
- package/agent/dashboard/dist/assets/addon-fit-YJmn1quW.js +12 -0
- package/agent/dashboard/dist/assets/addon-web-links-BWjmmSgS.js +12 -0
- package/agent/dashboard/dist/assets/index-B4OKDQ7e.css +32 -0
- package/agent/dashboard/dist/assets/index-fZ_N6Wsi.js +193 -0
- package/agent/dashboard/dist/assets/xterm-BqvuqXEL.js +27 -0
- package/agent/dashboard/dist/index.html +19 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_0.png +0 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_1.png +0 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_3.png +0 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_4.png +0 -0
- package/agent/dashboard/dist/pixel-engine/characters/char_5.png +0 -0
- package/agent/dashboard/dist/pixel-engine/default-layout.json +4320 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_0.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_1.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_3.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_4.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_5.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_6.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_7.png +0 -0
- package/agent/dashboard/dist/pixel-engine/floors/floor_8.png +0 -0
- package/agent/dashboard/dist/pixel-engine/fonts/FSPixelSansUnicode-Regular.ttf +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BIN/BIN.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BIN/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BLACKBOARD/BLACKBOARD.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BLACKBOARD/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BOOKSHELF/BOOKSHELF.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/BOOKSHELF/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CACTUS/CACTUS.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CACTUS/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CLOCK/CLOCK.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CLOCK/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/COFFEE/COFFEE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/COFFEE/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/COFFEE_TABLE/COFFEE_TABLE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/COFFEE_TABLE/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_BENCH/CUSHIONED_BENCH.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_BENCH/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_BACK.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/manifest.json +44 -0
- package/agent/dashboard/dist/pixel-engine/furniture/DESK/DESK_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/DESK/DESK_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/DESK/manifest.json +33 -0
- package/agent/dashboard/dist/pixel-engine/furniture/DOUBLE_BOOKSHELF/DOUBLE_BOOKSHELF.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/DOUBLE_BOOKSHELF/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_1/FILE_BOXES_1.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_1/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_2/FILE_BOXES_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_2/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/HANGING_PLANT/HANGING_PLANT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/HANGING_PLANT/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/LARGE_PAINTING/LARGE_PAINTING.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/LARGE_PAINTING/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/LARGE_PLANT/LARGE_PLANT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/LARGE_PLANT/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_BACK.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_OFF.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_1.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_3.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/PC_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PC/manifest.json +88 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PLANT/PLANT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PLANT/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PLANT_2/PLANT_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/PLANT_2/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/POT/POT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/POT/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING/SMALL_PAINTING.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING_2/SMALL_PAINTING_2.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING_2/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/manifest.json +33 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_BACK.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/SOFA/manifest.json +44 -0
- package/agent/dashboard/dist/pixel-engine/furniture/TABLE_FRONT/TABLE_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/TABLE_FRONT/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/VENDER_MACHINE/VENDER_MACHINE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/VENDER_MACHINE/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WATER_MACHINE/WATER_MACHINE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WATER_MACHINE/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WHITEBOARD/WHITEBOARD.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WHITEBOARD/manifest.json +16 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_BENCH/WOODEN_BENCH.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_BENCH/manifest.json +13 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_BACK.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_FRONT.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_SIDE.png +0 -0
- package/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/manifest.json +44 -0
- package/agent/dashboard/dist/pixel-engine/furniture/index.json +32 -0
- package/agent/dashboard/dist/pixel-engine/walls/wall_0.png +0 -0
- package/agent/dashboard/index.html +18 -0
- package/agent/dashboard/package.json +41 -0
- package/agent/dashboard/public/pixel-engine/CREDITS.md +17 -0
- package/agent/dashboard/public/pixel-engine/characters/char_0.png +0 -0
- package/agent/dashboard/public/pixel-engine/characters/char_1.png +0 -0
- package/agent/dashboard/public/pixel-engine/characters/char_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/characters/char_3.png +0 -0
- package/agent/dashboard/public/pixel-engine/characters/char_4.png +0 -0
- package/agent/dashboard/public/pixel-engine/characters/char_5.png +0 -0
- package/agent/dashboard/public/pixel-engine/default-layout.json +4320 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_0.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_1.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_3.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_4.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_5.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_6.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_7.png +0 -0
- package/agent/dashboard/public/pixel-engine/floors/floor_8.png +0 -0
- package/agent/dashboard/public/pixel-engine/fonts/FSPixelSansUnicode-Regular.ttf +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/BIN/BIN.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/BIN/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/BLACKBOARD/BLACKBOARD.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/BLACKBOARD/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/BOOKSHELF/BOOKSHELF.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/BOOKSHELF/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/CACTUS/CACTUS.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CACTUS/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/CLOCK/CLOCK.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CLOCK/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/COFFEE/COFFEE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/COFFEE/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/COFFEE_TABLE/COFFEE_TABLE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/COFFEE_TABLE/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_BENCH/CUSHIONED_BENCH.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_BENCH/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_BACK.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/CUSHIONED_CHAIR/manifest.json +44 -0
- package/agent/dashboard/public/pixel-engine/furniture/DESK/DESK_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/DESK/DESK_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/DESK/manifest.json +33 -0
- package/agent/dashboard/public/pixel-engine/furniture/DOUBLE_BOOKSHELF/DOUBLE_BOOKSHELF.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/DOUBLE_BOOKSHELF/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/FILE_BOXES_1/FILE_BOXES_1.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/FILE_BOXES_1/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/FILE_BOXES_2/FILE_BOXES_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/FILE_BOXES_2/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/HANGING_PLANT/HANGING_PLANT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/HANGING_PLANT/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/LARGE_PAINTING/LARGE_PAINTING.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/LARGE_PAINTING/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/LARGE_PLANT/LARGE_PLANT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/LARGE_PLANT/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_BACK.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_FRONT_OFF.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_FRONT_ON_1.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_FRONT_ON_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_FRONT_ON_3.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/PC_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PC/manifest.json +88 -0
- package/agent/dashboard/public/pixel-engine/furniture/PLANT/PLANT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PLANT/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/PLANT_2/PLANT_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/PLANT_2/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/POT/POT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/POT/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_PAINTING/SMALL_PAINTING.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_PAINTING/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_PAINTING_2/SMALL_PAINTING_2.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_PAINTING_2/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SMALL_TABLE/manifest.json +33 -0
- package/agent/dashboard/public/pixel-engine/furniture/SOFA/SOFA_BACK.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SOFA/SOFA_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SOFA/SOFA_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/SOFA/manifest.json +44 -0
- package/agent/dashboard/public/pixel-engine/furniture/TABLE_FRONT/TABLE_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/TABLE_FRONT/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/VENDER_MACHINE/VENDER_MACHINE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/VENDER_MACHINE/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/WATER_MACHINE/WATER_MACHINE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WATER_MACHINE/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/WHITEBOARD/WHITEBOARD.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WHITEBOARD/manifest.json +16 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_BENCH/WOODEN_BENCH.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_BENCH/manifest.json +13 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_BACK.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_FRONT.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_SIDE.png +0 -0
- package/agent/dashboard/public/pixel-engine/furniture/WOODEN_CHAIR/manifest.json +44 -0
- package/agent/dashboard/public/pixel-engine/furniture/index.json +32 -0
- package/agent/dashboard/public/pixel-engine/walls/wall_0.png +0 -0
- package/agent/dashboard/src/app.tsx +223 -0
- package/agent/dashboard/src/components/alert.tsx +24 -0
- package/agent/dashboard/src/components/badge.tsx +41 -0
- package/agent/dashboard/src/components/button.tsx +44 -0
- package/agent/dashboard/src/components/card.tsx +21 -0
- package/agent/dashboard/src/components/dialog.tsx +28 -0
- package/agent/dashboard/src/components/index.ts +7 -0
- package/agent/dashboard/src/components/input.tsx +45 -0
- package/agent/dashboard/src/components/status-dot.tsx +31 -0
- package/agent/dashboard/src/index.css +126 -0
- package/agent/dashboard/src/lib/api.test.ts +41 -0
- package/agent/dashboard/src/lib/api.ts +53 -0
- package/agent/dashboard/src/lib/fleet-context.tsx +92 -0
- package/agent/dashboard/src/lib/format.test.ts +119 -0
- package/agent/dashboard/src/lib/format.ts +41 -0
- package/agent/dashboard/src/lib/login-gate.tsx +117 -0
- package/agent/dashboard/src/lib/sanitize.test.ts +86 -0
- package/agent/dashboard/src/lib/sanitize.ts +13 -0
- package/agent/dashboard/src/lib/snippet.test.ts +50 -0
- package/agent/dashboard/src/lib/snippet.ts +15 -0
- package/agent/dashboard/src/lib/ws-parse.test.ts +72 -0
- package/agent/dashboard/src/lib/ws-parse.ts +46 -0
- package/agent/dashboard/src/main.tsx +25 -0
- package/agent/dashboard/src/pixel-engine/colorize.ts +230 -0
- package/agent/dashboard/src/pixel-engine/components/BottomToolbar.tsx +83 -0
- package/agent/dashboard/src/pixel-engine/components/DebugView.tsx +175 -0
- package/agent/dashboard/src/pixel-engine/components/OfficeCanvas.tsx +838 -0
- package/agent/dashboard/src/pixel-engine/components/PixelOffice.tsx +646 -0
- package/agent/dashboard/src/pixel-engine/components/SettingsModal.tsx +213 -0
- package/agent/dashboard/src/pixel-engine/components/ToolOverlay.tsx +203 -0
- package/agent/dashboard/src/pixel-engine/components/ZoomControls.tsx +177 -0
- package/agent/dashboard/src/pixel-engine/constants.ts +132 -0
- package/agent/dashboard/src/pixel-engine/editor/EditorToolbar.tsx +737 -0
- package/agent/dashboard/src/pixel-engine/editor/editorActions.ts +291 -0
- package/agent/dashboard/src/pixel-engine/editor/editorState.ts +123 -0
- package/agent/dashboard/src/pixel-engine/engine/characters.ts +595 -0
- package/agent/dashboard/src/pixel-engine/engine/gameLoop.ts +50 -0
- package/agent/dashboard/src/pixel-engine/engine/interactionScheduler.ts +442 -0
- package/agent/dashboard/src/pixel-engine/engine/matrixEffect.ts +139 -0
- package/agent/dashboard/src/pixel-engine/engine/officeState.ts +748 -0
- package/agent/dashboard/src/pixel-engine/engine/renderer.ts +693 -0
- package/agent/dashboard/src/pixel-engine/floorTiles.ts +74 -0
- package/agent/dashboard/src/pixel-engine/hooks/useAssetLoader.ts +488 -0
- package/agent/dashboard/src/pixel-engine/hooks/useEditorActions.ts +661 -0
- package/agent/dashboard/src/pixel-engine/hooks/useEditorKeyboard.ts +83 -0
- package/agent/dashboard/src/pixel-engine/hooks/useLayoutPersistence.ts +162 -0
- package/agent/dashboard/src/pixel-engine/hooks/useOfficeStream.ts +353 -0
- package/agent/dashboard/src/pixel-engine/layout/furnitureCatalog.ts +417 -0
- package/agent/dashboard/src/pixel-engine/layout/layoutSerializer.ts +416 -0
- package/agent/dashboard/src/pixel-engine/layout/tileMap.ts +109 -0
- package/agent/dashboard/src/pixel-engine/notificationSound.ts +69 -0
- package/agent/dashboard/src/pixel-engine/pixel-office.css +55 -0
- package/agent/dashboard/src/pixel-engine/sprites/bubble-permission.json +27 -0
- package/agent/dashboard/src/pixel-engine/sprites/bubble-waiting.json +27 -0
- package/agent/dashboard/src/pixel-engine/sprites/spriteCache.ts +82 -0
- package/agent/dashboard/src/pixel-engine/sprites/spriteData.ts +176 -0
- package/agent/dashboard/src/pixel-engine/toolUtils.ts +28 -0
- package/agent/dashboard/src/pixel-engine/types.ts +232 -0
- package/agent/dashboard/src/pixel-engine/wallTiles.ts +203 -0
- package/agent/dashboard/src/views/auth.tsx +249 -0
- package/agent/dashboard/src/views/fleet.tsx +263 -0
- package/agent/dashboard/src/views/network.tsx +106 -0
- package/agent/dashboard/src/views/schedule-types.ts +12 -0
- package/agent/dashboard/src/views/schedule-utils.ts +49 -0
- package/agent/dashboard/src/views/schedule.tsx +326 -0
- package/agent/dashboard/src/views/sessions/conversation-viewer.tsx +279 -0
- package/agent/dashboard/src/views/sessions/session-detail.tsx +48 -0
- package/agent/dashboard/src/views/sessions/session-list.tsx +265 -0
- package/agent/dashboard/src/views/sessions/terminal-pane.tsx +270 -0
- package/agent/dashboard/src/views/sessions.tsx +55 -0
- package/agent/dashboard/src/views/settings-config.tsx +265 -0
- package/agent/dashboard/src/views/settings-logs.tsx +99 -0
- package/agent/dashboard/src/views/settings-status.tsx +215 -0
- package/agent/dashboard/src/views/settings.tsx +324 -0
- package/agent/dashboard/src/views/webhooks.tsx +230 -0
- package/agent/dashboard/src/vite-env.d.ts +3 -0
- package/agent/dashboard/tsconfig.json +13 -0
- package/agent/entry.ts +168 -0
- package/agent/event-log.ts +103 -0
- package/agent/node-pty-adapter.ts +39 -0
- package/agent/paths.ts +12 -0
- package/agent/pty-manager.ts +265 -0
- package/agent/pty-types.ts +25 -0
- package/agent/routes/api.ts +149 -0
- package/agent/routes/config.ts +116 -0
- package/agent/routes/dashboard.ts +101 -0
- package/agent/routes/schedule.ts +84 -0
- package/agent/routes/sessions.ts +43 -0
- package/agent/routes/webhooks.ts +113 -0
- package/agent/scheduler.ts +373 -0
- package/agent/server-schema.ts +25 -0
- package/agent/server-utils.ts +163 -0
- package/agent/server.ts +218 -0
- package/agent/server.types.ts +39 -0
- package/agent/session-history-types.ts +78 -0
- package/agent/session-history-utils.ts +96 -0
- package/agent/session-history.ts +318 -0
- package/agent/session.ts +152 -0
- package/agent/tools/mecha-call.ts +106 -0
- package/agent/tools/mecha-fleet.ts +176 -0
- package/agent/tools/mecha-list.ts +56 -0
- package/agent/tools/mecha-server.ts +70 -0
- package/agent/types.ts +35 -0
- package/agent/webhook.ts +127 -0
- package/agent/ws-terminal.ts +174 -0
- package/dist/agent/activity.d.ts +14 -0
- package/dist/agent/activity.d.ts.map +1 -0
- package/dist/agent/activity.js +25 -0
- package/dist/agent/activity.js.map +1 -0
- package/dist/agent/character-config.test.d.ts +2 -0
- package/dist/agent/character-config.test.d.ts.map +1 -0
- package/dist/agent/character-config.test.js +51 -0
- package/dist/agent/character-config.test.js.map +1 -0
- package/dist/agent/costs.d.ts +16 -0
- package/dist/agent/costs.d.ts.map +1 -0
- package/dist/agent/costs.js +82 -0
- package/dist/agent/costs.js.map +1 -0
- package/dist/agent/dashboard/dist/assets/addon-fit-YJmn1quW.js +12 -0
- package/dist/agent/dashboard/dist/assets/addon-web-links-BWjmmSgS.js +12 -0
- package/dist/agent/dashboard/dist/assets/index-B4OKDQ7e.css +32 -0
- package/dist/agent/dashboard/dist/assets/index-fZ_N6Wsi.js +193 -0
- package/dist/agent/dashboard/dist/assets/xterm-BqvuqXEL.js +27 -0
- package/dist/agent/dashboard/dist/index.html +19 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_0.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_1.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_3.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_4.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/characters/char_5.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/default-layout.json +4320 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_0.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_1.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_3.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_4.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_5.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_6.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_7.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/floors/floor_8.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/fonts/FSPixelSansUnicode-Regular.ttf +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BIN/BIN.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BIN/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BLACKBOARD/BLACKBOARD.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BLACKBOARD/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BOOKSHELF/BOOKSHELF.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/BOOKSHELF/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CACTUS/CACTUS.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CACTUS/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CLOCK/CLOCK.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CLOCK/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/COFFEE/COFFEE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/COFFEE/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/COFFEE_TABLE/COFFEE_TABLE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/COFFEE_TABLE/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_BENCH/CUSHIONED_BENCH.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_BENCH/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_BACK.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/CUSHIONED_CHAIR_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/CUSHIONED_CHAIR/manifest.json +44 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/DESK/DESK_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/DESK/DESK_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/DESK/manifest.json +33 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/DOUBLE_BOOKSHELF/DOUBLE_BOOKSHELF.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/DOUBLE_BOOKSHELF/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_1/FILE_BOXES_1.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_1/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_2/FILE_BOXES_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/FILE_BOXES_2/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/HANGING_PLANT/HANGING_PLANT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/HANGING_PLANT/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/LARGE_PAINTING/LARGE_PAINTING.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/LARGE_PAINTING/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/LARGE_PLANT/LARGE_PLANT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/LARGE_PLANT/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_BACK.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_OFF.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_1.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_FRONT_ON_3.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/PC_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PC/manifest.json +88 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PLANT/PLANT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PLANT/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PLANT_2/PLANT_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/PLANT_2/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/POT/POT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/POT/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING/SMALL_PAINTING.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING_2/SMALL_PAINTING_2.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_PAINTING_2/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/SMALL_TABLE_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SMALL_TABLE/manifest.json +33 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_BACK.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SOFA/SOFA_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/SOFA/manifest.json +44 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/TABLE_FRONT/TABLE_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/TABLE_FRONT/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/VENDER_MACHINE/VENDER_MACHINE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/VENDER_MACHINE/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WATER_MACHINE/WATER_MACHINE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WATER_MACHINE/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WHITEBOARD/WHITEBOARD.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WHITEBOARD/manifest.json +16 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_BENCH/WOODEN_BENCH.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_BENCH/manifest.json +13 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_BACK.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_FRONT.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/WOODEN_CHAIR_SIDE.png +0 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/WOODEN_CHAIR/manifest.json +44 -0
- package/dist/agent/dashboard/dist/pixel-engine/furniture/index.json +32 -0
- package/dist/agent/dashboard/dist/pixel-engine/walls/wall_0.png +0 -0
- package/dist/agent/entry.d.ts +2 -0
- package/dist/agent/entry.d.ts.map +1 -0
- package/dist/agent/entry.js +157 -0
- package/dist/agent/entry.js.map +1 -0
- package/dist/agent/event-log.d.ts +11 -0
- package/dist/agent/event-log.d.ts.map +1 -0
- package/dist/agent/event-log.js +102 -0
- package/dist/agent/event-log.js.map +1 -0
- package/dist/agent/node-pty-adapter.d.ts +4 -0
- package/dist/agent/node-pty-adapter.d.ts.map +1 -0
- package/dist/agent/node-pty-adapter.js +35 -0
- package/dist/agent/node-pty-adapter.js.map +1 -0
- package/dist/agent/paths.d.ts +11 -0
- package/dist/agent/paths.d.ts.map +1 -0
- package/dist/agent/paths.js +12 -0
- package/dist/agent/paths.js.map +1 -0
- package/dist/agent/pty-manager.d.ts +34 -0
- package/dist/agent/pty-manager.d.ts.map +1 -0
- package/dist/agent/pty-manager.js +210 -0
- package/dist/agent/pty-manager.js.map +1 -0
- package/dist/agent/pty-types.d.ts +26 -0
- package/dist/agent/pty-types.d.ts.map +1 -0
- package/dist/agent/pty-types.js +2 -0
- package/dist/agent/pty-types.js.map +1 -0
- package/dist/agent/routes/api.d.ts +17 -0
- package/dist/agent/routes/api.d.ts.map +1 -0
- package/dist/agent/routes/api.js +125 -0
- package/dist/agent/routes/api.js.map +1 -0
- package/dist/agent/routes/config.d.ts +6 -0
- package/dist/agent/routes/config.d.ts.map +1 -0
- package/dist/agent/routes/config.js +116 -0
- package/dist/agent/routes/config.js.map +1 -0
- package/dist/agent/routes/dashboard.d.ts +4 -0
- package/dist/agent/routes/dashboard.d.ts.map +1 -0
- package/dist/agent/routes/dashboard.js +97 -0
- package/dist/agent/routes/dashboard.js.map +1 -0
- package/dist/agent/routes/schedule.d.ts +4 -0
- package/dist/agent/routes/schedule.d.ts.map +1 -0
- package/dist/agent/routes/schedule.js +98 -0
- package/dist/agent/routes/schedule.js.map +1 -0
- package/dist/agent/routes/sessions.d.ts +4 -0
- package/dist/agent/routes/sessions.d.ts.map +1 -0
- package/dist/agent/routes/sessions.js +43 -0
- package/dist/agent/routes/sessions.js.map +1 -0
- package/dist/agent/routes/webhooks.d.ts +5 -0
- package/dist/agent/routes/webhooks.d.ts.map +1 -0
- package/dist/agent/routes/webhooks.js +102 -0
- package/dist/agent/routes/webhooks.js.map +1 -0
- package/dist/agent/scheduler.d.ts +50 -0
- package/dist/agent/scheduler.d.ts.map +1 -0
- package/dist/agent/scheduler.js +332 -0
- package/dist/agent/scheduler.js.map +1 -0
- package/dist/agent/server-schema.d.ts +20 -0
- package/dist/agent/server-schema.d.ts.map +1 -0
- package/dist/agent/server-schema.js +20 -0
- package/dist/agent/server-schema.js.map +1 -0
- package/dist/agent/server-utils.d.ts +18 -0
- package/dist/agent/server-utils.d.ts.map +1 -0
- package/dist/agent/server-utils.js +132 -0
- package/dist/agent/server-utils.js.map +1 -0
- package/dist/agent/server.d.ts +17 -0
- package/dist/agent/server.d.ts.map +1 -0
- package/dist/agent/server.js +196 -0
- package/dist/agent/server.js.map +1 -0
- package/dist/agent/server.types.d.ts +38 -0
- package/dist/agent/server.types.d.ts.map +1 -0
- package/dist/agent/server.types.js +2 -0
- package/dist/agent/server.types.js.map +1 -0
- package/dist/agent/session-history-types.d.ts +74 -0
- package/dist/agent/session-history-types.d.ts.map +1 -0
- package/dist/agent/session-history-types.js +2 -0
- package/dist/agent/session-history-types.js.map +1 -0
- package/dist/agent/session-history-utils.d.ts +13 -0
- package/dist/agent/session-history-utils.d.ts.map +1 -0
- package/dist/agent/session-history-utils.js +102 -0
- package/dist/agent/session-history-utils.js.map +1 -0
- package/dist/agent/session-history.d.ts +20 -0
- package/dist/agent/session-history.d.ts.map +1 -0
- package/dist/agent/session-history.js +282 -0
- package/dist/agent/session-history.js.map +1 -0
- package/dist/agent/session.d.ts +51 -0
- package/dist/agent/session.d.ts.map +1 -0
- package/dist/agent/session.js +135 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/tools/mecha-call.d.ts +2 -0
- package/dist/agent/tools/mecha-call.d.ts.map +1 -0
- package/dist/agent/tools/mecha-call.js +101 -0
- package/dist/agent/tools/mecha-call.js.map +1 -0
- package/dist/agent/tools/mecha-fleet.d.ts +25 -0
- package/dist/agent/tools/mecha-fleet.d.ts.map +1 -0
- package/dist/agent/tools/mecha-fleet.js +144 -0
- package/dist/agent/tools/mecha-fleet.js.map +1 -0
- package/dist/agent/tools/mecha-list.d.ts +6 -0
- package/dist/agent/tools/mecha-list.d.ts.map +1 -0
- package/dist/agent/tools/mecha-list.js +46 -0
- package/dist/agent/tools/mecha-list.js.map +1 -0
- package/dist/agent/tools/mecha-server.d.ts +4 -0
- package/dist/agent/tools/mecha-server.d.ts.map +1 -0
- package/dist/agent/tools/mecha-server.js +49 -0
- package/dist/agent/tools/mecha-server.js.map +1 -0
- package/dist/agent/types.d.ts +38 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +32 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent/webhook.d.ts +12 -0
- package/dist/agent/webhook.d.ts.map +1 -0
- package/dist/agent/webhook.js +105 -0
- package/dist/agent/webhook.js.map +1 -0
- package/dist/agent/ws-terminal.d.ts +4 -0
- package/dist/agent/ws-terminal.d.ts.map +1 -0
- package/dist/agent/ws-terminal.js +160 -0
- package/dist/agent/ws-terminal.js.map +1 -0
- package/dist/shared/atomic-write.d.ts +5 -0
- package/dist/shared/atomic-write.d.ts.map +1 -0
- package/dist/shared/atomic-write.js +63 -0
- package/dist/shared/atomic-write.js.map +1 -0
- package/dist/shared/errors.d.ts +71 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +52 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/logger.d.ts +7 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +52 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/mutex.d.ts +12 -0
- package/dist/shared/mutex.d.ts.map +1 -0
- package/dist/shared/mutex.js +73 -0
- package/dist/shared/mutex.js.map +1 -0
- package/dist/shared/safe-read.d.ts +12 -0
- package/dist/shared/safe-read.d.ts.map +1 -0
- package/dist/shared/safe-read.js +33 -0
- package/dist/shared/safe-read.js.map +1 -0
- package/dist/shared/totp.d.ts +7 -0
- package/dist/shared/totp.d.ts.map +1 -0
- package/dist/shared/totp.js +75 -0
- package/dist/shared/totp.js.map +1 -0
- package/dist/shared/validation.d.ts +7 -0
- package/dist/shared/validation.d.ts.map +1 -0
- package/dist/shared/validation.js +30 -0
- package/dist/shared/validation.js.map +1 -0
- package/dist/src/auth.d.ts +48 -0
- package/dist/src/auth.d.ts.map +1 -0
- package/dist/src/auth.js +160 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/cli-output.d.ts +14 -0
- package/dist/src/cli-output.d.ts.map +1 -0
- package/dist/src/cli-output.js +47 -0
- package/dist/src/cli-output.js.map +1 -0
- package/dist/src/cli-utils.d.ts +15 -0
- package/dist/src/cli-utils.d.ts.map +1 -0
- package/dist/src/cli-utils.js +241 -0
- package/dist/src/cli-utils.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +535 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/cli.utils.d.ts +10 -0
- package/dist/src/cli.utils.d.ts.map +1 -0
- package/dist/src/cli.utils.js +127 -0
- package/dist/src/cli.utils.js.map +1 -0
- package/dist/src/commands/auth.d.ts +3 -0
- package/dist/src/commands/auth.d.ts.map +1 -0
- package/dist/src/commands/auth.js +139 -0
- package/dist/src/commands/auth.js.map +1 -0
- package/dist/src/commands/bot-api.d.ts +15 -0
- package/dist/src/commands/bot-api.d.ts.map +1 -0
- package/dist/src/commands/bot-api.js +40 -0
- package/dist/src/commands/bot-api.js.map +1 -0
- package/dist/src/commands/completion.d.ts +3 -0
- package/dist/src/commands/completion.d.ts.map +1 -0
- package/dist/src/commands/completion.js +108 -0
- package/dist/src/commands/completion.js.map +1 -0
- package/dist/src/commands/config.d.ts +3 -0
- package/dist/src/commands/config.d.ts.map +1 -0
- package/dist/src/commands/config.js +110 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/costs.d.ts +3 -0
- package/dist/src/commands/costs.d.ts.map +1 -0
- package/dist/src/commands/costs.js +88 -0
- package/dist/src/commands/costs.js.map +1 -0
- package/dist/src/commands/daemon.d.ts +3 -0
- package/dist/src/commands/daemon.d.ts.map +1 -0
- package/dist/src/commands/daemon.js +86 -0
- package/dist/src/commands/daemon.js.map +1 -0
- package/dist/src/commands/push-dashboard.d.ts +3 -0
- package/dist/src/commands/push-dashboard.d.ts.map +1 -0
- package/dist/src/commands/push-dashboard.js +48 -0
- package/dist/src/commands/push-dashboard.js.map +1 -0
- package/dist/src/commands/schedule.d.ts +3 -0
- package/dist/src/commands/schedule.d.ts.map +1 -0
- package/dist/src/commands/schedule.js +70 -0
- package/dist/src/commands/schedule.js.map +1 -0
- package/dist/src/commands/sessions.d.ts +3 -0
- package/dist/src/commands/sessions.d.ts.map +1 -0
- package/dist/src/commands/sessions.js +62 -0
- package/dist/src/commands/sessions.js.map +1 -0
- package/dist/src/commands/webhooks.d.ts +3 -0
- package/dist/src/commands/webhooks.d.ts.map +1 -0
- package/dist/src/commands/webhooks.js +44 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/config.d.ts +9 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +56 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/daemon-audit.d.ts +13 -0
- package/dist/src/daemon-audit.d.ts.map +1 -0
- package/dist/src/daemon-audit.js +33 -0
- package/dist/src/daemon-audit.js.map +1 -0
- package/dist/src/daemon.d.ts +25 -0
- package/dist/src/daemon.d.ts.map +1 -0
- package/dist/src/daemon.js +344 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/dashboard-server-schema.d.ts +23 -0
- package/dist/src/dashboard-server-schema.d.ts.map +1 -0
- package/dist/src/dashboard-server-schema.js +45 -0
- package/dist/src/dashboard-server-schema.js.map +1 -0
- package/dist/src/dashboard-server-utils.d.ts +18 -0
- package/dist/src/dashboard-server-utils.d.ts.map +1 -0
- package/dist/src/dashboard-server-utils.js +107 -0
- package/dist/src/dashboard-server-utils.js.map +1 -0
- package/dist/src/dashboard-server.d.ts +2 -0
- package/dist/src/dashboard-server.d.ts.map +1 -0
- package/dist/src/dashboard-server.js +777 -0
- package/dist/src/dashboard-server.js.map +1 -0
- package/dist/src/docker.constants.d.ts +5 -0
- package/dist/src/docker.constants.d.ts.map +1 -0
- package/dist/src/docker.constants.js +7 -0
- package/dist/src/docker.constants.js.map +1 -0
- package/dist/src/docker.d.ts +16 -0
- package/dist/src/docker.d.ts.map +1 -0
- package/dist/src/docker.js +437 -0
- package/dist/src/docker.js.map +1 -0
- package/dist/src/docker.types.d.ts +13 -0
- package/dist/src/docker.types.d.ts.map +1 -0
- package/dist/src/docker.types.js +2 -0
- package/dist/src/docker.types.js.map +1 -0
- package/dist/src/docker.utils.d.ts +24 -0
- package/dist/src/docker.utils.d.ts.map +1 -0
- package/dist/src/docker.utils.js +239 -0
- package/dist/src/docker.utils.js.map +1 -0
- package/dist/src/doctor.d.ts +3 -0
- package/dist/src/doctor.d.ts.map +1 -0
- package/dist/src/doctor.js +80 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/doctor.utils.d.ts +30 -0
- package/dist/src/doctor.utils.d.ts.map +1 -0
- package/dist/src/doctor.utils.js +192 -0
- package/dist/src/doctor.utils.js.map +1 -0
- package/dist/src/mcp-proxy.d.ts +2 -0
- package/dist/src/mcp-proxy.d.ts.map +1 -0
- package/dist/src/mcp-proxy.js +177 -0
- package/dist/src/mcp-proxy.js.map +1 -0
- package/dist/src/resolve-endpoint.d.ts +13 -0
- package/dist/src/resolve-endpoint.d.ts.map +1 -0
- package/dist/src/resolve-endpoint.js +112 -0
- package/dist/src/resolve-endpoint.js.map +1 -0
- package/dist/src/store.d.ts +41 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +263 -0
- package/dist/src/store.js.map +1 -0
- package/package.json +84 -0
- package/s6/mecha-agent/dependencies.d/tailscale-up +0 -0
- package/s6/mecha-agent/finish +4 -0
- package/s6/mecha-agent/run +39 -0
- package/s6/mecha-agent/type +1 -0
- package/s6/tailscale-up/dependencies.d/tailscaled +0 -0
- package/s6/tailscale-up/type +1 -0
- package/s6/tailscale-up/up +39 -0
- package/s6/tailscaled/run +14 -0
- package/s6/tailscaled/type +1 -0
- package/shared/atomic-write.ts +58 -0
- package/shared/errors.ts +137 -0
- package/shared/logger.ts +50 -0
- package/shared/mutex.ts +73 -0
- package/shared/safe-read.ts +52 -0
- package/shared/totp.ts +83 -0
- package/shared/validation.ts +29 -0
- package/tsconfig.agent.json +10 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { EditorState } from '../editor/editorState.js';
|
|
4
|
+
import { EditTool } from '../types.js';
|
|
5
|
+
|
|
6
|
+
export function useEditorKeyboard(
|
|
7
|
+
isEditMode: boolean,
|
|
8
|
+
editorState: EditorState,
|
|
9
|
+
onDeleteSelected: () => void,
|
|
10
|
+
onRotateSelected: () => void,
|
|
11
|
+
onToggleState: () => void,
|
|
12
|
+
onUndo: () => void,
|
|
13
|
+
onRedo: () => void,
|
|
14
|
+
onEditorTick: () => void,
|
|
15
|
+
onCloseEditMode: () => void,
|
|
16
|
+
): void {
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!isEditMode) return;
|
|
19
|
+
const handler = (e: KeyboardEvent) => {
|
|
20
|
+
// Ignore keyboard shortcuts when a form control is focused
|
|
21
|
+
const tag = (e.target as HTMLElement)?.tagName;
|
|
22
|
+
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') {
|
|
23
|
+
// Allow Escape to still work for closing edit mode
|
|
24
|
+
if (e.key !== 'Escape') return;
|
|
25
|
+
}
|
|
26
|
+
if (e.key === 'Escape') {
|
|
27
|
+
// Multi-stage Esc: deselect item → close tool → deselect placed → close editor
|
|
28
|
+
if (editorState.activeTool === EditTool.FURNITURE_PICK) {
|
|
29
|
+
editorState.activeTool = EditTool.FURNITURE_PLACE;
|
|
30
|
+
editorState.clearGhost();
|
|
31
|
+
} else if (
|
|
32
|
+
editorState.activeTool === EditTool.FURNITURE_PLACE &&
|
|
33
|
+
editorState.selectedFurnitureType !== ''
|
|
34
|
+
) {
|
|
35
|
+
editorState.selectedFurnitureType = '';
|
|
36
|
+
editorState.clearGhost();
|
|
37
|
+
} else if (editorState.activeTool !== EditTool.SELECT) {
|
|
38
|
+
editorState.activeTool = EditTool.SELECT;
|
|
39
|
+
editorState.clearGhost();
|
|
40
|
+
} else if (editorState.selectedFurnitureUid) {
|
|
41
|
+
editorState.clearSelection();
|
|
42
|
+
} else {
|
|
43
|
+
onCloseEditMode();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
editorState.clearDrag();
|
|
47
|
+
onEditorTick();
|
|
48
|
+
} else if (e.key === 'Delete' || e.key === 'Backspace') {
|
|
49
|
+
if (editorState.selectedFurnitureUid) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
onDeleteSelected();
|
|
52
|
+
}
|
|
53
|
+
} else if ((e.key === 'r' || e.key === 'R') && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
onRotateSelected();
|
|
56
|
+
} else if ((e.key === 't' || e.key === 'T') && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
onToggleState();
|
|
59
|
+
} else if (e.key === 'z' && (e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
onUndo();
|
|
62
|
+
} else if (
|
|
63
|
+
(e.key === 'y' && (e.ctrlKey || e.metaKey)) ||
|
|
64
|
+
(e.key === 'z' && (e.ctrlKey || e.metaKey) && e.shiftKey)
|
|
65
|
+
) {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
onRedo();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
window.addEventListener('keydown', handler);
|
|
71
|
+
return () => window.removeEventListener('keydown', handler);
|
|
72
|
+
}, [
|
|
73
|
+
isEditMode,
|
|
74
|
+
editorState,
|
|
75
|
+
onDeleteSelected,
|
|
76
|
+
onRotateSelected,
|
|
77
|
+
onToggleState,
|
|
78
|
+
onUndo,
|
|
79
|
+
onRedo,
|
|
80
|
+
onEditorTick,
|
|
81
|
+
onCloseEditMode,
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout persistence hook — loads and saves office layout via the backend API.
|
|
3
|
+
*
|
|
4
|
+
* On mount: GET /api/office/layout (stores ETag for conflict detection).
|
|
5
|
+
* If 404: falls back to the bundled default-layout.json from assets.
|
|
6
|
+
* On 5xx/network error: retries 3 times with backoff, then falls back to default.
|
|
7
|
+
*
|
|
8
|
+
* saveLayout: debounced 500ms POST with If-Match ETag.
|
|
9
|
+
* On 409 conflict: reloads server version.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
13
|
+
|
|
14
|
+
import { LAYOUT_SAVE_DEBOUNCE_MS } from '../constants';
|
|
15
|
+
import { migrateLayoutColors } from '../layout/layoutSerializer';
|
|
16
|
+
import type { OfficeLayout } from '../types';
|
|
17
|
+
|
|
18
|
+
const ASSET_BASE = '/pixel-engine';
|
|
19
|
+
const MAX_RETRIES = 3;
|
|
20
|
+
const RETRY_DELAYS = [2000, 5000, 10000];
|
|
21
|
+
|
|
22
|
+
export function useLayoutPersistence(): {
|
|
23
|
+
layout: OfficeLayout | null;
|
|
24
|
+
saveLayout: (layout: OfficeLayout) => void;
|
|
25
|
+
saveLayoutImmediate: (layout: OfficeLayout) => Promise<boolean>;
|
|
26
|
+
reloadLayout: () => void;
|
|
27
|
+
} {
|
|
28
|
+
const [layout, setLayout] = useState<OfficeLayout | null>(null);
|
|
29
|
+
const etagRef = useRef<string | null>(null);
|
|
30
|
+
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
31
|
+
const mountedRef = useRef(true);
|
|
32
|
+
|
|
33
|
+
/** Load bundled default-layout.json from public assets */
|
|
34
|
+
const loadDefaultLayout = useCallback(async () => {
|
|
35
|
+
try {
|
|
36
|
+
const resp = await fetch(`${ASSET_BASE}/default-layout.json`);
|
|
37
|
+
if (resp.ok) {
|
|
38
|
+
const data = (await resp.json()) as OfficeLayout;
|
|
39
|
+
if (data?.version === 1 && mountedRef.current) {
|
|
40
|
+
setLayout(migrateLayoutColors(data));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
console.warn('[LayoutPersistence] Failed to load default layout');
|
|
45
|
+
}
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
/** Fetch layout from API with retry on transient errors */
|
|
49
|
+
const fetchLayout = useCallback(async () => {
|
|
50
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
51
|
+
if (!mountedRef.current) return;
|
|
52
|
+
try {
|
|
53
|
+
const resp = await fetch('/api/office/layout');
|
|
54
|
+
if (resp.ok) {
|
|
55
|
+
const etag = resp.headers.get('ETag');
|
|
56
|
+
if (etag) etagRef.current = etag;
|
|
57
|
+
const data = (await resp.json()) as OfficeLayout;
|
|
58
|
+
if (data?.version === 1 && mountedRef.current) {
|
|
59
|
+
setLayout(migrateLayoutColors(data));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// 200 but invalid shape — fall back to default
|
|
63
|
+
await loadDefaultLayout();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (resp.status === 404) {
|
|
67
|
+
// No layout saved yet — use default
|
|
68
|
+
await loadDefaultLayout();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Server error — retry
|
|
72
|
+
console.warn(`[LayoutPersistence] Server error ${resp.status} (attempt ${attempt + 1}/${MAX_RETRIES + 1})`);
|
|
73
|
+
} catch {
|
|
74
|
+
console.warn(`[LayoutPersistence] Network error (attempt ${attempt + 1}/${MAX_RETRIES + 1})`);
|
|
75
|
+
}
|
|
76
|
+
// Wait before retry (skip wait on last attempt)
|
|
77
|
+
if (attempt < MAX_RETRIES) {
|
|
78
|
+
await new Promise(r => setTimeout(r, RETRY_DELAYS[attempt] ?? 10000));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// All retries exhausted — fall back to default
|
|
82
|
+
console.warn('[LayoutPersistence] Retries exhausted, using default layout');
|
|
83
|
+
await loadDefaultLayout();
|
|
84
|
+
}, [loadDefaultLayout]);
|
|
85
|
+
|
|
86
|
+
/** Save layout to the API with ETag conflict detection. Returns true on success. */
|
|
87
|
+
const doSave = useCallback(async (layoutToSave: OfficeLayout): Promise<boolean> => {
|
|
88
|
+
try {
|
|
89
|
+
const headers: Record<string, string> = {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
};
|
|
92
|
+
if (etagRef.current) {
|
|
93
|
+
headers['If-Match'] = etagRef.current;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const resp = await fetch('/api/office/layout', {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers,
|
|
99
|
+
body: JSON.stringify(layoutToSave),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (resp.ok) {
|
|
103
|
+
const etag = resp.headers.get('ETag');
|
|
104
|
+
if (etag) etagRef.current = etag;
|
|
105
|
+
return true;
|
|
106
|
+
} else if (resp.status === 409) {
|
|
107
|
+
// Conflict — reload server version
|
|
108
|
+
console.warn('[LayoutPersistence] Conflict detected, reloading server layout');
|
|
109
|
+
await fetchLayout();
|
|
110
|
+
}
|
|
111
|
+
} catch {
|
|
112
|
+
console.warn('[LayoutPersistence] Failed to save layout');
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}, [fetchLayout]);
|
|
116
|
+
|
|
117
|
+
/** Debounced save — waits 500ms after last call */
|
|
118
|
+
const saveLayout = useCallback(
|
|
119
|
+
(layoutToSave: OfficeLayout) => {
|
|
120
|
+
if (debounceRef.current) {
|
|
121
|
+
clearTimeout(debounceRef.current);
|
|
122
|
+
}
|
|
123
|
+
debounceRef.current = setTimeout(() => {
|
|
124
|
+
debounceRef.current = null;
|
|
125
|
+
doSave(layoutToSave);
|
|
126
|
+
}, LAYOUT_SAVE_DEBOUNCE_MS);
|
|
127
|
+
},
|
|
128
|
+
[doSave],
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
/** Immediate (non-debounced) save — returns true on success */
|
|
132
|
+
const saveLayoutImmediate = useCallback(
|
|
133
|
+
async (layoutToSave: OfficeLayout): Promise<boolean> => {
|
|
134
|
+
// Flush any pending debounced save
|
|
135
|
+
if (debounceRef.current) {
|
|
136
|
+
clearTimeout(debounceRef.current);
|
|
137
|
+
debounceRef.current = null;
|
|
138
|
+
}
|
|
139
|
+
return doSave(layoutToSave);
|
|
140
|
+
},
|
|
141
|
+
[doSave],
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const reloadLayout = useCallback(() => {
|
|
145
|
+
fetchLayout();
|
|
146
|
+
}, [fetchLayout]);
|
|
147
|
+
|
|
148
|
+
// Load on mount
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
mountedRef.current = true;
|
|
151
|
+
fetchLayout();
|
|
152
|
+
|
|
153
|
+
return () => {
|
|
154
|
+
mountedRef.current = false;
|
|
155
|
+
if (debounceRef.current) {
|
|
156
|
+
clearTimeout(debounceRef.current);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}, [fetchLayout]);
|
|
160
|
+
|
|
161
|
+
return { layout, saveLayout, saveLayoutImmediate, reloadLayout };
|
|
162
|
+
}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fleet SSE stream adapter for the pixel office engine.
|
|
3
|
+
*
|
|
4
|
+
* Connects to GET /api/office/stream and maps SSE events to OfficeState mutations.
|
|
5
|
+
* Handles snapshot reconciliation, delta events (bot_join, bot_leave, tool, state),
|
|
6
|
+
* heartbeat seq-gap detection, and automatic reconnection with backoff.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
10
|
+
|
|
11
|
+
import type { OfficeState } from '../engine/officeState';
|
|
12
|
+
import { extractToolName } from '../toolUtils';
|
|
13
|
+
|
|
14
|
+
// ── SSE event payload types ─────────────────────────────────
|
|
15
|
+
|
|
16
|
+
interface SnapshotBot {
|
|
17
|
+
bot_id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
status: 'idle' | 'active' | 'waiting' | 'permission';
|
|
20
|
+
tool?: string;
|
|
21
|
+
palette?: number;
|
|
22
|
+
hueShift?: number;
|
|
23
|
+
displayName?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface SnapshotEvent {
|
|
27
|
+
seq: number;
|
|
28
|
+
bots: SnapshotBot[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface DeltaStateEvent {
|
|
32
|
+
seq: number;
|
|
33
|
+
type: 'bot_join' | 'bot_leave' | 'status';
|
|
34
|
+
bot_id: string;
|
|
35
|
+
name?: string;
|
|
36
|
+
status?: string;
|
|
37
|
+
palette?: number;
|
|
38
|
+
hueShift?: number;
|
|
39
|
+
displayName?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface DeltaToolEvent {
|
|
43
|
+
seq: number;
|
|
44
|
+
type: 'tool_start' | 'tool_done' | 'tools_clear';
|
|
45
|
+
bot_id: string;
|
|
46
|
+
tool_id?: string;
|
|
47
|
+
tool?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface HeartbeatEvent {
|
|
51
|
+
seq: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ── ID management ───────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
interface BotEntry {
|
|
57
|
+
numericId: number;
|
|
58
|
+
name: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const RECONNECT_BASE_MS = 1000;
|
|
62
|
+
const RECONNECT_MAX_MS = 30000;
|
|
63
|
+
|
|
64
|
+
export function useOfficeStream(
|
|
65
|
+
officeState: OfficeState | null,
|
|
66
|
+
assetsReady: boolean,
|
|
67
|
+
): { getBotNameByNumericId: (id: number) => string | null; getDisplayName: (id: number) => string | null } {
|
|
68
|
+
// Stable maps persisted across reconnections via refs
|
|
69
|
+
const botMapRef = useRef(new Map<string, BotEntry>()); // botId → entry
|
|
70
|
+
const reverseMapRef = useRef(new Map<number, string>()); // numericId → botId
|
|
71
|
+
const displayNameMapRef = useRef(new Map<number, string>()); // numericId → displayName
|
|
72
|
+
const nextIdRef = useRef(1);
|
|
73
|
+
const expectedSeqRef = useRef(0);
|
|
74
|
+
const esRef = useRef<EventSource | null>(null);
|
|
75
|
+
const reconnectAttemptRef = useRef(0);
|
|
76
|
+
const reconnectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
77
|
+
|
|
78
|
+
/** Get or create a stable numeric ID for a bot */
|
|
79
|
+
const getNumericId = useCallback((botId: string, name: string): number => {
|
|
80
|
+
const existing = botMapRef.current.get(botId);
|
|
81
|
+
if (existing) return existing.numericId;
|
|
82
|
+
|
|
83
|
+
const id = nextIdRef.current++;
|
|
84
|
+
const entry: BotEntry = { numericId: id, name };
|
|
85
|
+
botMapRef.current.set(botId, entry);
|
|
86
|
+
reverseMapRef.current.set(id, botId);
|
|
87
|
+
return id;
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
const getBotNameByNumericId = useCallback((id: number): string | null => {
|
|
91
|
+
const botId = reverseMapRef.current.get(id);
|
|
92
|
+
if (!botId) return null;
|
|
93
|
+
return botMapRef.current.get(botId)?.name ?? null;
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
const getDisplayName = useCallback((id: number): string | null => {
|
|
97
|
+
return displayNameMapRef.current.get(id) ?? null;
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (!officeState || !assetsReady) return;
|
|
102
|
+
|
|
103
|
+
// Capture in a const so TypeScript narrows the type inside closures
|
|
104
|
+
const os = officeState;
|
|
105
|
+
|
|
106
|
+
function connect() {
|
|
107
|
+
// Clean up existing connection
|
|
108
|
+
if (esRef.current) {
|
|
109
|
+
esRef.current.close();
|
|
110
|
+
esRef.current = null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const url = '/api/office/stream';
|
|
114
|
+
const es = new EventSource(url);
|
|
115
|
+
esRef.current = es;
|
|
116
|
+
|
|
117
|
+
es.addEventListener('snapshot', (e: MessageEvent) => {
|
|
118
|
+
try {
|
|
119
|
+
const data = JSON.parse(e.data) as SnapshotEvent;
|
|
120
|
+
expectedSeqRef.current = data.seq + 1;
|
|
121
|
+
reconnectAttemptRef.current = 0; // Successful connection
|
|
122
|
+
|
|
123
|
+
// Reconcile: add new bots, remove stale ones
|
|
124
|
+
const incomingIds = new Set<string>();
|
|
125
|
+
for (const bot of data.bots) {
|
|
126
|
+
incomingIds.add(bot.bot_id);
|
|
127
|
+
const numId = getNumericId(bot.bot_id, bot.name);
|
|
128
|
+
|
|
129
|
+
if (!os.characters.has(numId)) {
|
|
130
|
+
os.addAgent(numId, bot.palette, bot.hueShift, undefined, true);
|
|
131
|
+
} else if (bot.palette !== undefined || bot.hueShift !== undefined) {
|
|
132
|
+
// Update existing agent's avatar if it changed (e.g., after reconnect)
|
|
133
|
+
const ch = os.characters.get(numId);
|
|
134
|
+
if (ch) {
|
|
135
|
+
if (bot.palette !== undefined && ch.palette !== bot.palette) ch.palette = bot.palette;
|
|
136
|
+
if (bot.hueShift !== undefined && ch.hueShift !== bot.hueShift) ch.hueShift = bot.hueShift;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (bot.displayName) displayNameMapRef.current.set(numId, bot.displayName);
|
|
140
|
+
|
|
141
|
+
// Apply current status
|
|
142
|
+
if (bot.status === 'active') {
|
|
143
|
+
os.setAgentActive(numId, true);
|
|
144
|
+
if (bot.tool) {
|
|
145
|
+
os.setAgentTool(numId, extractToolName(bot.tool));
|
|
146
|
+
}
|
|
147
|
+
} else if (bot.status === 'waiting') {
|
|
148
|
+
os.setAgentActive(numId, false);
|
|
149
|
+
os.showWaitingBubble(numId);
|
|
150
|
+
} else if (bot.status === 'permission') {
|
|
151
|
+
os.setAgentActive(numId, true);
|
|
152
|
+
os.showPermissionBubble(numId);
|
|
153
|
+
} else {
|
|
154
|
+
// idle
|
|
155
|
+
os.setAgentActive(numId, false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Remove characters not in snapshot
|
|
160
|
+
for (const [numId, botId] of reverseMapRef.current) {
|
|
161
|
+
if (!incomingIds.has(botId) && os.characters.has(numId)) {
|
|
162
|
+
os.removeAllSubagents(numId);
|
|
163
|
+
os.removeAgent(numId);
|
|
164
|
+
displayNameMapRef.current.delete(numId);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.error('[OfficeStream] Error processing snapshot:', err);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
es.addEventListener('state', (e: MessageEvent) => {
|
|
173
|
+
try {
|
|
174
|
+
const data = JSON.parse(e.data) as DeltaStateEvent;
|
|
175
|
+
|
|
176
|
+
// Seq gap detection
|
|
177
|
+
if (data.seq > expectedSeqRef.current) {
|
|
178
|
+
console.warn(
|
|
179
|
+
`[OfficeStream] Seq gap: expected ${expectedSeqRef.current}, got ${data.seq}. Reconnecting.`,
|
|
180
|
+
);
|
|
181
|
+
scheduleReconnect();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
expectedSeqRef.current = data.seq + 1;
|
|
185
|
+
|
|
186
|
+
if (data.type === 'bot_join') {
|
|
187
|
+
const numId = getNumericId(data.bot_id, data.name ?? data.bot_id);
|
|
188
|
+
os.addAgent(numId, data.palette, data.hueShift);
|
|
189
|
+
if (data.displayName) displayNameMapRef.current.set(numId, data.displayName);
|
|
190
|
+
} else if (data.type === 'bot_leave') {
|
|
191
|
+
const entry = botMapRef.current.get(data.bot_id);
|
|
192
|
+
if (entry) {
|
|
193
|
+
os.removeAllSubagents(entry.numericId);
|
|
194
|
+
os.removeAgent(entry.numericId);
|
|
195
|
+
displayNameMapRef.current.delete(entry.numericId);
|
|
196
|
+
}
|
|
197
|
+
} else if (data.type === 'status') {
|
|
198
|
+
const entry = botMapRef.current.get(data.bot_id);
|
|
199
|
+
if (entry) {
|
|
200
|
+
const numId = entry.numericId;
|
|
201
|
+
const status = data.status;
|
|
202
|
+
|
|
203
|
+
if (status === 'active') {
|
|
204
|
+
os.setAgentActive(numId, true);
|
|
205
|
+
os.clearPermissionBubble(numId);
|
|
206
|
+
} else if (status === 'waiting') {
|
|
207
|
+
os.setAgentActive(numId, false);
|
|
208
|
+
os.showWaitingBubble(numId);
|
|
209
|
+
} else if (status === 'permission') {
|
|
210
|
+
os.setAgentActive(numId, true);
|
|
211
|
+
os.showPermissionBubble(numId);
|
|
212
|
+
} else {
|
|
213
|
+
// idle
|
|
214
|
+
os.setAgentActive(numId, false);
|
|
215
|
+
os.setAgentTool(numId, null);
|
|
216
|
+
os.clearPermissionBubble(numId);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
} catch (err) {
|
|
221
|
+
console.error('[OfficeStream] Error processing state event:', err);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
es.addEventListener('tool', (e: MessageEvent) => {
|
|
226
|
+
try {
|
|
227
|
+
const data = JSON.parse(e.data) as DeltaToolEvent;
|
|
228
|
+
|
|
229
|
+
if (data.seq > expectedSeqRef.current) {
|
|
230
|
+
console.warn(`[OfficeStream] Seq gap in tool event. Reconnecting.`);
|
|
231
|
+
scheduleReconnect();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
expectedSeqRef.current = data.seq + 1;
|
|
235
|
+
|
|
236
|
+
const entry = botMapRef.current.get(data.bot_id);
|
|
237
|
+
if (!entry) return;
|
|
238
|
+
const numId = entry.numericId;
|
|
239
|
+
|
|
240
|
+
if (data.type === 'tool_start') {
|
|
241
|
+
const toolName = data.tool ? extractToolName(data.tool) : null;
|
|
242
|
+
os.setAgentTool(numId, toolName);
|
|
243
|
+
os.setAgentActive(numId, true);
|
|
244
|
+
os.clearPermissionBubble(numId);
|
|
245
|
+
|
|
246
|
+
// Handle subtask spawning
|
|
247
|
+
if (data.tool?.startsWith('Subtask:') && data.tool_id) {
|
|
248
|
+
const subAgentId = os.addSubagent(numId, data.tool_id);
|
|
249
|
+
// Request face-to-face chat if both parent and child are idle
|
|
250
|
+
const parentCh = os.characters.get(numId);
|
|
251
|
+
const childCh = os.characters.get(subAgentId);
|
|
252
|
+
if (parentCh && childCh && !parentCh.isActive && !childCh.isActive) {
|
|
253
|
+
os.scheduler.requestRealChat(numId, subAgentId);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
} else if (data.type === 'tool_done') {
|
|
257
|
+
// Tool completed — don't clear agent tool immediately
|
|
258
|
+
// (another tool may still be active)
|
|
259
|
+
} else if (data.type === 'tools_clear') {
|
|
260
|
+
os.setAgentTool(numId, null);
|
|
261
|
+
os.removeAllSubagents(numId);
|
|
262
|
+
os.clearPermissionBubble(numId);
|
|
263
|
+
}
|
|
264
|
+
} catch (err) {
|
|
265
|
+
console.error('[OfficeStream] Error processing tool event:', err);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
es.addEventListener('subagent', (e: MessageEvent) => {
|
|
270
|
+
try {
|
|
271
|
+
const data = JSON.parse(e.data) as {
|
|
272
|
+
seq: number;
|
|
273
|
+
type: string;
|
|
274
|
+
bot_id: string;
|
|
275
|
+
parent_tool_id: string;
|
|
276
|
+
tool_id?: string;
|
|
277
|
+
tool?: string;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
if (data.seq > expectedSeqRef.current) {
|
|
281
|
+
scheduleReconnect();
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
expectedSeqRef.current = data.seq + 1;
|
|
285
|
+
|
|
286
|
+
const entry = botMapRef.current.get(data.bot_id);
|
|
287
|
+
if (!entry) return;
|
|
288
|
+
const numId = entry.numericId;
|
|
289
|
+
|
|
290
|
+
if (data.type === 'tool_start') {
|
|
291
|
+
const subId = os.getSubagentId(numId, data.parent_tool_id);
|
|
292
|
+
if (subId !== null) {
|
|
293
|
+
const toolName = data.tool ? extractToolName(data.tool) : null;
|
|
294
|
+
os.setAgentTool(subId, toolName);
|
|
295
|
+
os.setAgentActive(subId, true);
|
|
296
|
+
}
|
|
297
|
+
} else if (data.type === 'clear') {
|
|
298
|
+
os.removeSubagent(numId, data.parent_tool_id);
|
|
299
|
+
}
|
|
300
|
+
} catch (err) {
|
|
301
|
+
console.error('[OfficeStream] Error processing subagent event:', err);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
es.addEventListener('heartbeat', (e: MessageEvent) => {
|
|
306
|
+
try {
|
|
307
|
+
const data = JSON.parse(e.data) as HeartbeatEvent;
|
|
308
|
+
expectedSeqRef.current = data.seq + 1;
|
|
309
|
+
reconnectAttemptRef.current = 0;
|
|
310
|
+
} catch {
|
|
311
|
+
// Ignore malformed heartbeats
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
es.onerror = () => {
|
|
316
|
+
console.warn('[OfficeStream] Connection error. Scheduling reconnect.');
|
|
317
|
+
scheduleReconnect();
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function scheduleReconnect() {
|
|
322
|
+
if (esRef.current) {
|
|
323
|
+
esRef.current.close();
|
|
324
|
+
esRef.current = null;
|
|
325
|
+
}
|
|
326
|
+
if (reconnectTimerRef.current) return; // Already scheduled
|
|
327
|
+
|
|
328
|
+
const attempt = reconnectAttemptRef.current++;
|
|
329
|
+
const delay = Math.min(RECONNECT_BASE_MS * Math.pow(2, attempt), RECONNECT_MAX_MS);
|
|
330
|
+
console.log(`[OfficeStream] Reconnecting in ${delay}ms (attempt ${attempt + 1})`);
|
|
331
|
+
|
|
332
|
+
reconnectTimerRef.current = setTimeout(() => {
|
|
333
|
+
reconnectTimerRef.current = null;
|
|
334
|
+
connect();
|
|
335
|
+
}, delay);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
connect();
|
|
339
|
+
|
|
340
|
+
return () => {
|
|
341
|
+
if (esRef.current) {
|
|
342
|
+
esRef.current.close();
|
|
343
|
+
esRef.current = null;
|
|
344
|
+
}
|
|
345
|
+
if (reconnectTimerRef.current) {
|
|
346
|
+
clearTimeout(reconnectTimerRef.current);
|
|
347
|
+
reconnectTimerRef.current = null;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}, [officeState, assetsReady, getNumericId]);
|
|
351
|
+
|
|
352
|
+
return { getBotNameByNumericId, getDisplayName };
|
|
353
|
+
}
|