@agentdeck/bridge 0.2.2 → 1.0.0
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/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/assets/fonts/IBMPlexSans-Bold.ttf +0 -0
- package/assets/fonts/IBMPlexSans-Regular.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
- package/assets/fonts/LICENSES.md +22 -0
- package/dist/adapters/claude-code.d.ts +6 -0
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +8 -0
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/openclaw.d.ts +24 -0
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +291 -35
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/adapters/opencode-adapter.d.ts +59 -0
- package/dist/adapters/opencode-adapter.d.ts.map +1 -1
- package/dist/adapters/opencode-adapter.js +297 -35
- package/dist/adapters/opencode-adapter.js.map +1 -1
- package/dist/adb-reverse.d.ts +1 -1
- package/dist/adb-reverse.js +1 -1
- package/dist/antigravity-local.d.ts +1 -0
- package/dist/antigravity-local.d.ts.map +1 -1
- package/dist/antigravity-local.js +33 -0
- package/dist/antigravity-local.js.map +1 -1
- package/dist/apme/adapters/claude-hook.d.ts.map +1 -1
- package/dist/apme/adapters/claude-hook.js +5 -0
- package/dist/apme/adapters/claude-hook.js.map +1 -1
- package/dist/apme/adapters/codex-hook.d.ts +17 -0
- package/dist/apme/adapters/codex-hook.d.ts.map +1 -0
- package/dist/apme/adapters/codex-hook.js +95 -0
- package/dist/apme/adapters/codex-hook.js.map +1 -0
- package/dist/apme/adapters/codex-turn-manager.d.ts +86 -0
- package/dist/apme/adapters/codex-turn-manager.d.ts.map +1 -0
- package/dist/apme/adapters/codex-turn-manager.js +496 -0
- package/dist/apme/adapters/codex-turn-manager.js.map +1 -0
- package/dist/apme/adapters/openclaw-hook.d.ts +99 -0
- package/dist/apme/adapters/openclaw-hook.d.ts.map +1 -0
- package/dist/apme/adapters/openclaw-hook.js +234 -0
- package/dist/apme/adapters/openclaw-hook.js.map +1 -0
- package/dist/apme/adapters/opencode-hook.d.ts +56 -0
- package/dist/apme/adapters/opencode-hook.d.ts.map +1 -0
- package/dist/apme/adapters/opencode-hook.js +182 -0
- package/dist/apme/adapters/opencode-hook.js.map +1 -0
- package/dist/apme/adapters/timeline.d.ts.map +1 -1
- package/dist/apme/adapters/timeline.js +6 -1
- package/dist/apme/adapters/timeline.js.map +1 -1
- package/dist/apme/antigravity-transcript.d.ts +18 -0
- package/dist/apme/antigravity-transcript.d.ts.map +1 -0
- package/dist/apme/antigravity-transcript.js +94 -0
- package/dist/apme/antigravity-transcript.js.map +1 -0
- package/dist/apme/classify-turn.d.ts +13 -0
- package/dist/apme/classify-turn.d.ts.map +1 -0
- package/dist/apme/classify-turn.js +49 -0
- package/dist/apme/classify-turn.js.map +1 -0
- package/dist/apme/claude-transcript-reader.d.ts +10 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
- package/dist/apme/claude-transcript-reader.js +35 -0
- package/dist/apme/claude-transcript-reader.js.map +1 -1
- package/dist/apme/collector.d.ts +133 -6
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +471 -23
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/dashboard-html.d.ts.map +1 -1
- package/dist/apme/dashboard-html.js +117 -11
- package/dist/apme/dashboard-html.js.map +1 -1
- package/dist/apme/http.d.ts.map +1 -1
- package/dist/apme/http.js +52 -6
- package/dist/apme/http.js.map +1 -1
- package/dist/apme/index.d.ts +26 -5
- package/dist/apme/index.d.ts.map +1 -1
- package/dist/apme/index.js +146 -9
- package/dist/apme/index.js.map +1 -1
- package/dist/apme/judge-detect.d.ts +26 -0
- package/dist/apme/judge-detect.d.ts.map +1 -0
- package/dist/apme/judge-detect.js +69 -0
- package/dist/apme/judge-detect.js.map +1 -0
- package/dist/apme/pareto.d.ts +39 -0
- package/dist/apme/pareto.d.ts.map +1 -0
- package/dist/apme/pareto.js +59 -0
- package/dist/apme/pareto.js.map +1 -0
- package/dist/apme/recommend.d.ts +3 -0
- package/dist/apme/recommend.d.ts.map +1 -1
- package/dist/apme/recommend.js +43 -1
- package/dist/apme/recommend.js.map +1 -1
- package/dist/apme/runner.d.ts +99 -4
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +743 -72
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/sample-to-timeline.d.ts +26 -0
- package/dist/apme/sample-to-timeline.d.ts.map +1 -0
- package/dist/apme/sample-to-timeline.js +95 -0
- package/dist/apme/sample-to-timeline.js.map +1 -0
- package/dist/apme/scorers/index.d.ts +47 -0
- package/dist/apme/scorers/index.d.ts.map +1 -0
- package/dist/apme/scorers/index.js +96 -0
- package/dist/apme/scorers/index.js.map +1 -0
- package/dist/apme/settings.d.ts +17 -11
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +30 -9
- package/dist/apme/settings.js.map +1 -1
- package/dist/apme/store.d.ts +33 -1
- package/dist/apme/store.d.ts.map +1 -1
- package/dist/apme/store.js +334 -25
- package/dist/apme/store.js.map +1 -1
- package/dist/awaiting-overlay.d.ts +112 -0
- package/dist/awaiting-overlay.d.ts.map +1 -0
- package/dist/awaiting-overlay.js +179 -0
- package/dist/awaiting-overlay.js.map +1 -0
- package/dist/ble-sync-spawn.d.ts +63 -0
- package/dist/ble-sync-spawn.d.ts.map +1 -0
- package/dist/ble-sync-spawn.js +196 -0
- package/dist/ble-sync-spawn.js.map +1 -0
- package/dist/bridge-core.d.ts +34 -1
- package/dist/bridge-core.d.ts.map +1 -1
- package/dist/bridge-core.js +207 -24
- package/dist/bridge-core.js.map +1 -1
- package/dist/broadcast.d.ts +3 -0
- package/dist/broadcast.d.ts.map +1 -0
- package/dist/broadcast.js +122 -0
- package/dist/broadcast.js.map +1 -0
- package/dist/check-deps.d.ts.map +1 -1
- package/dist/check-deps.js +25 -9
- package/dist/check-deps.js.map +1 -1
- package/dist/claude-permission-rules.d.ts +55 -0
- package/dist/claude-permission-rules.d.ts.map +1 -0
- package/dist/claude-permission-rules.js +197 -0
- package/dist/claude-permission-rules.js.map +1 -0
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1030 -93
- package/dist/cli.js.map +1 -1
- package/dist/codex-auth.d.ts +21 -0
- package/dist/codex-auth.d.ts.map +1 -1
- package/dist/codex-auth.js +52 -1
- package/dist/codex-auth.js.map +1 -1
- package/dist/codex-output-parser.d.ts +8 -0
- package/dist/codex-output-parser.d.ts.map +1 -1
- package/dist/codex-output-parser.js +110 -25
- package/dist/codex-output-parser.js.map +1 -1
- package/dist/codex-rate-limits.d.ts +16 -0
- package/dist/codex-rate-limits.d.ts.map +1 -0
- package/dist/codex-rate-limits.js +197 -0
- package/dist/codex-rate-limits.js.map +1 -0
- package/dist/codex-rollout-response.d.ts +31 -0
- package/dist/codex-rollout-response.d.ts.map +1 -0
- package/dist/codex-rollout-response.js +135 -0
- package/dist/codex-rollout-response.js.map +1 -0
- package/dist/d200h/image-renderer.d.ts +4 -16
- package/dist/d200h/image-renderer.d.ts.map +1 -1
- package/dist/d200h/image-renderer.js +46 -212
- package/dist/d200h/image-renderer.js.map +1 -1
- package/dist/daemon-server.d.ts +85 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +1975 -159
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon.js +15 -6
- package/dist/daemon.js.map +1 -1
- package/dist/display-dim.d.ts +9 -0
- package/dist/display-dim.d.ts.map +1 -0
- package/dist/display-dim.js +53 -0
- package/dist/display-dim.js.map +1 -0
- package/dist/display-monitor.d.ts +15 -2
- package/dist/display-monitor.d.ts.map +1 -1
- package/dist/display-monitor.js +104 -26
- package/dist/display-monitor.js.map +1 -1
- package/dist/esp32-serial.d.ts +190 -1
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +1090 -156
- package/dist/esp32-serial.js.map +1 -1
- package/dist/fallback-task-timeline.d.ts +42 -0
- package/dist/fallback-task-timeline.d.ts.map +1 -0
- package/dist/fallback-task-timeline.js +119 -0
- package/dist/fallback-task-timeline.js.map +1 -0
- package/dist/foundation-models-helper.d.ts +11 -0
- package/dist/foundation-models-helper.d.ts.map +1 -0
- package/dist/foundation-models-helper.js +241 -0
- package/dist/foundation-models-helper.js.map +1 -0
- package/dist/hook-migration.js +1 -1
- package/dist/hook-migration.js.map +1 -1
- package/dist/hook-server.d.ts +2 -3
- package/dist/hook-server.d.ts.map +1 -1
- package/dist/hook-server.js +23 -10
- package/dist/hook-server.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts +33 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.js +164 -0
- package/dist/idotmatrix/idotmatrix-daemon-sync.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts +18 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.js +85 -0
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts +20 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -0
- package/dist/idotmatrix/idotmatrix-settings.js +57 -0
- package/dist/idotmatrix/idotmatrix-settings.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +217 -179
- package/dist/index.js.map +1 -1
- package/dist/log-stream.d.ts +15 -16
- package/dist/log-stream.d.ts.map +1 -1
- package/dist/log-stream.js +18 -96
- package/dist/log-stream.js.map +1 -1
- package/dist/logger.d.ts +3 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +18 -5
- package/dist/logger.js.map +1 -1
- package/dist/mdns.d.ts +17 -0
- package/dist/mdns.d.ts.map +1 -1
- package/dist/mdns.js +52 -18
- package/dist/mdns.js.map +1 -1
- package/dist/model-catalog.d.ts +1 -1
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +2 -4
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.d.ts +1 -1
- package/dist/modules/adb-module.d.ts.map +1 -1
- package/dist/modules/adb-module.js +4 -3
- package/dist/modules/adb-module.js.map +1 -1
- package/dist/modules/broadcast-module.d.ts +17 -0
- package/dist/modules/broadcast-module.d.ts.map +1 -0
- package/dist/modules/broadcast-module.js +26 -0
- package/dist/modules/broadcast-module.js.map +1 -0
- package/dist/modules/d200h-module.d.ts +22 -0
- package/dist/modules/d200h-module.d.ts.map +1 -1
- package/dist/modules/d200h-module.js +200 -65
- package/dist/modules/d200h-module.js.map +1 -1
- package/dist/modules/idotmatrix-module.d.ts +9 -0
- package/dist/modules/idotmatrix-module.d.ts.map +1 -0
- package/dist/modules/idotmatrix-module.js +46 -0
- package/dist/modules/idotmatrix-module.js.map +1 -0
- package/dist/modules/index.d.ts +3 -1
- package/dist/modules/index.d.ts.map +1 -1
- package/dist/modules/index.js +9 -3
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/pixoo-module.d.ts.map +1 -1
- package/dist/modules/pixoo-module.js +14 -4
- package/dist/modules/pixoo-module.js.map +1 -1
- package/dist/modules/serial-module.d.ts +4 -0
- package/dist/modules/serial-module.d.ts.map +1 -1
- package/dist/modules/serial-module.js +14 -12
- package/dist/modules/serial-module.js.map +1 -1
- package/dist/modules/timebox-module.d.ts +9 -0
- package/dist/modules/timebox-module.d.ts.map +1 -0
- package/dist/modules/timebox-module.js +46 -0
- package/dist/modules/timebox-module.js.map +1 -0
- package/dist/modules/trmnl-module.d.ts +38 -0
- package/dist/modules/trmnl-module.d.ts.map +1 -0
- package/dist/modules/trmnl-module.js +111 -0
- package/dist/modules/trmnl-module.js.map +1 -0
- package/dist/modules/types.d.ts +4 -2
- package/dist/modules/types.d.ts.map +1 -1
- package/dist/observed-steering.d.ts +93 -0
- package/dist/observed-steering.d.ts.map +1 -0
- package/dist/observed-steering.js +247 -0
- package/dist/observed-steering.js.map +1 -0
- package/dist/openclaw-session.d.ts +18 -0
- package/dist/openclaw-session.d.ts.map +1 -0
- package/dist/openclaw-session.js +34 -0
- package/dist/openclaw-session.js.map +1 -0
- package/dist/opencode-steering.d.ts +36 -0
- package/dist/opencode-steering.d.ts.map +1 -0
- package/dist/opencode-steering.js +84 -0
- package/dist/opencode-steering.js.map +1 -0
- package/dist/output-parser.d.ts +30 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +172 -18
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +32 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +288 -49
- package/dist/passive-observer.js.map +1 -1
- package/dist/permission-resolver.d.ts +55 -0
- package/dist/permission-resolver.d.ts.map +1 -0
- package/dist/permission-resolver.js +112 -0
- package/dist/permission-resolver.js.map +1 -0
- package/dist/pixoo/micro-glyphs.d.ts +18 -0
- package/dist/pixoo/micro-glyphs.d.ts.map +1 -0
- package/dist/pixoo/micro-glyphs.js +143 -0
- package/dist/pixoo/micro-glyphs.js.map +1 -0
- package/dist/pixoo/official-dot-glyphs.generated.d.ts +8 -0
- package/dist/pixoo/official-dot-glyphs.generated.d.ts.map +1 -0
- package/dist/pixoo/official-dot-glyphs.generated.js +247 -0
- package/dist/pixoo/official-dot-glyphs.generated.js.map +1 -0
- package/dist/pixoo/pixoo-bridge.d.ts +16 -8
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
- package/dist/pixoo/pixoo-bridge.js +127 -35
- package/dist/pixoo/pixoo-bridge.js.map +1 -1
- package/dist/pixoo/pixoo-camera.d.ts +19 -3
- package/dist/pixoo/pixoo-camera.d.ts.map +1 -1
- package/dist/pixoo/pixoo-camera.js +62 -27
- package/dist/pixoo/pixoo-camera.js.map +1 -1
- package/dist/pixoo/pixoo-client.d.ts +13 -3
- package/dist/pixoo/pixoo-client.d.ts.map +1 -1
- package/dist/pixoo/pixoo-client.js +51 -22
- package/dist/pixoo/pixoo-client.js.map +1 -1
- package/dist/pixoo/pixoo-discover.d.ts +37 -0
- package/dist/pixoo/pixoo-discover.d.ts.map +1 -0
- package/dist/pixoo/pixoo-discover.js +105 -0
- package/dist/pixoo/pixoo-discover.js.map +1 -0
- package/dist/pixoo/pixoo-renderer.d.ts +27 -3
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
- package/dist/pixoo/pixoo-renderer.js +533 -135
- package/dist/pixoo/pixoo-renderer.js.map +1 -1
- package/dist/pixoo/pixoo-settings.d.ts +6 -0
- package/dist/pixoo/pixoo-settings.d.ts.map +1 -1
- package/dist/pixoo/pixoo-settings.js +9 -0
- package/dist/pixoo/pixoo-settings.js.map +1 -1
- package/dist/pixoo/pixoo-sprites.d.ts +84 -11
- package/dist/pixoo/pixoo-sprites.d.ts.map +1 -1
- package/dist/pixoo/pixoo-sprites.js +620 -209
- package/dist/pixoo/pixoo-sprites.js.map +1 -1
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +8 -2
- package/dist/pty-manager.js.map +1 -1
- package/dist/review-runner.d.ts +113 -0
- package/dist/review-runner.d.ts.map +1 -0
- package/dist/review-runner.js +428 -0
- package/dist/review-runner.js.map +1 -0
- package/dist/session-activity.d.ts +14 -0
- package/dist/session-activity.d.ts.map +1 -0
- package/dist/session-activity.js +160 -0
- package/dist/session-activity.js.map +1 -0
- package/dist/session-aggregator.d.ts +25 -0
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +48 -9
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-focus-relay.d.ts.map +1 -1
- package/dist/session-focus-relay.js +7 -1
- package/dist/session-focus-relay.js.map +1 -1
- package/dist/session-registry.d.ts +74 -3
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +140 -8
- package/dist/session-registry.js.map +1 -1
- package/dist/session-timeline-relay.d.ts.map +1 -1
- package/dist/session-timeline-relay.js +13 -4
- package/dist/session-timeline-relay.js.map +1 -1
- package/dist/session-transcript-timeline.d.ts +49 -0
- package/dist/session-transcript-timeline.d.ts.map +1 -0
- package/dist/session-transcript-timeline.js +276 -0
- package/dist/session-transcript-timeline.js.map +1 -0
- package/dist/state-machine.d.ts +6 -1
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +86 -28
- package/dist/state-machine.js.map +1 -1
- package/dist/timebox/timebox-daemon-sync.d.ts +19 -0
- package/dist/timebox/timebox-daemon-sync.d.ts.map +1 -0
- package/dist/timebox/timebox-daemon-sync.js +135 -0
- package/dist/timebox/timebox-daemon-sync.js.map +1 -0
- package/dist/timebox/timebox-discover.d.ts +19 -0
- package/dist/timebox/timebox-discover.d.ts.map +1 -0
- package/dist/timebox/timebox-discover.js +87 -0
- package/dist/timebox/timebox-discover.js.map +1 -0
- package/dist/timebox/timebox-settings.d.ts +32 -0
- package/dist/timebox/timebox-settings.d.ts.map +1 -0
- package/dist/timebox/timebox-settings.js +80 -0
- package/dist/timebox/timebox-settings.js.map +1 -0
- package/dist/timeline-store.d.ts +112 -3
- package/dist/timeline-store.d.ts.map +1 -1
- package/dist/timeline-store.js +460 -14
- package/dist/timeline-store.js.map +1 -1
- package/dist/timeline-summarizer.d.ts.map +1 -1
- package/dist/timeline-summarizer.js +29 -5
- package/dist/timeline-summarizer.js.map +1 -1
- package/dist/trmnl/byos-server.d.ts +39 -0
- package/dist/trmnl/byos-server.d.ts.map +1 -0
- package/dist/trmnl/byos-server.js +301 -0
- package/dist/trmnl/byos-server.js.map +1 -0
- package/dist/trmnl/frame-cache.d.ts +37 -0
- package/dist/trmnl/frame-cache.d.ts.map +1 -0
- package/dist/trmnl/frame-cache.js +157 -0
- package/dist/trmnl/frame-cache.js.map +1 -0
- package/dist/trmnl/image-renderer.d.ts +27 -0
- package/dist/trmnl/image-renderer.d.ts.map +1 -0
- package/dist/trmnl/image-renderer.js +235 -0
- package/dist/trmnl/image-renderer.js.map +1 -0
- package/dist/trmnl/trmnl-settings.d.ts +96 -0
- package/dist/trmnl/trmnl-settings.d.ts.map +1 -0
- package/dist/trmnl/trmnl-settings.js +177 -0
- package/dist/trmnl/trmnl-settings.js.map +1 -0
- package/dist/trmnl/trmnl-telemetry.d.ts +47 -0
- package/dist/trmnl/trmnl-telemetry.d.ts.map +1 -0
- package/dist/trmnl/trmnl-telemetry.js +56 -0
- package/dist/trmnl/trmnl-telemetry.js.map +1 -0
- package/dist/tui/ansi.d.ts +0 -4
- package/dist/tui/ansi.d.ts.map +1 -1
- package/dist/tui/ansi.js +14 -7
- package/dist/tui/ansi.js.map +1 -1
- package/dist/tui/dashboard.d.ts +1 -0
- package/dist/tui/dashboard.d.ts.map +1 -1
- package/dist/tui/dashboard.js +38 -11
- package/dist/tui/dashboard.js.map +1 -1
- package/dist/tui/renderer.d.ts +36 -0
- package/dist/tui/renderer.d.ts.map +1 -1
- package/dist/tui/renderer.js +355 -121
- package/dist/tui/renderer.js.map +1 -1
- package/dist/tui/terrarium.d.ts.map +1 -1
- package/dist/tui/terrarium.js +44 -51
- package/dist/tui/terrarium.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +7 -1
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +10 -3
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +98 -13
- package/dist/usage-event.js.map +1 -1
- package/dist/utility-proxy.d.ts.map +1 -1
- package/dist/utility-proxy.js +8 -0
- package/dist/utility-proxy.js.map +1 -1
- package/dist/utils/project-name.d.ts +3 -0
- package/dist/utils/project-name.d.ts.map +1 -1
- package/dist/utils/project-name.js +44 -2
- package/dist/utils/project-name.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +1 -17
- package/dist/version-check.js.map +1 -1
- package/dist/windows-service.d.ts +26 -0
- package/dist/windows-service.d.ts.map +1 -0
- package/dist/windows-service.js +145 -0
- package/dist/windows-service.js.map +1 -0
- package/dist/ws-server.d.ts +17 -3
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +78 -8
- package/dist/ws-server.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +112 -0
- package/package.json +10 -4
- package/scripts/build-fm-helper.mjs +26 -0
- package/LICENSE +0 -21
- package/dist/apme/tuner.d.ts +0 -64
- package/dist/apme/tuner.d.ts.map +0 -1
- package/dist/apme/tuner.js +0 -297
- package/dist/apme/tuner.js.map +0 -1
package/dist/tui/renderer.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { cursor, screen as screenCodes, RESET, colors, box, hLine, sgr, stateColor, stateIcon, truncText, padRight, visLen, terminalCaps, centerText, fg, } from './ansi.js';
|
|
11
11
|
import { blockGauge, resetTimeStr, formatTokens } from './gauge.js';
|
|
12
|
-
import { sortSessions, assignDisplayNames } from '@agentdeck/shared';
|
|
12
|
+
import { sortSessions, assignDisplayNames, timelineShouldRenderTaskRow, timelineTaskHeaderDisplay, } from '@agentdeck/shared';
|
|
13
13
|
// ===== Layout Breakpoints =====
|
|
14
14
|
export function getLayout(cols, rows) {
|
|
15
15
|
if (cols >= 120)
|
|
@@ -92,6 +92,11 @@ function typeIcon(type) {
|
|
|
92
92
|
case 'scheduled': return 's';
|
|
93
93
|
case 'user_action': return 'u';
|
|
94
94
|
case 'eval_result': return '#';
|
|
95
|
+
// Task hierarchy -- mirrors timelineIconKey() (shared/src/timeline-icons.ts):
|
|
96
|
+
// task_start/task_end -> task, task_milestone -> success.
|
|
97
|
+
case 'task_start':
|
|
98
|
+
case 'task_end': return '=';
|
|
99
|
+
case 'task_milestone': return '+';
|
|
95
100
|
default: return '*';
|
|
96
101
|
}
|
|
97
102
|
}
|
|
@@ -108,6 +113,10 @@ function typeIcon(type) {
|
|
|
108
113
|
case 'model_response': return '\u25C8';
|
|
109
114
|
case 'memory_recall': return '\u25CC';
|
|
110
115
|
case 'scheduled': return '\u25D1';
|
|
116
|
+
// Task hierarchy -- mirrors timelineIconKey() (shared/src/timeline-icons.ts).
|
|
117
|
+
case 'task_start':
|
|
118
|
+
case 'task_end': return '\u25A3'; // white square w/ centre
|
|
119
|
+
case 'task_milestone': return '\u2713'; // check mark
|
|
111
120
|
case 'eval_result': return '\u2605'; // ★
|
|
112
121
|
default: return '\u25C6';
|
|
113
122
|
}
|
|
@@ -140,20 +149,24 @@ function creatureEmoji(agentType) {
|
|
|
140
149
|
return 'D';
|
|
141
150
|
if (agentType === 'openclaw')
|
|
142
151
|
return 'C';
|
|
143
|
-
if (agentType === 'codex-cli')
|
|
152
|
+
if (agentType === 'codex-cli' || agentType === 'codex-app')
|
|
144
153
|
return 'X';
|
|
145
154
|
if (agentType === 'opencode')
|
|
146
155
|
return 'O';
|
|
156
|
+
if (agentType === 'antigravity')
|
|
157
|
+
return 'A';
|
|
147
158
|
return '*';
|
|
148
159
|
}
|
|
149
160
|
if (agentType === 'daemon')
|
|
150
161
|
return '\u2699\uFE0F'; // ⚙️
|
|
151
162
|
if (agentType === 'openclaw')
|
|
152
163
|
return '\uD83E\uDD9E'; // 🦞
|
|
153
|
-
if (agentType === 'codex-cli')
|
|
164
|
+
if (agentType === 'codex-cli' || agentType === 'codex-app')
|
|
154
165
|
return '\u2601'; // ☁ (cloud — matches creature)
|
|
155
166
|
if (agentType === 'opencode')
|
|
156
167
|
return '\u25A3'; // ▣ (nested square — matches creature)
|
|
168
|
+
if (agentType === 'antigravity')
|
|
169
|
+
return '\u25B2'; // ▲ (Antigravity peak)
|
|
157
170
|
return '\u273B'; // ✻ (teardrop-spoked asterisk — Claude sparkle)
|
|
158
171
|
}
|
|
159
172
|
function creatureBrandColor(agentType) {
|
|
@@ -162,8 +175,10 @@ function creatureBrandColor(agentType) {
|
|
|
162
175
|
switch (agentType) {
|
|
163
176
|
case 'claude-code': return fg(192, 112, 88); // terracotta
|
|
164
177
|
case 'openclaw': return fg(255, 77, 77); // red
|
|
165
|
-
case 'codex-cli':
|
|
178
|
+
case 'codex-cli':
|
|
179
|
+
case 'codex-app': return fg(177, 167, 255); // indigo
|
|
166
180
|
case 'opencode': return fg(241, 236, 236); // warm gray (#F1ECEC)
|
|
181
|
+
case 'antigravity': return fg(210, 214, 220); // Google gray
|
|
167
182
|
default: return '';
|
|
168
183
|
}
|
|
169
184
|
}
|
|
@@ -197,8 +212,129 @@ function sessionHotkeyLabel(index) {
|
|
|
197
212
|
return '·';
|
|
198
213
|
return String(index + 1);
|
|
199
214
|
}
|
|
200
|
-
|
|
201
|
-
|
|
215
|
+
/**
|
|
216
|
+
* Build the unified left-HUD entry list shared with macOS / iOS / Android.
|
|
217
|
+
*
|
|
218
|
+
* Collapses primary + siblings + virtual OpenClaw into one array, sorts via
|
|
219
|
+
* the shared sortSessions (agentType → projectName → startedAt → id), and
|
|
220
|
+
* applies #N suffix via assignDisplayNames so the display order and #N
|
|
221
|
+
* numbering match every other surface.
|
|
222
|
+
*
|
|
223
|
+
* Primary handling mirrors apple/AgentDeck/UI/Monitor/SessionListPanel.swift:
|
|
224
|
+
* - if a sibling matches our connected port, that sibling becomes the
|
|
225
|
+
* primary anchor (its startedAt anchors the sort position)
|
|
226
|
+
* - otherwise primary is appended only when no sibling shares its
|
|
227
|
+
* agentType (duplicatePrimaryWithoutId guard)
|
|
228
|
+
* - daemon / openclaw primaries are never appended (they're virtual)
|
|
229
|
+
*/
|
|
230
|
+
export function buildHudEntries(state) {
|
|
231
|
+
const items = [];
|
|
232
|
+
const portToItem = new Map();
|
|
233
|
+
for (const s of state.sessions) {
|
|
234
|
+
const ri = s;
|
|
235
|
+
const item = {
|
|
236
|
+
id: s.id,
|
|
237
|
+
projectName: s.projectName ?? 'unknown',
|
|
238
|
+
agentType: s.agentType ?? undefined,
|
|
239
|
+
state: s.state ?? 'idle',
|
|
240
|
+
modelName: s.modelName ?? undefined,
|
|
241
|
+
startedAt: s.startedAt ?? undefined,
|
|
242
|
+
port: s.port ?? undefined,
|
|
243
|
+
controlMode: ri.controlMode,
|
|
244
|
+
currentTask: ri.currentTask,
|
|
245
|
+
contextPercent: ri.contextPercent,
|
|
246
|
+
totalTokens: ri.totalTokens,
|
|
247
|
+
isPrimary: false,
|
|
248
|
+
isVirtualOpenClaw: false,
|
|
249
|
+
};
|
|
250
|
+
items.push(item);
|
|
251
|
+
if (item.port !== undefined)
|
|
252
|
+
portToItem.set(item.port, item);
|
|
253
|
+
}
|
|
254
|
+
if (state.agentType && state.agentType !== 'daemon' && state.agentType !== 'openclaw' && state.state) {
|
|
255
|
+
const anchor = state.currentPort != null ? portToItem.get(state.currentPort) : undefined;
|
|
256
|
+
if (anchor) {
|
|
257
|
+
// Patch anchor with primary's live fields. macOS / Android compose
|
|
258
|
+
// SessionEntry from primary state and only borrow the anchor sibling's
|
|
259
|
+
// startedAt; if we left the sibling's snapshot in place the row would
|
|
260
|
+
// render stale modelName / state / currentTask whenever the sibling
|
|
261
|
+
// payload lagged the primary state_update. startedAt, port, id, and
|
|
262
|
+
// controlMode stay with the anchor so sort position and hotkey
|
|
263
|
+
// identity match every other surface.
|
|
264
|
+
anchor.isPrimary = true;
|
|
265
|
+
anchor.projectName = state.projectName ?? anchor.projectName;
|
|
266
|
+
anchor.agentType = state.agentType;
|
|
267
|
+
anchor.state = state.state;
|
|
268
|
+
anchor.modelName = state.modelName ?? undefined;
|
|
269
|
+
anchor.currentTask = state.currentTool ?? undefined;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const duplicateAgentType = state.sessions.some(s => s.agentType === state.agentType);
|
|
273
|
+
if (!duplicateAgentType) {
|
|
274
|
+
items.push({
|
|
275
|
+
id: '__self__',
|
|
276
|
+
projectName: state.projectName ?? 'unknown',
|
|
277
|
+
agentType: state.agentType,
|
|
278
|
+
state: state.state,
|
|
279
|
+
modelName: state.modelName ?? undefined,
|
|
280
|
+
startedAt: undefined,
|
|
281
|
+
port: state.currentPort ?? undefined,
|
|
282
|
+
controlMode: undefined,
|
|
283
|
+
currentTask: state.currentTool ?? undefined,
|
|
284
|
+
contextPercent: undefined,
|
|
285
|
+
totalTokens: undefined,
|
|
286
|
+
isPrimary: true,
|
|
287
|
+
isVirtualOpenClaw: false,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const hasOpenClaw = items.some(it => it.agentType === 'openclaw' || it.agentType === 'gateway');
|
|
293
|
+
if (state.gatewayAvailable && !hasOpenClaw) {
|
|
294
|
+
items.push({
|
|
295
|
+
id: '__virtual_openclaw__',
|
|
296
|
+
projectName: 'OpenClaw',
|
|
297
|
+
agentType: 'openclaw',
|
|
298
|
+
state: state.crayfishRouting ? 'processing' : 'idle',
|
|
299
|
+
modelName: undefined,
|
|
300
|
+
startedAt: undefined,
|
|
301
|
+
port: undefined,
|
|
302
|
+
controlMode: undefined,
|
|
303
|
+
currentTask: undefined,
|
|
304
|
+
contextPercent: undefined,
|
|
305
|
+
totalTokens: undefined,
|
|
306
|
+
isPrimary: false,
|
|
307
|
+
isVirtualOpenClaw: true,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
const sorted = sortSessions(items);
|
|
311
|
+
const named = assignDisplayNames(sorted.map(it => ({
|
|
312
|
+
id: it.id,
|
|
313
|
+
projectName: it.projectName,
|
|
314
|
+
agentType: it.agentType,
|
|
315
|
+
state: it.state,
|
|
316
|
+
})));
|
|
317
|
+
return sorted.map((it, i) => ({
|
|
318
|
+
id: it.id,
|
|
319
|
+
displayName: named[i].displayName,
|
|
320
|
+
projectName: it.projectName,
|
|
321
|
+
agentType: it.agentType,
|
|
322
|
+
state: it.state,
|
|
323
|
+
modelName: it.modelName,
|
|
324
|
+
startedAt: it.startedAt,
|
|
325
|
+
port: it.port,
|
|
326
|
+
controlMode: it.controlMode,
|
|
327
|
+
currentTask: it.currentTask,
|
|
328
|
+
contextPercent: it.contextPercent,
|
|
329
|
+
totalTokens: it.totalTokens,
|
|
330
|
+
isPrimary: it.isPrimary,
|
|
331
|
+
isVirtualOpenClaw: it.isVirtualOpenClaw,
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
function hudHotkeyIndex(entry, nextIndex) {
|
|
335
|
+
if (entry.isPrimary || entry.isVirtualOpenClaw)
|
|
336
|
+
return null;
|
|
337
|
+
if (!entry.port || entry.controlMode === 'observed')
|
|
202
338
|
return null;
|
|
203
339
|
return nextIndex;
|
|
204
340
|
}
|
|
@@ -214,6 +350,125 @@ function observedDetailParts(session) {
|
|
|
214
350
|
parts.push(session.currentTask);
|
|
215
351
|
return parts;
|
|
216
352
|
}
|
|
353
|
+
function asRecord(value) {
|
|
354
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
355
|
+
? value
|
|
356
|
+
: undefined;
|
|
357
|
+
}
|
|
358
|
+
function asArray(value) {
|
|
359
|
+
return Array.isArray(value) ? value : [];
|
|
360
|
+
}
|
|
361
|
+
function asNumber(value) {
|
|
362
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
363
|
+
}
|
|
364
|
+
function moduleStatusIcon(ok, warning = false) {
|
|
365
|
+
if (!terminalCaps.unicode)
|
|
366
|
+
return ok ? 'o' : warning ? '!' : 'x';
|
|
367
|
+
return ok ? '\u25CF' : warning ? '\u25C6' : '\u25CB';
|
|
368
|
+
}
|
|
369
|
+
function renderModuleHealthLines(moduleHealth, width) {
|
|
370
|
+
const lines = [];
|
|
371
|
+
if (!moduleHealth)
|
|
372
|
+
return lines;
|
|
373
|
+
const push = (label, detail, ok, warning = false) => {
|
|
374
|
+
const color = ok ? colors.idle : warning ? colors.awaiting : colors.dim;
|
|
375
|
+
lines.push(` ${color}${moduleStatusIcon(ok, warning)}${RESET} ${truncText(`${label} ${detail}`.trim(), width - 4)}`);
|
|
376
|
+
};
|
|
377
|
+
const serial = asRecord(moduleHealth.serial);
|
|
378
|
+
if (serial) {
|
|
379
|
+
const connections = asArray(serial.connections).map(asRecord).filter(Boolean);
|
|
380
|
+
const connected = connections.filter((c) => c.connected === true || c.transportOpen === true);
|
|
381
|
+
const boards = connected
|
|
382
|
+
.map((c) => asRecord(c.deviceInfo)?.board)
|
|
383
|
+
.filter((b) => typeof b === 'string' && b.length > 0);
|
|
384
|
+
const count = asNumber(serial.connectionCount) ?? connected.length;
|
|
385
|
+
const shown = boards.slice(0, 3).join(', ');
|
|
386
|
+
const more = boards.length > 3 ? ` +${boards.length - 3}` : '';
|
|
387
|
+
const detail = count > 0 ? `${count}${shown ? `: ${shown}${more}` : ''}` : 'none';
|
|
388
|
+
push('Serial', detail, count > 0, Boolean(serial.lastError));
|
|
389
|
+
}
|
|
390
|
+
const pixoo = asRecord(moduleHealth.pixoo);
|
|
391
|
+
if (pixoo) {
|
|
392
|
+
const devices = asArray(pixoo.devices).map(asRecord).filter(Boolean);
|
|
393
|
+
const configured = asNumber(pixoo.configuredDeviceCount) ?? devices.length;
|
|
394
|
+
const online = devices.filter((d) => d.online === true && d.backedOff !== true).length;
|
|
395
|
+
const dimmed = pixoo.displayDimmed === true ? ' dim' : '';
|
|
396
|
+
push('Pixoo', `${online}/${configured}${dimmed}`, configured > 0 && online > 0, configured > 0);
|
|
397
|
+
}
|
|
398
|
+
// BLE matrix panels — Divoom Timebox Mini + iDotMatrix. The Swift daemon
|
|
399
|
+
// reports a live `connected`/`statusReason`; the Node daemon only knows a
|
|
400
|
+
// panel is configured (the Python BLE sync subprocess owns the link), so a
|
|
401
|
+
// configured-but-state-unknown panel reads as amber "cfg" rather than a red
|
|
402
|
+
// offline, which would be a false negative for a working Node-driven panel.
|
|
403
|
+
for (const [key, label] of [['timebox', 'Timebox'], ['idotmatrix', 'iDotMatrix']]) {
|
|
404
|
+
const m = asRecord(moduleHealth[key]);
|
|
405
|
+
if (!m)
|
|
406
|
+
continue;
|
|
407
|
+
const configured = asNumber(m.configuredDeviceCount) ?? asArray(m.devices).length;
|
|
408
|
+
if (configured <= 0)
|
|
409
|
+
continue;
|
|
410
|
+
const connected = m.connected === true;
|
|
411
|
+
const dimmed = m.displayDimmed === true ? ' dim' : '';
|
|
412
|
+
const reason = typeof m.statusReason === 'string' ? m.statusReason : '';
|
|
413
|
+
const detail = connected ? `ready${dimmed}` : (reason || `${configured} cfg`);
|
|
414
|
+
push(label, detail, connected, !connected);
|
|
415
|
+
}
|
|
416
|
+
// The daemon only emits d200h while the Ulanzi Studio plugin is connected —
|
|
417
|
+
// an absent key means no D200H row at all, not an offline one.
|
|
418
|
+
const d200h = asRecord(moduleHealth.d200h);
|
|
419
|
+
if (d200h) {
|
|
420
|
+
const connected = d200h.connected === true;
|
|
421
|
+
push('D200H', connected ? 'ready plugin' : 'offline', connected);
|
|
422
|
+
}
|
|
423
|
+
const adb = asRecord(moduleHealth.adb);
|
|
424
|
+
if (adb) {
|
|
425
|
+
const devices = asArray(adb.devices);
|
|
426
|
+
const reverse = asNumber(adb.reverseReadyCount) ?? devices.length;
|
|
427
|
+
const available = adb.available === true;
|
|
428
|
+
push('ADB', available ? `${reverse} reverse` : 'missing', available && reverse > 0, available);
|
|
429
|
+
}
|
|
430
|
+
// Stream Deck plugin roster — the plugin registers over WS; the daemon
|
|
431
|
+
// reports one row per attached deck. Mirrors the macOS TopologyRail /
|
|
432
|
+
// menubar Stream Deck section (Node-tier row added in bf23fb8e).
|
|
433
|
+
const streamDeck = asRecord(moduleHealth.streamDeck);
|
|
434
|
+
if (streamDeck) {
|
|
435
|
+
const devices = asArray(streamDeck.devices).map(asRecord).filter(Boolean);
|
|
436
|
+
for (const dev of devices) {
|
|
437
|
+
const name = typeof dev.name === 'string' && dev.name.length > 0 ? dev.name : 'Stream Deck';
|
|
438
|
+
const cols = asNumber(dev.columns);
|
|
439
|
+
const rows = asNumber(dev.rows);
|
|
440
|
+
const detail = cols && rows ? `${cols}×${rows}` : '';
|
|
441
|
+
push(name, detail, true);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
// WiFi-only ESP32 boards. Dual-homed boards (also live on USB serial) are
|
|
445
|
+
// already shown in the Serial row, so filter them out here via the
|
|
446
|
+
// per-board `serialActive` flag — mirrors TopologyRail.wifiOnlyEsp32Boards.
|
|
447
|
+
const esp32Wifi = asRecord(moduleHealth.esp32Wifi);
|
|
448
|
+
if (esp32Wifi) {
|
|
449
|
+
const devices = asArray(esp32Wifi.devices).map(asRecord).filter(Boolean);
|
|
450
|
+
const wifiOnly = devices.filter((d) => d.serialActive !== true);
|
|
451
|
+
for (const dev of wifiOnly) {
|
|
452
|
+
const board = typeof dev.board === 'string' && dev.board.length > 0 ? dev.board : 'esp32';
|
|
453
|
+
const ip = typeof dev.ip === 'string' ? dev.ip : '';
|
|
454
|
+
const stale = dev.stale === true;
|
|
455
|
+
const detail = [ip, 'WiFi', stale ? 'stale' : ''].filter(Boolean).join(' · ');
|
|
456
|
+
push(`Wi-Fi ESP32 ${board}`, detail, !stale, stale);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// Terminal dashboards (`agentdeck dashboard`) attached to the daemon —
|
|
460
|
+
// presence-only roster, one row per open TUI WS. Mirrors the macOS
|
|
461
|
+
// TopologyRail "Terminal · TUI Dashboard" section.
|
|
462
|
+
const tuiDashboards = asRecord(moduleHealth.tuiDashboards);
|
|
463
|
+
if (tuiDashboards) {
|
|
464
|
+
const devices = asArray(tuiDashboards.devices).map(asRecord).filter(Boolean);
|
|
465
|
+
for (const dev of devices) {
|
|
466
|
+
const host = typeof dev.name === 'string' ? dev.name : '';
|
|
467
|
+
push('TUI Dashboard', host, true);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return lines;
|
|
471
|
+
}
|
|
217
472
|
// ===== Panel Renderers =====
|
|
218
473
|
function renderAgentLines(state, maxWidth, useLogo) {
|
|
219
474
|
const lines = [];
|
|
@@ -241,68 +496,33 @@ function renderAgentLines(state, maxWidth, useLogo) {
|
|
|
241
496
|
lines.push(` ${hotkey} ${emoji} ${col}${name}${RESET}`);
|
|
242
497
|
lines.push(`${colors.dim} ${truncText(secondary, maxWidth - 4)}${RESET}`);
|
|
243
498
|
};
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
currentTask:
|
|
257
|
-
contextPercent:
|
|
258
|
-
totalTokens:
|
|
259
|
-
})
|
|
260
|
-
let focusableIndex = 0;
|
|
261
|
-
for (const d of displayed) {
|
|
262
|
-
const hotkeyIndex = sessionHotkeyIndex(d.session, focusableIndex);
|
|
263
|
-
if (hotkeyIndex !== null)
|
|
264
|
-
focusableIndex += 1;
|
|
265
|
-
renderSession(d.displayName, d.session.modelName, d.session.state || 'idle', d.session.agentType, hotkeyIndex, d.session);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else if (state.state) {
|
|
269
|
-
// Self (primary session)
|
|
270
|
-
renderSession(state.projectName || 'unknown', state.modelName ?? undefined, state.state, state.agentType ?? undefined, null);
|
|
271
|
-
// Siblings — include self as virtual entry for correct #N numbering
|
|
272
|
-
const sorted = sortSessions(state.sessions);
|
|
273
|
-
const selfEntry = {
|
|
274
|
-
id: '__self__', projectName: state.projectName || 'unknown',
|
|
275
|
-
agentType: state.agentType ?? undefined, state: state.state,
|
|
276
|
-
};
|
|
277
|
-
const allForNumbering = [selfEntry, ...sorted.map(s => ({
|
|
278
|
-
id: s.id, projectName: s.projectName || 'unknown', agentType: s.agentType, state: s.state,
|
|
279
|
-
modelName: s.modelName,
|
|
280
|
-
port: s.port, controlMode: s.controlMode,
|
|
281
|
-
currentTask: s.currentTask,
|
|
282
|
-
contextPercent: s.contextPercent,
|
|
283
|
-
totalTokens: s.totalTokens,
|
|
284
|
-
}))];
|
|
285
|
-
const displayed = assignDisplayNames(allForNumbering);
|
|
286
|
-
// Skip the self entry (index 0), render siblings with hotkey indices
|
|
287
|
-
let focusableIndex = 0;
|
|
288
|
-
for (let i = 1; i < displayed.length; i++) {
|
|
289
|
-
const d = displayed[i];
|
|
290
|
-
const sessionInfo = d.session;
|
|
291
|
-
const hotkeyIndex = sessionHotkeyIndex(sessionInfo, focusableIndex);
|
|
292
|
-
if (hotkeyIndex !== null)
|
|
293
|
-
focusableIndex += 1;
|
|
294
|
-
renderSession(d.displayName, d.session.modelName, d.session.state || 'idle', d.session.agentType, hotkeyIndex, sessionInfo);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// Virtual OpenClaw entry when gateway detected but not in sessions list
|
|
298
|
-
const hasOcSession = state.sessions.some(s => s.agentType === 'openclaw' || s.agentType === 'gateway');
|
|
299
|
-
if (state.gatewayAvailable && !hasOcSession) {
|
|
300
|
-
renderSession('OpenClaw', undefined, state.crayfishRouting ? 'processing' : 'idle', 'openclaw', null);
|
|
499
|
+
// Unified entry list (primary + siblings + virtual OpenClaw). Order and #N
|
|
500
|
+
// suffix matches macOS / iOS / Android via the shared sortSessions +
|
|
501
|
+
// assignDisplayNames pipeline inside buildHudEntries.
|
|
502
|
+
const entries = buildHudEntries(state);
|
|
503
|
+
let focusableIndex = 0;
|
|
504
|
+
for (const e of entries) {
|
|
505
|
+
const hotkeyIndex = hudHotkeyIndex(e, focusableIndex);
|
|
506
|
+
if (hotkeyIndex !== null)
|
|
507
|
+
focusableIndex += 1;
|
|
508
|
+
renderSession(e.displayName, e.modelName, e.state, e.agentType, hotkeyIndex, {
|
|
509
|
+
port: e.port,
|
|
510
|
+
controlMode: e.controlMode,
|
|
511
|
+
currentTask: e.currentTask,
|
|
512
|
+
contextPercent: e.contextPercent,
|
|
513
|
+
totalTokens: e.totalTokens,
|
|
514
|
+
});
|
|
301
515
|
}
|
|
302
516
|
// Gateway error warning
|
|
303
517
|
if (state.gatewayHasError) {
|
|
304
518
|
lines.push(`${colors.error} \u26A0 Gateway Error${RESET}`);
|
|
305
519
|
}
|
|
520
|
+
const moduleLines = renderModuleHealthLines(state.moduleHealth, maxWidth);
|
|
521
|
+
if (moduleLines.length > 0) {
|
|
522
|
+
lines.push('');
|
|
523
|
+
lines.push(`${colors.header} DOWNSTREAM${RESET}`);
|
|
524
|
+
lines.push(...moduleLines);
|
|
525
|
+
}
|
|
306
526
|
// Voice assistant indicator
|
|
307
527
|
if (state.voiceAssistantState && state.voiceAssistantState !== 'disabled' && state.voiceAssistantState !== 'idle') {
|
|
308
528
|
lines.push('');
|
|
@@ -391,9 +611,9 @@ function renderStatusLines(state, width) {
|
|
|
391
611
|
}
|
|
392
612
|
function renderOauthCatalogLines(modelCatalog, oauthConnected, width) {
|
|
393
613
|
const lines = [];
|
|
394
|
-
const models = modelCatalog.filter((m) => m.available).map((m) => m.name);
|
|
614
|
+
const models = (modelCatalog ?? []).filter((m) => m.available).map((m) => m.name);
|
|
395
615
|
if (models.length > 0) {
|
|
396
|
-
return wrapCommaList(' OAuth: ', models, width);
|
|
616
|
+
return wrapCommaList(' OAuth: ', models, width, 4);
|
|
397
617
|
}
|
|
398
618
|
if (oauthConnected === true) {
|
|
399
619
|
lines.push(`${colors.dim}${truncText(' OAuth: connected', width)}${RESET}`);
|
|
@@ -403,22 +623,38 @@ function renderOauthCatalogLines(modelCatalog, oauthConnected, width) {
|
|
|
403
623
|
}
|
|
404
624
|
return lines;
|
|
405
625
|
}
|
|
406
|
-
function wrapCommaList(prefix, items, width) {
|
|
626
|
+
function wrapCommaList(prefix, items, width, maxLines = Number.POSITIVE_INFINITY) {
|
|
407
627
|
const lines = [];
|
|
408
628
|
const indent = ' '.repeat(prefix.length);
|
|
409
629
|
let current = prefix;
|
|
630
|
+
let consumed = 0;
|
|
410
631
|
for (let i = 0; i < items.length; i++) {
|
|
411
632
|
const chunk = i === 0 ? items[i] : `, ${items[i]}`;
|
|
412
633
|
if (visLen(current) + visLen(chunk) <= width) {
|
|
413
634
|
current += chunk;
|
|
635
|
+
consumed = i + 1;
|
|
414
636
|
continue;
|
|
415
637
|
}
|
|
416
638
|
if (visLen(current) > visLen(prefix)) {
|
|
417
639
|
lines.push(`${colors.dim}${padRight(current, width)}${RESET}`.trimEnd());
|
|
640
|
+
if (lines.length >= maxLines) {
|
|
641
|
+
const hidden = items.length - consumed;
|
|
642
|
+
if (hidden > 0)
|
|
643
|
+
lines.push(`${colors.dim}${truncText(` ${hidden} more models`, width)}${RESET}`);
|
|
644
|
+
return lines;
|
|
645
|
+
}
|
|
418
646
|
current = indent + items[i];
|
|
647
|
+
consumed = i + 1;
|
|
419
648
|
continue;
|
|
420
649
|
}
|
|
421
650
|
lines.push(`${colors.dim}${truncText(current + chunk, width)}${RESET}`);
|
|
651
|
+
consumed = i + 1;
|
|
652
|
+
if (lines.length >= maxLines) {
|
|
653
|
+
const hidden = items.length - consumed;
|
|
654
|
+
if (hidden > 0)
|
|
655
|
+
lines.push(`${colors.dim}${truncText(` ${hidden} more models`, width)}${RESET}`);
|
|
656
|
+
return lines;
|
|
657
|
+
}
|
|
422
658
|
current = indent;
|
|
423
659
|
}
|
|
424
660
|
if (visLen(current.trim()) > 0) {
|
|
@@ -440,7 +676,11 @@ function renderOllamaSummaryLines(ollamaStatus, width) {
|
|
|
440
676
|
}
|
|
441
677
|
function renderTimelineLines(state, width, maxLines, scrollOffset) {
|
|
442
678
|
const lines = [];
|
|
443
|
-
|
|
679
|
+
// One-row-per-task render contract (shared/src/timeline-task-display.ts):
|
|
680
|
+
// task_end rows are data-only closure records — the task_start header folds
|
|
681
|
+
// in the closure label + judge verdict instead. Bare "Task N" headers with
|
|
682
|
+
// no eval payload (including every interrupted reaper closure) drop out.
|
|
683
|
+
const entries = state.timeline.filter((e) => timelineShouldRenderTaskRow(e, state.timeline));
|
|
444
684
|
if (entries.length === 0) {
|
|
445
685
|
lines.push(`${colors.dim} No events yet${RESET}`);
|
|
446
686
|
return lines;
|
|
@@ -451,12 +691,39 @@ function renderTimelineLines(state, width, maxLines, scrollOffset) {
|
|
|
451
691
|
const e = entries[i];
|
|
452
692
|
const time = new Date(e.ts);
|
|
453
693
|
const timeStr = `${String(time.getHours()).padStart(2, '0')}:${String(time.getMinutes()).padStart(2, '0')}`;
|
|
454
|
-
|
|
694
|
+
// Task headers render their folded closure: judge summary as title when
|
|
695
|
+
// the own title is a bare "Task N", the closure label ("Session end ·
|
|
696
|
+
// 2 turns · 6m") as a chip, and the score+outcome suffix once the judge
|
|
697
|
+
// resolves (5–30 s after the boundary itself).
|
|
698
|
+
let text = e.raw;
|
|
699
|
+
let evalSuffix = '';
|
|
700
|
+
if (e.type === 'task_start') {
|
|
701
|
+
const d = timelineTaskHeaderDisplay(e, state.timeline);
|
|
702
|
+
text = d.closureText ? `${d.title} · ${d.closureText}` : d.title;
|
|
703
|
+
if (d.taskOutcome)
|
|
704
|
+
evalSuffix = formatTaskEvalSuffix(d.taskScore, d.taskOutcome);
|
|
705
|
+
}
|
|
706
|
+
const raw = truncText(`${text}${evalSuffix}`, width - 10);
|
|
455
707
|
const pending = e.status === 'pending' ? `${colors.dim} [PENDING]${RESET}` : '';
|
|
456
708
|
lines.push(` ${colors.dim}${timeStr}${RESET} ${typeColor(e.type)}${typeIcon(e.type)}${RESET} ${raw}${pending}`);
|
|
457
709
|
}
|
|
458
710
|
return lines;
|
|
459
711
|
}
|
|
712
|
+
export function formatTaskEvalSuffix(score, outcome) {
|
|
713
|
+
// `abandoned` flows from the manual `agentdeck task cancel` path and
|
|
714
|
+
// must render as its own glyph — not fall through to '' (which would
|
|
715
|
+
// make the task look pending) and not borrow the fail glyph (which
|
|
716
|
+
// would read as agent failure rather than user-initiated stop).
|
|
717
|
+
const glyph = outcome === 'success' ? '✓'
|
|
718
|
+
: outcome === 'fail' ? '✗'
|
|
719
|
+
: outcome === 'partial' ? '△'
|
|
720
|
+
: outcome === 'abandoned' ? '⊘'
|
|
721
|
+
: '';
|
|
722
|
+
if (!glyph)
|
|
723
|
+
return '';
|
|
724
|
+
const scoreText = typeof score === 'number' ? score.toFixed(2) : '?';
|
|
725
|
+
return ` · ${scoreText} ${glyph}`;
|
|
726
|
+
}
|
|
460
727
|
function timelineHeader(state, width, maxLines, scrollOffset) {
|
|
461
728
|
const total = state.timeline.length;
|
|
462
729
|
if (total === 0)
|
|
@@ -649,64 +916,31 @@ function renderStandardLayout(state, cols, rows, terrariumLines, frame, scrollOf
|
|
|
649
916
|
}
|
|
650
917
|
function renderAgentCompactLines(state, width) {
|
|
651
918
|
const lines = [];
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
if (hotkeyIndex !== null)
|
|
668
|
-
focusableIndex += 1;
|
|
669
|
-
lines.push(` ${colors.dim}[${sessionHotkeyLabel(hotkeyIndex)}]${RESET} ${emoji} ${project} ${status}${marker}${model}`);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
else if (state.state) {
|
|
673
|
-
// Self first
|
|
674
|
-
const col = stateColor(state.state);
|
|
675
|
-
const proj = truncText(state.projectName || '?', Math.max(8, width - 16));
|
|
676
|
-
const status = `${col}${stateIcon(state.state)} ${compactStateLabel(state.state)}${RESET}`;
|
|
677
|
-
const model = state.modelName ? `${colors.dim} · ${truncText(state.modelName, Math.max(8, width - 24))}${RESET}` : '';
|
|
678
|
-
const emoji = `${creatureBrandColor(state.agentType ?? undefined)}${creatureEmoji(state.agentType ?? undefined)}${RESET}`;
|
|
679
|
-
lines.push(` ${emoji} ${proj} ${status}${model}`);
|
|
680
|
-
// Siblings
|
|
681
|
-
let focusableIndex = 0;
|
|
682
|
-
for (const s of sortSessions(state.sessions)) {
|
|
683
|
-
const renderInfo = s;
|
|
684
|
-
const st = s.state || 'idle';
|
|
685
|
-
const sCol = stateColor(st);
|
|
686
|
-
const sEmoji = `${creatureBrandColor(s.agentType)}${creatureEmoji(s.agentType)}${RESET}`;
|
|
687
|
-
const sStatus = `${sCol}${stateIcon(st)} ${compactStateLabel(st)}${RESET}`;
|
|
688
|
-
const detail = renderInfo.currentTask || s.modelName;
|
|
689
|
-
const sModel = detail ? `${colors.dim} · ${truncText(detail, Math.max(8, width - 24))}${RESET}` : '';
|
|
690
|
-
const marker = renderInfo.controlMode === 'observed' ? `${colors.dim} · obs${RESET}` : '';
|
|
691
|
-
const sProject = truncText(s.projectName || '?', Math.max(8, width - 20));
|
|
692
|
-
const hotkeyIndex = sessionHotkeyIndex(renderInfo, focusableIndex);
|
|
693
|
-
if (hotkeyIndex !== null)
|
|
694
|
-
focusableIndex += 1;
|
|
695
|
-
lines.push(` ${colors.dim}[${sessionHotkeyLabel(hotkeyIndex)}]${RESET} ${sEmoji} ${sProject} ${sStatus}${marker}${sModel}`);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
// Virtual OpenClaw entry
|
|
699
|
-
const hasOcCompact = state.sessions.some(s => s.agentType === 'openclaw' || s.agentType === 'gateway');
|
|
700
|
-
if (state.gatewayAvailable && !hasOcCompact) {
|
|
701
|
-
const ocState = state.crayfishRouting ? 'processing' : 'idle';
|
|
702
|
-
const ocCol = stateColor(ocState);
|
|
703
|
-
const ocEmoji = `${creatureBrandColor('openclaw')}${creatureEmoji('openclaw')}${RESET}`;
|
|
704
|
-
lines.push(` ${ocEmoji} OpenClaw ${ocCol}${stateIcon(ocState)}${ocState.toUpperCase()}${RESET}`);
|
|
919
|
+
// Unified entry list — same ordering and #N suffix as macOS / iOS / Android.
|
|
920
|
+
const entries = buildHudEntries(state);
|
|
921
|
+
let focusableIndex = 0;
|
|
922
|
+
for (const e of entries) {
|
|
923
|
+
const hotkeyIndex = hudHotkeyIndex(e, focusableIndex);
|
|
924
|
+
if (hotkeyIndex !== null)
|
|
925
|
+
focusableIndex += 1;
|
|
926
|
+
const col = stateColor(e.state);
|
|
927
|
+
const emoji = `${creatureBrandColor(e.agentType)}${creatureEmoji(e.agentType)}${RESET}`;
|
|
928
|
+
const status = `${col}${stateIcon(e.state)} ${compactStateLabel(e.state)}${RESET}`;
|
|
929
|
+
const detail = e.currentTask || e.modelName;
|
|
930
|
+
const model = detail ? `${colors.dim} · ${truncText(detail, Math.max(8, width - 24))}${RESET}` : '';
|
|
931
|
+
const marker = e.controlMode === 'observed' ? `${colors.dim} · obs${RESET}` : '';
|
|
932
|
+
const project = truncText(e.displayName, Math.max(8, width - 20));
|
|
933
|
+
lines.push(` ${colors.dim}[${sessionHotkeyLabel(hotkeyIndex)}]${RESET} ${emoji} ${project} ${status}${marker}${model}`);
|
|
705
934
|
}
|
|
706
935
|
// Gateway error warning
|
|
707
936
|
if (state.gatewayHasError) {
|
|
708
937
|
lines.push(`${colors.error} \u26A0 Gateway Error${RESET}`);
|
|
709
938
|
}
|
|
939
|
+
const moduleLines = renderModuleHealthLines(state.moduleHealth, width);
|
|
940
|
+
if (moduleLines.length > 0) {
|
|
941
|
+
lines.push(`${colors.header} DOWNSTREAM${RESET}`);
|
|
942
|
+
lines.push(...moduleLines);
|
|
943
|
+
}
|
|
710
944
|
// Voice assistant indicator (compact)
|
|
711
945
|
if (state.voiceAssistantState && state.voiceAssistantState !== 'disabled' && state.voiceAssistantState !== 'idle') {
|
|
712
946
|
if (state.voiceAssistantState === 'listening') {
|