@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/timeline-store.js
CHANGED
|
@@ -3,39 +3,409 @@
|
|
|
3
3
|
* Stores recent timeline entries for relay to Android/plugin clients.
|
|
4
4
|
* No scroll/grouping logic (that's client-side).
|
|
5
5
|
*/
|
|
6
|
-
import { deduplicateEntry } from '@agentdeck/shared';
|
|
6
|
+
import { deduplicateEntry, formatDurationSec, normalizeTimelineEntryForStorage } from '@agentdeck/shared';
|
|
7
|
+
import { readFileSync, writeFileSync, renameSync, mkdirSync, unlinkSync } from 'fs';
|
|
8
|
+
import { dirname } from 'path';
|
|
7
9
|
const MAX_ENTRIES = 200;
|
|
10
|
+
/** Separate retention cap for task hierarchy rows (task_start/task_end/
|
|
11
|
+
* task_milestone). Task rows are exempt from the generic FIFO shift —
|
|
12
|
+
* a long task's `task_start` must not scroll away while its turns stream
|
|
13
|
+
* in, or the eventual `task_end` renders as an unpaired orphan. ~30 pairs. */
|
|
14
|
+
const MAX_TASK_ENTRIES = 60;
|
|
15
|
+
/** Coalescing window for persistence writes. Timeline mutation is bursty (a
|
|
16
|
+
* single turn emits chat_start + several tool rows + chat_response + chat_end),
|
|
17
|
+
* so writing per mutation would amplify a turn into a dozen disk writes. */
|
|
18
|
+
const PERSIST_DEBOUNCE_MS = 500;
|
|
19
|
+
function isTaskRow(e) {
|
|
20
|
+
return e.type === 'task_start' || e.type === 'task_end' || e.type === 'task_milestone';
|
|
21
|
+
}
|
|
22
|
+
/** Chat/tool entry types that, in projection mode, come from the SessionSample
|
|
23
|
+
* projection instead of the adapters' direct emitters. Locally-emitted entries
|
|
24
|
+
* of these types are suppressed when projection mode is on so the timeline has
|
|
25
|
+
* exactly one source. Task hierarchy + error/scheduled rows are never affected. */
|
|
26
|
+
const PROJECTED_TYPES = new Set([
|
|
27
|
+
'chat_start', 'chat_response', 'chat_end', 'tool_request', 'tool_resolved', 'tool_exec',
|
|
28
|
+
]);
|
|
8
29
|
export class BridgeTimelineStore {
|
|
9
30
|
entries = [];
|
|
10
31
|
listeners = [];
|
|
11
|
-
|
|
12
|
-
|
|
32
|
+
attributor = null;
|
|
33
|
+
/** Set only by the daemon (see enablePersistence). Session bridges share this
|
|
34
|
+
* class but must never write: several can run at once and would clobber each
|
|
35
|
+
* other and the daemon's file. */
|
|
36
|
+
persistPath = null;
|
|
37
|
+
persistTimer = null;
|
|
38
|
+
dirty = false;
|
|
39
|
+
/** Phase 6 cutover (default OFF). When true, locally-emitted chat/tool rows
|
|
40
|
+
* are dropped — the SessionSample projection (added via `bypassSuppression`)
|
|
41
|
+
* becomes the single source. Relayed + projected entries bypass this. */
|
|
42
|
+
suppressLocalChatTool = false;
|
|
43
|
+
setSuppressLocalChatTool(v) {
|
|
44
|
+
this.suppressLocalChatTool = v;
|
|
45
|
+
}
|
|
46
|
+
/** Install (or replace) the attributor invoked on every addEntry / upsertEntry
|
|
47
|
+
* before dedup. Wired by `BridgeCore.wireTimeline` so the store and the
|
|
48
|
+
* live broadcast see identical, fully-attributed entries — critical for
|
|
49
|
+
* history replay (`timeline_history`). */
|
|
50
|
+
setAttributor(fn) {
|
|
51
|
+
this.attributor = fn;
|
|
52
|
+
}
|
|
53
|
+
addEntry(entry, opts) {
|
|
54
|
+
// Phase 6: in projection mode, drop locally-emitted chat/tool rows — they
|
|
55
|
+
// now come from the SessionSample projection (which bypasses) or are
|
|
56
|
+
// relayed from another bridge (which bypasses). No-op when mode is off.
|
|
57
|
+
if (this.suppressLocalChatTool && !opts?.bypassSuppression && PROJECTED_TYPES.has(entry.type)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const enriched = this.attributor ? this.attributor(entry) : entry;
|
|
61
|
+
const normalized = normalizeTimelineEntryForStorage(enriched);
|
|
62
|
+
if (!normalized)
|
|
63
|
+
return;
|
|
64
|
+
if (this.tryMergeTaskEndByTaskId(normalized)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const result = deduplicateEntry(normalized, this.entries);
|
|
13
68
|
if (result.action === 'skip')
|
|
14
69
|
return;
|
|
15
70
|
if (result.action === 'merge') {
|
|
71
|
+
// Merge path is an *update* — the existing entry was attributed at its
|
|
72
|
+
// own creation time and that attribution is the truth. Do NOT pull
|
|
73
|
+
// session/task/run/project from `enriched` (the attributor on this call
|
|
74
|
+
// reflects the *current* active task, which may have rotated since the
|
|
75
|
+
// original entry was stored). Use the raw caller `entry` so explicit
|
|
76
|
+
// caller-set fields still win, and otherwise keep `existing.*`.
|
|
16
77
|
const existing = this.entries[result.index];
|
|
17
78
|
existing.repeatCount = (existing.repeatCount || 1) + 1;
|
|
18
|
-
existing.ts =
|
|
79
|
+
existing.ts = normalized.ts;
|
|
80
|
+
existing.raw = normalized.raw;
|
|
81
|
+
existing.detail = normalized.detail ?? existing.detail;
|
|
82
|
+
existing.agentType = entry.agentType ?? existing.agentType;
|
|
83
|
+
existing.projectName = entry.projectName ?? existing.projectName;
|
|
84
|
+
existing.sessionId = entry.sessionId ?? existing.sessionId;
|
|
85
|
+
existing.runId = entry.runId ?? existing.runId;
|
|
86
|
+
existing.taskId = entry.taskId ?? existing.taskId;
|
|
87
|
+
existing.startedAt = normalized.startedAt ?? existing.startedAt;
|
|
88
|
+
existing.endedAt = normalized.endedAt ?? existing.endedAt;
|
|
89
|
+
existing.automated = normalized.automated ?? existing.automated;
|
|
90
|
+
existing.summaryKind = normalized.summaryKind ?? existing.summaryKind;
|
|
91
|
+
existing.boundarySignal = normalized.boundarySignal ?? existing.boundarySignal;
|
|
92
|
+
existing.taskScore = normalized.taskScore ?? existing.taskScore;
|
|
93
|
+
existing.taskOutcome = normalized.taskOutcome ?? existing.taskOutcome;
|
|
94
|
+
existing.taskCategory = normalized.taskCategory ?? existing.taskCategory;
|
|
95
|
+
existing.taskSummary = normalized.taskSummary ?? existing.taskSummary;
|
|
19
96
|
if (result.removeChatStartIndex != null) {
|
|
20
97
|
this.entries.splice(result.removeChatStartIndex, 1);
|
|
21
98
|
}
|
|
99
|
+
this.schedulePersist();
|
|
22
100
|
for (const cb of this.listeners)
|
|
23
101
|
cb(existing, true);
|
|
24
102
|
return;
|
|
25
103
|
}
|
|
26
|
-
// action === 'add'
|
|
104
|
+
// action === 'add' — fresh entry. Push the enriched form so storage and
|
|
105
|
+
// history replay carry attribution from the time of creation.
|
|
27
106
|
this.entries.push(result.entry);
|
|
28
107
|
if (this.entries.length > MAX_ENTRIES) {
|
|
29
|
-
this.
|
|
108
|
+
this.evictOne();
|
|
30
109
|
}
|
|
110
|
+
this.schedulePersist();
|
|
31
111
|
for (const cb of this.listeners)
|
|
32
112
|
cb(result.entry);
|
|
33
113
|
}
|
|
114
|
+
/** Evict a single entry to enforce MAX_ENTRIES, protecting task rows.
|
|
115
|
+
*
|
|
116
|
+
* Task rows only leave under their own cap (MAX_TASK_ENTRIES), and an
|
|
117
|
+
* in-flight task's `task_start` (no matching `task_end` yet) is never
|
|
118
|
+
* evicted — otherwise a long task's start scrolls away mid-task and the
|
|
119
|
+
* pair splits. Everything else FIFOs as before. */
|
|
120
|
+
evictOne() {
|
|
121
|
+
const taskRowCount = this.entries.reduce((n, e) => n + (isTaskRow(e) ? 1 : 0), 0);
|
|
122
|
+
if (taskRowCount > MAX_TASK_ENTRIES) {
|
|
123
|
+
const closed = new Set();
|
|
124
|
+
for (const e of this.entries) {
|
|
125
|
+
if (e.type === 'task_end' && e.taskId)
|
|
126
|
+
closed.add(e.taskId);
|
|
127
|
+
}
|
|
128
|
+
const idx = this.entries.findIndex((e) => isTaskRow(e) && !(e.type === 'task_start' && e.taskId && !closed.has(e.taskId)));
|
|
129
|
+
if (idx >= 0) {
|
|
130
|
+
this.entries.splice(idx, 1);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Shed the oldest `tool_exec` before any chat/turn row. Observed codex/
|
|
135
|
+
// opencode command rows carry real sessionIds + command detail, so they
|
|
136
|
+
// pass the anonymous-noise storage filter and accumulate — a live daemon
|
|
137
|
+
// snapshot ran 87% tool_exec (87/100). Undifferentiated FIFO would then
|
|
138
|
+
// evict a turn's `chat_start` (always the oldest ts in its turn) before its
|
|
139
|
+
// own tool_exec rows, leaving an orphaned chat_response/chat_end in the
|
|
140
|
+
// `timeline_history` replay a reconnecting client receives — the Node-side
|
|
141
|
+
// face of the "answer with no prompt" symptom. tool_exec is standalone
|
|
142
|
+
// (unlike the tool_request/tool_resolved approval pair, which must not be
|
|
143
|
+
// split), so shedding it first is safe and preserves the turn skeleton.
|
|
144
|
+
const toolIdx = this.entries.findIndex((e) => e.type === 'tool_exec');
|
|
145
|
+
if (toolIdx >= 0) {
|
|
146
|
+
this.entries.splice(toolIdx, 1);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const idx = this.entries.findIndex((e) => !isTaskRow(e));
|
|
150
|
+
if (idx >= 0) {
|
|
151
|
+
this.entries.splice(idx, 1);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Pathological: buffer is 100% task rows — fall back to plain FIFO so the
|
|
155
|
+
// buffer stays bounded.
|
|
156
|
+
this.entries.shift();
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Take ownership of on-disk persistence.
|
|
160
|
+
*
|
|
161
|
+
* The daemon is the timeline's source of truth — every surface's entries flow
|
|
162
|
+
* through it — so it is also the only process that may write the file. Call
|
|
163
|
+
* this once at daemon startup, AFTER `loadPersistedFile`, so the first write
|
|
164
|
+
* carries the rehydrated history rather than truncating it.
|
|
165
|
+
*
|
|
166
|
+
* Session bridges deliberately do not call this: they are per-session and
|
|
167
|
+
* short-lived, and concurrent writers would interleave partial histories.
|
|
168
|
+
*/
|
|
169
|
+
enablePersistence(path) {
|
|
170
|
+
this.persistPath = path;
|
|
171
|
+
}
|
|
172
|
+
/** Mark the buffer dirty and schedule a coalesced write. */
|
|
173
|
+
schedulePersist() {
|
|
174
|
+
if (!this.persistPath)
|
|
175
|
+
return;
|
|
176
|
+
this.dirty = true;
|
|
177
|
+
if (this.persistTimer)
|
|
178
|
+
return;
|
|
179
|
+
this.persistTimer = setTimeout(() => {
|
|
180
|
+
this.persistTimer = null;
|
|
181
|
+
this.flushPersist();
|
|
182
|
+
}, PERSIST_DEBOUNCE_MS);
|
|
183
|
+
this.persistTimer.unref?.();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Write the buffer to disk now. Safe to call when persistence is off or the
|
|
187
|
+
* buffer is clean — both are no-ops.
|
|
188
|
+
*
|
|
189
|
+
* Writes through a temp file + rename so a crash or a concurrent reader can
|
|
190
|
+
* never observe a half-written array: `loadPersistedFile` treats malformed
|
|
191
|
+
* JSON as "no history", so a torn write would silently erase the timeline.
|
|
192
|
+
*/
|
|
193
|
+
flushPersist() {
|
|
194
|
+
if (!this.persistPath || !this.dirty)
|
|
195
|
+
return;
|
|
196
|
+
this.dirty = false;
|
|
197
|
+
const target = this.persistPath;
|
|
198
|
+
const tmp = `${target}.tmp`;
|
|
199
|
+
try {
|
|
200
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
201
|
+
writeFileSync(tmp, JSON.stringify(this.entries), 'utf-8');
|
|
202
|
+
renameSync(tmp, target);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Disk full, permissions, read-only home — persistence is best-effort and
|
|
206
|
+
// must never take the daemon down with it.
|
|
207
|
+
try {
|
|
208
|
+
unlinkSync(tmp);
|
|
209
|
+
}
|
|
210
|
+
catch { /* nothing to clean up */ }
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** Stop the pending write timer, flushing anything outstanding first. */
|
|
214
|
+
stopPersistence() {
|
|
215
|
+
if (this.persistTimer) {
|
|
216
|
+
clearTimeout(this.persistTimer);
|
|
217
|
+
this.persistTimer = null;
|
|
218
|
+
}
|
|
219
|
+
this.flushPersist();
|
|
220
|
+
}
|
|
34
221
|
getHistory(since) {
|
|
35
|
-
|
|
36
|
-
|
|
222
|
+
const entries = since
|
|
223
|
+
? this.entries.filter((e) => e.ts > since)
|
|
224
|
+
: this.entries;
|
|
225
|
+
return [...entries].sort((a, b) => a.ts - b.ts);
|
|
226
|
+
}
|
|
227
|
+
/** Load persisted timeline rows into the bounded replay buffer without
|
|
228
|
+
* broadcasting them as live events. The Node daemon normally keeps the
|
|
229
|
+
* device timeline in memory, but macOS/previous daemon runs may leave a
|
|
230
|
+
* timeline.json behind. Rehydrating it lets reconnecting Android/tablet
|
|
231
|
+
* clients receive a non-empty initial `timeline_history`.
|
|
232
|
+
*/
|
|
233
|
+
loadPersistedFile(path) {
|
|
234
|
+
let parsed;
|
|
235
|
+
try {
|
|
236
|
+
parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return 0;
|
|
37
240
|
}
|
|
38
|
-
|
|
241
|
+
const rows = Array.isArray(parsed)
|
|
242
|
+
? parsed
|
|
243
|
+
: parsed && typeof parsed === 'object' && Array.isArray(parsed.entries)
|
|
244
|
+
? parsed.entries
|
|
245
|
+
: [];
|
|
246
|
+
const before = this.entries.length;
|
|
247
|
+
this.loadPersistedEntries(rows);
|
|
248
|
+
return Math.max(0, this.entries.length - before);
|
|
249
|
+
}
|
|
250
|
+
loadPersistedEntries(rows) {
|
|
251
|
+
const normalized = [];
|
|
252
|
+
for (const row of rows) {
|
|
253
|
+
if (!row || typeof row !== 'object')
|
|
254
|
+
continue;
|
|
255
|
+
const entry = row;
|
|
256
|
+
if (typeof entry.ts !== 'number' || typeof entry.type !== 'string' || typeof entry.raw !== 'string')
|
|
257
|
+
continue;
|
|
258
|
+
const clean = normalizeTimelineEntryForStorage(entry);
|
|
259
|
+
if (clean)
|
|
260
|
+
normalized.push(clean);
|
|
261
|
+
}
|
|
262
|
+
if (normalized.length === 0)
|
|
263
|
+
return;
|
|
264
|
+
const byKey = new Map();
|
|
265
|
+
for (const entry of [...this.entries, ...normalized].sort((a, b) => a.ts - b.ts)) {
|
|
266
|
+
byKey.set(`${entry.ts}:${entry.type}:${entry.raw}`, entry);
|
|
267
|
+
}
|
|
268
|
+
const merged = Array.from(byKey.values()).sort((a, b) => a.ts - b.ts);
|
|
269
|
+
// Trim with the same task-row protection as live eviction: task rows keep
|
|
270
|
+
// their own (deeper) retention so start/end pairs survive a reload even
|
|
271
|
+
// when chat/tool rows overflowed the generic cap.
|
|
272
|
+
const taskRows = merged.filter(isTaskRow).slice(-MAX_TASK_ENTRIES);
|
|
273
|
+
const rest = merged.filter((e) => !isTaskRow(e)).slice(-(MAX_ENTRIES - taskRows.length));
|
|
274
|
+
this.entries = [...taskRows, ...rest].sort((a, b) => a.ts - b.ts);
|
|
275
|
+
}
|
|
276
|
+
/** Node mirror of the Swift daemon's orphan reaper
|
|
277
|
+
* (DaemonServer.computeOrphanTaskEnds): synthesize a `task_end` for every
|
|
278
|
+
* `task_start` whose pair was never written. The producer only guarantees
|
|
279
|
+
* the pair within a single daemon lifetime (ApmeCollector.closeTask is
|
|
280
|
+
* in-memory), so a daemon killed mid-task leaves task_start rows that
|
|
281
|
+
* clients render as in-flight — spinning the task marker forever. Called
|
|
282
|
+
* once after `loadPersistedFile` at daemon startup. Idempotent: a real
|
|
283
|
+
* task_end arriving later merges over the synthetic via
|
|
284
|
+
* `tryMergeTaskEndByTaskId`. Returns the number of synthesized rows. */
|
|
285
|
+
reapOrphanTaskStarts() {
|
|
286
|
+
const closed = new Set();
|
|
287
|
+
for (const e of this.entries) {
|
|
288
|
+
if (e.type === 'task_end' && e.taskId)
|
|
289
|
+
closed.add(e.taskId);
|
|
290
|
+
}
|
|
291
|
+
let count = 0;
|
|
292
|
+
for (const start of [...this.entries]) {
|
|
293
|
+
if (start.type !== 'task_start' || !start.taskId || closed.has(start.taskId))
|
|
294
|
+
continue;
|
|
295
|
+
const startedAtMs = start.startedAt ?? start.ts;
|
|
296
|
+
// Anchor the synthetic end 1ms after the task's LAST known row so it
|
|
297
|
+
// sorts below the turns it closes. Anchoring at task_start+1 (the
|
|
298
|
+
// original behavior) rendered "TASK END" directly under its header,
|
|
299
|
+
// ABOVE every turn of the task — an empty-looking closed task with its
|
|
300
|
+
// rows dangling underneath. The last row's ts also gives an honest
|
|
301
|
+
// lower-bound duration ("Interrupted · ~55m"); "–" remains only when
|
|
302
|
+
// the task has no other rows at all.
|
|
303
|
+
let lastTs = startedAtMs;
|
|
304
|
+
for (const e of this.entries) {
|
|
305
|
+
if (e !== start && e.taskId === start.taskId && e.ts > lastTs)
|
|
306
|
+
lastTs = e.ts;
|
|
307
|
+
}
|
|
308
|
+
const approxSec = Math.round((lastTs - startedAtMs) / 1000);
|
|
309
|
+
this.addEntry({
|
|
310
|
+
ts: lastTs + 1,
|
|
311
|
+
type: 'task_end',
|
|
312
|
+
raw: approxSec > 0 ? `Interrupted · ~${formatDurationSec(approxSec)}` : 'Interrupted · –',
|
|
313
|
+
...(start.agentType ? { agentType: start.agentType } : {}),
|
|
314
|
+
...(start.projectName ? { projectName: start.projectName } : {}),
|
|
315
|
+
...(start.sessionId ? { sessionId: start.sessionId } : {}),
|
|
316
|
+
...(start.runId ? { runId: start.runId } : {}),
|
|
317
|
+
startedAt: startedAtMs,
|
|
318
|
+
...(approxSec > 0 ? { endedAt: lastTs } : {}),
|
|
319
|
+
taskId: start.taskId,
|
|
320
|
+
boundarySignal: 'interrupted',
|
|
321
|
+
}, { bypassSuppression: true });
|
|
322
|
+
closed.add(start.taskId);
|
|
323
|
+
count++;
|
|
324
|
+
}
|
|
325
|
+
return count;
|
|
326
|
+
}
|
|
327
|
+
/** Chat-turn counterpart of `reapOrphanTaskStarts`: close persisted
|
|
328
|
+
* `chat_start` rows whose completion (chat_response / chat_end) never
|
|
329
|
+
* arrived — a session killed mid-turn (no Stop, no SessionEnd — e.g. a
|
|
330
|
+
* /merge skill removing its own worktree+tmux window) leaves the prompt
|
|
331
|
+
* row spinning "in progress" forever on every dashboard.
|
|
332
|
+
*
|
|
333
|
+
* Two live-turn guards, because agentic turns regularly run past any
|
|
334
|
+
* fixed age threshold: only rows older than `staleMs` (default: the
|
|
335
|
+
* 30-minute interactive idle TTL) are considered, AND sessions in
|
|
336
|
+
* `skipSessionIds` — sessions that posted a hook since this daemon
|
|
337
|
+
* started, i.e. provably alive — are never touched. Callers should
|
|
338
|
+
* therefore run this DELAYED after startup, not immediately, so live
|
|
339
|
+
* sessions have had a chance to identify themselves. The synthetic
|
|
340
|
+
* close is anchored after the turn's last same-session row but strictly
|
|
341
|
+
* BEFORE the session's next chat_start — a completion row placed after
|
|
342
|
+
* a newer prompt would stop that newer (possibly live) turn's spinner
|
|
343
|
+
* too. */
|
|
344
|
+
reapOrphanChatStarts(staleMs = 30 * 60_000, now = Date.now(), skipSessionIds) {
|
|
345
|
+
let count = 0;
|
|
346
|
+
const sorted = [...this.entries].sort((a, b) => a.ts - b.ts);
|
|
347
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
348
|
+
const start = sorted[i];
|
|
349
|
+
if (start.type !== 'chat_start' || !start.sessionId)
|
|
350
|
+
continue;
|
|
351
|
+
if (skipSessionIds?.has(start.sessionId))
|
|
352
|
+
continue;
|
|
353
|
+
if (now - start.ts <= staleMs)
|
|
354
|
+
continue;
|
|
355
|
+
// Next chat_start of the same session bounds this turn.
|
|
356
|
+
let nextStartTs = Number.POSITIVE_INFINITY;
|
|
357
|
+
let completed = false;
|
|
358
|
+
let lastTurnTs = start.ts;
|
|
359
|
+
for (let j = i + 1; j < sorted.length; j++) {
|
|
360
|
+
const e = sorted[j];
|
|
361
|
+
if (e.sessionId !== start.sessionId)
|
|
362
|
+
continue;
|
|
363
|
+
if (e.type === 'chat_start') {
|
|
364
|
+
nextStartTs = e.ts;
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
if (e.type === 'chat_response' || e.type === 'chat_end') {
|
|
368
|
+
completed = true;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
if (e.ts > lastTurnTs)
|
|
372
|
+
lastTurnTs = e.ts;
|
|
373
|
+
}
|
|
374
|
+
if (completed)
|
|
375
|
+
continue;
|
|
376
|
+
const approxSec = Math.round((lastTurnTs - start.ts) / 1000);
|
|
377
|
+
this.addEntry({
|
|
378
|
+
ts: Math.min(lastTurnTs + 1, nextStartTs - 1),
|
|
379
|
+
type: 'chat_end',
|
|
380
|
+
raw: approxSec > 0 ? `Interrupted · ~${formatDurationSec(approxSec)}` : 'Interrupted · –',
|
|
381
|
+
summaryKind: 'none',
|
|
382
|
+
...(start.agentType ? { agentType: start.agentType } : {}),
|
|
383
|
+
...(start.projectName ? { projectName: start.projectName } : {}),
|
|
384
|
+
sessionId: start.sessionId,
|
|
385
|
+
...(start.runId ? { runId: start.runId } : {}),
|
|
386
|
+
...(start.taskId ? { taskId: start.taskId } : {}),
|
|
387
|
+
startedAt: start.startedAt ?? start.ts,
|
|
388
|
+
}, { bypassSuppression: true });
|
|
389
|
+
count++;
|
|
390
|
+
}
|
|
391
|
+
return count;
|
|
392
|
+
}
|
|
393
|
+
/** Recent entries attributed to one session, for the `query_session_timeline`
|
|
394
|
+
* poll — lets a device that connects mid-session fill its Detail view. */
|
|
395
|
+
getHistoryForSession(sessionId, since, limit = 16) {
|
|
396
|
+
// sessions_list ids for passively-observed sessions are prefixed
|
|
397
|
+
// ("observed:claude:<uuid>") while timeline entries are keyed by the raw uuid,
|
|
398
|
+
// so accept either form.
|
|
399
|
+
const raw = sessionId.replace(/^observed:(?:claude|codex|opencode|antigravity):/, '');
|
|
400
|
+
const matched = this.entries.filter((e) => (e.sessionId === sessionId || e.sessionId === raw) && (since == null || e.ts > since));
|
|
401
|
+
matched.sort((a, b) => a.ts - b.ts);
|
|
402
|
+
// `limit` applies to the chat/tool stream; task hierarchy rows ride along
|
|
403
|
+
// in full so a long task's start/end pair never splits at the per-session
|
|
404
|
+
// window (a task_start older than the last `limit` rows used to vanish,
|
|
405
|
+
// leaving the Detail view an unpaired task_end).
|
|
406
|
+
const taskRows = matched.filter(isTaskRow);
|
|
407
|
+
const rest = matched.filter((e) => !isTaskRow(e)).slice(-limit);
|
|
408
|
+
return [...taskRows, ...rest].sort((a, b) => a.ts - b.ts);
|
|
39
409
|
}
|
|
40
410
|
updateEntryStatus(approvalId, status) {
|
|
41
411
|
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
@@ -45,19 +415,60 @@ export class BridgeTimelineStore {
|
|
|
45
415
|
}
|
|
46
416
|
}
|
|
47
417
|
}
|
|
48
|
-
/** Update existing entry with same ts+type (1s tolerance), or add new
|
|
49
|
-
|
|
418
|
+
/** Update existing entry with same ts+type (1s tolerance), or add new.
|
|
419
|
+
*
|
|
420
|
+
* Update path: the existing entry's session/task/run/project attribution
|
|
421
|
+
* was set at *its* creation time and is authoritative. We do NOT re-run
|
|
422
|
+
* the attributor on update — by the time a late upsert lands (e.g. async
|
|
423
|
+
* LLM summary on a chat_end), the active task may have rotated, and
|
|
424
|
+
* re-attributing would silently move the entry to the wrong task. The
|
|
425
|
+
* raw caller `entry` only overrides existing fields when the caller
|
|
426
|
+
* explicitly set them.
|
|
427
|
+
*
|
|
428
|
+
* Insert path (no match): falls through to `addEntry`, which runs the
|
|
429
|
+
* attributor as usual to capture creation-time attribution. */
|
|
430
|
+
upsertEntry(entry, opts) {
|
|
431
|
+
// An upsert that finds no match falls through to addEntry; honor the same
|
|
432
|
+
// suppression bypass on that insert path (relayed task_end upserts, etc.).
|
|
433
|
+
const normalized = normalizeTimelineEntryForStorage(entry);
|
|
434
|
+
if (!normalized)
|
|
435
|
+
return;
|
|
436
|
+
if (this.tryMergeTaskEndByTaskId(normalized)) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
50
439
|
const tolerance = 1000;
|
|
51
440
|
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
52
441
|
const e = this.entries[i];
|
|
53
|
-
if (e.type ===
|
|
54
|
-
this.entries[i] = {
|
|
442
|
+
if (e.type === normalized.type && Math.abs(e.ts - normalized.ts) < tolerance) {
|
|
443
|
+
this.entries[i] = {
|
|
444
|
+
...e,
|
|
445
|
+
raw: normalized.raw,
|
|
446
|
+
...(normalized.detail ? { detail: normalized.detail } : {}),
|
|
447
|
+
...(normalized.agentType ? { agentType: normalized.agentType } : {}),
|
|
448
|
+
...(normalized.projectName ? { projectName: normalized.projectName } : {}),
|
|
449
|
+
...(normalized.sessionId ? { sessionId: normalized.sessionId } : {}),
|
|
450
|
+
...(normalized.runId ? { runId: normalized.runId } : {}),
|
|
451
|
+
...(normalized.taskId ? { taskId: normalized.taskId } : {}),
|
|
452
|
+
...(normalized.boundarySignal ? { boundarySignal: normalized.boundarySignal } : {}),
|
|
453
|
+
...(normalized.startedAt != null ? { startedAt: normalized.startedAt } : {}),
|
|
454
|
+
...(normalized.endedAt != null ? { endedAt: normalized.endedAt } : {}),
|
|
455
|
+
...(normalized.automated ? { automated: normalized.automated } : {}),
|
|
456
|
+
// summaryKind progresses heuristic/none → llm when the async LLM
|
|
457
|
+
// summary lands. Without this propagation, the dashboard never
|
|
458
|
+
// sees the kind upgrade and (for `summaryKind: 'none'` rows) the
|
|
459
|
+
// detail pane stays suppressed even after the LLM rescues it.
|
|
460
|
+
...(normalized.summaryKind ? { summaryKind: normalized.summaryKind } : {}),
|
|
461
|
+
...(normalized.taskScore != null ? { taskScore: normalized.taskScore } : {}),
|
|
462
|
+
...(normalized.taskOutcome ? { taskOutcome: normalized.taskOutcome } : {}),
|
|
463
|
+
...(normalized.taskCategory ? { taskCategory: normalized.taskCategory } : {}),
|
|
464
|
+
...(normalized.taskSummary ? { taskSummary: normalized.taskSummary } : {}),
|
|
465
|
+
};
|
|
55
466
|
for (const cb of this.listeners)
|
|
56
467
|
cb(this.entries[i], true);
|
|
57
468
|
return;
|
|
58
469
|
}
|
|
59
470
|
}
|
|
60
|
-
this.addEntry(
|
|
471
|
+
this.addEntry(normalized, opts);
|
|
61
472
|
}
|
|
62
473
|
/** Get the most recent entry of a given type */
|
|
63
474
|
getLastEntry(type) {
|
|
@@ -75,5 +486,40 @@ export class BridgeTimelineStore {
|
|
|
75
486
|
if (idx !== -1)
|
|
76
487
|
this.listeners.splice(idx, 1);
|
|
77
488
|
}
|
|
489
|
+
tryMergeTaskEndByTaskId(entry) {
|
|
490
|
+
if (entry.type !== 'task_end' || !entry.taskId)
|
|
491
|
+
return false;
|
|
492
|
+
let idx = -1;
|
|
493
|
+
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
494
|
+
const e = this.entries[i];
|
|
495
|
+
if (e.type === 'task_end' && e.taskId === entry.taskId) {
|
|
496
|
+
idx = i;
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (idx < 0)
|
|
501
|
+
return false;
|
|
502
|
+
const existing = this.entries[idx];
|
|
503
|
+
this.entries[idx] = {
|
|
504
|
+
...existing,
|
|
505
|
+
raw: entry.raw,
|
|
506
|
+
...(entry.detail ? { detail: entry.detail } : {}),
|
|
507
|
+
...(entry.agentType ? { agentType: entry.agentType } : {}),
|
|
508
|
+
...(entry.projectName ? { projectName: entry.projectName } : {}),
|
|
509
|
+
...(entry.sessionId ? { sessionId: entry.sessionId } : {}),
|
|
510
|
+
...(entry.runId ? { runId: entry.runId } : {}),
|
|
511
|
+
...(entry.startedAt != null ? { startedAt: entry.startedAt } : {}),
|
|
512
|
+
...(entry.endedAt != null ? { endedAt: entry.endedAt } : {}),
|
|
513
|
+
...(entry.boundarySignal ? { boundarySignal: entry.boundarySignal } : {}),
|
|
514
|
+
...(entry.summaryKind ? { summaryKind: entry.summaryKind } : {}),
|
|
515
|
+
...(entry.taskScore != null ? { taskScore: entry.taskScore } : {}),
|
|
516
|
+
...(entry.taskOutcome ? { taskOutcome: entry.taskOutcome } : {}),
|
|
517
|
+
...(entry.taskCategory ? { taskCategory: entry.taskCategory } : {}),
|
|
518
|
+
...(entry.taskSummary ? { taskSummary: entry.taskSummary } : {}),
|
|
519
|
+
};
|
|
520
|
+
for (const cb of this.listeners)
|
|
521
|
+
cb(this.entries[idx], true);
|
|
522
|
+
return true;
|
|
523
|
+
}
|
|
78
524
|
}
|
|
79
525
|
//# sourceMappingURL=timeline-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-store.js","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"timeline-store.js","sourceRoot":"","sources":["../src/timeline-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline-summarizer.d.ts","sourceRoot":"","sources":["../src/timeline-summarizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAiCrD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"timeline-summarizer.d.ts","sourceRoot":"","sources":["../src/timeline-summarizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAiCrD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoE5E"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Tries: local mlx-serve qwen (port 8800) → Ollama → heuristic fallback.
|
|
6
6
|
* Non-blocking — caller should fire-and-forget, update entry when ready.
|
|
7
7
|
*/
|
|
8
|
-
import { debug } from './logger.js';
|
|
8
|
+
import { debug, log } from './logger.js';
|
|
9
9
|
import { SUMMARY_SYSTEM_PROMPT, cleanLLMOutput, mlxChatUrl, resolveMlxModel } from '@agentdeck/shared';
|
|
10
10
|
import { fetchMlxModels } from './mlx-probe.js';
|
|
11
11
|
export { extractTopicHint } from '@agentdeck/shared';
|
|
@@ -47,19 +47,26 @@ export async function summarizeResponse(text) {
|
|
|
47
47
|
const input = text.length > MAX_INPUT_CHARS
|
|
48
48
|
? text.slice(0, MAX_INPUT_CHARS) + '...'
|
|
49
49
|
: text;
|
|
50
|
+
let mlxJustFailed = false;
|
|
51
|
+
let ollamaJustFailed = false;
|
|
50
52
|
// Try MLX qwen first (retry after RETRY_INTERVAL_MS)
|
|
51
53
|
if (mlxAvailable !== false || (Date.now() - mlxFailedAt > RETRY_INTERVAL_MS)) {
|
|
52
54
|
try {
|
|
53
55
|
const result = await callMLX(input);
|
|
54
56
|
if (result) {
|
|
57
|
+
if (mlxAvailable === false) {
|
|
58
|
+
// MLX recovered — note the transition.
|
|
59
|
+
debug('summarizer', 'MLX recovered');
|
|
60
|
+
}
|
|
55
61
|
mlxAvailable = true;
|
|
56
62
|
return result;
|
|
57
63
|
}
|
|
58
64
|
}
|
|
59
|
-
catch {
|
|
65
|
+
catch (err) {
|
|
66
|
+
mlxJustFailed = mlxAvailable !== false; // first time we observe failure
|
|
60
67
|
mlxAvailable = false;
|
|
61
68
|
mlxFailedAt = Date.now();
|
|
62
|
-
debug('summarizer',
|
|
69
|
+
debug('summarizer', `MLX not available: ${String(err)}`);
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
// Try Ollama (retry after RETRY_INTERVAL_MS)
|
|
@@ -67,16 +74,33 @@ export async function summarizeResponse(text) {
|
|
|
67
74
|
try {
|
|
68
75
|
const result = await callOllama(input);
|
|
69
76
|
if (result) {
|
|
77
|
+
if (ollamaAvailable === false) {
|
|
78
|
+
debug('summarizer', 'Ollama recovered');
|
|
79
|
+
}
|
|
70
80
|
ollamaAvailable = true;
|
|
71
81
|
return result;
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
|
-
catch {
|
|
84
|
+
catch (err) {
|
|
85
|
+
ollamaJustFailed = ollamaAvailable !== false;
|
|
75
86
|
ollamaAvailable = false;
|
|
76
87
|
ollamaFailedAt = Date.now();
|
|
77
|
-
debug('summarizer',
|
|
88
|
+
debug('summarizer', `Ollama not available: ${String(err)}`);
|
|
78
89
|
}
|
|
79
90
|
}
|
|
91
|
+
// Surface backend-down state to the user — but ONLY on the transition
|
|
92
|
+
// (first time we observe both providers failing) and via `log`, NOT
|
|
93
|
+
// `logError`. The summarizer is *optional* — when the user hasn't
|
|
94
|
+
// installed MLX/Ollama, the heuristic row is the intended UX. Routing
|
|
95
|
+
// through `log` means PTY mode (`agentdeck claude`) suppresses it
|
|
96
|
+
// entirely (the message would otherwise bleed into Claude's terminal
|
|
97
|
+
// session and read as a critical error). Daemon/CLI surfaces still see
|
|
98
|
+
// it in stderr as a regular `[agentdeck]` info line.
|
|
99
|
+
if ((mlxJustFailed && ollamaJustFailed)
|
|
100
|
+
|| (mlxJustFailed && ollamaAvailable === false)
|
|
101
|
+
|| (ollamaJustFailed && mlxAvailable === false)) {
|
|
102
|
+
log('[timeline] LLM summary backend offline (MLX:8800 / Ollama:11434).', 'Timeline rows will use heuristic summaries.', 'Install MLX (`mlx_vlm.server`) or Ollama to get LLM-summarized chat_end rows.');
|
|
103
|
+
}
|
|
80
104
|
return null;
|
|
81
105
|
}
|
|
82
106
|
// extractTopicHint and cleanLLMOutput moved to @agentdeck/shared/timeline-summarizer
|