@telora/daemon 0.15.3 → 0.15.5
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/build-info.json +2 -2
- package/dist/directive-executor.d.ts +18 -3
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +45 -4
- package/dist/directive-executor.js.map +1 -1
- package/dist/focus-completion.js +12 -12
- package/dist/focus-completion.js.map +1 -1
- package/dist/focus-executor.d.ts.map +1 -1
- package/dist/focus-executor.js +30 -13
- package/dist/focus-executor.js.map +1 -1
- package/dist/focus-phase.d.ts +22 -0
- package/dist/focus-phase.d.ts.map +1 -0
- package/dist/focus-phase.js +54 -0
- package/dist/focus-phase.js.map +1 -0
- package/dist/focus-team-state.d.ts +6 -0
- package/dist/focus-team-state.d.ts.map +1 -1
- package/dist/focus-team-state.js +13 -0
- package/dist/focus-team-state.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/listener.d.ts.map +1 -1
- package/dist/listener.js +0 -5
- package/dist/listener.js.map +1 -1
- package/dist/queries/focuses.d.ts +5 -0
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +15 -0
- package/dist/queries/focuses.js.map +1 -1
- package/dist/review-defect-detector.d.ts +16 -95
- package/dist/review-defect-detector.d.ts.map +1 -1
- package/dist/review-defect-detector.js +19 -211
- package/dist/review-defect-detector.js.map +1 -1
- package/dist/state-cascade.d.ts +45 -41
- package/dist/state-cascade.d.ts.map +1 -1
- package/dist/state-cascade.js +123 -215
- package/dist/state-cascade.js.map +1 -1
- package/package.json +2 -2
- package/dist/listener-review.d.ts +0 -37
- package/dist/listener-review.d.ts.map +0 -1
- package/dist/listener-review.js +0 -217
- package/dist/listener-review.js.map +0 -1
- package/dist/queries/strategies.d.ts +0 -97
- package/dist/queries/strategies.d.ts.map +0 -1
- package/dist/queries/strategies.js +0 -136
- package/dist/queries/strategies.js.map +0 -1
- package/dist/review-spawner.d.ts +0 -32
- package/dist/review-spawner.d.ts.map +0 -1
- package/dist/review-spawner.js +0 -170
- package/dist/review-spawner.js.map +0 -1
- package/dist/strategy-completion-event.d.ts +0 -63
- package/dist/strategy-completion-event.d.ts.map +0 -1
- package/dist/strategy-completion-event.js +0 -138
- package/dist/strategy-completion-event.js.map +0 -1
- package/dist/strategy-completion.d.ts +0 -85
- package/dist/strategy-completion.d.ts.map +0 -1
- package/dist/strategy-completion.js +0 -459
- package/dist/strategy-completion.js.map +0 -1
- package/dist/strategy-engine.d.ts +0 -47
- package/dist/strategy-engine.d.ts.map +0 -1
- package/dist/strategy-engine.js +0 -421
- package/dist/strategy-engine.js.map +0 -1
- package/dist/strategy-executor.d.ts +0 -55
- package/dist/strategy-executor.d.ts.map +0 -1
- package/dist/strategy-executor.js +0 -519
- package/dist/strategy-executor.js.map +0 -1
- package/dist/strategy-lifecycle.d.ts +0 -61
- package/dist/strategy-lifecycle.d.ts.map +0 -1
- package/dist/strategy-lifecycle.js +0 -544
- package/dist/strategy-lifecycle.js.map +0 -1
- package/dist/strategy-merge.d.ts +0 -77
- package/dist/strategy-merge.d.ts.map +0 -1
- package/dist/strategy-merge.js +0 -378
- package/dist/strategy-merge.js.map +0 -1
- package/dist/strategy-prompt-builder.d.ts +0 -24
- package/dist/strategy-prompt-builder.d.ts.map +0 -1
- package/dist/strategy-prompt-builder.js +0 -87
- package/dist/strategy-prompt-builder.js.map +0 -1
- package/dist/strategy-provisioning.d.ts +0 -16
- package/dist/strategy-provisioning.d.ts.map +0 -1
- package/dist/strategy-provisioning.js +0 -119
- package/dist/strategy-provisioning.js.map +0 -1
- package/dist/strategy-spawn-helpers.d.ts +0 -67
- package/dist/strategy-spawn-helpers.d.ts.map +0 -1
- package/dist/strategy-spawn-helpers.js +0 -160
- package/dist/strategy-spawn-helpers.js.map +0 -1
- package/dist/strategy-team-lifecycle.d.ts +0 -50
- package/dist/strategy-team-lifecycle.d.ts.map +0 -1
- package/dist/strategy-team-lifecycle.js +0 -256
- package/dist/strategy-team-lifecycle.js.map +0 -1
- package/dist/strategy-team-state.d.ts +0 -24
- package/dist/strategy-team-state.d.ts.map +0 -1
- package/dist/strategy-team-state.js +0 -43
- package/dist/strategy-team-state.js.map +0 -1
- package/dist/strategy-teardown.d.ts +0 -24
- package/dist/strategy-teardown.d.ts.map +0 -1
- package/dist/strategy-teardown.js +0 -158
- package/dist/strategy-teardown.js.map +0 -1
- package/dist/strategy-worktree-state.d.ts +0 -47
- package/dist/strategy-worktree-state.d.ts.map +0 -1
- package/dist/strategy-worktree-state.js +0 -104
- package/dist/strategy-worktree-state.js.map +0 -1
- package/dist/team-prompt-variants.d.ts +0 -17
- package/dist/team-prompt-variants.d.ts.map +0 -1
- package/dist/team-prompt-variants.js +0 -79
- package/dist/team-prompt-variants.js.map +0 -1
- package/dist/types/strategy.d.ts +0 -180
- package/dist/types/strategy.d.ts.map +0 -1
- package/dist/types/strategy.js +0 -5
- package/dist/types/strategy.js.map +0 -1
- package/dist/worktree-merge.d.ts +0 -23
- package/dist/worktree-merge.d.ts.map +0 -1
- package/dist/worktree-merge.js +0 -57
- package/dist/worktree-merge.js.map +0 -1
- package/dist/worktree-strategy.d.ts +0 -69
- package/dist/worktree-strategy.d.ts.map +0 -1
- package/dist/worktree-strategy.js +0 -214
- package/dist/worktree-strategy.js.map +0 -1
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy lifecycle management.
|
|
3
|
-
*
|
|
4
|
-
* Handles persistent worktree provisioning for active strategies and
|
|
5
|
-
* coordinated teardown when strategies are deactivated. Replaces the
|
|
6
|
-
* separate detectDeactivatedStrategies() and checkQaForDeactivatedStrategies()
|
|
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 { getReadyStrategies, getActiveStrategies, reportGitState } from './supabase.js';
|
|
13
|
-
import { createWorktree, syncIntegrationWithMain, runGitSync, safeRemoveStrategyWorktree, commitWipChanges, generateMcpConfigInWorktree, ensureIntegrationBranch, ensureMergeWorktree } from './git.js';
|
|
14
|
-
import { generateStrategyBranchName, terminateTeam, waitForTeamExit } from './strategy-executor.js';
|
|
15
|
-
import { getActiveTeams } from './strategy-team-state.js';
|
|
16
|
-
import { recordStrategyTeardown } from './spawn-cooldown.js';
|
|
17
|
-
import { getStrategyWorktree, setStrategyWorktree, removeStrategyWorktree, getAllStrategyWorktrees, hasStrategyWorktree, } from './strategy-worktree-state.js';
|
|
18
|
-
import { getStrategyDeliveries } from './queries/strategies.js';
|
|
19
|
-
import { isStatusAgentActionable } from './stage-classifier.js';
|
|
20
|
-
import { escalateMergeConflict } from './strategy-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 strategies.
|
|
27
|
-
*
|
|
28
|
-
* Called each poll cycle BEFORE processReadyStrategies(). Creates
|
|
29
|
-
* worktrees for active strategies that don't have one yet.
|
|
30
|
-
* Syncs integration with main once per cycle (not per strategy).
|
|
31
|
-
*/
|
|
32
|
-
export async function ensureStrategyWorktrees(config, roles) {
|
|
33
|
-
let readyStrategies;
|
|
34
|
-
try {
|
|
35
|
-
readyStrategies = await getReadyStrategies(config.organizationId, config.productId);
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
console.warn(`[strategy-lifecycle] Failed to query ready strategies for worktree provisioning: ${err.message}`);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
// Find strategies that need worktrees
|
|
42
|
-
const needsWorktree = readyStrategies.filter(s => !hasStrategyWorktree(s.strategy_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(`[strategy-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(`[strategy-lifecycle] Synced integration with main before worktree provisioning`);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
console.warn(`[strategy-lifecycle] Could not sync integration with main: ${syncResult.error}`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
console.warn(`[strategy-lifecycle] Sync failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
67
|
-
}
|
|
68
|
-
for (const strategy of needsWorktree) {
|
|
69
|
-
const role = roles.get(strategy.assigned_agent_role_id);
|
|
70
|
-
if (!role) {
|
|
71
|
-
console.warn(`[strategy-lifecycle] Unknown agent role ${strategy.assigned_agent_role_id} for strategy "${strategy.strategy_name}", skipping worktree`);
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
const branchName = generateStrategyBranchName(role, strategy.strategy_name, strategy.strategy_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(`[strategy-lifecycle] Adopting existing worktree for "${strategy.strategy_name}": ${worktreePath}`);
|
|
84
|
-
setStrategyWorktree(strategy.strategy_id, {
|
|
85
|
-
strategyId: strategy.strategy_id,
|
|
86
|
-
strategyName: strategy.strategy_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(`[strategy-lifecycle] Could not rebase adopted worktree for "${strategy.strategy_name}" onto integration. Continuing with existing state.`);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
console.log(`[strategy-lifecycle] Rebased adopted worktree for "${strategy.strategy_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 strategies
|
|
104
|
-
if (strategy.read_only) {
|
|
105
|
-
installAuditPreCommitHook(worktreePath);
|
|
106
|
-
console.log(`[strategy-lifecycle] Installed audit pre-commit hook for "${strategy.strategy_name}"`);
|
|
107
|
-
}
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
// Directory exists but is not a valid worktree for this branch -- fall through to createWorktree
|
|
111
|
-
console.log(`[strategy-lifecycle] Existing directory at ${worktreePath} is not a valid worktree for ${branchName}, recreating`);
|
|
112
|
-
}
|
|
113
|
-
try {
|
|
114
|
-
const createdPath = await createWorktree(config, branchName);
|
|
115
|
-
setStrategyWorktree(strategy.strategy_id, {
|
|
116
|
-
strategyId: strategy.strategy_id,
|
|
117
|
-
strategyName: strategy.strategy_name,
|
|
118
|
-
worktreePath: createdPath,
|
|
119
|
-
branchName,
|
|
120
|
-
createdAt: new Date(),
|
|
121
|
-
hasQaDevServer: false,
|
|
122
|
-
});
|
|
123
|
-
console.log(`[strategy-lifecycle] Created persistent worktree for "${strategy.strategy_name}": ${createdPath}`);
|
|
124
|
-
// Install audit pre-commit hook for read-only strategies
|
|
125
|
-
if (strategy.read_only) {
|
|
126
|
-
installAuditPreCommitHook(createdPath);
|
|
127
|
-
console.log(`[strategy-lifecycle] Installed audit pre-commit hook for "${strategy.strategy_name}"`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
catch (err) {
|
|
131
|
-
console.error(`[strategy-lifecycle] Failed to create worktree for "${strategy.strategy_name}": ${err instanceof Error ? err.message : String(err)}`);
|
|
132
|
-
// Continue with other strategies
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// ── Coordinated teardown ─────────────────────────────────────────────
|
|
137
|
-
/**
|
|
138
|
-
* Tear down a single strategy: 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 teardownStrategy(config, strategyId, strategyName) {
|
|
144
|
-
console.log(`[strategy-lifecycle] Tearing down strategy "${strategyName}"`);
|
|
145
|
-
// Record teardown for spawn cooldown (prevents immediate respawn crash loops)
|
|
146
|
-
recordStrategyTeardown(strategyId);
|
|
147
|
-
// 1. Stop QA dev server if running
|
|
148
|
-
try {
|
|
149
|
-
const qaState = getQaEnvironment(strategyId);
|
|
150
|
-
if (qaState?.pid) {
|
|
151
|
-
console.log(`[strategy-lifecycle] Stopping QA dev server for "${strategyName}" (PID: ${qaState.pid})`);
|
|
152
|
-
await stopQaDevServer(qaState.pid);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (err) {
|
|
156
|
-
console.warn(`[strategy-lifecycle] Failed to stop QA dev server for "${strategyName}": ${err.message}`);
|
|
157
|
-
}
|
|
158
|
-
// 2. Clear QA in-memory state
|
|
159
|
-
try {
|
|
160
|
-
removeQaEnvironment(strategyId);
|
|
161
|
-
}
|
|
162
|
-
catch (err) {
|
|
163
|
-
console.warn(`[strategy-lifecycle] Failed to clear QA state for "${strategyName}": ${err.message}`);
|
|
164
|
-
}
|
|
165
|
-
// 3. Clear QA DB state
|
|
166
|
-
try {
|
|
167
|
-
await updateQaStatus(strategyId, {
|
|
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(`[strategy-lifecycle] Failed to clear QA DB state for "${strategyName}": ${err.message}`);
|
|
178
|
-
}
|
|
179
|
-
// 4. Terminate agent team and wait for process exit
|
|
180
|
-
try {
|
|
181
|
-
const activeTeams = getActiveTeams();
|
|
182
|
-
const team = activeTeams.get(strategyId);
|
|
183
|
-
if (team && team.phase !== 'shutting_down' && team.phase !== 'terminated') {
|
|
184
|
-
console.log(`[strategy-lifecycle] Terminating team for "${strategyName}"`);
|
|
185
|
-
terminateTeam(strategyId);
|
|
186
|
-
// Wait for process to actually exit (default 30s, then SIGKILL)
|
|
187
|
-
const exited = await waitForTeamExit(strategyId);
|
|
188
|
-
if (!exited) {
|
|
189
|
-
console.warn(`[strategy-lifecycle] Team for "${strategyName}" did not exit cleanly after SIGKILL`);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
catch (err) {
|
|
194
|
-
console.warn(`[strategy-lifecycle] Failed to terminate team for "${strategyName}": ${err.message}`);
|
|
195
|
-
}
|
|
196
|
-
// 4b. Commit any uncommitted WIP changes left by the agent
|
|
197
|
-
try {
|
|
198
|
-
const worktreeInfo = getStrategyWorktree(strategyId);
|
|
199
|
-
if (worktreeInfo) {
|
|
200
|
-
commitWipChanges(worktreeInfo.worktreePath, strategyName);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch (err) {
|
|
204
|
-
console.warn(`[strategy-lifecycle] WIP commit failed for "${strategyName}": ${err.message}`);
|
|
205
|
-
}
|
|
206
|
-
// 5. Remove strategy 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. safeRemoveStrategyWorktree closes that gap.
|
|
209
|
-
try {
|
|
210
|
-
const worktreeInfo = getStrategyWorktree(strategyId);
|
|
211
|
-
if (worktreeInfo) {
|
|
212
|
-
console.log(`[strategy-lifecycle] Removing worktree for "${strategyName}": ${worktreeInfo.worktreePath}`);
|
|
213
|
-
const removeResult = await safeRemoveStrategyWorktree({
|
|
214
|
-
config,
|
|
215
|
-
worktreePath: worktreeInfo.worktreePath,
|
|
216
|
-
branchName: worktreeInfo.branchName,
|
|
217
|
-
deliveryName: strategyName,
|
|
218
|
-
deliveryId: strategyId,
|
|
219
|
-
strategyId,
|
|
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: strategyId,
|
|
227
|
-
deliveryName: strategyName,
|
|
228
|
-
branchName: worktreeInfo.branchName,
|
|
229
|
-
integrationBranch: config.integrationBranch,
|
|
230
|
-
mergeError: removeResult.mergeError,
|
|
231
|
-
}).catch(err => console.warn(`[strategy-lifecycle] escalateMergeConflict failed for "${strategyName}": ${err.message}`));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
catch (err) {
|
|
236
|
-
console.warn(`[strategy-lifecycle] Failed to remove worktree for "${strategyName}": ${err.message}`);
|
|
237
|
-
}
|
|
238
|
-
console.log(`[strategy-lifecycle] Teardown complete for "${strategyName}"`);
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Detect deactivated strategies and tear them down.
|
|
242
|
-
*
|
|
243
|
-
* Replaces both detectDeactivatedStrategies() from strategy-executor.ts
|
|
244
|
-
* and checkQaForDeactivatedStrategies() from qa-orchestrator.ts.
|
|
245
|
-
* A single pass handles both team termination and QA cleanup.
|
|
246
|
-
*/
|
|
247
|
-
export async function checkForDeactivatedStrategies(config) {
|
|
248
|
-
const allWorktrees = getAllStrategyWorktrees();
|
|
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 activeStrategyIds;
|
|
254
|
-
try {
|
|
255
|
-
// Use getActiveStrategies (not getReadyStrategies) -- a strategy is "active" even
|
|
256
|
-
// when all deliveries are done. Worktrees must persist for QA and idle queues.
|
|
257
|
-
const activeStrategies = await getActiveStrategies(config.organizationId, config.productId);
|
|
258
|
-
activeStrategyIds = new Set(activeStrategies.map(s => s.strategy_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(`[strategy-lifecycle] Cannot determine active strategies (skipping deactivation check): ${err.message}`);
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
// In multi-product setups, the global worktree/team maps contain strategies
|
|
267
|
-
// from ALL products. Only check strategies we can confirm belong to THIS
|
|
268
|
-
// product — otherwise Product B's poll tears down Product A's strategies.
|
|
269
|
-
//
|
|
270
|
-
// Strategy ownership is determined by:
|
|
271
|
-
// 1. Active team with matching productId (definitive)
|
|
272
|
-
// 2. Worktree for a strategy that appears in this product's active set
|
|
273
|
-
// (if it's active for this product, it's this product's strategy)
|
|
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 trackedStrategyIds = new Set();
|
|
278
|
-
for (const [id, team] of activeTeams) {
|
|
279
|
-
if (team.productId === config.productId) {
|
|
280
|
-
trackedStrategyIds.add(id);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
for (const strategyId of trackedStrategyIds) {
|
|
284
|
-
if (activeStrategyIds.has(strategyId))
|
|
285
|
-
continue;
|
|
286
|
-
const worktreeInfo = getStrategyWorktree(strategyId);
|
|
287
|
-
const team = activeTeams.get(strategyId);
|
|
288
|
-
const name = worktreeInfo?.strategyName ?? team?.strategyName ?? strategyId;
|
|
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 strategy no longer active'
|
|
295
|
-
: team && !worktreeInfo
|
|
296
|
-
? 'team running but strategy no longer active'
|
|
297
|
-
: 'strategy no longer active';
|
|
298
|
-
console.log(`[strategy-lifecycle] Strategy "${name}" deactivated (${reason}) -- coordinated teardown`);
|
|
299
|
-
await teardownStrategy(config, strategyId, name);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
// ── Startup recovery ─────────────────────────────────────────────
|
|
303
|
-
/**
|
|
304
|
-
* Rebuild the strategy-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 strategy names. Removes
|
|
309
|
-
* stale entries (worktree deleted from disk) and cleans up entries
|
|
310
|
-
* for deactivated strategies.
|
|
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 strategies.
|
|
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 rebuildStrategyWorktreeState(config) {
|
|
320
|
-
const { worktreeDir, repoPath, organizationId, productId } = config;
|
|
321
|
-
if (!existsSync(worktreeDir)) {
|
|
322
|
-
console.log('[strategy-lifecycle] No worktree directory — nothing to rebuild');
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
// Query active strategies for enrichment and deactivation detection
|
|
326
|
-
let activeStrategies;
|
|
327
|
-
try {
|
|
328
|
-
activeStrategies = await getActiveStrategies(organizationId, productId);
|
|
329
|
-
}
|
|
330
|
-
catch (err) {
|
|
331
|
-
console.warn(`[strategy-lifecycle] Cannot determine active strategies for state rebuild (preserving all): ${err.message}`);
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const strategyById = new Map(activeStrategies.map(s => [s.strategy_id, s]));
|
|
335
|
-
const strategyByPrefix = new Map(activeStrategies.map(s => [s.strategy_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 = getAllStrategyWorktrees();
|
|
341
|
-
if (allWorktrees.size > 0) {
|
|
342
|
-
console.log(`[strategy-lifecycle] Validating ${allWorktrees.size} DB-hydrated worktree(s) against disk`);
|
|
343
|
-
for (const [strategyId, info] of [...allWorktrees]) {
|
|
344
|
-
if (!existsSync(info.worktreePath)) {
|
|
345
|
-
// Worktree was manually deleted — remove from state (also fires async DB remove)
|
|
346
|
-
console.log(`[strategy-lifecycle] DB-hydrated worktree no longer on disk: ${info.worktreePath}`);
|
|
347
|
-
removeStrategyWorktree(strategyId);
|
|
348
|
-
removedStale++;
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
const strategy = strategyById.get(strategyId);
|
|
352
|
-
if (strategy) {
|
|
353
|
-
// Active — enrich with strategy name (not stored in DB)
|
|
354
|
-
info.strategyName = strategy.strategy_name;
|
|
355
|
-
validated++;
|
|
356
|
-
console.log(`[strategy-lifecycle] Validated worktree for "${strategy.strategy_name}": ${info.worktreePath}`);
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
// Deactivated — clean up via canonical path
|
|
360
|
-
console.log(`[strategy-lifecycle] DB-hydrated worktree for deactivated strategy: ${info.worktreePath}`);
|
|
361
|
-
try {
|
|
362
|
-
const result = await safeRemoveStrategyWorktree({
|
|
363
|
-
config,
|
|
364
|
-
worktreePath: info.worktreePath,
|
|
365
|
-
branchName: info.branchName,
|
|
366
|
-
deliveryName: info.strategyName || strategyId,
|
|
367
|
-
deliveryId: strategyId,
|
|
368
|
-
strategyId,
|
|
369
|
-
});
|
|
370
|
-
if (result.removed)
|
|
371
|
-
deactivatedCleaned++;
|
|
372
|
-
}
|
|
373
|
-
catch (err) {
|
|
374
|
-
console.warn(`[strategy-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(`[strategy-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([...getAllStrategyWorktrees().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(`[strategy-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 strategy = idPrefix ? strategyByPrefix.get(idPrefix) : undefined;
|
|
431
|
-
if (strategy) {
|
|
432
|
-
setStrategyWorktree(strategy.strategy_id, {
|
|
433
|
-
strategyId: strategy.strategy_id,
|
|
434
|
-
strategyName: strategy.strategy_name,
|
|
435
|
-
worktreePath: fullPath,
|
|
436
|
-
branchName,
|
|
437
|
-
createdAt: new Date(),
|
|
438
|
-
hasQaDevServer: false,
|
|
439
|
-
});
|
|
440
|
-
diskRegistered++;
|
|
441
|
-
console.log(`[strategy-lifecycle] Registered orphan worktree for "${strategy.strategy_name}": ${fullPath}`);
|
|
442
|
-
}
|
|
443
|
-
else {
|
|
444
|
-
// Deactivated — canonical removal
|
|
445
|
-
console.log(`[strategy-lifecycle] Cleaning up orphan deactivated worktree: ${fullPath} [${branchName}]`);
|
|
446
|
-
try {
|
|
447
|
-
const result = await safeRemoveStrategyWorktree({
|
|
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(`[strategy-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(`[strategy-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(`[strategy-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(`[strategy-lifecycle] State rebuild complete: ${parts.join(', ')}`);
|
|
504
|
-
}
|
|
505
|
-
// ── Git state reconciliation ──────────────────────────────────────
|
|
506
|
-
/**
|
|
507
|
-
* Reconcile git state for active strategy worktrees after startup.
|
|
508
|
-
*
|
|
509
|
-
* Checks all rebuilt strategy 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 rebuildStrategyWorktreeState().
|
|
515
|
-
*/
|
|
516
|
-
export async function reconcileGitState(_config) {
|
|
517
|
-
const worktrees = getAllStrategyWorktrees();
|
|
518
|
-
if (worktrees.size === 0) {
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
console.log(`[strategy-lifecycle] Reconciling git state for ${worktrees.size} strategy worktree(s)...`);
|
|
522
|
-
let reconciled = 0;
|
|
523
|
-
for (const [strategyId, worktree] of worktrees) {
|
|
524
|
-
try {
|
|
525
|
-
const deliveries = await getStrategyDeliveries(strategyId);
|
|
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(`[strategy-lifecycle] Failed to reconcile git state for "${worktree.strategyName}": ` +
|
|
534
|
-
`${err.message}`);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (reconciled > 0) {
|
|
538
|
-
console.log(`[strategy-lifecycle] Reconciled git state for ${reconciled} delivery(ies)`);
|
|
539
|
-
}
|
|
540
|
-
else {
|
|
541
|
-
console.log('[strategy-lifecycle] No deliveries needed git state reconciliation');
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
//# sourceMappingURL=strategy-lifecycle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"strategy-lifecycle.js","sourceRoot":"","sources":["../src/strategy-lifecycle.ts"],"names":[],"mappings":"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"}
|
package/dist/strategy-merge.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy branch merge logic.
|
|
3
|
-
*
|
|
4
|
-
* Handles merging a strategy's work branch into the integration branch,
|
|
5
|
-
* including workflow resolution and per-delivery git state reporting.
|
|
6
|
-
*/
|
|
7
|
-
import type { DaemonConfig, StrategyTeamState, 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 strategy-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: StrategyTeamState, conflictFiles: string[], branchName: string, integrationBranch: string, timeoutMs?: number): Promise<MergeConflictResolutionResult>;
|
|
62
|
-
/**
|
|
63
|
-
* Merge the strategy 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 strategy 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 strategy branch but were never touched.
|
|
72
|
-
*/
|
|
73
|
-
export declare function mergeStrategyBranch(config: DaemonConfig, teamState: StrategyTeamState, sessionId: string, branchName: string, workedDeliveryIds: string[]): Promise<{
|
|
74
|
-
mergeSucceeded: boolean;
|
|
75
|
-
exitReason: string;
|
|
76
|
-
}>;
|
|
77
|
-
//# sourceMappingURL=strategy-merge.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"strategy-merge.d.ts","sourceRoot":"","sources":["../src/strategy-merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,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,iBAAiB,EAC5B,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,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,iBAAiB,EAC5B,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"}
|