@telora/daemon 0.15.1 → 0.15.3
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/README.md +11 -11
- package/build-info.json +2 -2
- package/dist/assembly-engine.d.ts +1 -1
- package/dist/assembly-engine.d.ts.map +1 -1
- package/dist/assembly-resolvers.js +41 -41
- package/dist/assembly-resolvers.js.map +1 -1
- package/dist/branch-status.d.ts +4 -4
- package/dist/branch-status.d.ts.map +1 -1
- package/dist/branch-status.js +23 -23
- package/dist/branch-status.js.map +1 -1
- package/dist/cli/connect.js +1 -1
- package/dist/cli/connect.js.map +1 -1
- package/dist/completion-detector.d.ts +1 -1
- package/dist/completion-detector.js +1 -1
- package/dist/completion-handler.d.ts +1 -1
- package/dist/completion-handler.js +4 -4
- package/dist/completion-handler.js.map +1 -1
- package/dist/condition-evaluators.js +4 -4
- package/dist/condition-evaluators.js.map +1 -1
- package/dist/control-state.d.ts +6 -6
- package/dist/control-state.d.ts.map +1 -1
- package/dist/control-state.js +43 -43
- package/dist/control-state.js.map +1 -1
- package/dist/crash-recovery-scan.d.ts +1 -1
- package/dist/crash-recovery-scan.js +20 -20
- package/dist/crash-recovery-scan.js.map +1 -1
- package/dist/crash-recovery-types.d.ts +3 -3
- package/dist/crash-recovery-types.d.ts.map +1 -1
- package/dist/crash-recovery-types.js +2 -2
- package/dist/crash-recovery-types.js.map +1 -1
- package/dist/crash-recovery.d.ts +3 -3
- package/dist/crash-recovery.d.ts.map +1 -1
- package/dist/crash-recovery.js +21 -21
- package/dist/crash-recovery.js.map +1 -1
- package/dist/daemon-process.d.ts +1 -1
- package/dist/daemon-process.d.ts.map +1 -1
- package/dist/dag-validator.d.ts +6 -6
- package/dist/dag-validator.d.ts.map +1 -1
- package/dist/dag-validator.js +2 -2
- package/dist/dag-validator.js.map +1 -1
- package/dist/delivery-guards.d.ts +1 -1
- package/dist/delivery-guards.js +1 -1
- package/dist/delivery-lifecycle.d.ts +5 -5
- package/dist/delivery-lifecycle.d.ts.map +1 -1
- package/dist/delivery-lifecycle.js +12 -12
- package/dist/delivery-lifecycle.js.map +1 -1
- package/dist/delivery-merge.js +1 -1
- package/dist/delivery-merge.js.map +1 -1
- package/dist/dependency-resolver.d.ts +7 -7
- package/dist/dependency-resolver.d.ts.map +1 -1
- package/dist/dependency-resolver.js.map +1 -1
- package/dist/directive-executor.d.ts +15 -15
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +76 -76
- package/dist/directive-executor.js.map +1 -1
- package/dist/evaluation-context.d.ts +2 -2
- package/dist/evaluation-context.d.ts.map +1 -1
- package/dist/evaluation-context.js +4 -4
- package/dist/evaluation-context.js.map +1 -1
- package/dist/focus-completion-event.d.ts +97 -0
- package/dist/focus-completion-event.d.ts.map +1 -0
- package/dist/focus-completion-event.js +257 -0
- package/dist/focus-completion-event.js.map +1 -0
- package/dist/focus-completion.d.ts +85 -0
- package/dist/focus-completion.d.ts.map +1 -0
- package/dist/focus-completion.js +459 -0
- package/dist/focus-completion.js.map +1 -0
- package/dist/focus-engine.d.ts +47 -0
- package/dist/focus-engine.d.ts.map +1 -0
- package/dist/focus-engine.js +421 -0
- package/dist/focus-engine.js.map +1 -0
- package/dist/focus-executor.d.ts +55 -0
- package/dist/focus-executor.d.ts.map +1 -0
- package/dist/focus-executor.js +549 -0
- package/dist/focus-executor.js.map +1 -0
- package/dist/focus-lifecycle.d.ts +61 -0
- package/dist/focus-lifecycle.d.ts.map +1 -0
- package/dist/focus-lifecycle.js +544 -0
- package/dist/focus-lifecycle.js.map +1 -0
- package/dist/focus-merge.d.ts +77 -0
- package/dist/focus-merge.d.ts.map +1 -0
- package/dist/focus-merge.js +378 -0
- package/dist/focus-merge.js.map +1 -0
- package/dist/focus-prompt-builder.d.ts +35 -0
- package/dist/focus-prompt-builder.d.ts.map +1 -0
- package/dist/focus-prompt-builder.js +138 -0
- package/dist/focus-prompt-builder.js.map +1 -0
- package/dist/focus-provisioning.d.ts +16 -0
- package/dist/focus-provisioning.d.ts.map +1 -0
- package/dist/focus-provisioning.js +119 -0
- package/dist/focus-provisioning.js.map +1 -0
- package/dist/focus-spawn-helpers.d.ts +67 -0
- package/dist/focus-spawn-helpers.d.ts.map +1 -0
- package/dist/focus-spawn-helpers.js +160 -0
- package/dist/focus-spawn-helpers.js.map +1 -0
- package/dist/focus-team-lifecycle.d.ts +50 -0
- package/dist/focus-team-lifecycle.d.ts.map +1 -0
- package/dist/focus-team-lifecycle.js +256 -0
- package/dist/focus-team-lifecycle.js.map +1 -0
- package/dist/focus-team-state.d.ts +24 -0
- package/dist/focus-team-state.d.ts.map +1 -0
- package/dist/focus-team-state.js +43 -0
- package/dist/focus-team-state.js.map +1 -0
- package/dist/focus-worktree-state.d.ts +47 -0
- package/dist/focus-worktree-state.d.ts.map +1 -0
- package/dist/focus-worktree-state.js +104 -0
- package/dist/focus-worktree-state.js.map +1 -0
- package/dist/git-merge.d.ts +5 -5
- package/dist/git-merge.d.ts.map +1 -1
- package/dist/git-merge.js +5 -5
- package/dist/git-merge.js.map +1 -1
- package/dist/git-state-detector.d.ts +1 -1
- package/dist/git-state-detector.js +9 -9
- package/dist/git-state-detector.js.map +1 -1
- package/dist/git-utils.d.ts +1 -1
- package/dist/git-utils.js +1 -1
- package/dist/git.d.ts +2 -2
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +3 -3
- package/dist/git.js.map +1 -1
- package/dist/heartbeat.d.ts +4 -4
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +7 -7
- package/dist/heartbeat.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/listener-auto-advance.d.ts +2 -2
- package/dist/listener-auto-advance.js +21 -21
- package/dist/listener-auto-advance.js.map +1 -1
- package/dist/listener.d.ts +12 -12
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +80 -75
- package/dist/listener.js.map +1 -1
- package/dist/loop-engine.d.ts +20 -20
- package/dist/loop-engine.d.ts.map +1 -1
- package/dist/loop-engine.js +82 -82
- package/dist/loop-engine.js.map +1 -1
- package/dist/loop-event-bus.d.ts +5 -5
- package/dist/loop-event-bus.d.ts.map +1 -1
- package/dist/loop-event-bus.js +3 -3
- package/dist/loop-llm-client.d.ts +1 -1
- package/dist/loop-llm-client.js +1 -1
- package/dist/loop-variance.d.ts +1 -1
- package/dist/loop-variance.js +1 -1
- package/dist/merge-detector.d.ts +6 -6
- package/dist/merge-detector.d.ts.map +1 -1
- package/dist/merge-detector.js +47 -47
- package/dist/merge-detector.js.map +1 -1
- package/dist/otlp-log-parser.js +2 -2
- package/dist/otlp-log-parser.js.map +1 -1
- package/dist/otlp-metric-parser.js +1 -1
- package/dist/otlp-metric-parser.js.map +1 -1
- package/dist/otlp-receiver.d.ts +1 -1
- package/dist/otlp-receiver.js +7 -7
- package/dist/otlp-receiver.js.map +1 -1
- package/dist/otlp-types.d.ts +1 -1
- package/dist/otlp-types.d.ts.map +1 -1
- package/dist/otlp-types.js +3 -3
- package/dist/otlp-types.js.map +1 -1
- package/dist/output-monitor.d.ts +6 -6
- package/dist/output-monitor.d.ts.map +1 -1
- package/dist/output-monitor.js +11 -11
- package/dist/output-monitor.js.map +1 -1
- package/dist/planning-prompt-builder.d.ts +17 -15
- package/dist/planning-prompt-builder.d.ts.map +1 -1
- package/dist/planning-prompt-builder.js +34 -32
- package/dist/planning-prompt-builder.js.map +1 -1
- package/dist/pm/mitigation-correlator.d.ts +7 -7
- package/dist/pm/mitigation-correlator.d.ts.map +1 -1
- package/dist/pm/mitigation-correlator.js +33 -33
- package/dist/pm/mitigation-correlator.js.map +1 -1
- package/dist/pm-engine.js +1 -1
- package/dist/pm-engine.js.map +1 -1
- package/dist/prompt-builder.d.ts +1 -1
- package/dist/prompt-builder.js +9 -9
- package/dist/prompt-builder.js.map +1 -1
- package/dist/prompts/starter-prompt.d.ts +2 -2
- package/dist/prompts/starter-prompt.d.ts.map +1 -1
- package/dist/prompts/starter-prompt.js +6 -6
- package/dist/qa-crash-recovery.d.ts +10 -10
- package/dist/qa-crash-recovery.d.ts.map +1 -1
- package/dist/qa-crash-recovery.js +32 -32
- package/dist/qa-crash-recovery.js.map +1 -1
- package/dist/qa-dev-server.d.ts +3 -3
- package/dist/qa-dev-server.d.ts.map +1 -1
- package/dist/qa-dev-server.js +3 -3
- package/dist/qa-dev-server.js.map +1 -1
- package/dist/qa-orchestrator.d.ts +18 -18
- package/dist/qa-orchestrator.d.ts.map +1 -1
- package/dist/qa-orchestrator.js +47 -47
- package/dist/qa-orchestrator.js.map +1 -1
- package/dist/qa-provisioner.d.ts +3 -3
- package/dist/qa-provisioner.d.ts.map +1 -1
- package/dist/qa-provisioner.js +14 -14
- package/dist/qa-provisioner.js.map +1 -1
- package/dist/qa-state.d.ts +10 -10
- package/dist/qa-state.d.ts.map +1 -1
- package/dist/qa-state.js +11 -11
- package/dist/qa-state.js.map +1 -1
- package/dist/queries/control-state.d.ts +5 -5
- package/dist/queries/control-state.d.ts.map +1 -1
- package/dist/queries/control-state.js +4 -4
- package/dist/queries/control-state.js.map +1 -1
- package/dist/queries/deliveries.d.ts +28 -24
- package/dist/queries/deliveries.d.ts.map +1 -1
- package/dist/queries/deliveries.js +32 -28
- package/dist/queries/deliveries.js.map +1 -1
- package/dist/queries/focuses.d.ts +97 -0
- package/dist/queries/focuses.d.ts.map +1 -0
- package/dist/queries/focuses.js +136 -0
- package/dist/queries/focuses.js.map +1 -0
- package/dist/queries/index.d.ts +3 -3
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +2 -2
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/qa.d.ts +16 -16
- package/dist/queries/qa.d.ts.map +1 -1
- package/dist/queries/qa.js +22 -22
- package/dist/queries/qa.js.map +1 -1
- package/dist/queries/schemas.d.ts +40 -34
- package/dist/queries/schemas.d.ts.map +1 -1
- package/dist/queries/schemas.js +31 -26
- package/dist/queries/schemas.js.map +1 -1
- package/dist/queries/sessions.d.ts +1 -1
- package/dist/queries/sessions.d.ts.map +1 -1
- package/dist/queries/sessions.js +2 -2
- package/dist/queries/sessions.js.map +1 -1
- package/dist/queries/shared.js +10 -10
- package/dist/queries/shared.js.map +1 -1
- package/dist/queries/workflows.d.ts +1 -1
- package/dist/queries/workflows.js +1 -1
- package/dist/queries/worktrees.d.ts +7 -7
- package/dist/queries/worktrees.d.ts.map +1 -1
- package/dist/queries/worktrees.js +7 -7
- package/dist/queries/worktrees.js.map +1 -1
- package/dist/review-defect-detector.d.ts +125 -0
- package/dist/review-defect-detector.d.ts.map +1 -0
- package/dist/review-defect-detector.js +289 -0
- package/dist/review-defect-detector.js.map +1 -0
- package/dist/session-lifecycle.d.ts +17 -17
- package/dist/session-lifecycle.d.ts.map +1 -1
- package/dist/session-lifecycle.js +82 -82
- package/dist/session-lifecycle.js.map +1 -1
- package/dist/spawn-cooldown.d.ts +8 -8
- package/dist/spawn-cooldown.d.ts.map +1 -1
- package/dist/spawn-cooldown.js +15 -15
- package/dist/spawn-cooldown.js.map +1 -1
- package/dist/spawn-environment.d.ts +2 -2
- package/dist/spawn-environment.d.ts.map +1 -1
- package/dist/spawn-environment.js +3 -3
- package/dist/spawn-environment.js.map +1 -1
- package/dist/spawner-lifecycle.d.ts +2 -2
- package/dist/spawner-lifecycle.d.ts.map +1 -1
- package/dist/spawner-lifecycle.js +3 -3
- package/dist/spawner-lifecycle.js.map +1 -1
- package/dist/spawner-resolution.d.ts +3 -3
- package/dist/spawner-resolution.d.ts.map +1 -1
- package/dist/spawner-resolution.js +4 -4
- package/dist/spawner-resolution.js.map +1 -1
- package/dist/spawner-stream-handlers.js +2 -2
- package/dist/spawner-stream-handlers.js.map +1 -1
- package/dist/spawner.d.ts +1 -1
- package/dist/spawner.d.ts.map +1 -1
- package/dist/spawner.js +6 -6
- package/dist/spawner.js.map +1 -1
- package/dist/stage-classifier.d.ts +1 -1
- package/dist/stage-classifier.js +1 -1
- package/dist/state-cascade.d.ts +25 -25
- package/dist/state-cascade.d.ts.map +1 -1
- package/dist/state-cascade.js +89 -89
- package/dist/state-cascade.js.map +1 -1
- package/dist/strategy-completion-event.d.ts +37 -3
- package/dist/strategy-completion-event.d.ts.map +1 -1
- package/dist/strategy-completion-event.js +78 -9
- package/dist/strategy-completion-event.js.map +1 -1
- package/dist/strategy-completion.d.ts +11 -0
- package/dist/strategy-completion.d.ts.map +1 -1
- package/dist/strategy-completion.js +22 -1
- package/dist/strategy-completion.js.map +1 -1
- package/dist/strategy-executor.d.ts.map +1 -1
- package/dist/strategy-executor.js +46 -14
- package/dist/strategy-executor.js.map +1 -1
- package/dist/strategy-merge.d.ts.map +1 -1
- package/dist/strategy-merge.js +4 -0
- package/dist/strategy-merge.js.map +1 -1
- package/dist/strategy-team-lifecycle.d.ts.map +1 -1
- package/dist/strategy-team-lifecycle.js +3 -0
- package/dist/strategy-team-lifecycle.js.map +1 -1
- package/dist/supabase.d.ts +4 -4
- package/dist/supabase.d.ts.map +1 -1
- package/dist/supabase.js +5 -5
- package/dist/supabase.js.map +1 -1
- package/dist/task-converter.d.ts +4 -4
- package/dist/task-converter.d.ts.map +1 -1
- package/dist/task-converter.js +1 -1
- package/dist/task-converter.js.map +1 -1
- package/dist/team-prompt-base.d.ts +59 -19
- package/dist/team-prompt-base.d.ts.map +1 -1
- package/dist/team-prompt-base.js +206 -25
- package/dist/team-prompt-base.js.map +1 -1
- package/dist/team-spawner.d.ts +9 -9
- package/dist/team-spawner.d.ts.map +1 -1
- package/dist/team-spawner.js +87 -83
- package/dist/team-spawner.js.map +1 -1
- package/dist/telemetry-writer.d.ts +2 -2
- package/dist/telemetry-writer.d.ts.map +1 -1
- package/dist/templates/claude-md.js +8 -8
- package/dist/templates/claude-settings.d.ts +1 -1
- package/dist/templates/claude-settings.js +2 -2
- package/dist/templates/claude-settings.js.map +1 -1
- package/dist/trigger-executor.d.ts +4 -4
- package/dist/trigger-executor.d.ts.map +1 -1
- package/dist/trigger-executor.js +11 -11
- package/dist/trigger-executor.js.map +1 -1
- package/dist/types/dag.d.ts +1 -1
- package/dist/types/delivery.d.ts +3 -3
- package/dist/types/delivery.d.ts.map +1 -1
- package/dist/types/focus.d.ts +214 -0
- package/dist/types/focus.d.ts.map +1 -0
- package/dist/types/focus.js +5 -0
- package/dist/types/focus.js.map +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/merge.d.ts +1 -1
- package/dist/types/session.d.ts +2 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/strategy.d.ts +7 -0
- package/dist/types/strategy.d.ts.map +1 -1
- package/dist/unified-engine-lifecycle.js +11 -11
- package/dist/unified-engine-lifecycle.js.map +1 -1
- package/dist/unified-init.d.ts +1 -1
- package/dist/unified-init.js +9 -9
- package/dist/unified-init.js.map +1 -1
- package/dist/unified-shell-config.d.ts +4 -4
- package/dist/unified-shell-config.d.ts.map +1 -1
- package/dist/unified-shell-config.js +5 -5
- package/dist/unified-shell-config.js.map +1 -1
- package/dist/unified-shell-status.js +3 -3
- package/dist/unified-shell-status.js.map +1 -1
- package/dist/unified-shell.d.ts +1 -1
- package/dist/unified-shell.js +4 -4
- package/dist/unified-shell.js.map +1 -1
- package/dist/workflow-engine.d.ts +1 -1
- package/dist/workflow-engine.d.ts.map +1 -1
- package/dist/worktree-focus.d.ts +69 -0
- package/dist/worktree-focus.d.ts.map +1 -0
- package/dist/worktree-focus.js +214 -0
- package/dist/worktree-focus.js.map +1 -0
- package/dist/worktree.d.ts +10 -10
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js +39 -39
- package/dist/worktree.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focus lifecycle management.
|
|
3
|
+
*
|
|
4
|
+
* Handles persistent worktree provisioning for active focuses and
|
|
5
|
+
* coordinated teardown when focuses are deactivated. Replaces the
|
|
6
|
+
* separate detectDeactivatedFocuses() and checkQaForDeactivatedFocuses()
|
|
7
|
+
* flows with a single unified lifecycle.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
10
|
+
import { join, resolve } from 'node:path';
|
|
11
|
+
import { installAuditPreCommitHook } from './audit-hooks.js';
|
|
12
|
+
import { getReadyFocuses, getActiveFocuses, reportGitState } from './supabase.js';
|
|
13
|
+
import { createWorktree, syncIntegrationWithMain, runGitSync, safeRemoveFocusWorktree, commitWipChanges, generateMcpConfigInWorktree, ensureIntegrationBranch, ensureMergeWorktree } from './git.js';
|
|
14
|
+
import { generateFocusBranchName, terminateTeam, waitForTeamExit } from './focus-executor.js';
|
|
15
|
+
import { getActiveTeams } from './focus-team-state.js';
|
|
16
|
+
import { recordFocusTeardown } from './spawn-cooldown.js';
|
|
17
|
+
import { getFocusWorktree, setFocusWorktree, removeFocusWorktree, getAllFocusWorktrees, hasFocusWorktree, } from './focus-worktree-state.js';
|
|
18
|
+
import { getFocusDeliveries } from './queries/focuses.js';
|
|
19
|
+
import { isStatusAgentActionable } from './stage-classifier.js';
|
|
20
|
+
import { escalateMergeConflict } from './focus-merge.js';
|
|
21
|
+
import { getQaEnvironment, removeQaEnvironment } from './qa-state.js';
|
|
22
|
+
import { stopQaDevServer } from './qa-dev-server.js';
|
|
23
|
+
import { updateQaStatus } from './supabase.js';
|
|
24
|
+
// ── Persistent worktree provisioning ─────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Ensure persistent worktrees exist for all active focuses.
|
|
27
|
+
*
|
|
28
|
+
* Called each poll cycle BEFORE processReadyFocuses(). Creates
|
|
29
|
+
* worktrees for active focuses that don't have one yet.
|
|
30
|
+
* Syncs integration with main once per cycle (not per focus).
|
|
31
|
+
*/
|
|
32
|
+
export async function ensureFocusWorktrees(config, roles) {
|
|
33
|
+
let readyFocuses;
|
|
34
|
+
try {
|
|
35
|
+
readyFocuses = await getReadyFocuses(config.organizationId, config.productId);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.warn(`[focus-lifecycle] Failed to query ready focuses for worktree provisioning: ${err.message}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Find focuses that need worktrees
|
|
42
|
+
const needsWorktree = readyFocuses.filter(s => !hasFocusWorktree(s.focus_id));
|
|
43
|
+
if (needsWorktree.length === 0)
|
|
44
|
+
return;
|
|
45
|
+
// Ensure git infrastructure exists (normally handled by initGit on startup,
|
|
46
|
+
// but guard here as a safety net in case of partial initialization).
|
|
47
|
+
try {
|
|
48
|
+
await ensureIntegrationBranch(config);
|
|
49
|
+
ensureMergeWorktree(config);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
console.warn(`[focus-lifecycle] Failed to ensure git infrastructure: ${err.message}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Sync integration with main once before creating any worktrees
|
|
56
|
+
try {
|
|
57
|
+
const syncResult = await syncIntegrationWithMain(config);
|
|
58
|
+
if (syncResult.success) {
|
|
59
|
+
console.log(`[focus-lifecycle] Synced integration with main before worktree provisioning`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.warn(`[focus-lifecycle] Could not sync integration with main: ${syncResult.error}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.warn(`[focus-lifecycle] Sync failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
67
|
+
}
|
|
68
|
+
for (const focus of needsWorktree) {
|
|
69
|
+
const role = roles.get(focus.assigned_agent_role_id);
|
|
70
|
+
if (!role) {
|
|
71
|
+
console.warn(`[focus-lifecycle] Unknown agent role ${focus.assigned_agent_role_id} for focus "${focus.focus_name}", skipping worktree`);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const branchName = generateFocusBranchName(role, focus.focus_name, focus.focus_id);
|
|
75
|
+
const worktreePath = join(config.worktreeDir, branchName.replace(/\//g, '-'));
|
|
76
|
+
// Check if a valid worktree already exists on disk (e.g., after daemon restart
|
|
77
|
+
// or reactivation). Adopt it instead of destroying and rebuilding.
|
|
78
|
+
if (existsSync(worktreePath)) {
|
|
79
|
+
const gitDirResult = runGitSync(['rev-parse', '--git-dir'], worktreePath);
|
|
80
|
+
const branchResult = runGitSync(['rev-parse', '--abbrev-ref', 'HEAD'], worktreePath);
|
|
81
|
+
if (gitDirResult.success && branchResult.success && branchResult.output === branchName) {
|
|
82
|
+
// Valid worktree on the expected branch -- adopt it
|
|
83
|
+
console.log(`[focus-lifecycle] Adopting existing worktree for "${focus.focus_name}": ${worktreePath}`);
|
|
84
|
+
setFocusWorktree(focus.focus_id, {
|
|
85
|
+
focusId: focus.focus_id,
|
|
86
|
+
focusName: focus.focus_name,
|
|
87
|
+
worktreePath,
|
|
88
|
+
branchName,
|
|
89
|
+
createdAt: new Date(),
|
|
90
|
+
hasQaDevServer: false,
|
|
91
|
+
});
|
|
92
|
+
// Rebase onto integration to bring it current
|
|
93
|
+
const rebaseResult = runGitSync(['rebase', config.integrationBranch], worktreePath);
|
|
94
|
+
if (!rebaseResult.success) {
|
|
95
|
+
runGitSync(['rebase', '--abort'], worktreePath);
|
|
96
|
+
console.warn(`[focus-lifecycle] Could not rebase adopted worktree for "${focus.focus_name}" onto integration. Continuing with existing state.`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.log(`[focus-lifecycle] Rebased adopted worktree for "${focus.focus_name}" onto ${config.integrationBranch}`);
|
|
100
|
+
}
|
|
101
|
+
// Generate .mcp.json with absolute path to MCP server
|
|
102
|
+
generateMcpConfigInWorktree(worktreePath, config);
|
|
103
|
+
// Install audit pre-commit hook for read-only focuses
|
|
104
|
+
if (focus.read_only) {
|
|
105
|
+
installAuditPreCommitHook(worktreePath);
|
|
106
|
+
console.log(`[focus-lifecycle] Installed audit pre-commit hook for "${focus.focus_name}"`);
|
|
107
|
+
}
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Directory exists but is not a valid worktree for this branch -- fall through to createWorktree
|
|
111
|
+
console.log(`[focus-lifecycle] Existing directory at ${worktreePath} is not a valid worktree for ${branchName}, recreating`);
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const createdPath = await createWorktree(config, branchName);
|
|
115
|
+
setFocusWorktree(focus.focus_id, {
|
|
116
|
+
focusId: focus.focus_id,
|
|
117
|
+
focusName: focus.focus_name,
|
|
118
|
+
worktreePath: createdPath,
|
|
119
|
+
branchName,
|
|
120
|
+
createdAt: new Date(),
|
|
121
|
+
hasQaDevServer: false,
|
|
122
|
+
});
|
|
123
|
+
console.log(`[focus-lifecycle] Created persistent worktree for "${focus.focus_name}": ${createdPath}`);
|
|
124
|
+
// Install audit pre-commit hook for read-only focuses
|
|
125
|
+
if (focus.read_only) {
|
|
126
|
+
installAuditPreCommitHook(createdPath);
|
|
127
|
+
console.log(`[focus-lifecycle] Installed audit pre-commit hook for "${focus.focus_name}"`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
console.error(`[focus-lifecycle] Failed to create worktree for "${focus.focus_name}": ${err instanceof Error ? err.message : String(err)}`);
|
|
132
|
+
// Continue with other focuses
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// ── Coordinated teardown ─────────────────────────────────────────────
|
|
137
|
+
/**
|
|
138
|
+
* Tear down a single focus: stop QA, terminate team, remove worktree.
|
|
139
|
+
*
|
|
140
|
+
* Each step is independently try/caught so a failure in one
|
|
141
|
+
* does not prevent the others from running.
|
|
142
|
+
*/
|
|
143
|
+
export async function teardownFocus(config, focusId, focusName) {
|
|
144
|
+
console.log(`[focus-lifecycle] Tearing down focus "${focusName}"`);
|
|
145
|
+
// Record teardown for spawn cooldown (prevents immediate respawn crash loops)
|
|
146
|
+
recordFocusTeardown(focusId);
|
|
147
|
+
// 1. Stop QA dev server if running
|
|
148
|
+
try {
|
|
149
|
+
const qaState = getQaEnvironment(focusId);
|
|
150
|
+
if (qaState?.pid) {
|
|
151
|
+
console.log(`[focus-lifecycle] Stopping QA dev server for "${focusName}" (PID: ${qaState.pid})`);
|
|
152
|
+
await stopQaDevServer(qaState.pid);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.warn(`[focus-lifecycle] Failed to stop QA dev server for "${focusName}": ${err.message}`);
|
|
157
|
+
}
|
|
158
|
+
// 2. Clear QA in-memory state
|
|
159
|
+
try {
|
|
160
|
+
removeQaEnvironment(focusId);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.warn(`[focus-lifecycle] Failed to clear QA state for "${focusName}": ${err.message}`);
|
|
164
|
+
}
|
|
165
|
+
// 3. Clear QA DB state
|
|
166
|
+
try {
|
|
167
|
+
await updateQaStatus(focusId, {
|
|
168
|
+
qaStatus: null,
|
|
169
|
+
qaUrl: null,
|
|
170
|
+
qaPort: null,
|
|
171
|
+
qaWorktreePath: null,
|
|
172
|
+
qaReadyAt: null,
|
|
173
|
+
qaError: null,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
console.warn(`[focus-lifecycle] Failed to clear QA DB state for "${focusName}": ${err.message}`);
|
|
178
|
+
}
|
|
179
|
+
// 4. Terminate agent team and wait for process exit
|
|
180
|
+
try {
|
|
181
|
+
const activeTeams = getActiveTeams();
|
|
182
|
+
const team = activeTeams.get(focusId);
|
|
183
|
+
if (team && team.phase !== 'shutting_down' && team.phase !== 'terminated') {
|
|
184
|
+
console.log(`[focus-lifecycle] Terminating team for "${focusName}"`);
|
|
185
|
+
terminateTeam(focusId);
|
|
186
|
+
// Wait for process to actually exit (default 30s, then SIGKILL)
|
|
187
|
+
const exited = await waitForTeamExit(focusId);
|
|
188
|
+
if (!exited) {
|
|
189
|
+
console.warn(`[focus-lifecycle] Team for "${focusName}" did not exit cleanly after SIGKILL`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
console.warn(`[focus-lifecycle] Failed to terminate team for "${focusName}": ${err.message}`);
|
|
195
|
+
}
|
|
196
|
+
// 4b. Commit any uncommitted WIP changes left by the agent
|
|
197
|
+
try {
|
|
198
|
+
const worktreeInfo = getFocusWorktree(focusId);
|
|
199
|
+
if (worktreeInfo) {
|
|
200
|
+
commitWipChanges(worktreeInfo.worktreePath, focusName);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
console.warn(`[focus-lifecycle] WIP commit failed for "${focusName}": ${err.message}`);
|
|
205
|
+
}
|
|
206
|
+
// 5. Remove focus worktree via canonical path (merge-before-remove + conditional state cleanup).
|
|
207
|
+
// If the team was killed mid-work (OOM, signal, crash) before handleTeamCompletion ran,
|
|
208
|
+
// there may be commits that never got a merge attempt. safeRemoveFocusWorktree closes that gap.
|
|
209
|
+
try {
|
|
210
|
+
const worktreeInfo = getFocusWorktree(focusId);
|
|
211
|
+
if (worktreeInfo) {
|
|
212
|
+
console.log(`[focus-lifecycle] Removing worktree for "${focusName}": ${worktreeInfo.worktreePath}`);
|
|
213
|
+
const removeResult = await safeRemoveFocusWorktree({
|
|
214
|
+
config,
|
|
215
|
+
worktreePath: worktreeInfo.worktreePath,
|
|
216
|
+
branchName: worktreeInfo.branchName,
|
|
217
|
+
deliveryName: focusName,
|
|
218
|
+
deliveryId: focusId,
|
|
219
|
+
focusId,
|
|
220
|
+
});
|
|
221
|
+
// Escalate if merge failed (worktree preserved with unmerged work)
|
|
222
|
+
if (removeResult.merged && removeResult.mergeError) {
|
|
223
|
+
escalateMergeConflict({
|
|
224
|
+
organizationId: config.organizationId,
|
|
225
|
+
sessionId: '',
|
|
226
|
+
deliveryId: focusId,
|
|
227
|
+
deliveryName: focusName,
|
|
228
|
+
branchName: worktreeInfo.branchName,
|
|
229
|
+
integrationBranch: config.integrationBranch,
|
|
230
|
+
mergeError: removeResult.mergeError,
|
|
231
|
+
}).catch(err => console.warn(`[focus-lifecycle] escalateMergeConflict failed for "${focusName}": ${err.message}`));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
console.warn(`[focus-lifecycle] Failed to remove worktree for "${focusName}": ${err.message}`);
|
|
237
|
+
}
|
|
238
|
+
console.log(`[focus-lifecycle] Teardown complete for "${focusName}"`);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Detect deactivated focuses and tear them down.
|
|
242
|
+
*
|
|
243
|
+
* Replaces both detectDeactivatedFocuses() from focus-executor.ts
|
|
244
|
+
* and checkQaForDeactivatedFocuses() from qa-orchestrator.ts.
|
|
245
|
+
* A single pass handles both team termination and QA cleanup.
|
|
246
|
+
*/
|
|
247
|
+
export async function checkForDeactivatedFocuses(config) {
|
|
248
|
+
const allWorktrees = getAllFocusWorktrees();
|
|
249
|
+
const activeTeams = getActiveTeams();
|
|
250
|
+
// Nothing to check if no worktrees and no teams
|
|
251
|
+
if (allWorktrees.size === 0 && activeTeams.size === 0)
|
|
252
|
+
return;
|
|
253
|
+
let activeFocusIds;
|
|
254
|
+
try {
|
|
255
|
+
// Use getActiveFocuses (not getReadyFocuses) -- a focus is "active" even
|
|
256
|
+
// when all deliveries are done. Worktrees must persist for QA and idle queues.
|
|
257
|
+
const activeFocuses = await getActiveFocuses(config.organizationId, config.productId);
|
|
258
|
+
activeFocusIds = new Set(activeFocuses.map(s => s.focus_id));
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
// If the endpoint isn't deployed yet, skip deactivation checks entirely.
|
|
262
|
+
// Better to leave worktrees alive than to tear them down incorrectly.
|
|
263
|
+
console.warn(`[focus-lifecycle] Cannot determine active focuses (skipping deactivation check): ${err.message}`);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
// In multi-product setups, the global worktree/team maps contain focuses
|
|
267
|
+
// from ALL products. Only check focuses we can confirm belong to THIS
|
|
268
|
+
// product — otherwise Product B's poll tears down Product A's focuses.
|
|
269
|
+
//
|
|
270
|
+
// Focus ownership is determined by:
|
|
271
|
+
// 1. Active team with matching productId (definitive)
|
|
272
|
+
// 2. Worktree for a focus that appears in this product's active set
|
|
273
|
+
// (if it's active for this product, it's this product's focus)
|
|
274
|
+
//
|
|
275
|
+
// Orphan worktrees (no team, not in active set) have unknown product
|
|
276
|
+
// ownership and are left alone — startup recovery handles them.
|
|
277
|
+
const trackedFocusIds = new Set();
|
|
278
|
+
for (const [id, team] of activeTeams) {
|
|
279
|
+
if (team.productId === config.productId) {
|
|
280
|
+
trackedFocusIds.add(id);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (const focusId of trackedFocusIds) {
|
|
284
|
+
if (activeFocusIds.has(focusId))
|
|
285
|
+
continue;
|
|
286
|
+
const worktreeInfo = getFocusWorktree(focusId);
|
|
287
|
+
const team = activeTeams.get(focusId);
|
|
288
|
+
const name = worktreeInfo?.focusName ?? team?.focusName ?? focusId;
|
|
289
|
+
// Skip teams already shutting down
|
|
290
|
+
if (team && (team.phase === 'shutting_down' || team.phase === 'terminated') && !worktreeInfo) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const reason = worktreeInfo && !team
|
|
294
|
+
? 'worktree exists but focus no longer active'
|
|
295
|
+
: team && !worktreeInfo
|
|
296
|
+
? 'team running but focus no longer active'
|
|
297
|
+
: 'focus no longer active';
|
|
298
|
+
console.log(`[focus-lifecycle] Focus "${name}" deactivated (${reason}) -- coordinated teardown`);
|
|
299
|
+
await teardownFocus(config, focusId, name);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// ── Startup recovery ─────────────────────────────────────────────
|
|
303
|
+
/**
|
|
304
|
+
* Rebuild the focus-worktree-state after a daemon restart.
|
|
305
|
+
*
|
|
306
|
+
* Two-phase approach:
|
|
307
|
+
* Phase 1 (DB-first): If hydrateFromDb() populated the Map, validate
|
|
308
|
+
* each entry against disk and enrich with focus names. Removes
|
|
309
|
+
* stale entries (worktree deleted from disk) and cleans up entries
|
|
310
|
+
* for deactivated focuses.
|
|
311
|
+
* Phase 2 (disk fallback): Scans for agent-* directories NOT already
|
|
312
|
+
* in the Map. Covers first-run after migration and manually created
|
|
313
|
+
* worktrees. Matches by ID prefix against active focuses.
|
|
314
|
+
*
|
|
315
|
+
* Also removes legacy qa-* directories from the pre-persistent worktree era.
|
|
316
|
+
*
|
|
317
|
+
* Must run AFTER hydrateFromDb() and crash recovery but BEFORE startListeners().
|
|
318
|
+
*/
|
|
319
|
+
export async function rebuildFocusWorktreeState(config) {
|
|
320
|
+
const { worktreeDir, repoPath, organizationId, productId } = config;
|
|
321
|
+
if (!existsSync(worktreeDir)) {
|
|
322
|
+
console.log('[focus-lifecycle] No worktree directory — nothing to rebuild');
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// Query active focuses for enrichment and deactivation detection
|
|
326
|
+
let activeFocuses;
|
|
327
|
+
try {
|
|
328
|
+
activeFocuses = await getActiveFocuses(organizationId, productId);
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
console.warn(`[focus-lifecycle] Cannot determine active focuses for state rebuild (preserving all): ${err.message}`);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const focusById = new Map(activeFocuses.map(s => [s.focus_id, s]));
|
|
335
|
+
const focusByPrefix = new Map(activeFocuses.map(s => [s.focus_id.slice(0, 8), s]));
|
|
336
|
+
let validated = 0;
|
|
337
|
+
let removedStale = 0;
|
|
338
|
+
let deactivatedCleaned = 0;
|
|
339
|
+
// ── Phase 1: Validate DB-hydrated entries ──────────────────────
|
|
340
|
+
const allWorktrees = getAllFocusWorktrees();
|
|
341
|
+
if (allWorktrees.size > 0) {
|
|
342
|
+
console.log(`[focus-lifecycle] Validating ${allWorktrees.size} DB-hydrated worktree(s) against disk`);
|
|
343
|
+
for (const [focusId, info] of [...allWorktrees]) {
|
|
344
|
+
if (!existsSync(info.worktreePath)) {
|
|
345
|
+
// Worktree was manually deleted — remove from state (also fires async DB remove)
|
|
346
|
+
console.log(`[focus-lifecycle] DB-hydrated worktree no longer on disk: ${info.worktreePath}`);
|
|
347
|
+
removeFocusWorktree(focusId);
|
|
348
|
+
removedStale++;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
const focus = focusById.get(focusId);
|
|
352
|
+
if (focus) {
|
|
353
|
+
// Active — enrich with focus name (not stored in DB)
|
|
354
|
+
info.focusName = focus.focus_name;
|
|
355
|
+
validated++;
|
|
356
|
+
console.log(`[focus-lifecycle] Validated worktree for "${focus.focus_name}": ${info.worktreePath}`);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
// Deactivated — clean up via canonical path
|
|
360
|
+
console.log(`[focus-lifecycle] DB-hydrated worktree for deactivated focus: ${info.worktreePath}`);
|
|
361
|
+
try {
|
|
362
|
+
const result = await safeRemoveFocusWorktree({
|
|
363
|
+
config,
|
|
364
|
+
worktreePath: info.worktreePath,
|
|
365
|
+
branchName: info.branchName,
|
|
366
|
+
deliveryName: info.focusName || focusId,
|
|
367
|
+
deliveryId: focusId,
|
|
368
|
+
focusId,
|
|
369
|
+
});
|
|
370
|
+
if (result.removed)
|
|
371
|
+
deactivatedCleaned++;
|
|
372
|
+
}
|
|
373
|
+
catch (err) {
|
|
374
|
+
console.warn(`[focus-lifecycle] Failed to clean up deactivated worktree: ${err.message}`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// ── Phase 2: Disk scan for orphans not in the Map ─────────────
|
|
380
|
+
// Catches pre-migration worktrees and manually created ones.
|
|
381
|
+
let agentDirs;
|
|
382
|
+
try {
|
|
383
|
+
agentDirs = readdirSync(worktreeDir).filter(entry => {
|
|
384
|
+
if (!entry.startsWith('agent-'))
|
|
385
|
+
return false;
|
|
386
|
+
try {
|
|
387
|
+
return statSync(join(worktreeDir, entry)).isDirectory();
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
console.warn(`[focus-lifecycle] Failed to scan worktree directory: ${err.message}`);
|
|
396
|
+
agentDirs = [];
|
|
397
|
+
}
|
|
398
|
+
// Filter to directories whose full path is NOT already tracked
|
|
399
|
+
const trackedPaths = new Set([...getAllFocusWorktrees().values()].map(w => w.worktreePath));
|
|
400
|
+
const orphanDirs = agentDirs.filter(dirName => {
|
|
401
|
+
const fullPath = resolve(join(worktreeDir, dirName));
|
|
402
|
+
return !trackedPaths.has(fullPath);
|
|
403
|
+
});
|
|
404
|
+
let diskRegistered = 0;
|
|
405
|
+
if (orphanDirs.length > 0) {
|
|
406
|
+
console.log(`[focus-lifecycle] Found ${orphanDirs.length} untracked agent-* dir(s) on disk (migration fallback)`);
|
|
407
|
+
// Parse git worktree list for branch names
|
|
408
|
+
const pathToBranch = new Map();
|
|
409
|
+
const worktreeListResult = runGitSync(['worktree', 'list', '--porcelain'], repoPath);
|
|
410
|
+
if (worktreeListResult.success) {
|
|
411
|
+
let currentPath = null;
|
|
412
|
+
for (const line of worktreeListResult.output.split('\n')) {
|
|
413
|
+
if (line.startsWith('worktree ')) {
|
|
414
|
+
currentPath = line.slice('worktree '.length);
|
|
415
|
+
}
|
|
416
|
+
else if (line.startsWith('branch refs/heads/') && currentPath) {
|
|
417
|
+
pathToBranch.set(resolve(currentPath), line.slice('branch refs/heads/'.length));
|
|
418
|
+
currentPath = null;
|
|
419
|
+
}
|
|
420
|
+
else if (line === '') {
|
|
421
|
+
currentPath = null;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
for (const dirName of orphanDirs) {
|
|
426
|
+
const fullPath = resolve(join(worktreeDir, dirName));
|
|
427
|
+
const branchName = pathToBranch.get(fullPath) ?? dirName.replace(/-/g, '/');
|
|
428
|
+
const idMatch = dirName.match(/-([0-9a-f]{8})$/);
|
|
429
|
+
const idPrefix = idMatch ? idMatch[1] : null;
|
|
430
|
+
const focus = idPrefix ? focusByPrefix.get(idPrefix) : undefined;
|
|
431
|
+
if (focus) {
|
|
432
|
+
setFocusWorktree(focus.focus_id, {
|
|
433
|
+
focusId: focus.focus_id,
|
|
434
|
+
focusName: focus.focus_name,
|
|
435
|
+
worktreePath: fullPath,
|
|
436
|
+
branchName,
|
|
437
|
+
createdAt: new Date(),
|
|
438
|
+
hasQaDevServer: false,
|
|
439
|
+
});
|
|
440
|
+
diskRegistered++;
|
|
441
|
+
console.log(`[focus-lifecycle] Registered orphan worktree for "${focus.focus_name}": ${fullPath}`);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
// Deactivated — canonical removal
|
|
445
|
+
console.log(`[focus-lifecycle] Cleaning up orphan deactivated worktree: ${fullPath} [${branchName}]`);
|
|
446
|
+
try {
|
|
447
|
+
const result = await safeRemoveFocusWorktree({
|
|
448
|
+
config,
|
|
449
|
+
worktreePath: fullPath,
|
|
450
|
+
branchName,
|
|
451
|
+
deliveryName: dirName,
|
|
452
|
+
deliveryId: dirName,
|
|
453
|
+
});
|
|
454
|
+
if (result.removed)
|
|
455
|
+
deactivatedCleaned++;
|
|
456
|
+
}
|
|
457
|
+
catch (err) {
|
|
458
|
+
console.warn(`[focus-lifecycle] Failed to clean up orphan worktree ${dirName}: ${err.message}`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// ── Phase 3: Legacy qa-* cleanup ──────────────────────────────
|
|
464
|
+
let legacyCleaned = 0;
|
|
465
|
+
try {
|
|
466
|
+
const legacyQaDirs = readdirSync(worktreeDir).filter(entry => {
|
|
467
|
+
if (!entry.startsWith('qa-'))
|
|
468
|
+
return false;
|
|
469
|
+
try {
|
|
470
|
+
return statSync(join(worktreeDir, entry)).isDirectory();
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
for (const qaDir of legacyQaDirs) {
|
|
477
|
+
const qaPath = join(worktreeDir, qaDir);
|
|
478
|
+
console.log(`[focus-lifecycle] Removing legacy qa-* directory: ${qaPath}`);
|
|
479
|
+
try {
|
|
480
|
+
const removeResult = runGitSync(['worktree', 'remove', '--force', qaPath], repoPath);
|
|
481
|
+
if (!removeResult.success) {
|
|
482
|
+
const { rmSync } = await import('node:fs');
|
|
483
|
+
rmSync(qaPath, { recursive: true, force: true });
|
|
484
|
+
runGitSync(['worktree', 'prune'], repoPath);
|
|
485
|
+
}
|
|
486
|
+
legacyCleaned++;
|
|
487
|
+
}
|
|
488
|
+
catch (err) {
|
|
489
|
+
console.warn(`[focus-lifecycle] Failed to remove legacy QA directory ${qaDir}: ${err.message}`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
// Non-fatal — legacy cleanup is best-effort
|
|
495
|
+
}
|
|
496
|
+
const parts = [
|
|
497
|
+
`${validated} validated from DB`,
|
|
498
|
+
removedStale > 0 ? `${removedStale} stale removed` : null,
|
|
499
|
+
diskRegistered > 0 ? `${diskRegistered} registered from disk` : null,
|
|
500
|
+
deactivatedCleaned > 0 ? `${deactivatedCleaned} deactivated cleaned` : null,
|
|
501
|
+
legacyCleaned > 0 ? `${legacyCleaned} legacy qa-* removed` : null,
|
|
502
|
+
].filter(Boolean);
|
|
503
|
+
console.log(`[focus-lifecycle] State rebuild complete: ${parts.join(', ')}`);
|
|
504
|
+
}
|
|
505
|
+
// ── Git state reconciliation ──────────────────────────────────────
|
|
506
|
+
/**
|
|
507
|
+
* Reconcile git state for active focus worktrees after startup.
|
|
508
|
+
*
|
|
509
|
+
* Checks all rebuilt focus worktrees and re-reports `worktree_active`
|
|
510
|
+
* for deliveries in coding/queued status. This ensures the DB reflects
|
|
511
|
+
* accurate git state even if previous reportGitState calls were lost
|
|
512
|
+
* (network blip, circuit breaker, daemon crash).
|
|
513
|
+
*
|
|
514
|
+
* Must run AFTER rebuildFocusWorktreeState().
|
|
515
|
+
*/
|
|
516
|
+
export async function reconcileGitState(_config) {
|
|
517
|
+
const worktrees = getAllFocusWorktrees();
|
|
518
|
+
if (worktrees.size === 0) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
console.log(`[focus-lifecycle] Reconciling git state for ${worktrees.size} focus worktree(s)...`);
|
|
522
|
+
let reconciled = 0;
|
|
523
|
+
for (const [focusId, worktree] of worktrees) {
|
|
524
|
+
try {
|
|
525
|
+
const deliveries = await getFocusDeliveries(focusId);
|
|
526
|
+
const activeDeliveries = deliveries.filter(d => isStatusAgentActionable(d.executionStatus ?? ''));
|
|
527
|
+
for (const delivery of activeDeliveries) {
|
|
528
|
+
await reportGitState(delivery.id, 'worktree_active', worktree.branchName);
|
|
529
|
+
reconciled++;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
catch (err) {
|
|
533
|
+
console.warn(`[focus-lifecycle] Failed to reconcile git state for "${worktree.focusName}": ` +
|
|
534
|
+
`${err.message}`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (reconciled > 0) {
|
|
538
|
+
console.log(`[focus-lifecycle] Reconciled git state for ${reconciled} delivery(ies)`);
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
console.log('[focus-lifecycle] No deliveries needed git state reconciliation');
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
//# sourceMappingURL=focus-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-lifecycle.js","sourceRoot":"","sources":["../src/focus-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focus branch merge logic.
|
|
3
|
+
*
|
|
4
|
+
* Handles merging a focus's work branch into the integration branch,
|
|
5
|
+
* including workflow resolution and per-delivery git state reporting.
|
|
6
|
+
*/
|
|
7
|
+
import type { DaemonConfig, FocusTeamState, MergeConflictResolutionResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parameters for merge conflict escalation/reporting.
|
|
10
|
+
*/
|
|
11
|
+
export interface MergeConflictParams {
|
|
12
|
+
organizationId: string;
|
|
13
|
+
sessionId: string;
|
|
14
|
+
deliveryId: string;
|
|
15
|
+
deliveryName: string;
|
|
16
|
+
branchName: string;
|
|
17
|
+
integrationBranch: string;
|
|
18
|
+
mergeError: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Report merge_conflict git state for a delivery.
|
|
22
|
+
*
|
|
23
|
+
* Makes the merge failure visible in the frontend delivery detail view.
|
|
24
|
+
*/
|
|
25
|
+
export declare function reportMergeConflictState(deliveryId: string, branchName: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Create an escalation for a merge conflict and report the git state.
|
|
28
|
+
*
|
|
29
|
+
* Idempotent: skips escalation creation if one is already pending for
|
|
30
|
+
* the same delivery (tracked in-memory via pendingMergeConflictDeliveries).
|
|
31
|
+
* Always reports merge_conflict git state regardless.
|
|
32
|
+
*
|
|
33
|
+
* Called by all focus-level merge callers when mergeToIntegration fails.
|
|
34
|
+
*/
|
|
35
|
+
export declare function escalateMergeConflict(params: MergeConflictParams): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Clear the pending merge conflict flag for a delivery (e.g., after successful retry).
|
|
38
|
+
*/
|
|
39
|
+
export declare function clearMergeConflictFlag(deliveryId: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Check for deliveries stuck in merge_conflict state and retry the merge.
|
|
42
|
+
*
|
|
43
|
+
* Called once per poll cycle. Queries the API for deliveries with
|
|
44
|
+
* merge_conflict git state, groups them by branch (to avoid duplicate
|
|
45
|
+
* merges), and retries mergeToIntegration for each unique branch.
|
|
46
|
+
*
|
|
47
|
+
* On success: reports merged_to_integration for all deliveries on that
|
|
48
|
+
* branch and clears their pending merge conflict flags.
|
|
49
|
+
* On failure: logs quietly (the existing escalation remains active).
|
|
50
|
+
*/
|
|
51
|
+
export declare function checkResolvedMergeConflicts(config: DaemonConfig): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Request the team lead to resolve merge conflicts in the worktree.
|
|
54
|
+
*
|
|
55
|
+
* Sends a user message via stdin with conflict details and instructions,
|
|
56
|
+
* then polls git state to detect when conflicts are resolved (no more
|
|
57
|
+
* unmerged files and a merge commit exists).
|
|
58
|
+
*
|
|
59
|
+
* Returns when resolution is detected or timeout expires.
|
|
60
|
+
*/
|
|
61
|
+
export declare function requestTeamLeadResolution(teamState: FocusTeamState, conflictFiles: string[], branchName: string, integrationBranch: string, timeoutMs?: number): Promise<MergeConflictResolutionResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Merge the focus branch to integration.
|
|
64
|
+
*
|
|
65
|
+
* Uses the first delivery ID as the representative for merge operations
|
|
66
|
+
* (all deliveries share the same branch in the focus model).
|
|
67
|
+
*
|
|
68
|
+
* `workedDeliveryIds` is the set of deliveries the team actually built in
|
|
69
|
+
* this merge cycle. Git state and the merge commit SHA are recorded only
|
|
70
|
+
* for these deliveries — never for queued/planning deliveries that happen
|
|
71
|
+
* to share the same focus branch but were never touched.
|
|
72
|
+
*/
|
|
73
|
+
export declare function mergeFocusBranch(config: DaemonConfig, teamState: FocusTeamState, sessionId: string, branchName: string, workedDeliveryIds: string[]): Promise<{
|
|
74
|
+
mergeSucceeded: boolean;
|
|
75
|
+
exitReason: string;
|
|
76
|
+
}>;
|
|
77
|
+
//# sourceMappingURL=focus-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-merge.d.ts","sourceRoot":"","sources":["../src/focus-merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EAEd,6BAA6B,EAC9B,MAAM,YAAY,CAAC;AAepB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Gf;AAUD;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,cAAc,EACzB,aAAa,EAAE,MAAM,EAAE,EACvB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,SAAS,GAAE,MAA6C,GACvD,OAAO,CAAC,6BAA6B,CAAC,CA4DxC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,cAAc,EACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA6J1D"}
|