@openrig/cli 0.1.11 → 0.2.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/daemon/assets/openrig-activity-hook-relay.cjs +104 -0
- package/daemon/dist/adapters/claude-code-adapter.d.ts +14 -6
- package/daemon/dist/adapters/claude-code-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-code-adapter.js +192 -60
- package/daemon/dist/adapters/claude-code-adapter.js.map +1 -1
- package/daemon/dist/adapters/claude-resume.d.ts +5 -0
- package/daemon/dist/adapters/claude-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/claude-resume.js +15 -2
- package/daemon/dist/adapters/claude-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-resume.d.ts +8 -1
- package/daemon/dist/adapters/codex-resume.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-resume.js +74 -5
- package/daemon/dist/adapters/codex-resume.js.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts +11 -6
- package/daemon/dist/adapters/codex-runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/codex-runtime-adapter.js +322 -34
- package/daemon/dist/adapters/codex-runtime-adapter.js.map +1 -1
- package/daemon/dist/adapters/terminal-adapter.d.ts +2 -1
- package/daemon/dist/adapters/terminal-adapter.d.ts.map +1 -1
- package/daemon/dist/adapters/terminal-adapter.js +7 -1
- package/daemon/dist/adapters/terminal-adapter.js.map +1 -1
- package/daemon/dist/adapters/tmux.d.ts.map +1 -1
- package/daemon/dist/adapters/tmux.js +53 -5
- package/daemon/dist/adapters/tmux.js.map +1 -1
- package/daemon/dist/db/migrations/021_seat_handover_observability.d.ts +3 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.d.ts.map +1 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.js +11 -0
- package/daemon/dist/db/migrations/021_seat_handover_observability.js.map +1 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.d.ts +3 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.d.ts.map +1 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.js +7 -0
- package/daemon/dist/db/migrations/022_node_codex_config_profile.js.map +1 -0
- package/daemon/dist/db/migrations/023_stream_items.d.ts +16 -0
- package/daemon/dist/db/migrations/023_stream_items.d.ts.map +1 -0
- package/daemon/dist/db/migrations/023_stream_items.js +37 -0
- package/daemon/dist/db/migrations/023_stream_items.js.map +1 -0
- package/daemon/dist/db/migrations/024_queue_items.d.ts +19 -0
- package/daemon/dist/db/migrations/024_queue_items.d.ts.map +1 -0
- package/daemon/dist/db/migrations/024_queue_items.js +52 -0
- package/daemon/dist/db/migrations/024_queue_items.js.map +1 -0
- package/daemon/dist/db/migrations/025_queue_transitions.d.ts +13 -0
- package/daemon/dist/db/migrations/025_queue_transitions.d.ts.map +1 -0
- package/daemon/dist/db/migrations/025_queue_transitions.js +28 -0
- package/daemon/dist/db/migrations/025_queue_transitions.js.map +1 -0
- package/daemon/dist/db/migrations/026_inbox_entries.d.ts +14 -0
- package/daemon/dist/db/migrations/026_inbox_entries.d.ts.map +1 -0
- package/daemon/dist/db/migrations/026_inbox_entries.js +35 -0
- package/daemon/dist/db/migrations/026_inbox_entries.js.map +1 -0
- package/daemon/dist/db/migrations/027_outbox_entries.d.ts +12 -0
- package/daemon/dist/db/migrations/027_outbox_entries.d.ts.map +1 -0
- package/daemon/dist/db/migrations/027_outbox_entries.js +30 -0
- package/daemon/dist/db/migrations/027_outbox_entries.js.map +1 -0
- package/daemon/dist/db/migrations/028_project_classifications.d.ts +26 -0
- package/daemon/dist/db/migrations/028_project_classifications.d.ts.map +1 -0
- package/daemon/dist/db/migrations/028_project_classifications.js +44 -0
- package/daemon/dist/db/migrations/028_project_classifications.js.map +1 -0
- package/daemon/dist/db/migrations/029_classifier_leases.d.ts +22 -0
- package/daemon/dist/db/migrations/029_classifier_leases.d.ts.map +1 -0
- package/daemon/dist/db/migrations/029_classifier_leases.js +41 -0
- package/daemon/dist/db/migrations/029_classifier_leases.js.map +1 -0
- package/daemon/dist/db/migrations/030_views_custom.d.ts +15 -0
- package/daemon/dist/db/migrations/030_views_custom.d.ts.map +1 -0
- package/daemon/dist/db/migrations/030_views_custom.js +27 -0
- package/daemon/dist/db/migrations/030_views_custom.js.map +1 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.d.ts +34 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.d.ts.map +1 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.js +59 -0
- package/daemon/dist/db/migrations/031_watchdog_jobs.js.map +1 -0
- package/daemon/dist/db/migrations/032_watchdog_history.d.ts +28 -0
- package/daemon/dist/db/migrations/032_watchdog_history.d.ts.map +1 -0
- package/daemon/dist/db/migrations/032_watchdog_history.js +46 -0
- package/daemon/dist/db/migrations/032_watchdog_history.js.map +1 -0
- package/daemon/dist/db/migrations/033_workflow_specs.d.ts +30 -0
- package/daemon/dist/db/migrations/033_workflow_specs.d.ts.map +1 -0
- package/daemon/dist/db/migrations/033_workflow_specs.js +50 -0
- package/daemon/dist/db/migrations/033_workflow_specs.js.map +1 -0
- package/daemon/dist/db/migrations/034_workflow_instances.d.ts +42 -0
- package/daemon/dist/db/migrations/034_workflow_instances.d.ts.map +1 -0
- package/daemon/dist/db/migrations/034_workflow_instances.js +63 -0
- package/daemon/dist/db/migrations/034_workflow_instances.js.map +1 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.d.ts +29 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.d.ts.map +1 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.js +48 -0
- package/daemon/dist/db/migrations/035_workflow_step_trails.js.map +1 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.d.ts +35 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.d.ts.map +1 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.js +43 -0
- package/daemon/dist/db/migrations/036_watchdog_policy_enum_extension.js.map +1 -0
- package/daemon/dist/domain/agent-activity-store.d.ts +42 -0
- package/daemon/dist/domain/agent-activity-store.d.ts.map +1 -0
- package/daemon/dist/domain/agent-activity-store.js +177 -0
- package/daemon/dist/domain/agent-activity-store.js.map +1 -0
- package/daemon/dist/domain/agent-manifest.d.ts.map +1 -1
- package/daemon/dist/domain/agent-manifest.js +3 -0
- package/daemon/dist/domain/agent-manifest.js.map +1 -1
- package/daemon/dist/domain/agent-starter-resolver.d.ts +100 -0
- package/daemon/dist/domain/agent-starter-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/agent-starter-resolver.js +200 -0
- package/daemon/dist/domain/agent-starter-resolver.js.map +1 -0
- package/daemon/dist/domain/classifier-lease-manager.d.ts +130 -0
- package/daemon/dist/domain/classifier-lease-manager.d.ts.map +1 -0
- package/daemon/dist/domain/classifier-lease-manager.js +285 -0
- package/daemon/dist/domain/classifier-lease-manager.js.map +1 -0
- package/daemon/dist/domain/codex-thread-id.d.ts.map +1 -1
- package/daemon/dist/domain/codex-thread-id.js +44 -15
- package/daemon/dist/domain/codex-thread-id.js.map +1 -1
- package/daemon/dist/domain/context-monitor.d.ts +12 -7
- package/daemon/dist/domain/context-monitor.d.ts.map +1 -1
- package/daemon/dist/domain/context-monitor.js +51 -3
- package/daemon/dist/domain/context-monitor.js.map +1 -1
- package/daemon/dist/domain/context-usage-store.d.ts +1 -1
- package/daemon/dist/domain/context-usage-store.js +1 -1
- package/daemon/dist/domain/context-usage-store.js.map +1 -1
- package/daemon/dist/domain/hot-potato-enforcer.d.ts +45 -0
- package/daemon/dist/domain/hot-potato-enforcer.d.ts.map +1 -0
- package/daemon/dist/domain/hot-potato-enforcer.js +94 -0
- package/daemon/dist/domain/hot-potato-enforcer.js.map +1 -0
- package/daemon/dist/domain/inbox-handler.d.ts +68 -0
- package/daemon/dist/domain/inbox-handler.d.ts.map +1 -0
- package/daemon/dist/domain/inbox-handler.js +177 -0
- package/daemon/dist/domain/inbox-handler.js.map +1 -0
- package/daemon/dist/domain/native-resume-probe.d.ts +1 -1
- package/daemon/dist/domain/native-resume-probe.d.ts.map +1 -1
- package/daemon/dist/domain/native-resume-probe.js +89 -4
- package/daemon/dist/domain/native-resume-probe.js.map +1 -1
- package/daemon/dist/domain/node-inventory.d.ts +29 -1
- package/daemon/dist/domain/node-inventory.d.ts.map +1 -1
- package/daemon/dist/domain/node-inventory.js +208 -31
- package/daemon/dist/domain/node-inventory.js.map +1 -1
- package/daemon/dist/domain/node-launcher.d.ts +2 -0
- package/daemon/dist/domain/node-launcher.d.ts.map +1 -1
- package/daemon/dist/domain/node-launcher.js +14 -2
- package/daemon/dist/domain/node-launcher.js.map +1 -1
- package/daemon/dist/domain/outbox-handler.d.ts +48 -0
- package/daemon/dist/domain/outbox-handler.d.ts.map +1 -0
- package/daemon/dist/domain/outbox-handler.js +106 -0
- package/daemon/dist/domain/outbox-handler.js.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.d.ts +64 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.d.ts.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.js +226 -0
- package/daemon/dist/domain/policies/artifact-pool-helpers.js.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.d.ts +3 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.d.ts.map +1 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.js +41 -0
- package/daemon/dist/domain/policies/artifact-pool-ready.js.map +1 -0
- package/daemon/dist/domain/policies/edge-artifact-required.d.ts +3 -0
- package/daemon/dist/domain/policies/edge-artifact-required.d.ts.map +1 -0
- package/daemon/dist/domain/policies/edge-artifact-required.js +90 -0
- package/daemon/dist/domain/policies/edge-artifact-required.js.map +1 -0
- package/daemon/dist/domain/policies/periodic-reminder.d.ts +3 -0
- package/daemon/dist/domain/policies/periodic-reminder.d.ts.map +1 -0
- package/daemon/dist/domain/policies/periodic-reminder.js +30 -0
- package/daemon/dist/domain/policies/periodic-reminder.js.map +1 -0
- package/daemon/dist/domain/policies/types.d.ts +51 -0
- package/daemon/dist/domain/policies/types.d.ts.map +1 -0
- package/daemon/dist/domain/policies/types.js +9 -0
- package/daemon/dist/domain/policies/types.js.map +1 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts +7 -0
- package/daemon/dist/domain/policies/workflow-keepalive.d.ts.map +1 -0
- package/daemon/dist/domain/policies/workflow-keepalive.js +123 -0
- package/daemon/dist/domain/policies/workflow-keepalive.js.map +1 -0
- package/daemon/dist/domain/project-classifier.d.ts +75 -0
- package/daemon/dist/domain/project-classifier.d.ts.map +1 -0
- package/daemon/dist/domain/project-classifier.js +132 -0
- package/daemon/dist/domain/project-classifier.js.map +1 -0
- package/daemon/dist/domain/projection-planner.d.ts +1 -0
- package/daemon/dist/domain/projection-planner.d.ts.map +1 -1
- package/daemon/dist/domain/projection-planner.js +3 -0
- package/daemon/dist/domain/projection-planner.js.map +1 -1
- package/daemon/dist/domain/ps-projection.d.ts +31 -0
- package/daemon/dist/domain/ps-projection.d.ts.map +1 -1
- package/daemon/dist/domain/ps-projection.js +38 -0
- package/daemon/dist/domain/ps-projection.js.map +1 -1
- package/daemon/dist/domain/queue-repository.d.ts +322 -0
- package/daemon/dist/domain/queue-repository.d.ts.map +1 -0
- package/daemon/dist/domain/queue-repository.js +686 -0
- package/daemon/dist/domain/queue-repository.js.map +1 -0
- package/daemon/dist/domain/queue-transition-log.d.ts +38 -0
- package/daemon/dist/domain/queue-transition-log.d.ts.map +1 -0
- package/daemon/dist/domain/queue-transition-log.js +52 -0
- package/daemon/dist/domain/queue-transition-log.js.map +1 -0
- package/daemon/dist/domain/restore-check-service.d.ts +203 -0
- package/daemon/dist/domain/restore-check-service.d.ts.map +1 -0
- package/daemon/dist/domain/restore-check-service.js +1047 -0
- package/daemon/dist/domain/restore-check-service.js.map +1 -0
- package/daemon/dist/domain/restore-orchestrator.d.ts +50 -2
- package/daemon/dist/domain/restore-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/restore-orchestrator.js +476 -24
- package/daemon/dist/domain/restore-orchestrator.js.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.d.ts.map +1 -1
- package/daemon/dist/domain/resume-metadata-refresher.js +27 -7
- package/daemon/dist/domain/resume-metadata-refresher.js.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-expansion-service.js +13 -0
- package/daemon/dist/domain/rig-expansion-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +17 -1
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +63 -5
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-codec.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-codec.js +13 -0
- package/daemon/dist/domain/rigspec-codec.js.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.js +2 -0
- package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +63 -1
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/rigspec-schema.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-schema.js +196 -0
- package/daemon/dist/domain/rigspec-schema.js.map +1 -1
- package/daemon/dist/domain/runtime-adapter.d.ts +30 -1
- package/daemon/dist/domain/runtime-adapter.d.ts.map +1 -1
- package/daemon/dist/domain/runtime-adapter.js +14 -0
- package/daemon/dist/domain/runtime-adapter.js.map +1 -1
- package/daemon/dist/domain/seat-handover-planner.d.ts +84 -0
- package/daemon/dist/domain/seat-handover-planner.d.ts.map +1 -0
- package/daemon/dist/domain/seat-handover-planner.js +188 -0
- package/daemon/dist/domain/seat-handover-planner.js.map +1 -0
- package/daemon/dist/domain/seat-handover-service.d.ts +104 -0
- package/daemon/dist/domain/seat-handover-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-handover-service.js +343 -0
- package/daemon/dist/domain/seat-handover-service.js.map +1 -0
- package/daemon/dist/domain/seat-status-service.d.ts +50 -0
- package/daemon/dist/domain/seat-status-service.d.ts.map +1 -0
- package/daemon/dist/domain/seat-status-service.js +66 -0
- package/daemon/dist/domain/seat-status-service.js.map +1 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.d.ts +53 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.d.ts.map +1 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.js +59 -0
- package/daemon/dist/domain/session-source-rebuild-resolver.js.map +1 -0
- package/daemon/dist/domain/session-transport.d.ts +30 -0
- package/daemon/dist/domain/session-transport.d.ts.map +1 -1
- package/daemon/dist/domain/session-transport.js +322 -12
- package/daemon/dist/domain/session-transport.js.map +1 -1
- package/daemon/dist/domain/snapshot-repository.d.ts +18 -0
- package/daemon/dist/domain/snapshot-repository.d.ts.map +1 -1
- package/daemon/dist/domain/snapshot-repository.js +77 -0
- package/daemon/dist/domain/snapshot-repository.js.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.d.ts +27 -3
- package/daemon/dist/domain/startup-orchestrator.d.ts.map +1 -1
- package/daemon/dist/domain/startup-orchestrator.js +125 -40
- package/daemon/dist/domain/startup-orchestrator.js.map +1 -1
- package/daemon/dist/domain/stream-store.d.ts +56 -0
- package/daemon/dist/domain/stream-store.d.ts.map +1 -0
- package/daemon/dist/domain/stream-store.js +108 -0
- package/daemon/dist/domain/stream-store.js.map +1 -0
- package/daemon/dist/domain/transcript-redaction.d.ts +13 -0
- package/daemon/dist/domain/transcript-redaction.d.ts.map +1 -0
- package/daemon/dist/domain/transcript-redaction.js +34 -0
- package/daemon/dist/domain/transcript-redaction.js.map +1 -0
- package/daemon/dist/domain/transcript-store.d.ts +15 -0
- package/daemon/dist/domain/transcript-store.d.ts.map +1 -1
- package/daemon/dist/domain/transcript-store.js +76 -1
- package/daemon/dist/domain/transcript-store.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +323 -3
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/view-event-bridge.d.ts +12 -0
- package/daemon/dist/domain/view-event-bridge.d.ts.map +1 -0
- package/daemon/dist/domain/view-event-bridge.js +92 -0
- package/daemon/dist/domain/view-event-bridge.js.map +1 -0
- package/daemon/dist/domain/view-projector.d.ts +83 -0
- package/daemon/dist/domain/view-projector.d.ts.map +1 -0
- package/daemon/dist/domain/view-projector.js +296 -0
- package/daemon/dist/domain/view-projector.js.map +1 -0
- package/daemon/dist/domain/watchdog-history-log.d.ts +49 -0
- package/daemon/dist/domain/watchdog-history-log.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-history-log.js +67 -0
- package/daemon/dist/domain/watchdog-history-log.js.map +1 -0
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts +81 -0
- package/daemon/dist/domain/watchdog-jobs-repository.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-jobs-repository.js +164 -0
- package/daemon/dist/domain/watchdog-jobs-repository.js.map +1 -0
- package/daemon/dist/domain/watchdog-policy-engine.d.ts +92 -0
- package/daemon/dist/domain/watchdog-policy-engine.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-policy-engine.js +442 -0
- package/daemon/dist/domain/watchdog-policy-engine.js.map +1 -0
- package/daemon/dist/domain/watchdog-scheduler.d.ts +76 -0
- package/daemon/dist/domain/watchdog-scheduler.d.ts.map +1 -0
- package/daemon/dist/domain/watchdog-scheduler.js +112 -0
- package/daemon/dist/domain/watchdog-scheduler.js.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts +46 -0
- package/daemon/dist/domain/workflow-instance-store.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-instance-store.js +116 -0
- package/daemon/dist/domain/workflow-instance-store.js.map +1 -0
- package/daemon/dist/domain/workflow-projector.d.ts +64 -0
- package/daemon/dist/domain/workflow-projector.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-projector.js +424 -0
- package/daemon/dist/domain/workflow-projector.js.map +1 -0
- package/daemon/dist/domain/workflow-runtime.d.ts +63 -0
- package/daemon/dist/domain/workflow-runtime.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-runtime.js +150 -0
- package/daemon/dist/domain/workflow-runtime.js.map +1 -0
- package/daemon/dist/domain/workflow-spec-cache.d.ts +35 -0
- package/daemon/dist/domain/workflow-spec-cache.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-spec-cache.js +171 -0
- package/daemon/dist/domain/workflow-spec-cache.js.map +1 -0
- package/daemon/dist/domain/workflow-step-trail-log.d.ts +27 -0
- package/daemon/dist/domain/workflow-step-trail-log.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-step-trail-log.js +73 -0
- package/daemon/dist/domain/workflow-step-trail-log.js.map +1 -0
- package/daemon/dist/domain/workflow-types.d.ts +108 -0
- package/daemon/dist/domain/workflow-types.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-types.js +11 -0
- package/daemon/dist/domain/workflow-types.js.map +1 -0
- package/daemon/dist/domain/workflow-validator.d.ts +31 -0
- package/daemon/dist/domain/workflow-validator.d.ts.map +1 -0
- package/daemon/dist/domain/workflow-validator.js +115 -0
- package/daemon/dist/domain/workflow-validator.js.map +1 -0
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +21 -2
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/routes/activity.d.ts +3 -0
- package/daemon/dist/routes/activity.d.ts.map +1 -0
- package/daemon/dist/routes/activity.js +47 -0
- package/daemon/dist/routes/activity.js.map +1 -0
- package/daemon/dist/routes/projects.d.ts +12 -0
- package/daemon/dist/routes/projects.d.ts.map +1 -0
- package/daemon/dist/routes/projects.js +178 -0
- package/daemon/dist/routes/projects.js.map +1 -0
- package/daemon/dist/routes/queue.d.ts +10 -0
- package/daemon/dist/routes/queue.d.ts.map +1 -0
- package/daemon/dist/routes/queue.js +374 -0
- package/daemon/dist/routes/queue.js.map +1 -0
- package/daemon/dist/routes/restore-check.d.ts +3 -0
- package/daemon/dist/routes/restore-check.d.ts.map +1 -0
- package/daemon/dist/routes/restore-check.js +200 -0
- package/daemon/dist/routes/restore-check.js.map +1 -0
- package/daemon/dist/routes/rigs.d.ts.map +1 -1
- package/daemon/dist/routes/rigs.js +60 -4
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/seat.d.ts +3 -0
- package/daemon/dist/routes/seat.d.ts.map +1 -0
- package/daemon/dist/routes/seat.js +69 -0
- package/daemon/dist/routes/seat.js.map +1 -0
- package/daemon/dist/routes/sessions.d.ts.map +1 -1
- package/daemon/dist/routes/sessions.js +41 -5
- package/daemon/dist/routes/sessions.js.map +1 -1
- package/daemon/dist/routes/snapshots.js +66 -17
- package/daemon/dist/routes/snapshots.js.map +1 -1
- package/daemon/dist/routes/stream.d.ts +9 -0
- package/daemon/dist/routes/stream.d.ts.map +1 -0
- package/daemon/dist/routes/stream.js +119 -0
- package/daemon/dist/routes/stream.js.map +1 -0
- package/daemon/dist/routes/transcripts.d.ts.map +1 -1
- package/daemon/dist/routes/transcripts.js +38 -0
- package/daemon/dist/routes/transcripts.js.map +1 -1
- package/daemon/dist/routes/transport.d.ts.map +1 -1
- package/daemon/dist/routes/transport.js +21 -0
- package/daemon/dist/routes/transport.js.map +1 -1
- package/daemon/dist/routes/up.js +24 -3
- package/daemon/dist/routes/up.js.map +1 -1
- package/daemon/dist/routes/views.d.ts +13 -0
- package/daemon/dist/routes/views.d.ts.map +1 -0
- package/daemon/dist/routes/views.js +120 -0
- package/daemon/dist/routes/views.js.map +1 -0
- package/daemon/dist/routes/watchdog.d.ts +18 -0
- package/daemon/dist/routes/watchdog.d.ts.map +1 -0
- package/daemon/dist/routes/watchdog.js +148 -0
- package/daemon/dist/routes/watchdog.js.map +1 -0
- package/daemon/dist/routes/workflow.d.ts +20 -0
- package/daemon/dist/routes/workflow.d.ts.map +1 -0
- package/daemon/dist/routes/workflow.js +184 -0
- package/daemon/dist/routes/workflow.js.map +1 -0
- package/daemon/dist/server.d.ts +30 -0
- package/daemon/dist/server.d.ts.map +1 -1
- package/daemon/dist/server.js +33 -0
- package/daemon/dist/server.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +202 -8
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-spec.md +12 -5
- package/daemon/docs/reference/agent-startup-guide.md +9 -9
- package/daemon/specs/agents/apps/vault-specialist/agent.yaml +1 -1
- package/daemon/specs/agents/design/product-designer/agent.yaml +1 -1
- package/daemon/specs/agents/development/implementer/agent.yaml +1 -1
- package/daemon/specs/agents/development/qa/agent.yaml +1 -1
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +1 -1
- package/daemon/specs/agents/product-management/pm/agent.yaml +4 -0
- package/daemon/specs/agents/research/analyst/agent.yaml +1 -1
- package/daemon/specs/agents/research/synthesizer/agent.yaml +1 -1
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +1 -1
- package/daemon/specs/agents/shared/agent.yaml +17 -0
- package/daemon/specs/agents/shared/runtime/claude-mcp.fragment.json +12 -0
- package/daemon/specs/agents/shared/runtime/claude-settings.fragment.json +16 -0
- package/daemon/specs/agents/shared/runtime/codex-config.fragment.toml +5 -0
- package/daemon/specs/agents/shared/skills/claude-compact-in-place/SKILL.md +100 -0
- package/daemon/specs/agents/shared/skills/core/openrig-operator/SKILL.md +110 -0
- package/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md +44 -1
- package/daemon/specs/agents/shared/skills/mental-model-ha/SKILL.md +3 -0
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +3 -0
- package/dist/commands/capture.d.ts +7 -1
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +59 -1
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/compact-plan.d.ts +9 -0
- package/dist/commands/compact-plan.d.ts.map +1 -0
- package/dist/commands/compact-plan.js +354 -0
- package/dist/commands/compact-plan.js.map +1 -0
- package/dist/commands/context.d.ts +9 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +220 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +19 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/expand.d.ts.map +1 -1
- package/dist/commands/expand.js +15 -4
- package/dist/commands/expand.js.map +1 -1
- package/dist/commands/heartbeat.d.ts +99 -0
- package/dist/commands/heartbeat.d.ts.map +1 -0
- package/dist/commands/heartbeat.js +393 -0
- package/dist/commands/heartbeat.js.map +1 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +2 -1
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/preflight.js +1 -1
- package/dist/commands/preflight.js.map +1 -1
- package/dist/commands/project.d.ts +14 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +157 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/ps.d.ts +20 -3
- package/dist/commands/ps.d.ts.map +1 -1
- package/dist/commands/ps.js +455 -33
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/queue.d.ts +16 -0
- package/dist/commands/queue.d.ts.map +1 -0
- package/dist/commands/queue.js +401 -0
- package/dist/commands/queue.js.map +1 -0
- package/dist/commands/restore-check.d.ts +9 -0
- package/dist/commands/restore-check.d.ts.map +1 -0
- package/dist/commands/restore-check.js +234 -0
- package/dist/commands/restore-check.js.map +1 -0
- package/dist/commands/restore-packet.d.ts +9 -0
- package/dist/commands/restore-packet.d.ts.map +1 -0
- package/dist/commands/restore-packet.js +383 -0
- package/dist/commands/restore-packet.js.map +1 -0
- package/dist/commands/restore.d.ts.map +1 -1
- package/dist/commands/restore.js +69 -1
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/seat.d.ts +5 -0
- package/dist/commands/seat.d.ts.map +1 -0
- package/dist/commands/seat.js +170 -0
- package/dist/commands/seat.js.map +1 -0
- package/dist/commands/send.d.ts +12 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +93 -5
- package/dist/commands/send.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +20 -8
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/specs.d.ts.map +1 -1
- package/dist/commands/specs.js +99 -16
- package/dist/commands/specs.js.map +1 -1
- package/dist/commands/stream.d.ts +12 -0
- package/dist/commands/stream.d.ts.map +1 -0
- package/dist/commands/stream.js +111 -0
- package/dist/commands/stream.js.map +1 -0
- package/dist/commands/up.d.ts +1 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +65 -4
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/view.d.ts +12 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +82 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/commands/watchdog.d.ts +15 -0
- package/dist/commands/watchdog.d.ts.map +1 -0
- package/dist/commands/watchdog.js +120 -0
- package/dist/commands/watchdog.js.map +1 -0
- package/dist/commands/whoami.d.ts +8 -1
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +60 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workflow.d.ts +17 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +138 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/cross-host-cli-helpers.d.ts +12 -0
- package/dist/cross-host-cli-helpers.d.ts.map +1 -0
- package/dist/cross-host-cli-helpers.js +48 -0
- package/dist/cross-host-cli-helpers.js.map +1 -0
- package/dist/cross-host-executor.d.ts +84 -0
- package/dist/cross-host-executor.d.ts.map +1 -0
- package/dist/cross-host-executor.js +138 -0
- package/dist/cross-host-executor.js.map +1 -0
- package/dist/host-registry.d.ts +50 -0
- package/dist/host-registry.d.ts.map +1 -0
- package/dist/host-registry.js +116 -0
- package/dist/host-registry.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +22 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/restore-packet/claude-transcript-parser.d.ts +12 -0
- package/dist/restore-packet/claude-transcript-parser.d.ts.map +1 -0
- package/dist/restore-packet/claude-transcript-parser.js +221 -0
- package/dist/restore-packet/claude-transcript-parser.js.map +1 -0
- package/dist/restore-packet/codex-jsonl-parser.d.ts +11 -0
- package/dist/restore-packet/codex-jsonl-parser.d.ts.map +1 -0
- package/dist/restore-packet/codex-jsonl-parser.js +159 -0
- package/dist/restore-packet/codex-jsonl-parser.js.map +1 -0
- package/dist/restore-packet/omitted-records.d.ts +60 -0
- package/dist/restore-packet/omitted-records.d.ts.map +1 -0
- package/dist/restore-packet/omitted-records.js +116 -0
- package/dist/restore-packet/omitted-records.js.map +1 -0
- package/dist/restore-packet/packet-writer.d.ts +59 -0
- package/dist/restore-packet/packet-writer.d.ts.map +1 -0
- package/dist/restore-packet/packet-writer.js +224 -0
- package/dist/restore-packet/packet-writer.js.map +1 -0
- package/dist/restore-packet/redaction.d.ts +30 -0
- package/dist/restore-packet/redaction.d.ts.map +1 -0
- package/dist/restore-packet/redaction.js +71 -0
- package/dist/restore-packet/redaction.js.map +1 -0
- package/dist/restore-packet/runtime-detect.d.ts +19 -0
- package/dist/restore-packet/runtime-detect.d.ts.map +1 -0
- package/dist/restore-packet/runtime-detect.js +81 -0
- package/dist/restore-packet/runtime-detect.js.map +1 -0
- package/dist/restore-packet/schema-validator.d.ts +13 -0
- package/dist/restore-packet/schema-validator.d.ts.map +1 -0
- package/dist/restore-packet/schema-validator.js +245 -0
- package/dist/restore-packet/schema-validator.js.map +1 -0
- package/dist/restore-packet/types.d.ts +76 -0
- package/dist/restore-packet/types.d.ts.map +1 -0
- package/dist/restore-packet/types.js +15 -0
- package/dist/restore-packet/types.js.map +1 -0
- package/dist/schemas/restore-summary.schema.json +98 -0
- package/dist/system-preflight.d.ts.map +1 -1
- package/dist/system-preflight.js +16 -5
- package/dist/system-preflight.js.map +1 -1
- package/dist/tmux-health.d.ts +16 -0
- package/dist/tmux-health.d.ts.map +1 -0
- package/dist/tmux-health.js +105 -0
- package/dist/tmux-health.js.map +1 -0
- package/package.json +10 -3
- package/scripts/check-abi.mjs +123 -0
- package/ui/dist/assets/{index-DlMH-REm.css → index-Dec25siz.css} +1 -1
- package/ui/dist/assets/{index-lEO-zBxz.js → index-GNYaWmBj.js} +9 -9
- package/ui/dist/index.html +2 -2
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
import { QueueTransitionLog } from "./queue-transition-log.js";
|
|
2
|
+
import { computeClosureRequiredAt, validateClosure, } from "./hot-potato-enforcer.js";
|
|
3
|
+
export const QUEUE_STATES = [
|
|
4
|
+
"pending",
|
|
5
|
+
"in-progress",
|
|
6
|
+
"done",
|
|
7
|
+
"blocked",
|
|
8
|
+
"failed",
|
|
9
|
+
"denied",
|
|
10
|
+
"canceled",
|
|
11
|
+
"handed-off",
|
|
12
|
+
];
|
|
13
|
+
export const QUEUE_PRIORITIES = ["routine", "urgent", "critical"];
|
|
14
|
+
export class QueueRepositoryError extends Error {
|
|
15
|
+
code;
|
|
16
|
+
meta;
|
|
17
|
+
constructor(code, message, meta) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.meta = meta;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function newQitemId() {
|
|
24
|
+
const ts = new Date().toISOString().replace(/[-:T.Z]/g, "").slice(0, 14);
|
|
25
|
+
const hex = Math.floor(Math.random() * 0xffffffff)
|
|
26
|
+
.toString(16)
|
|
27
|
+
.padStart(8, "0");
|
|
28
|
+
return `qitem-${ts}-${hex}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* L3 — Queue repository. Owns CRUD over `queue_items` plus the wired-in
|
|
32
|
+
* append-only transition log and hot-potato strict-rejection contract.
|
|
33
|
+
*
|
|
34
|
+
* Pattern mirrors `chat-repository.ts` (single class, atomic transactions,
|
|
35
|
+
* persist-event-then-notify). Cross-rig validation hook is `validateRig` —
|
|
36
|
+
* Phase A wires no-op; Phase B can plug in the rig registry to reject
|
|
37
|
+
* phantom-rig destinations. POC compatibility: `qitem_id` shape preserved.
|
|
38
|
+
*/
|
|
39
|
+
export class QueueRepository {
|
|
40
|
+
db;
|
|
41
|
+
transitionLog;
|
|
42
|
+
eventBus;
|
|
43
|
+
validateRig;
|
|
44
|
+
transport;
|
|
45
|
+
constructor(db, eventBus, opts) {
|
|
46
|
+
this.db = db;
|
|
47
|
+
this.eventBus = eventBus;
|
|
48
|
+
this.transitionLog = new QueueTransitionLog(db);
|
|
49
|
+
this.validateRig = opts?.validateRig ?? (() => true);
|
|
50
|
+
this.transport = opts?.transport;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Attach the wake-path transport AFTER construction. Used by daemon
|
|
54
|
+
* startup, where SessionTransport is constructed later in the dep graph
|
|
55
|
+
* than QueueRepository (because SessionTransport needs agentActivityStore
|
|
56
|
+
* which itself needs eventBus). Calling this is safe at any time; create /
|
|
57
|
+
* handoff / handoff-and-complete will start nudging on the next call.
|
|
58
|
+
*/
|
|
59
|
+
attachTransport(transport) {
|
|
60
|
+
this.transport = transport;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Issue a default nudge to the destination after a create / handoff /
|
|
64
|
+
* handoff-and-complete commit. Records the result via recordNudgeAttempt.
|
|
65
|
+
* Errors are caught and surfaced as nudge_result strings — they do not
|
|
66
|
+
* unwind the underlying queue mutation.
|
|
67
|
+
*
|
|
68
|
+
* Phase D extension point (orch-ratified): public so workflow-projector
|
|
69
|
+
* can invoke after its outer transaction commits, completing the
|
|
70
|
+
* createWithinTransaction()'s deferred post-commit side effects.
|
|
71
|
+
*/
|
|
72
|
+
async maybeNudge(qitemId, destinationSession, nudgeOpt) {
|
|
73
|
+
if (nudgeOpt === false)
|
|
74
|
+
return;
|
|
75
|
+
if (!this.transport)
|
|
76
|
+
return;
|
|
77
|
+
const text = `Queue handoff: ${qitemId} - check your queue.`;
|
|
78
|
+
try {
|
|
79
|
+
const res = await this.transport.send(destinationSession, text, { verify: true });
|
|
80
|
+
const result = res.ok
|
|
81
|
+
? (res.verified ? "verified" : "sent-unverified")
|
|
82
|
+
: `failed:${res.error ?? res.reason ?? "unknown"}`;
|
|
83
|
+
this.recordNudgeAttempt(qitemId, result);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
87
|
+
this.recordNudgeAttempt(qitemId, `failed:${msg}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async create(input) {
|
|
91
|
+
if (!this.validateRig(input.destinationSession)) {
|
|
92
|
+
throw new QueueRepositoryError("unknown_destination_rig", `destination_session ${input.destinationSession} references an unknown rig`);
|
|
93
|
+
}
|
|
94
|
+
const txn = this.db.transaction(() => this.createInTransactionalContext(input));
|
|
95
|
+
const { qitemId: id, persistedEvent } = txn();
|
|
96
|
+
this.eventBus.notifySubscribers(persistedEvent);
|
|
97
|
+
await this.maybeNudge(id, input.destinationSession, input.nudge);
|
|
98
|
+
return this.getByIdOrThrow(id);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* PL-004 Phase D extension point (orch-ratified per slice IMPL §
|
|
102
|
+
* Driver Handoff Contract). Creates a queue item using the SAME
|
|
103
|
+
* caller-managed db.transaction for transactional-scribe semantics
|
|
104
|
+
* (workflow-projector folds step closure + next-qitem creation into
|
|
105
|
+
* one atomic unit). Returns the persisted event AND qitem id so the
|
|
106
|
+
* caller can defer notifySubscribers/maybeNudge until AFTER its
|
|
107
|
+
* outer transaction commits.
|
|
108
|
+
*
|
|
109
|
+
* Caller MUST:
|
|
110
|
+
* 1. Invoke this from inside a `db.transaction(() => {...})` block.
|
|
111
|
+
* 2. After the outer txn commits, call:
|
|
112
|
+
* - eventBus.notifySubscribers(persistedEvent)
|
|
113
|
+
* - this.maybeNudge(qitemId, destinationSession, input.nudge)
|
|
114
|
+
* 3. NOT call this from outside a transaction (will produce a
|
|
115
|
+
* half-state if the caller errors before committing).
|
|
116
|
+
*
|
|
117
|
+
* The split exists ONLY because notifySubscribers + maybeNudge are
|
|
118
|
+
* post-commit side effects (subscribers should not see events for
|
|
119
|
+
* data that may roll back; nudges should not fire for handoffs that
|
|
120
|
+
* may roll back). For independent create()s that don't need to
|
|
121
|
+
* compose with an outer transaction, use create() instead.
|
|
122
|
+
*/
|
|
123
|
+
createWithinTransaction(input) {
|
|
124
|
+
if (!this.validateRig(input.destinationSession)) {
|
|
125
|
+
throw new QueueRepositoryError("unknown_destination_rig", `destination_session ${input.destinationSession} references an unknown rig`);
|
|
126
|
+
}
|
|
127
|
+
const result = this.createInTransactionalContext(input);
|
|
128
|
+
return {
|
|
129
|
+
qitemId: result.qitemId,
|
|
130
|
+
persistedEvent: result.persistedEvent,
|
|
131
|
+
destinationSession: input.destinationSession,
|
|
132
|
+
nudge: input.nudge,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Internal: insert + transition + emit event. Caller is responsible
|
|
137
|
+
* for transaction wrapping (the public create() wraps; the public
|
|
138
|
+
* createWithinTransaction() does not — caller's outer transaction
|
|
139
|
+
* provides the atomic boundary).
|
|
140
|
+
*/
|
|
141
|
+
createInTransactionalContext(input) {
|
|
142
|
+
const id = input.qitemId ?? newQitemId();
|
|
143
|
+
const ts = new Date().toISOString();
|
|
144
|
+
const priority = input.priority ?? "routine";
|
|
145
|
+
const tier = input.tier ?? null;
|
|
146
|
+
const tags = input.tags ? JSON.stringify(input.tags) : null;
|
|
147
|
+
const chain = input.chainOfRecord ? JSON.stringify(input.chainOfRecord) : null;
|
|
148
|
+
const expiresAt = input.expiresAt ?? null;
|
|
149
|
+
this.db
|
|
150
|
+
.prepare(`INSERT INTO queue_items (
|
|
151
|
+
qitem_id, ts_created, ts_updated, source_session, destination_session,
|
|
152
|
+
state, priority, tier, tags, expires_at, chain_of_record, body
|
|
153
|
+
) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?, ?, ?)`)
|
|
154
|
+
.run(id, ts, ts, input.sourceSession, input.destinationSession, priority, tier, tags, expiresAt, chain, input.body);
|
|
155
|
+
this.transitionLog.append({
|
|
156
|
+
qitemId: id,
|
|
157
|
+
state: "pending",
|
|
158
|
+
actorSession: input.sourceSession,
|
|
159
|
+
transitionNote: "created",
|
|
160
|
+
});
|
|
161
|
+
const persistedEvent = this.eventBus.persistWithinTransaction({
|
|
162
|
+
type: "queue.created",
|
|
163
|
+
qitemId: id,
|
|
164
|
+
sourceSession: input.sourceSession,
|
|
165
|
+
destinationSession: input.destinationSession,
|
|
166
|
+
priority,
|
|
167
|
+
tier,
|
|
168
|
+
});
|
|
169
|
+
return { qitemId: id, persistedEvent };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Transactional handoff: close the source qitem (state=done,
|
|
173
|
+
* closure_reason=handed_off_to) and create a new qitem owned by `toSession`,
|
|
174
|
+
* with `handed_off_from` recording the chain. One atomic transaction.
|
|
175
|
+
*/
|
|
176
|
+
async handoff(input) {
|
|
177
|
+
const source = this.getById(input.qitemId);
|
|
178
|
+
if (!source) {
|
|
179
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${input.qitemId} not found`);
|
|
180
|
+
}
|
|
181
|
+
if (source.state === "done" || source.state === "handed-off") {
|
|
182
|
+
throw new QueueRepositoryError("qitem_already_terminal", `qitem ${input.qitemId} is already in terminal state ${source.state}`);
|
|
183
|
+
}
|
|
184
|
+
if (!this.validateRig(input.toSession)) {
|
|
185
|
+
throw new QueueRepositoryError("unknown_destination_rig", `to_session ${input.toSession} references an unknown rig`);
|
|
186
|
+
}
|
|
187
|
+
const newId = newQitemId();
|
|
188
|
+
const ts = new Date().toISOString();
|
|
189
|
+
const body = input.body ?? source.body;
|
|
190
|
+
const priority = input.priority ?? source.priority;
|
|
191
|
+
const tier = input.tier ?? source.tier;
|
|
192
|
+
const tags = input.tags ? JSON.stringify(input.tags) : (source.tags ? JSON.stringify(source.tags) : null);
|
|
193
|
+
const chain = JSON.stringify([...(source.chainOfRecord ?? []), source.qitemId]);
|
|
194
|
+
const events = [];
|
|
195
|
+
const txn = this.db.transaction(() => {
|
|
196
|
+
this.db
|
|
197
|
+
.prepare(`UPDATE queue_items
|
|
198
|
+
SET state = 'handed-off',
|
|
199
|
+
ts_updated = ?,
|
|
200
|
+
handed_off_to = ?,
|
|
201
|
+
closure_reason = 'handed_off_to',
|
|
202
|
+
closure_target = ?
|
|
203
|
+
WHERE qitem_id = ?`)
|
|
204
|
+
.run(ts, input.toSession, input.toSession, source.qitemId);
|
|
205
|
+
this.transitionLog.append({
|
|
206
|
+
qitemId: source.qitemId,
|
|
207
|
+
state: "handed-off",
|
|
208
|
+
actorSession: input.fromSession,
|
|
209
|
+
transitionNote: input.transitionNote ?? `handed off to ${input.toSession}`,
|
|
210
|
+
closureReason: "handed_off_to",
|
|
211
|
+
closureTarget: input.toSession,
|
|
212
|
+
});
|
|
213
|
+
this.db
|
|
214
|
+
.prepare(`INSERT INTO queue_items (
|
|
215
|
+
qitem_id, ts_created, ts_updated, source_session, destination_session,
|
|
216
|
+
state, priority, tier, tags, handed_off_from, chain_of_record, body
|
|
217
|
+
) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?, ?, ?)`)
|
|
218
|
+
.run(newId, ts, ts, input.fromSession, input.toSession, priority, tier, tags, source.qitemId, chain, body);
|
|
219
|
+
this.transitionLog.append({
|
|
220
|
+
qitemId: newId,
|
|
221
|
+
state: "pending",
|
|
222
|
+
actorSession: input.fromSession,
|
|
223
|
+
transitionNote: `handoff from ${source.qitemId}`,
|
|
224
|
+
});
|
|
225
|
+
const handoffEvent = this.eventBus.persistWithinTransaction({
|
|
226
|
+
type: "queue.handed_off",
|
|
227
|
+
qitemId: source.qitemId,
|
|
228
|
+
fromSession: input.fromSession,
|
|
229
|
+
toSession: input.toSession,
|
|
230
|
+
closureReason: "handed_off_to",
|
|
231
|
+
});
|
|
232
|
+
events.push({ name: "queue.handed_off", payload: handoffEvent });
|
|
233
|
+
const createdEvent = this.eventBus.persistWithinTransaction({
|
|
234
|
+
type: "queue.created",
|
|
235
|
+
qitemId: newId,
|
|
236
|
+
sourceSession: input.fromSession,
|
|
237
|
+
destinationSession: input.toSession,
|
|
238
|
+
priority,
|
|
239
|
+
tier,
|
|
240
|
+
});
|
|
241
|
+
events.push({ name: "queue.created", payload: createdEvent });
|
|
242
|
+
});
|
|
243
|
+
txn();
|
|
244
|
+
for (const e of events) {
|
|
245
|
+
this.eventBus.notifySubscribers(e.payload);
|
|
246
|
+
}
|
|
247
|
+
await this.maybeNudge(newId, input.toSession, input.nudge);
|
|
248
|
+
return {
|
|
249
|
+
closed: this.getByIdOrThrow(source.qitemId),
|
|
250
|
+
created: this.getByIdOrThrow(newId),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Variant of {@link handoff} that closes the source qitem as `done`
|
|
255
|
+
* (terminal closure) instead of `handed-off` (intermediate). Same atomic
|
|
256
|
+
* close+create, same chain_of_record semantics, same default-nudge behavior.
|
|
257
|
+
* Use when the source seat is fully complete with the work — no follow-up
|
|
258
|
+
* tracking needed against the source qitem.
|
|
259
|
+
*/
|
|
260
|
+
async handoffAndComplete(input) {
|
|
261
|
+
const source = this.getById(input.qitemId);
|
|
262
|
+
if (!source) {
|
|
263
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${input.qitemId} not found`);
|
|
264
|
+
}
|
|
265
|
+
if (source.state === "done" || source.state === "handed-off") {
|
|
266
|
+
throw new QueueRepositoryError("qitem_already_terminal", `qitem ${input.qitemId} is already in terminal state ${source.state}`);
|
|
267
|
+
}
|
|
268
|
+
if (!this.validateRig(input.toSession)) {
|
|
269
|
+
throw new QueueRepositoryError("unknown_destination_rig", `to_session ${input.toSession} references an unknown rig`);
|
|
270
|
+
}
|
|
271
|
+
const newId = newQitemId();
|
|
272
|
+
const ts = new Date().toISOString();
|
|
273
|
+
const body = input.body ?? source.body;
|
|
274
|
+
const priority = input.priority ?? source.priority;
|
|
275
|
+
const tier = input.tier ?? source.tier;
|
|
276
|
+
const tags = input.tags ? JSON.stringify(input.tags) : (source.tags ? JSON.stringify(source.tags) : null);
|
|
277
|
+
const chain = JSON.stringify([...(source.chainOfRecord ?? []), source.qitemId]);
|
|
278
|
+
const events = [];
|
|
279
|
+
const txn = this.db.transaction(() => {
|
|
280
|
+
this.db
|
|
281
|
+
.prepare(`UPDATE queue_items
|
|
282
|
+
SET state = 'done',
|
|
283
|
+
ts_updated = ?,
|
|
284
|
+
handed_off_to = ?,
|
|
285
|
+
closure_reason = 'handed_off_to',
|
|
286
|
+
closure_target = ?
|
|
287
|
+
WHERE qitem_id = ?`)
|
|
288
|
+
.run(ts, input.toSession, input.toSession, source.qitemId);
|
|
289
|
+
this.transitionLog.append({
|
|
290
|
+
qitemId: source.qitemId,
|
|
291
|
+
state: "done",
|
|
292
|
+
actorSession: input.fromSession,
|
|
293
|
+
transitionNote: input.transitionNote ?? `handoff-and-complete to ${input.toSession}`,
|
|
294
|
+
closureReason: "handed_off_to",
|
|
295
|
+
closureTarget: input.toSession,
|
|
296
|
+
});
|
|
297
|
+
this.db
|
|
298
|
+
.prepare(`INSERT INTO queue_items (
|
|
299
|
+
qitem_id, ts_created, ts_updated, source_session, destination_session,
|
|
300
|
+
state, priority, tier, tags, handed_off_from, chain_of_record, body
|
|
301
|
+
) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?, ?, ?)`)
|
|
302
|
+
.run(newId, ts, ts, input.fromSession, input.toSession, priority, tier, tags, source.qitemId, chain, body);
|
|
303
|
+
this.transitionLog.append({
|
|
304
|
+
qitemId: newId,
|
|
305
|
+
state: "pending",
|
|
306
|
+
actorSession: input.fromSession,
|
|
307
|
+
transitionNote: `handoff-and-complete from ${source.qitemId}`,
|
|
308
|
+
});
|
|
309
|
+
const handoffEvent = this.eventBus.persistWithinTransaction({
|
|
310
|
+
type: "queue.handed_off",
|
|
311
|
+
qitemId: source.qitemId,
|
|
312
|
+
fromSession: input.fromSession,
|
|
313
|
+
toSession: input.toSession,
|
|
314
|
+
closureReason: "handed_off_to",
|
|
315
|
+
});
|
|
316
|
+
events.push({ name: "queue.handed_off", payload: handoffEvent });
|
|
317
|
+
const createdEvent = this.eventBus.persistWithinTransaction({
|
|
318
|
+
type: "queue.created",
|
|
319
|
+
qitemId: newId,
|
|
320
|
+
sourceSession: input.fromSession,
|
|
321
|
+
destinationSession: input.toSession,
|
|
322
|
+
priority,
|
|
323
|
+
tier,
|
|
324
|
+
});
|
|
325
|
+
events.push({ name: "queue.created", payload: createdEvent });
|
|
326
|
+
});
|
|
327
|
+
txn();
|
|
328
|
+
for (const e of events) {
|
|
329
|
+
this.eventBus.notifySubscribers(e.payload);
|
|
330
|
+
}
|
|
331
|
+
await this.maybeNudge(newId, input.toSession, input.nudge);
|
|
332
|
+
return {
|
|
333
|
+
closed: this.getByIdOrThrow(source.qitemId),
|
|
334
|
+
created: this.getByIdOrThrow(newId),
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* `whoami` — return the seat's queue position from the daemon's perspective.
|
|
339
|
+
* Counts active qitems (pending + in-progress + blocked) destined for the
|
|
340
|
+
* caller, lists the most recent active qitems, and reports counts for the
|
|
341
|
+
* caller's outgoing source role too. Read-only; no mutations.
|
|
342
|
+
*
|
|
343
|
+
* Per PL-004 Phase A § Routes: GET /api/queue/whoami.
|
|
344
|
+
*/
|
|
345
|
+
whoami(session, opts) {
|
|
346
|
+
const limit = Math.max(1, Math.min(opts?.recentLimit ?? 25, 200));
|
|
347
|
+
const countByState = (state) => {
|
|
348
|
+
const row = this.db
|
|
349
|
+
.prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE destination_session = ? AND state = ?`)
|
|
350
|
+
.get(session, state);
|
|
351
|
+
return row.n;
|
|
352
|
+
};
|
|
353
|
+
const recent = this.db
|
|
354
|
+
.prepare(`SELECT * FROM queue_items
|
|
355
|
+
WHERE destination_session = ?
|
|
356
|
+
AND state IN ('pending','in-progress','blocked')
|
|
357
|
+
ORDER BY ts_updated DESC
|
|
358
|
+
LIMIT ?`)
|
|
359
|
+
.all(session, limit);
|
|
360
|
+
const sourceTotalRow = this.db
|
|
361
|
+
.prepare(`SELECT COUNT(*) AS n FROM queue_items WHERE source_session = ?`)
|
|
362
|
+
.get(session);
|
|
363
|
+
return {
|
|
364
|
+
session,
|
|
365
|
+
asDestination: {
|
|
366
|
+
pending: countByState("pending"),
|
|
367
|
+
inProgress: countByState("in-progress"),
|
|
368
|
+
blocked: countByState("blocked"),
|
|
369
|
+
recent: recent.map((r) => this.rowToItem(r)),
|
|
370
|
+
},
|
|
371
|
+
asSource: { total: sourceTotalRow.n },
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Mark a qitem `in-progress` (claim). Computes closure_required_at from tier.
|
|
376
|
+
*/
|
|
377
|
+
claim(input) {
|
|
378
|
+
const qitem = this.getById(input.qitemId);
|
|
379
|
+
if (!qitem) {
|
|
380
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${input.qitemId} not found`);
|
|
381
|
+
}
|
|
382
|
+
if (qitem.destinationSession !== input.destinationSession) {
|
|
383
|
+
throw new QueueRepositoryError("claim_destination_mismatch", `qitem ${input.qitemId} destination is ${qitem.destinationSession}, not ${input.destinationSession}`);
|
|
384
|
+
}
|
|
385
|
+
if (qitem.state !== "pending" && qitem.state !== "blocked") {
|
|
386
|
+
throw new QueueRepositoryError("qitem_not_claimable", `qitem ${input.qitemId} is in state ${qitem.state}; only pending/blocked are claimable`);
|
|
387
|
+
}
|
|
388
|
+
const ts = new Date().toISOString();
|
|
389
|
+
const closureRequiredAt = computeClosureRequiredAt(ts, qitem.tier);
|
|
390
|
+
const txn = this.db.transaction(() => {
|
|
391
|
+
this.db
|
|
392
|
+
.prepare(`UPDATE queue_items
|
|
393
|
+
SET state = 'in-progress',
|
|
394
|
+
ts_updated = ?,
|
|
395
|
+
claimed_at = ?,
|
|
396
|
+
closure_required_at = ?
|
|
397
|
+
WHERE qitem_id = ?`)
|
|
398
|
+
.run(ts, ts, closureRequiredAt, input.qitemId);
|
|
399
|
+
this.transitionLog.append({
|
|
400
|
+
qitemId: input.qitemId,
|
|
401
|
+
state: "in-progress",
|
|
402
|
+
actorSession: input.destinationSession,
|
|
403
|
+
transitionNote: "claimed",
|
|
404
|
+
});
|
|
405
|
+
return this.eventBus.persistWithinTransaction({
|
|
406
|
+
type: "queue.claimed",
|
|
407
|
+
qitemId: input.qitemId,
|
|
408
|
+
destinationSession: input.destinationSession,
|
|
409
|
+
claimedAt: ts,
|
|
410
|
+
closureRequiredAt,
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
const persistedEvent = txn();
|
|
414
|
+
this.eventBus.notifySubscribers(persistedEvent);
|
|
415
|
+
return this.getByIdOrThrow(input.qitemId);
|
|
416
|
+
}
|
|
417
|
+
unclaim(qitemId, destinationSession, reason) {
|
|
418
|
+
const qitem = this.getById(qitemId);
|
|
419
|
+
if (!qitem) {
|
|
420
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${qitemId} not found`);
|
|
421
|
+
}
|
|
422
|
+
if (qitem.state !== "in-progress") {
|
|
423
|
+
throw new QueueRepositoryError("qitem_not_in_progress", `qitem ${qitemId} is in state ${qitem.state}; only in-progress can be unclaimed`);
|
|
424
|
+
}
|
|
425
|
+
const ts = new Date().toISOString();
|
|
426
|
+
const txn = this.db.transaction(() => {
|
|
427
|
+
this.db
|
|
428
|
+
.prepare(`UPDATE queue_items
|
|
429
|
+
SET state = 'pending',
|
|
430
|
+
ts_updated = ?,
|
|
431
|
+
claimed_at = NULL,
|
|
432
|
+
closure_required_at = NULL
|
|
433
|
+
WHERE qitem_id = ?`)
|
|
434
|
+
.run(ts, qitemId);
|
|
435
|
+
this.transitionLog.append({
|
|
436
|
+
qitemId,
|
|
437
|
+
state: "pending",
|
|
438
|
+
actorSession: destinationSession,
|
|
439
|
+
transitionNote: `unclaimed: ${reason}`,
|
|
440
|
+
});
|
|
441
|
+
return this.eventBus.persistWithinTransaction({
|
|
442
|
+
type: "queue.unclaimed",
|
|
443
|
+
qitemId,
|
|
444
|
+
destinationSession,
|
|
445
|
+
reason,
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
const persistedEvent = txn();
|
|
449
|
+
this.eventBus.notifySubscribers(persistedEvent);
|
|
450
|
+
return this.getByIdOrThrow(qitemId);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* General state mutator. Routes through hot-potato strict-rejection on
|
|
454
|
+
* `done` transitions. All transitions append to the log.
|
|
455
|
+
*
|
|
456
|
+
* Phase B R2: emits queue.updated event atomically with the UPDATE +
|
|
457
|
+
* transition log append, so the view-event-bridge can wake SSE consumers
|
|
458
|
+
* on /api/views/:name/sse for normal state transitions (pending → blocked,
|
|
459
|
+
* in-progress → done, closure, escalation). Phase A write semantics are
|
|
460
|
+
* UNCHANGED — only an additional event emission inside the existing
|
|
461
|
+
* transaction. Per slice IMPL § Guard Checkpoint Focus item 9, this is
|
|
462
|
+
* an explicit narrow event-only extension to a Phase A write surface,
|
|
463
|
+
* justified by the R2 guard finding that update-path mutations were
|
|
464
|
+
* invisible to the view bridge.
|
|
465
|
+
*/
|
|
466
|
+
update(input) {
|
|
467
|
+
const txn = this.db.transaction(() => this.updateInTransactionalContext(input));
|
|
468
|
+
const persistedEvent = txn();
|
|
469
|
+
this.eventBus.notifySubscribers(persistedEvent);
|
|
470
|
+
return this.getByIdOrThrow(input.qitemId);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* PL-004 Phase D extension point (orch-ratified per slice IMPL Driver
|
|
474
|
+
* Handoff Contract / Guard R1 repair). Same closure validation +
|
|
475
|
+
* UPDATE + transition log + queue.updated event as update(), but
|
|
476
|
+
* runs inside the caller's outer db.transaction so it composes with
|
|
477
|
+
* workflow-projector's transactional-scribe contract.
|
|
478
|
+
*
|
|
479
|
+
* Caller MUST:
|
|
480
|
+
* 1. Invoke from inside a `db.transaction(() => {...})` block.
|
|
481
|
+
* 2. After the outer txn commits, call:
|
|
482
|
+
* eventBus.notifySubscribers(persistedEvent)
|
|
483
|
+
* 3. NOT call this from outside a transaction (will produce a
|
|
484
|
+
* half-state if the caller errors before committing).
|
|
485
|
+
*
|
|
486
|
+
* Closure validation runs at call time (before the UPDATE) so a
|
|
487
|
+
* Phase A invariant violation (e.g., state=done without closure_reason)
|
|
488
|
+
* throws before the workflow projector's outer transaction can commit
|
|
489
|
+
* any partial state. The Phase A hot-potato strict-rejection rule
|
|
490
|
+
* therefore applies to workflow projection unchanged.
|
|
491
|
+
*/
|
|
492
|
+
updateWithinTransaction(input) {
|
|
493
|
+
const persistedEvent = this.updateInTransactionalContext(input);
|
|
494
|
+
return { qitemId: input.qitemId, persistedEvent };
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Internal: closure validation + UPDATE + transition log + emit
|
|
498
|
+
* queue.updated event. Caller is responsible for transaction wrapping
|
|
499
|
+
* (the public update() wraps; the public updateWithinTransaction()
|
|
500
|
+
* composes inside the caller's outer transaction).
|
|
501
|
+
*/
|
|
502
|
+
updateInTransactionalContext(input) {
|
|
503
|
+
const qitem = this.getById(input.qitemId);
|
|
504
|
+
if (!qitem) {
|
|
505
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${input.qitemId} not found`);
|
|
506
|
+
}
|
|
507
|
+
if (!isQueueState(input.state)) {
|
|
508
|
+
throw new QueueRepositoryError("invalid_state", `state=${input.state} not valid; valid: ${QUEUE_STATES.join(", ")}`);
|
|
509
|
+
}
|
|
510
|
+
const validation = validateClosure({
|
|
511
|
+
state: input.state,
|
|
512
|
+
closureReason: input.closureReason ?? null,
|
|
513
|
+
closureTarget: input.closureTarget ?? null,
|
|
514
|
+
});
|
|
515
|
+
if (!validation.ok) {
|
|
516
|
+
throw new QueueRepositoryError(validation.code, validation.message, {
|
|
517
|
+
validReasons: "validReasons" in validation ? validation.validReasons : undefined,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
const ts = new Date().toISOString();
|
|
521
|
+
const fromState = qitem.state;
|
|
522
|
+
this.db
|
|
523
|
+
.prepare(`UPDATE queue_items
|
|
524
|
+
SET state = ?,
|
|
525
|
+
ts_updated = ?,
|
|
526
|
+
closure_reason = COALESCE(?, closure_reason),
|
|
527
|
+
closure_target = COALESCE(?, closure_target),
|
|
528
|
+
handed_off_to = COALESCE(?, handed_off_to),
|
|
529
|
+
blocked_on = COALESCE(?, blocked_on)
|
|
530
|
+
WHERE qitem_id = ?`)
|
|
531
|
+
.run(input.state, ts, validation.closureReason, validation.closureTarget, input.handedOffTo ?? null, input.blockedOn ?? null, input.qitemId);
|
|
532
|
+
this.transitionLog.append({
|
|
533
|
+
qitemId: input.qitemId,
|
|
534
|
+
state: input.state,
|
|
535
|
+
actorSession: input.actorSession,
|
|
536
|
+
transitionNote: input.transitionNote,
|
|
537
|
+
closureReason: validation.closureReason ?? undefined,
|
|
538
|
+
closureTarget: validation.closureTarget ?? undefined,
|
|
539
|
+
});
|
|
540
|
+
return this.eventBus.persistWithinTransaction({
|
|
541
|
+
type: "queue.updated",
|
|
542
|
+
qitemId: input.qitemId,
|
|
543
|
+
fromState,
|
|
544
|
+
toState: input.state,
|
|
545
|
+
closureReason: validation.closureReason ?? null,
|
|
546
|
+
closureTarget: validation.closureTarget ?? null,
|
|
547
|
+
actorSession: input.actorSession,
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
getById(qitemId) {
|
|
551
|
+
const row = this.db
|
|
552
|
+
.prepare("SELECT * FROM queue_items WHERE qitem_id = ?")
|
|
553
|
+
.get(qitemId);
|
|
554
|
+
return row ? this.rowToItem(row) : null;
|
|
555
|
+
}
|
|
556
|
+
list(opts) {
|
|
557
|
+
const limit = opts?.limit ?? 100;
|
|
558
|
+
const conditions = [];
|
|
559
|
+
const params = [];
|
|
560
|
+
if (opts?.destinationSession) {
|
|
561
|
+
conditions.push("destination_session = ?");
|
|
562
|
+
params.push(opts.destinationSession);
|
|
563
|
+
}
|
|
564
|
+
if (opts?.sourceSession) {
|
|
565
|
+
conditions.push("source_session = ?");
|
|
566
|
+
params.push(opts.sourceSession);
|
|
567
|
+
}
|
|
568
|
+
if (opts?.state) {
|
|
569
|
+
const states = Array.isArray(opts.state) ? opts.state : [opts.state];
|
|
570
|
+
const placeholders = states.map(() => "?").join(", ");
|
|
571
|
+
conditions.push(`state IN (${placeholders})`);
|
|
572
|
+
params.push(...states);
|
|
573
|
+
}
|
|
574
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
575
|
+
params.push(limit);
|
|
576
|
+
const rows = this.db
|
|
577
|
+
.prepare(`SELECT * FROM queue_items ${where} ORDER BY ts_created DESC LIMIT ?`)
|
|
578
|
+
.all(...params);
|
|
579
|
+
return rows.map((r) => this.rowToItem(r));
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Find qitems whose `closure_required_at` is past now. Used by watchdog;
|
|
583
|
+
* does NOT itself emit events — callers decide whether to nudge or escalate.
|
|
584
|
+
*/
|
|
585
|
+
findOverdue(now) {
|
|
586
|
+
const cutoff = now ?? new Date().toISOString();
|
|
587
|
+
const rows = this.db
|
|
588
|
+
.prepare(`SELECT * FROM queue_items
|
|
589
|
+
WHERE state = 'in-progress'
|
|
590
|
+
AND closure_required_at IS NOT NULL
|
|
591
|
+
AND closure_required_at <= ?`)
|
|
592
|
+
.all(cutoff);
|
|
593
|
+
return rows.map((r) => this.rowToItem(r));
|
|
594
|
+
}
|
|
595
|
+
recordNudgeAttempt(qitemId, result) {
|
|
596
|
+
const ts = new Date().toISOString();
|
|
597
|
+
this.db
|
|
598
|
+
.prepare(`UPDATE queue_items
|
|
599
|
+
SET last_nudge_attempt = ?, last_nudge_result = ?
|
|
600
|
+
WHERE qitem_id = ?`)
|
|
601
|
+
.run(ts, result, qitemId);
|
|
602
|
+
}
|
|
603
|
+
recordHeartbeat(qitemId) {
|
|
604
|
+
const ts = new Date().toISOString();
|
|
605
|
+
this.db
|
|
606
|
+
.prepare(`UPDATE queue_items SET last_heartbeat = ? WHERE qitem_id = ?`)
|
|
607
|
+
.run(ts, qitemId);
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Pod-fallback: redirect qitem to a fallback destination (e.g., when a seat
|
|
611
|
+
* is unreachable). Emits qitem.fallback_routed; preserves chain_of_record.
|
|
612
|
+
*/
|
|
613
|
+
routeToFallback(qitemId, fallbackDestination, reason) {
|
|
614
|
+
const qitem = this.getById(qitemId);
|
|
615
|
+
if (!qitem) {
|
|
616
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${qitemId} not found`);
|
|
617
|
+
}
|
|
618
|
+
const ts = new Date().toISOString();
|
|
619
|
+
const originalDestination = qitem.destinationSession;
|
|
620
|
+
const newChain = JSON.stringify([...(qitem.chainOfRecord ?? []), `fallback-from:${originalDestination}`]);
|
|
621
|
+
const txn = this.db.transaction(() => {
|
|
622
|
+
this.db
|
|
623
|
+
.prepare(`UPDATE queue_items
|
|
624
|
+
SET destination_session = ?,
|
|
625
|
+
ts_updated = ?,
|
|
626
|
+
chain_of_record = ?,
|
|
627
|
+
resolution = ?
|
|
628
|
+
WHERE qitem_id = ?`)
|
|
629
|
+
.run(fallbackDestination, ts, newChain, `fallback: ${reason}`, qitemId);
|
|
630
|
+
this.transitionLog.append({
|
|
631
|
+
qitemId,
|
|
632
|
+
state: qitem.state,
|
|
633
|
+
actorSession: "system:queue-fallback",
|
|
634
|
+
transitionNote: `fallback-routed: ${originalDestination} → ${fallbackDestination} (${reason})`,
|
|
635
|
+
});
|
|
636
|
+
return this.eventBus.persistWithinTransaction({
|
|
637
|
+
type: "qitem.fallback_routed",
|
|
638
|
+
qitemId,
|
|
639
|
+
originalDestination,
|
|
640
|
+
rerouteDestination: fallbackDestination,
|
|
641
|
+
reason,
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
const persistedEvent = txn();
|
|
645
|
+
this.eventBus.notifySubscribers(persistedEvent);
|
|
646
|
+
return this.getByIdOrThrow(qitemId);
|
|
647
|
+
}
|
|
648
|
+
getByIdOrThrow(qitemId) {
|
|
649
|
+
const item = this.getById(qitemId);
|
|
650
|
+
if (!item) {
|
|
651
|
+
throw new QueueRepositoryError("qitem_not_found", `qitem ${qitemId} not found after write`);
|
|
652
|
+
}
|
|
653
|
+
return item;
|
|
654
|
+
}
|
|
655
|
+
rowToItem(row) {
|
|
656
|
+
return {
|
|
657
|
+
qitemId: row.qitem_id,
|
|
658
|
+
tsCreated: row.ts_created,
|
|
659
|
+
tsUpdated: row.ts_updated,
|
|
660
|
+
sourceSession: row.source_session,
|
|
661
|
+
destinationSession: row.destination_session,
|
|
662
|
+
state: row.state,
|
|
663
|
+
priority: row.priority,
|
|
664
|
+
tier: row.tier,
|
|
665
|
+
tags: row.tags ? JSON.parse(row.tags) : null,
|
|
666
|
+
blockedOn: row.blocked_on,
|
|
667
|
+
handedOffTo: row.handed_off_to,
|
|
668
|
+
handedOffFrom: row.handed_off_from,
|
|
669
|
+
expiresAt: row.expires_at,
|
|
670
|
+
chainOfRecord: row.chain_of_record ? JSON.parse(row.chain_of_record) : null,
|
|
671
|
+
body: row.body,
|
|
672
|
+
closureReason: row.closure_reason,
|
|
673
|
+
closureTarget: row.closure_target,
|
|
674
|
+
closureRequiredAt: row.closure_required_at,
|
|
675
|
+
claimedAt: row.claimed_at,
|
|
676
|
+
lastNudgeAttempt: row.last_nudge_attempt,
|
|
677
|
+
lastNudgeResult: row.last_nudge_result,
|
|
678
|
+
lastHeartbeat: row.last_heartbeat,
|
|
679
|
+
resolution: row.resolution,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function isQueueState(value) {
|
|
684
|
+
return QUEUE_STATES.includes(value);
|
|
685
|
+
}
|
|
686
|
+
//# sourceMappingURL=queue-repository.js.map
|