@telora/daemon 0.12.33
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/.env.example +64 -0
- package/README.md +229 -0
- package/build-info.json +4 -0
- package/dist/activity-tracker.d.ts +13 -0
- package/dist/activity-tracker.d.ts.map +1 -0
- package/dist/activity-tracker.js +19 -0
- package/dist/activity-tracker.js.map +1 -0
- package/dist/agent-state.d.ts +45 -0
- package/dist/agent-state.d.ts.map +1 -0
- package/dist/agent-state.js +61 -0
- package/dist/agent-state.js.map +1 -0
- package/dist/audit-hooks.d.ts +12 -0
- package/dist/audit-hooks.d.ts.map +1 -0
- package/dist/audit-hooks.js +45 -0
- package/dist/audit-hooks.js.map +1 -0
- package/dist/auto-update.d.ts +42 -0
- package/dist/auto-update.d.ts.map +1 -0
- package/dist/auto-update.js +96 -0
- package/dist/auto-update.js.map +1 -0
- package/dist/branch-status.d.ts +40 -0
- package/dist/branch-status.d.ts.map +1 -0
- package/dist/branch-status.js +107 -0
- package/dist/branch-status.js.map +1 -0
- package/dist/completion-detector.d.ts +87 -0
- package/dist/completion-detector.d.ts.map +1 -0
- package/dist/completion-detector.js +160 -0
- package/dist/completion-detector.js.map +1 -0
- package/dist/completion-handler.d.ts +48 -0
- package/dist/completion-handler.d.ts.map +1 -0
- package/dist/completion-handler.js +200 -0
- package/dist/completion-handler.js.map +1 -0
- package/dist/condition-evaluators.d.ts +31 -0
- package/dist/condition-evaluators.d.ts.map +1 -0
- package/dist/condition-evaluators.js +416 -0
- package/dist/condition-evaluators.js.map +1 -0
- package/dist/config.d.ts +55 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +311 -0
- package/dist/config.js.map +1 -0
- package/dist/control-state.d.ts +41 -0
- package/dist/control-state.d.ts.map +1 -0
- package/dist/control-state.js +204 -0
- package/dist/control-state.js.map +1 -0
- package/dist/crash-recovery-cleanup.d.ts +21 -0
- package/dist/crash-recovery-cleanup.d.ts.map +1 -0
- package/dist/crash-recovery-cleanup.js +198 -0
- package/dist/crash-recovery-cleanup.js.map +1 -0
- package/dist/crash-recovery-scan.d.ts +19 -0
- package/dist/crash-recovery-scan.d.ts.map +1 -0
- package/dist/crash-recovery-scan.js +145 -0
- package/dist/crash-recovery-scan.js.map +1 -0
- package/dist/crash-recovery-types.d.ts +54 -0
- package/dist/crash-recovery-types.d.ts.map +1 -0
- package/dist/crash-recovery-types.js +13 -0
- package/dist/crash-recovery-types.js.map +1 -0
- package/dist/crash-recovery.d.ts +88 -0
- package/dist/crash-recovery.d.ts.map +1 -0
- package/dist/crash-recovery.js +448 -0
- package/dist/crash-recovery.js.map +1 -0
- package/dist/daemon-logs.d.ts +19 -0
- package/dist/daemon-logs.d.ts.map +1 -0
- package/dist/daemon-logs.js +81 -0
- package/dist/daemon-logs.js.map +1 -0
- package/dist/daemon-process.d.ts +154 -0
- package/dist/daemon-process.d.ts.map +1 -0
- package/dist/daemon-process.js +427 -0
- package/dist/daemon-process.js.map +1 -0
- package/dist/dag-validator.d.ts +52 -0
- package/dist/dag-validator.d.ts.map +1 -0
- package/dist/dag-validator.js +199 -0
- package/dist/dag-validator.js.map +1 -0
- package/dist/delivery-guards.d.ts +41 -0
- package/dist/delivery-guards.d.ts.map +1 -0
- package/dist/delivery-guards.js +195 -0
- package/dist/delivery-guards.js.map +1 -0
- package/dist/delivery-lifecycle.d.ts +110 -0
- package/dist/delivery-lifecycle.d.ts.map +1 -0
- package/dist/delivery-lifecycle.js +353 -0
- package/dist/delivery-lifecycle.js.map +1 -0
- package/dist/delivery-merge.d.ts +17 -0
- package/dist/delivery-merge.d.ts.map +1 -0
- package/dist/delivery-merge.js +89 -0
- package/dist/delivery-merge.js.map +1 -0
- package/dist/dependency-resolver.d.ts +77 -0
- package/dist/dependency-resolver.d.ts.map +1 -0
- package/dist/dependency-resolver.js +337 -0
- package/dist/dependency-resolver.js.map +1 -0
- package/dist/evaluation-context.d.ts +49 -0
- package/dist/evaluation-context.d.ts.map +1 -0
- package/dist/evaluation-context.js +98 -0
- package/dist/evaluation-context.js.map +1 -0
- package/dist/git-activity.d.ts +24 -0
- package/dist/git-activity.d.ts.map +1 -0
- package/dist/git-activity.js +97 -0
- package/dist/git-activity.js.map +1 -0
- package/dist/git-branch.d.ts +33 -0
- package/dist/git-branch.d.ts.map +1 -0
- package/dist/git-branch.js +88 -0
- package/dist/git-branch.js.map +1 -0
- package/dist/git-integration.d.ts +27 -0
- package/dist/git-integration.d.ts.map +1 -0
- package/dist/git-integration.js +82 -0
- package/dist/git-integration.js.map +1 -0
- package/dist/git-merge-helpers.d.ts +48 -0
- package/dist/git-merge-helpers.d.ts.map +1 -0
- package/dist/git-merge-helpers.js +105 -0
- package/dist/git-merge-helpers.js.map +1 -0
- package/dist/git-merge-lock.d.ts +67 -0
- package/dist/git-merge-lock.d.ts.map +1 -0
- package/dist/git-merge-lock.js +157 -0
- package/dist/git-merge-lock.js.map +1 -0
- package/dist/git-merge-strategies.d.ts +39 -0
- package/dist/git-merge-strategies.d.ts.map +1 -0
- package/dist/git-merge-strategies.js +127 -0
- package/dist/git-merge-strategies.js.map +1 -0
- package/dist/git-merge.d.ts +80 -0
- package/dist/git-merge.d.ts.map +1 -0
- package/dist/git-merge.js +373 -0
- package/dist/git-merge.js.map +1 -0
- package/dist/git-state-detector.d.ts +24 -0
- package/dist/git-state-detector.d.ts.map +1 -0
- package/dist/git-state-detector.js +122 -0
- package/dist/git-state-detector.js.map +1 -0
- package/dist/git-types.d.ts +40 -0
- package/dist/git-types.d.ts.map +1 -0
- package/dist/git-types.js +23 -0
- package/dist/git-types.js.map +1 -0
- package/dist/git-utils.d.ts +28 -0
- package/dist/git-utils.d.ts.map +1 -0
- package/dist/git-utils.js +57 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/git.d.ts +24 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +64 -0
- package/dist/git.js.map +1 -0
- package/dist/guard-engine.d.ts +19 -0
- package/dist/guard-engine.d.ts.map +1 -0
- package/dist/guard-engine.js +21 -0
- package/dist/guard-engine.js.map +1 -0
- package/dist/guard-evaluator.d.ts +47 -0
- package/dist/guard-evaluator.d.ts.map +1 -0
- package/dist/guard-evaluator.js +193 -0
- package/dist/guard-evaluator.js.map +1 -0
- package/dist/heartbeat.d.ts +73 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +306 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +493 -0
- package/dist/index.js.map +1 -0
- package/dist/listener-auto-advance.d.ts +29 -0
- package/dist/listener-auto-advance.d.ts.map +1 -0
- package/dist/listener-auto-advance.js +172 -0
- package/dist/listener-auto-advance.js.map +1 -0
- package/dist/listener-review.d.ts +37 -0
- package/dist/listener-review.d.ts.map +1 -0
- package/dist/listener-review.js +217 -0
- package/dist/listener-review.js.map +1 -0
- package/dist/listener.d.ts +57 -0
- package/dist/listener.d.ts.map +1 -0
- package/dist/listener.js +361 -0
- package/dist/listener.js.map +1 -0
- package/dist/log-manager.d.ts +18 -0
- package/dist/log-manager.d.ts.map +1 -0
- package/dist/log-manager.js +18 -0
- package/dist/log-manager.js.map +1 -0
- package/dist/otlp-log-parser.d.ts +21 -0
- package/dist/otlp-log-parser.d.ts.map +1 -0
- package/dist/otlp-log-parser.js +143 -0
- package/dist/otlp-log-parser.js.map +1 -0
- package/dist/otlp-metric-parser.d.ts +20 -0
- package/dist/otlp-metric-parser.d.ts.map +1 -0
- package/dist/otlp-metric-parser.js +113 -0
- package/dist/otlp-metric-parser.js.map +1 -0
- package/dist/otlp-port-manager.d.ts +26 -0
- package/dist/otlp-port-manager.d.ts.map +1 -0
- package/dist/otlp-port-manager.js +130 -0
- package/dist/otlp-port-manager.js.map +1 -0
- package/dist/otlp-receiver.d.ts +51 -0
- package/dist/otlp-receiver.d.ts.map +1 -0
- package/dist/otlp-receiver.js +663 -0
- package/dist/otlp-receiver.js.map +1 -0
- package/dist/otlp-types.d.ts +92 -0
- package/dist/otlp-types.d.ts.map +1 -0
- package/dist/otlp-types.js +133 -0
- package/dist/otlp-types.js.map +1 -0
- package/dist/output-monitor.d.ts +33 -0
- package/dist/output-monitor.d.ts.map +1 -0
- package/dist/output-monitor.js +67 -0
- package/dist/output-monitor.js.map +1 -0
- package/dist/planning-prompt-builder.d.ts +67 -0
- package/dist/planning-prompt-builder.d.ts.map +1 -0
- package/dist/planning-prompt-builder.js +515 -0
- package/dist/planning-prompt-builder.js.map +1 -0
- package/dist/prompt-builder.d.ts +14 -0
- package/dist/prompt-builder.d.ts.map +1 -0
- package/dist/prompt-builder.js +174 -0
- package/dist/prompt-builder.js.map +1 -0
- package/dist/qa-crash-recovery.d.ts +77 -0
- package/dist/qa-crash-recovery.d.ts.map +1 -0
- package/dist/qa-crash-recovery.js +243 -0
- package/dist/qa-crash-recovery.js.map +1 -0
- package/dist/qa-dev-server.d.ts +73 -0
- package/dist/qa-dev-server.d.ts.map +1 -0
- package/dist/qa-dev-server.js +279 -0
- package/dist/qa-dev-server.js.map +1 -0
- package/dist/qa-orchestrator.d.ts +79 -0
- package/dist/qa-orchestrator.d.ts.map +1 -0
- package/dist/qa-orchestrator.js +349 -0
- package/dist/qa-orchestrator.js.map +1 -0
- package/dist/qa-port-allocator.d.ts +34 -0
- package/dist/qa-port-allocator.d.ts.map +1 -0
- package/dist/qa-port-allocator.js +75 -0
- package/dist/qa-port-allocator.js.map +1 -0
- package/dist/qa-provisioner.d.ts +33 -0
- package/dist/qa-provisioner.d.ts.map +1 -0
- package/dist/qa-provisioner.js +141 -0
- package/dist/qa-provisioner.js.map +1 -0
- package/dist/qa-state.d.ts +93 -0
- package/dist/qa-state.d.ts.map +1 -0
- package/dist/qa-state.js +74 -0
- package/dist/qa-state.js.map +1 -0
- package/dist/queries/control-state.d.ts +25 -0
- package/dist/queries/control-state.d.ts.map +1 -0
- package/dist/queries/control-state.js +34 -0
- package/dist/queries/control-state.js.map +1 -0
- package/dist/queries/daemon-connection.d.ts +25 -0
- package/dist/queries/daemon-connection.d.ts.map +1 -0
- package/dist/queries/daemon-connection.js +28 -0
- package/dist/queries/daemon-connection.js.map +1 -0
- package/dist/queries/deliveries.d.ts +100 -0
- package/dist/queries/deliveries.d.ts.map +1 -0
- package/dist/queries/deliveries.js +184 -0
- package/dist/queries/deliveries.js.map +1 -0
- package/dist/queries/git-activity.d.ts +20 -0
- package/dist/queries/git-activity.d.ts.map +1 -0
- package/dist/queries/git-activity.js +22 -0
- package/dist/queries/git-activity.js.map +1 -0
- package/dist/queries/guards.d.ts +47 -0
- package/dist/queries/guards.d.ts.map +1 -0
- package/dist/queries/guards.js +138 -0
- package/dist/queries/guards.js.map +1 -0
- package/dist/queries/index.d.ts +19 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +17 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/issues.d.ts +41 -0
- package/dist/queries/issues.d.ts.map +1 -0
- package/dist/queries/issues.js +67 -0
- package/dist/queries/issues.js.map +1 -0
- package/dist/queries/qa.d.ts +79 -0
- package/dist/queries/qa.d.ts.map +1 -0
- package/dist/queries/qa.js +85 -0
- package/dist/queries/qa.js.map +1 -0
- package/dist/queries/roles.d.ts +13 -0
- package/dist/queries/roles.d.ts.map +1 -0
- package/dist/queries/roles.js +39 -0
- package/dist/queries/roles.js.map +1 -0
- package/dist/queries/schemas.d.ts +777 -0
- package/dist/queries/schemas.d.ts.map +1 -0
- package/dist/queries/schemas.js +391 -0
- package/dist/queries/schemas.js.map +1 -0
- package/dist/queries/sessions.d.ts +64 -0
- package/dist/queries/sessions.d.ts.map +1 -0
- package/dist/queries/sessions.js +100 -0
- package/dist/queries/sessions.js.map +1 -0
- package/dist/queries/shared.d.ts +61 -0
- package/dist/queries/shared.d.ts.map +1 -0
- package/dist/queries/shared.js +187 -0
- package/dist/queries/shared.js.map +1 -0
- package/dist/queries/strategies.d.ts +69 -0
- package/dist/queries/strategies.d.ts.map +1 -0
- package/dist/queries/strategies.js +80 -0
- package/dist/queries/strategies.js.map +1 -0
- package/dist/queries/workflows.d.ts +17 -0
- package/dist/queries/workflows.d.ts.map +1 -0
- package/dist/queries/workflows.js +49 -0
- package/dist/queries/workflows.js.map +1 -0
- package/dist/queries/worktrees.d.ts +38 -0
- package/dist/queries/worktrees.d.ts.map +1 -0
- package/dist/queries/worktrees.js +37 -0
- package/dist/queries/worktrees.js.map +1 -0
- package/dist/self-update.d.ts +94 -0
- package/dist/self-update.d.ts.map +1 -0
- package/dist/self-update.js +438 -0
- package/dist/self-update.js.map +1 -0
- package/dist/session-lifecycle.d.ts +77 -0
- package/dist/session-lifecycle.d.ts.map +1 -0
- package/dist/session-lifecycle.js +379 -0
- package/dist/session-lifecycle.js.map +1 -0
- package/dist/shutdown-state.d.ts +17 -0
- package/dist/shutdown-state.d.ts.map +1 -0
- package/dist/shutdown-state.js +22 -0
- package/dist/shutdown-state.js.map +1 -0
- package/dist/spawn-cooldown.d.ts +14 -0
- package/dist/spawn-cooldown.d.ts.map +1 -0
- package/dist/spawn-cooldown.js +34 -0
- package/dist/spawn-cooldown.js.map +1 -0
- package/dist/spawn-environment.d.ts +35 -0
- package/dist/spawn-environment.d.ts.map +1 -0
- package/dist/spawn-environment.js +48 -0
- package/dist/spawn-environment.js.map +1 -0
- package/dist/spawner-liveness.d.ts +23 -0
- package/dist/spawner-liveness.d.ts.map +1 -0
- package/dist/spawner-liveness.js +99 -0
- package/dist/spawner-liveness.js.map +1 -0
- package/dist/spawner-resolution.d.ts +27 -0
- package/dist/spawner-resolution.d.ts.map +1 -0
- package/dist/spawner-resolution.js +99 -0
- package/dist/spawner-resolution.js.map +1 -0
- package/dist/spawner-timeout.d.ts +32 -0
- package/dist/spawner-timeout.d.ts.map +1 -0
- package/dist/spawner-timeout.js +124 -0
- package/dist/spawner-timeout.js.map +1 -0
- package/dist/spawner.d.ts +77 -0
- package/dist/spawner.d.ts.map +1 -0
- package/dist/spawner.js +734 -0
- package/dist/spawner.js.map +1 -0
- package/dist/strategy-completion.d.ts +110 -0
- package/dist/strategy-completion.d.ts.map +1 -0
- package/dist/strategy-completion.js +434 -0
- package/dist/strategy-completion.js.map +1 -0
- package/dist/strategy-engine.d.ts +47 -0
- package/dist/strategy-engine.d.ts.map +1 -0
- package/dist/strategy-engine.js +419 -0
- package/dist/strategy-engine.js.map +1 -0
- package/dist/strategy-executor.d.ts +93 -0
- package/dist/strategy-executor.d.ts.map +1 -0
- package/dist/strategy-executor.js +775 -0
- package/dist/strategy-executor.js.map +1 -0
- package/dist/strategy-lifecycle.d.ts +61 -0
- package/dist/strategy-lifecycle.d.ts.map +1 -0
- package/dist/strategy-lifecycle.js +516 -0
- package/dist/strategy-lifecycle.js.map +1 -0
- package/dist/strategy-merge.d.ts +72 -0
- package/dist/strategy-merge.d.ts.map +1 -0
- package/dist/strategy-merge.js +371 -0
- package/dist/strategy-merge.js.map +1 -0
- package/dist/strategy-prompt-builder.d.ts +62 -0
- package/dist/strategy-prompt-builder.d.ts.map +1 -0
- package/dist/strategy-prompt-builder.js +538 -0
- package/dist/strategy-prompt-builder.js.map +1 -0
- package/dist/strategy-provisioning.d.ts +16 -0
- package/dist/strategy-provisioning.d.ts.map +1 -0
- package/dist/strategy-provisioning.js +119 -0
- package/dist/strategy-provisioning.js.map +1 -0
- package/dist/strategy-team-state.d.ts +24 -0
- package/dist/strategy-team-state.d.ts.map +1 -0
- package/dist/strategy-team-state.js +43 -0
- package/dist/strategy-team-state.js.map +1 -0
- package/dist/strategy-teardown.d.ts +24 -0
- package/dist/strategy-teardown.d.ts.map +1 -0
- package/dist/strategy-teardown.js +158 -0
- package/dist/strategy-teardown.js.map +1 -0
- package/dist/strategy-worktree-state.d.ts +47 -0
- package/dist/strategy-worktree-state.d.ts.map +1 -0
- package/dist/strategy-worktree-state.js +104 -0
- package/dist/strategy-worktree-state.js.map +1 -0
- package/dist/supabase.d.ts +36 -0
- package/dist/supabase.d.ts.map +1 -0
- package/dist/supabase.js +50 -0
- package/dist/supabase.js.map +1 -0
- package/dist/task-converter.d.ts +61 -0
- package/dist/task-converter.d.ts.map +1 -0
- package/dist/task-converter.js +286 -0
- package/dist/task-converter.js.map +1 -0
- package/dist/task-dag-builder.d.ts +14 -0
- package/dist/task-dag-builder.d.ts.map +1 -0
- package/dist/task-dag-builder.js +17 -0
- package/dist/task-dag-builder.js.map +1 -0
- package/dist/team-prompt-base.d.ts +114 -0
- package/dist/team-prompt-base.d.ts.map +1 -0
- package/dist/team-prompt-base.js +531 -0
- package/dist/team-prompt-base.js.map +1 -0
- package/dist/team-prompt-variants.d.ts +27 -0
- package/dist/team-prompt-variants.d.ts.map +1 -0
- package/dist/team-prompt-variants.js +134 -0
- package/dist/team-prompt-variants.js.map +1 -0
- package/dist/team-spawner.d.ts +50 -0
- package/dist/team-spawner.d.ts.map +1 -0
- package/dist/team-spawner.js +410 -0
- package/dist/team-spawner.js.map +1 -0
- package/dist/telemetry-writer.d.ts +66 -0
- package/dist/telemetry-writer.d.ts.map +1 -0
- package/dist/telemetry-writer.js +96 -0
- package/dist/telemetry-writer.js.map +1 -0
- package/dist/trigger-executor.d.ts +56 -0
- package/dist/trigger-executor.d.ts.map +1 -0
- package/dist/trigger-executor.js +313 -0
- package/dist/trigger-executor.js.map +1 -0
- package/dist/types/config.d.ts +60 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/dag.d.ts +53 -0
- package/dist/types/dag.d.ts.map +1 -0
- package/dist/types/dag.js +5 -0
- package/dist/types/dag.js.map +1 -0
- package/dist/types/delivery.d.ts +71 -0
- package/dist/types/delivery.d.ts.map +1 -0
- package/dist/types/delivery.js +5 -0
- package/dist/types/delivery.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +15 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/issue.d.ts +22 -0
- package/dist/types/issue.d.ts.map +1 -0
- package/dist/types/issue.js +5 -0
- package/dist/types/issue.js.map +1 -0
- package/dist/types/merge.d.ts +28 -0
- package/dist/types/merge.d.ts.map +1 -0
- package/dist/types/merge.js +5 -0
- package/dist/types/merge.js.map +1 -0
- package/dist/types/session.d.ts +98 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +5 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/strategy.d.ts +175 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +5 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/types/workflow.d.ts +34 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +9 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/unified-init.d.ts +16 -0
- package/dist/unified-init.d.ts.map +1 -0
- package/dist/unified-init.js +183 -0
- package/dist/unified-init.js.map +1 -0
- package/dist/unified-shell-config.d.ts +34 -0
- package/dist/unified-shell-config.d.ts.map +1 -0
- package/dist/unified-shell-config.js +238 -0
- package/dist/unified-shell-config.js.map +1 -0
- package/dist/unified-shell-status.d.ts +15 -0
- package/dist/unified-shell-status.d.ts.map +1 -0
- package/dist/unified-shell-status.js +100 -0
- package/dist/unified-shell-status.js.map +1 -0
- package/dist/unified-shell.d.ts +50 -0
- package/dist/unified-shell.d.ts.map +1 -0
- package/dist/unified-shell.js +682 -0
- package/dist/unified-shell.js.map +1 -0
- package/dist/version-check.d.ts +19 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +67 -0
- package/dist/version-check.js.map +1 -0
- package/dist/workflow-engine.d.ts +95 -0
- package/dist/workflow-engine.d.ts.map +1 -0
- package/dist/workflow-engine.js +165 -0
- package/dist/workflow-engine.js.map +1 -0
- package/dist/worktree-merge.d.ts +23 -0
- package/dist/worktree-merge.d.ts.map +1 -0
- package/dist/worktree-merge.js +57 -0
- package/dist/worktree-merge.js.map +1 -0
- package/dist/worktree-safety.d.ts +48 -0
- package/dist/worktree-safety.d.ts.map +1 -0
- package/dist/worktree-safety.js +113 -0
- package/dist/worktree-safety.js.map +1 -0
- package/dist/worktree-strategy.d.ts +69 -0
- package/dist/worktree-strategy.d.ts.map +1 -0
- package/dist/worktree-strategy.js +214 -0
- package/dist/worktree-strategy.js.map +1 -0
- package/dist/worktree.d.ts +159 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +512 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +76 -0
- package/scripts/telora-daemon-wrapper.sh +31 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt builder - constructs the initial prompt for Claude Code agents.
|
|
3
|
+
*
|
|
4
|
+
* Assembles full delivery context including product vision, strategy,
|
|
5
|
+
* pipeline position, work structure (context groups and tasks),
|
|
6
|
+
* and guard directives into a structured markdown prompt.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Build the prompt for the agent with full delivery context.
|
|
10
|
+
* When guardDirective is provided, it's injected as a governance section.
|
|
11
|
+
*/
|
|
12
|
+
export function buildDeliveryPrompt(role, context, guardDirective) {
|
|
13
|
+
const parts = [];
|
|
14
|
+
// Role context
|
|
15
|
+
if (role.system_prompt_template) {
|
|
16
|
+
parts.push(role.system_prompt_template);
|
|
17
|
+
parts.push('');
|
|
18
|
+
}
|
|
19
|
+
// Domain boundaries
|
|
20
|
+
if (role.allowed_file_patterns.length > 0) {
|
|
21
|
+
parts.push('## Domain Boundaries');
|
|
22
|
+
parts.push('You are authorized to work on files matching these patterns:');
|
|
23
|
+
for (const pattern of role.allowed_file_patterns) {
|
|
24
|
+
parts.push(`- ${pattern}`);
|
|
25
|
+
}
|
|
26
|
+
parts.push('');
|
|
27
|
+
}
|
|
28
|
+
// Product vision -- north star for judgment calls
|
|
29
|
+
if (context.product) {
|
|
30
|
+
parts.push('## Product');
|
|
31
|
+
parts.push(`**${context.product.name}**`);
|
|
32
|
+
if (context.product.vision) {
|
|
33
|
+
parts.push(`**Vision:** ${context.product.vision}`);
|
|
34
|
+
}
|
|
35
|
+
if (context.product.target_audience) {
|
|
36
|
+
parts.push(`**Target Audience:** ${context.product.target_audience}`);
|
|
37
|
+
}
|
|
38
|
+
parts.push('');
|
|
39
|
+
}
|
|
40
|
+
// Strategy context -- the semantic throughline connecting deliveries
|
|
41
|
+
if (context.strategy) {
|
|
42
|
+
parts.push('## Strategy');
|
|
43
|
+
parts.push(`**${context.strategy.name}**`);
|
|
44
|
+
if (context.strategy.description) {
|
|
45
|
+
parts.push(context.strategy.description);
|
|
46
|
+
}
|
|
47
|
+
parts.push('');
|
|
48
|
+
parts.push('This delivery is part of the above strategy. Use this strategic context to guide scope decisions and prioritization.');
|
|
49
|
+
parts.push('');
|
|
50
|
+
}
|
|
51
|
+
// Pipeline context -- show where this delivery sits in the strategy sequence
|
|
52
|
+
if (context.pipelineDeliveries.length > 1) {
|
|
53
|
+
parts.push('## Pipeline');
|
|
54
|
+
for (let i = 0; i < context.pipelineDeliveries.length; i++) {
|
|
55
|
+
const sibling = context.pipelineDeliveries[i];
|
|
56
|
+
const status = sibling.executionStatus ?? 'draft';
|
|
57
|
+
const isCurrent = sibling.id === context.delivery.id;
|
|
58
|
+
const marker = isCurrent ? ' <-- you are here' : '';
|
|
59
|
+
parts.push(`${i + 1}. [${status}] ${sibling.name}${marker}`);
|
|
60
|
+
}
|
|
61
|
+
parts.push('');
|
|
62
|
+
parts.push('Complete your delivery with awareness of what downstream deliveries will need from your output.');
|
|
63
|
+
parts.push('');
|
|
64
|
+
}
|
|
65
|
+
// Delivery assignment -- keep prompt lean, agent pulls details via MCP
|
|
66
|
+
parts.push('## Delivery Assignment');
|
|
67
|
+
parts.push(`**Delivery ID:** ${context.delivery.id}`);
|
|
68
|
+
parts.push(`**Delivery:** ${context.delivery.name}`);
|
|
69
|
+
if (context.delivery.description) {
|
|
70
|
+
parts.push(`**Description:** ${context.delivery.description}`);
|
|
71
|
+
}
|
|
72
|
+
if (context.acceptanceCriteria) {
|
|
73
|
+
parts.push('');
|
|
74
|
+
parts.push('**Acceptance Criteria:**');
|
|
75
|
+
parts.push(context.acceptanceCriteria);
|
|
76
|
+
}
|
|
77
|
+
if (context.techContext) {
|
|
78
|
+
parts.push('');
|
|
79
|
+
parts.push('**Technical Context:**');
|
|
80
|
+
parts.push(context.techContext);
|
|
81
|
+
}
|
|
82
|
+
parts.push('');
|
|
83
|
+
// Work structure -- render Context Groups so agent understands grouping, context, and scope
|
|
84
|
+
const hasIssues = context.contextGroups.length > 0;
|
|
85
|
+
if (hasIssues) {
|
|
86
|
+
parts.push('## Work Structure');
|
|
87
|
+
parts.push('');
|
|
88
|
+
const realGroups = context.contextGroups.filter(g => g.children.length > 0);
|
|
89
|
+
const standalone = context.contextGroups.filter(g => g.children.length === 0);
|
|
90
|
+
for (const group of realGroups) {
|
|
91
|
+
const { issue, children } = group;
|
|
92
|
+
parts.push(`### Group: "${issue.title}"`);
|
|
93
|
+
if (issue.context) {
|
|
94
|
+
parts.push('**Context:**');
|
|
95
|
+
parts.push(issue.context);
|
|
96
|
+
parts.push('');
|
|
97
|
+
}
|
|
98
|
+
if (issue.relevant_files) {
|
|
99
|
+
parts.push('**Relevant Files:**');
|
|
100
|
+
for (const fileLine of issue.relevant_files.split('\n')) {
|
|
101
|
+
const trimmed = fileLine.trim();
|
|
102
|
+
if (trimmed)
|
|
103
|
+
parts.push(`- ${trimmed}`);
|
|
104
|
+
}
|
|
105
|
+
parts.push('');
|
|
106
|
+
}
|
|
107
|
+
parts.push('**Tasks:**');
|
|
108
|
+
for (const child of children) {
|
|
109
|
+
const checkbox = child.status === 'Done' ? '[x]' : '[ ]';
|
|
110
|
+
const label = child.key ? `${child.key}: ${child.title}` : child.title;
|
|
111
|
+
parts.push(`- ${checkbox} ${label} (${child.status})`);
|
|
112
|
+
}
|
|
113
|
+
parts.push('');
|
|
114
|
+
}
|
|
115
|
+
if (standalone.length > 0) {
|
|
116
|
+
parts.push('### Standalone Tasks');
|
|
117
|
+
for (const item of standalone) {
|
|
118
|
+
const checkbox = item.issue.status === 'Done' ? '[x]' : '[ ]';
|
|
119
|
+
const label = item.issue.key ? `${item.issue.key}: ${item.issue.title}` : item.issue.title;
|
|
120
|
+
parts.push(`- ${checkbox} ${label} (${item.issue.status})`);
|
|
121
|
+
}
|
|
122
|
+
parts.push('');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Guard directive -- injected when delivery resumes after human routing decision
|
|
126
|
+
if (guardDirective) {
|
|
127
|
+
parts.push('## Guard Directive');
|
|
128
|
+
parts.push('The following governance directive has been set by a guard decision. Follow these instructions in addition to the delivery requirements:');
|
|
129
|
+
parts.push('');
|
|
130
|
+
parts.push(guardDirective);
|
|
131
|
+
parts.push('');
|
|
132
|
+
}
|
|
133
|
+
// Mandatory status update rules
|
|
134
|
+
parts.push('## Status Update Rules (MANDATORY)');
|
|
135
|
+
parts.push('');
|
|
136
|
+
parts.push('- Every issue MUST follow: To Do -> In Progress -> Done');
|
|
137
|
+
parts.push('- NEVER skip "In Progress". Set it BEFORE starting any work on an issue.');
|
|
138
|
+
parts.push('- NEVER move an issue directly from "To Do" to "Done".');
|
|
139
|
+
parts.push('- Use `telora_product_issue_update`:');
|
|
140
|
+
parts.push(' - Start work: `{ "issueId": "<id>", "status": "In Progress" }`');
|
|
141
|
+
parts.push(' - Finish work: `{ "issueId": "<id>", "status": "Done" }`');
|
|
142
|
+
parts.push('');
|
|
143
|
+
// Instructions -- adapt based on whether the delivery has issues
|
|
144
|
+
parts.push('## Instructions');
|
|
145
|
+
if (hasIssues) {
|
|
146
|
+
parts.push('1. Read the CLAUDE.md file at the repo root for repository conventions before starting implementation');
|
|
147
|
+
parts.push('2. Review the Work Structure above for context and relevant files per group');
|
|
148
|
+
parts.push(`3. Use \`telora_product_issue_list\` with deliveryId "${context.delivery.id}" to get current work items (issues may have been added or updated since this prompt was built)`);
|
|
149
|
+
parts.push('4. Work through groups in order. Within each group, complete all child tasks before moving to the next group.');
|
|
150
|
+
parts.push('5. For each task:');
|
|
151
|
+
parts.push(' - Update its status to "In Progress" using `telora_product_issue_update`');
|
|
152
|
+
parts.push(' - Implement the required changes, focusing on the relevant files listed for its group');
|
|
153
|
+
parts.push(' - Create commits as you make progress');
|
|
154
|
+
parts.push(' - Update status to "Done" when complete');
|
|
155
|
+
parts.push('6. If you discover work not covered by existing issues, create new issues using `telora_product_issue_create` — assign them to the appropriate Context Group via parentIssueId, or create them as standalone tasks');
|
|
156
|
+
parts.push('7. If you get stuck or need human input, use `telora_agent_escalate`');
|
|
157
|
+
parts.push('8. Before finishing, re-query `telora_product_issue_list` and verify EVERY issue is Done. If any remain open, either complete them or escalate — do not exit with incomplete work');
|
|
158
|
+
parts.push('9. When all items are Done, summarize the changes made');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
parts.push('1. Read the CLAUDE.md file at the repo root for repository conventions before starting implementation');
|
|
162
|
+
parts.push('2. Implement the acceptance criteria above — that is your work breakdown');
|
|
163
|
+
parts.push(`3. Check \`telora_product_issue_list\` with deliveryId "${context.delivery.id}" in case issues have been added since this prompt was generated`);
|
|
164
|
+
parts.push('4. Create commits as you make progress');
|
|
165
|
+
parts.push('5. If you discover work not covered by existing issues, create new issues using `telora_product_issue_create`');
|
|
166
|
+
parts.push(' For any issues created, follow the Status Update Rules above (In Progress before Done)');
|
|
167
|
+
parts.push('6. If you get stuck or need human input, use `telora_agent_escalate`');
|
|
168
|
+
parts.push('7. Before finishing, re-query `telora_product_issue_list` and verify all issues are Done if any were created');
|
|
169
|
+
parts.push('8. When done, summarize the changes made');
|
|
170
|
+
}
|
|
171
|
+
parts.push('');
|
|
172
|
+
return parts.join('\n');
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../src/prompt-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA environment crash recovery.
|
|
3
|
+
*
|
|
4
|
+
* When the daemon crashes, QA dev server processes may be left in inconsistent
|
|
5
|
+
* states. This module runs on daemon startup AFTER normal crash recovery to
|
|
6
|
+
* reconcile QA-specific state.
|
|
7
|
+
*
|
|
8
|
+
* Under the persistent worktree model, QA does not own its own worktrees.
|
|
9
|
+
* Recovery is purely DB-driven: query strategies with QA state and reset
|
|
10
|
+
* dead dev servers to 'requested' for re-provisioning by the poll loop.
|
|
11
|
+
*
|
|
12
|
+
* Runs after recoverFromCrash() and before startListeners().
|
|
13
|
+
*/
|
|
14
|
+
import type { DaemonConfig } from './types.js';
|
|
15
|
+
export interface QaRecoveryDeps {
|
|
16
|
+
getQaStrategies: () => Promise<Array<{
|
|
17
|
+
strategyId: string;
|
|
18
|
+
strategyName: string;
|
|
19
|
+
qaStatus: string | null;
|
|
20
|
+
qaWorktreePath: string | null;
|
|
21
|
+
qaPort: number | null;
|
|
22
|
+
strategyStatus: string;
|
|
23
|
+
}>>;
|
|
24
|
+
updateQaStatus: (strategyId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface QaRecoveryResult {
|
|
27
|
+
strategiesWithQa: number;
|
|
28
|
+
resetToRequested: number;
|
|
29
|
+
deactivatedTeardowns: number;
|
|
30
|
+
errors: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reconcile QA environments after a daemon crash.
|
|
34
|
+
*
|
|
35
|
+
* DB-driven recovery: queries strategies with active QA states and handles:
|
|
36
|
+
*
|
|
37
|
+
* 1. 'ready': Dev server died in crash. Reset to 'requested' for re-provision.
|
|
38
|
+
* 2. 'provisioning': Crashed mid-provision. Reset to 'requested'.
|
|
39
|
+
* 3. 'requested': Normal (daemon was down). Leave for poll loop.
|
|
40
|
+
* 4. 'stop_requested': Leave for poll loop to handle.
|
|
41
|
+
* 5. Deactivated strategy: Clear QA state. Worktree cleanup handled by
|
|
42
|
+
* strategy lifecycle (teardownStrategy).
|
|
43
|
+
*
|
|
44
|
+
* Safe to call multiple times -- idempotent by design.
|
|
45
|
+
*/
|
|
46
|
+
export declare function reconcileQaEnvironments(config: DaemonConfig, deps: QaRecoveryDeps): Promise<QaRecoveryResult>;
|
|
47
|
+
export interface ProductQaRecoveryDeps {
|
|
48
|
+
getProductQaStatus: (productId: string) => Promise<{
|
|
49
|
+
productId: string;
|
|
50
|
+
productName: string;
|
|
51
|
+
qaStatus: string | null;
|
|
52
|
+
qaPort: number | null;
|
|
53
|
+
qaWorktreePath: string | null;
|
|
54
|
+
productStatus: string;
|
|
55
|
+
}>;
|
|
56
|
+
updateProductQaStatus: (productId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
57
|
+
removeQaWorktree: (repoPath: string, worktreePath: string) => void;
|
|
58
|
+
}
|
|
59
|
+
export interface ProductQaRecoveryResult {
|
|
60
|
+
hadQaState: boolean;
|
|
61
|
+
resetToRequested: boolean;
|
|
62
|
+
cleared: boolean;
|
|
63
|
+
errors: string[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Reconcile product-level QA environment after a daemon crash.
|
|
67
|
+
*
|
|
68
|
+
* Handles:
|
|
69
|
+
* 1. 'ready': Dev server died in crash. Reset to 'requested' for re-provision.
|
|
70
|
+
* 2. 'provisioning': Crashed mid-provision. Clean up worktree, reset to 'requested'.
|
|
71
|
+
* 3. 'requested': Normal. Leave for poll loop.
|
|
72
|
+
* 4. 'stop_requested': Clean up worktree, clear to null.
|
|
73
|
+
*
|
|
74
|
+
* Safe to call multiple times -- idempotent by design.
|
|
75
|
+
*/
|
|
76
|
+
export declare function reconcileProductQaEnvironment(config: DaemonConfig, deps: ProductQaRecoveryDeps): Promise<ProductQaRecoveryResult>;
|
|
77
|
+
//# sourceMappingURL=qa-crash-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-crash-recovery.d.ts","sourceRoot":"","sources":["../src/qa-crash-recovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC,CAAC;IACJ,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxF;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA+C3B;AAmGD,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;QACjD,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;IACH,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,uBAAuB,CAAC,CA+GlC"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA environment crash recovery.
|
|
3
|
+
*
|
|
4
|
+
* When the daemon crashes, QA dev server processes may be left in inconsistent
|
|
5
|
+
* states. This module runs on daemon startup AFTER normal crash recovery to
|
|
6
|
+
* reconcile QA-specific state.
|
|
7
|
+
*
|
|
8
|
+
* Under the persistent worktree model, QA does not own its own worktrees.
|
|
9
|
+
* Recovery is purely DB-driven: query strategies with QA state and reset
|
|
10
|
+
* dead dev servers to 'requested' for re-provisioning by the poll loop.
|
|
11
|
+
*
|
|
12
|
+
* Runs after recoverFromCrash() and before startListeners().
|
|
13
|
+
*/
|
|
14
|
+
// -- Main entry point -------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Reconcile QA environments after a daemon crash.
|
|
17
|
+
*
|
|
18
|
+
* DB-driven recovery: queries strategies with active QA states and handles:
|
|
19
|
+
*
|
|
20
|
+
* 1. 'ready': Dev server died in crash. Reset to 'requested' for re-provision.
|
|
21
|
+
* 2. 'provisioning': Crashed mid-provision. Reset to 'requested'.
|
|
22
|
+
* 3. 'requested': Normal (daemon was down). Leave for poll loop.
|
|
23
|
+
* 4. 'stop_requested': Leave for poll loop to handle.
|
|
24
|
+
* 5. Deactivated strategy: Clear QA state. Worktree cleanup handled by
|
|
25
|
+
* strategy lifecycle (teardownStrategy).
|
|
26
|
+
*
|
|
27
|
+
* Safe to call multiple times -- idempotent by design.
|
|
28
|
+
*/
|
|
29
|
+
export async function reconcileQaEnvironments(config, deps) {
|
|
30
|
+
console.log('[qa-recovery] Starting QA environment recovery scan...');
|
|
31
|
+
const result = {
|
|
32
|
+
strategiesWithQa: 0,
|
|
33
|
+
resetToRequested: 0,
|
|
34
|
+
deactivatedTeardowns: 0,
|
|
35
|
+
errors: [],
|
|
36
|
+
};
|
|
37
|
+
// Query DB for strategies with active QA states
|
|
38
|
+
let strategies;
|
|
39
|
+
try {
|
|
40
|
+
strategies = await deps.getQaStrategies();
|
|
41
|
+
result.strategiesWithQa = strategies.length;
|
|
42
|
+
console.log(`[qa-recovery] Found ${strategies.length} strategy/strategies with QA state in DB`);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const msg = `Failed to query QA strategies from DB: ${err instanceof Error ? err.message : String(err)}`;
|
|
46
|
+
console.error(`[qa-recovery] ${msg}`);
|
|
47
|
+
result.errors.push(msg);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
// Process each strategy with QA state
|
|
51
|
+
for (const strategy of strategies) {
|
|
52
|
+
try {
|
|
53
|
+
await handleStrategyRecovery(strategy, config, deps, result);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const msg = `Error recovering QA for strategy ${strategy.strategyId} (${strategy.strategyName}): ${err instanceof Error ? err.message : String(err)}`;
|
|
57
|
+
console.error(`[qa-recovery] ${msg}`);
|
|
58
|
+
result.errors.push(msg);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Summary
|
|
62
|
+
console.log(`[qa-recovery] Recovery complete: ` +
|
|
63
|
+
`${result.strategiesWithQa} strategy/strategies with QA state, ` +
|
|
64
|
+
`${result.resetToRequested} reset to requested, ` +
|
|
65
|
+
`${result.deactivatedTeardowns} deactivated teardown(s)`);
|
|
66
|
+
if (result.errors.length > 0) {
|
|
67
|
+
console.warn(`[qa-recovery] ${result.errors.length} error(s) during recovery (non-fatal)`);
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
// -- Internal helpers -------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Handle recovery for a single strategy based on its QA status.
|
|
74
|
+
*/
|
|
75
|
+
async function handleStrategyRecovery(strategy, _config, deps, result) {
|
|
76
|
+
const { strategyId, strategyName, qaStatus, strategyStatus } = strategy;
|
|
77
|
+
const label = `${strategyId.slice(0, 8)} (${strategyName})`;
|
|
78
|
+
// Deactivated strategy -- clear QA DB state.
|
|
79
|
+
// Worktree removal is handled by strategy lifecycle (teardownStrategy / rebuildStrategyWorktreeState).
|
|
80
|
+
if (strategyStatus !== 'active') {
|
|
81
|
+
console.log(`[qa-recovery] Strategy ${label}: status is '${strategyStatus}' (not active) with qa_status '${qaStatus}'. ` +
|
|
82
|
+
`Clearing QA state.`);
|
|
83
|
+
await deps.updateQaStatus(strategyId, {
|
|
84
|
+
qaStatus: null,
|
|
85
|
+
qaUrl: null,
|
|
86
|
+
qaPort: null,
|
|
87
|
+
qaWorktreePath: null,
|
|
88
|
+
qaRequestedAt: null,
|
|
89
|
+
qaReadyAt: null,
|
|
90
|
+
qaError: null,
|
|
91
|
+
});
|
|
92
|
+
result.deactivatedTeardowns++;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
switch (qaStatus) {
|
|
96
|
+
case 'ready': {
|
|
97
|
+
// Dev server died in crash. Reset to 'requested' so poll loop re-provisions.
|
|
98
|
+
console.log(`[qa-recovery] Strategy ${label}: dev server dead (daemon crashed). Resetting to 'requested'.`);
|
|
99
|
+
await deps.updateQaStatus(strategyId, { qaStatus: 'requested' });
|
|
100
|
+
result.resetToRequested++;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case 'provisioning': {
|
|
104
|
+
// Crashed mid-provision. Reset to 'requested'.
|
|
105
|
+
console.log(`[qa-recovery] Strategy ${label}: crashed mid-provision. Resetting to 'requested'.`);
|
|
106
|
+
await deps.updateQaStatus(strategyId, {
|
|
107
|
+
qaStatus: 'requested',
|
|
108
|
+
qaWorktreePath: null,
|
|
109
|
+
qaPort: null,
|
|
110
|
+
});
|
|
111
|
+
result.resetToRequested++;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'requested': {
|
|
115
|
+
// Normal -- daemon was down when request came in. Leave for poll loop.
|
|
116
|
+
console.log(`[qa-recovery] Strategy ${label}: 'requested' -- leaving for poll loop.`);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case 'stop_requested': {
|
|
120
|
+
// Leave for poll loop to handle.
|
|
121
|
+
console.log(`[qa-recovery] Strategy ${label}: 'stop_requested' -- leaving for poll loop.`);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
default: {
|
|
125
|
+
if (qaStatus != null) {
|
|
126
|
+
console.log(`[qa-recovery] Strategy ${label}: unexpected qa_status '${qaStatus}' -- no action taken.`);
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Reconcile product-level QA environment after a daemon crash.
|
|
134
|
+
*
|
|
135
|
+
* Handles:
|
|
136
|
+
* 1. 'ready': Dev server died in crash. Reset to 'requested' for re-provision.
|
|
137
|
+
* 2. 'provisioning': Crashed mid-provision. Clean up worktree, reset to 'requested'.
|
|
138
|
+
* 3. 'requested': Normal. Leave for poll loop.
|
|
139
|
+
* 4. 'stop_requested': Clean up worktree, clear to null.
|
|
140
|
+
*
|
|
141
|
+
* Safe to call multiple times -- idempotent by design.
|
|
142
|
+
*/
|
|
143
|
+
export async function reconcileProductQaEnvironment(config, deps) {
|
|
144
|
+
console.log('[product-qa-recovery] Starting product QA environment recovery scan...');
|
|
145
|
+
const result = {
|
|
146
|
+
hadQaState: false,
|
|
147
|
+
resetToRequested: false,
|
|
148
|
+
cleared: false,
|
|
149
|
+
errors: [],
|
|
150
|
+
};
|
|
151
|
+
let product;
|
|
152
|
+
try {
|
|
153
|
+
product = await deps.getProductQaStatus(config.productId);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
const msg = `Failed to query product QA status: ${err instanceof Error ? err.message : String(err)}`;
|
|
157
|
+
console.error(`[product-qa-recovery] ${msg}`);
|
|
158
|
+
result.errors.push(msg);
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
if (!product.qaStatus) {
|
|
162
|
+
console.log('[product-qa-recovery] No product QA state in DB -- nothing to recover.');
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
result.hadQaState = true;
|
|
166
|
+
const label = `${product.productId.slice(0, 8)} (${product.productName})`;
|
|
167
|
+
switch (product.qaStatus) {
|
|
168
|
+
case 'ready':
|
|
169
|
+
case 'provisioning': {
|
|
170
|
+
// Dev server died in crash. Clean up stale worktree and reset to 'requested'.
|
|
171
|
+
const reason = product.qaStatus === 'ready' ? 'dev server dead (daemon crashed)' : 'crashed mid-provision';
|
|
172
|
+
console.log(`[product-qa-recovery] Product ${label}: ${reason}. Resetting to 'requested'.`);
|
|
173
|
+
// Remove stale worktree so re-provision creates a fresh one
|
|
174
|
+
if (product.qaWorktreePath) {
|
|
175
|
+
try {
|
|
176
|
+
deps.removeQaWorktree(config.repoPath, product.qaWorktreePath);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
console.warn(`[product-qa-recovery] Failed to remove stale worktree: ${err instanceof Error ? err.message : String(err)}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
await deps.updateProductQaStatus(config.productId, {
|
|
184
|
+
qaStatus: 'requested',
|
|
185
|
+
qaPort: null,
|
|
186
|
+
qaWorktreePath: null,
|
|
187
|
+
});
|
|
188
|
+
result.resetToRequested = true;
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
const msg = `Failed to reset product QA: ${err instanceof Error ? err.message : String(err)}`;
|
|
192
|
+
console.error(`[product-qa-recovery] ${msg}`);
|
|
193
|
+
result.errors.push(msg);
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
case 'requested': {
|
|
198
|
+
// Normal -- daemon was down when request came in. Leave for poll loop.
|
|
199
|
+
console.log(`[product-qa-recovery] Product ${label}: 'requested' -- leaving for poll loop.`);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case 'stop_requested': {
|
|
203
|
+
// Daemon was down when user requested stop. Clean up worktree and clear state.
|
|
204
|
+
console.log(`[product-qa-recovery] Product ${label}: 'stop_requested' -- clearing QA state.`);
|
|
205
|
+
if (product.qaWorktreePath) {
|
|
206
|
+
try {
|
|
207
|
+
deps.removeQaWorktree(config.repoPath, product.qaWorktreePath);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
console.warn(`[product-qa-recovery] Failed to remove worktree: ${err instanceof Error ? err.message : String(err)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
await deps.updateProductQaStatus(config.productId, {
|
|
215
|
+
qaStatus: null,
|
|
216
|
+
qaUrl: null,
|
|
217
|
+
qaPort: null,
|
|
218
|
+
qaWorktreePath: null,
|
|
219
|
+
qaReadyAt: null,
|
|
220
|
+
qaError: null,
|
|
221
|
+
});
|
|
222
|
+
result.cleared = true;
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
const msg = `Failed to clear product QA: ${err instanceof Error ? err.message : String(err)}`;
|
|
226
|
+
console.error(`[product-qa-recovery] ${msg}`);
|
|
227
|
+
result.errors.push(msg);
|
|
228
|
+
}
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
default: {
|
|
232
|
+
console.log(`[product-qa-recovery] Product ${label}: unexpected qa_status '${product.qaStatus}' -- no action taken.`);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
console.log(`[product-qa-recovery] Recovery complete: ` +
|
|
237
|
+
`hadQaState=${result.hadQaState}, resetToRequested=${result.resetToRequested}, cleared=${result.cleared}`);
|
|
238
|
+
if (result.errors.length > 0) {
|
|
239
|
+
console.warn(`[product-qa-recovery] ${result.errors.length} error(s) during recovery (non-fatal)`);
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=qa-crash-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-crash-recovery.js","sourceRoot":"","sources":["../src/qa-crash-recovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA dev server spawn and health monitoring.
|
|
3
|
+
*
|
|
4
|
+
* Manages the lifecycle of Vite dev servers in QA worktrees:
|
|
5
|
+
* runs npm install, spawns `npm run dev` on an allocated port,
|
|
6
|
+
* streams stdout/stderr to log files, and provides stop/health helpers.
|
|
7
|
+
*/
|
|
8
|
+
import type { DaemonConfig } from './types.js';
|
|
9
|
+
/** Options for starting a QA dev server. */
|
|
10
|
+
export interface StartQaDevServerOptions {
|
|
11
|
+
/** Daemon configuration (for logDir). */
|
|
12
|
+
config: DaemonConfig;
|
|
13
|
+
/** Strategy UUID (used for log directory naming). */
|
|
14
|
+
strategyId: string;
|
|
15
|
+
/** Absolute path to the QA worktree. */
|
|
16
|
+
worktreePath: string;
|
|
17
|
+
/** Port to bind the dev server to. */
|
|
18
|
+
port: number;
|
|
19
|
+
/** Callback invoked if the dev server exits unexpectedly. */
|
|
20
|
+
onUnexpectedExit: (error: string) => void;
|
|
21
|
+
}
|
|
22
|
+
/** Result from a successful dev server start. */
|
|
23
|
+
export interface StartQaDevServerResult {
|
|
24
|
+
/** PID of the spawned dev server process. */
|
|
25
|
+
pid: number;
|
|
26
|
+
/** Absolute path to the stdout log file. */
|
|
27
|
+
stdoutPath: string;
|
|
28
|
+
/** Absolute path to the stderr log file. */
|
|
29
|
+
stderrPath: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Install dependencies and spawn a dev server in a QA worktree.
|
|
33
|
+
*
|
|
34
|
+
* 1. Runs `npm install` synchronously in the worktree.
|
|
35
|
+
* 2. Spawns `npm run dev` with `PORT` env var set to the allocated port.
|
|
36
|
+
* 3. Pipes stdout/stderr to log files under `{logDir}/qa-{strategyId-prefix}/`.
|
|
37
|
+
* 4. Registers an on-exit handler that calls `onUnexpectedExit` if the
|
|
38
|
+
* process exits without an intentional stop.
|
|
39
|
+
*
|
|
40
|
+
* @returns The child process PID and log file paths.
|
|
41
|
+
* @throws If npm install fails or the dev server process cannot be spawned.
|
|
42
|
+
*/
|
|
43
|
+
export declare function startQaDevServer(options: StartQaDevServerOptions): StartQaDevServerResult;
|
|
44
|
+
/**
|
|
45
|
+
* Gracefully stop a running QA dev server.
|
|
46
|
+
*
|
|
47
|
+
* Sends SIGTERM first, then escalates to SIGKILL if the process
|
|
48
|
+
* does not exit within the grace period.
|
|
49
|
+
*/
|
|
50
|
+
export declare function stopQaDevServer(pid: number): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if a QA dev server process is still alive.
|
|
53
|
+
*
|
|
54
|
+
* Uses the `process.kill(pid, 0)` pattern which sends no signal
|
|
55
|
+
* but throws if the process does not exist.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isQaDevServerRunning(pid: number): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Build the browser-accessible Supabase URL for a QA environment.
|
|
60
|
+
*
|
|
61
|
+
* The local Supabase typically listens on 127.0.0.1:54321, but the QA
|
|
62
|
+
* browser is remote (e.g. on a different machine). Replace the host
|
|
63
|
+
* portion with the daemon's LAN IP (qaHost) so the browser can reach it.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildQaSupabaseUrl(localSupabaseUrl: string, qaHost: string): string;
|
|
66
|
+
type DevFramework = 'vite' | 'nextjs' | 'unknown';
|
|
67
|
+
/**
|
|
68
|
+
* Detect the dev framework from the project's package.json.
|
|
69
|
+
* Checks devDependencies and dependencies for known frameworks.
|
|
70
|
+
*/
|
|
71
|
+
export declare function detectFramework(worktreePath: string): DevFramework;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=qa-dev-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qa-dev-server.d.ts","sourceRoot":"","sources":["../src/qa-dev-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,MAAM,EAAE,YAAY,CAAC;IACrB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,iDAAiD;AACjD,MAAM,WAAW,sBAAsB;IACrC,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CAmHzF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuChE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOzD;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASnF;AAED,KAAK,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAclE"}
|