steroids-cli 0.14.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/ai-run.d.ts +10 -0
- package/dist/commands/ai-run.d.ts.map +1 -0
- package/dist/commands/ai-run.js +255 -0
- package/dist/commands/ai-run.js.map +1 -0
- package/dist/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +7 -1
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/coder-noop-submission.d.ts +2 -2
- package/dist/commands/coder-noop-submission.d.ts.map +1 -1
- package/dist/commands/coder-noop-submission.js +8 -1
- package/dist/commands/coder-noop-submission.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +9 -0
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/loop-phases-coder-decision.d.ts +2 -0
- package/dist/commands/loop-phases-coder-decision.d.ts.map +1 -1
- package/dist/commands/loop-phases-coder-decision.js +18 -41
- package/dist/commands/loop-phases-coder-decision.js.map +1 -1
- package/dist/commands/loop-phases-coder.d.ts.map +1 -1
- package/dist/commands/loop-phases-coder.js +2 -1
- package/dist/commands/loop-phases-coder.js.map +1 -1
- package/dist/commands/loop-phases-reviewer.d.ts.map +1 -1
- package/dist/commands/loop-phases-reviewer.js +78 -74
- package/dist/commands/loop-phases-reviewer.js.map +1 -1
- package/dist/commands/loop.d.ts.map +1 -1
- package/dist/commands/loop.js +6 -0
- package/dist/commands/loop.js.map +1 -1
- package/dist/commands/push-task-branch.d.ts +12 -0
- package/dist/commands/push-task-branch.d.ts.map +1 -0
- package/dist/commands/push-task-branch.js +24 -0
- package/dist/commands/push-task-branch.js.map +1 -0
- package/dist/commands/tasks.js +1 -1
- package/dist/commands/tasks.js.map +1 -1
- package/dist/database/queries.d.ts +8 -2
- package/dist/database/queries.d.ts.map +1 -1
- package/dist/database/queries.js +17 -1
- package/dist/database/queries.js.map +1 -1
- package/dist/git/section-pr.js +1 -1
- package/dist/health/stuck-task-detector-types.d.ts +3 -3
- package/dist/health/stuck-task-detector-types.d.ts.map +1 -1
- package/dist/health/stuck-task-detector.js +21 -5
- package/dist/health/stuck-task-detector.js.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/monitor/investigator-actions.d.ts.map +1 -1
- package/dist/monitor/investigator-actions.js +44 -39
- package/dist/monitor/investigator-actions.js.map +1 -1
- package/dist/monitor/investigator-agent.d.ts +9 -0
- package/dist/monitor/investigator-agent.d.ts.map +1 -1
- package/dist/monitor/investigator-agent.js +2 -0
- package/dist/monitor/investigator-agent.js.map +1 -1
- package/dist/monitor/investigator-helpers.d.ts +5 -0
- package/dist/monitor/investigator-helpers.d.ts.map +1 -0
- package/dist/monitor/investigator-helpers.js +44 -0
- package/dist/monitor/investigator-helpers.js.map +1 -0
- package/dist/monitor/investigator-prompt.d.ts.map +1 -1
- package/dist/monitor/investigator-prompt.js +11 -3
- package/dist/monitor/investigator-prompt.js.map +1 -1
- package/dist/monitor/scanner-queries.d.ts +3 -0
- package/dist/monitor/scanner-queries.d.ts.map +1 -1
- package/dist/monitor/scanner-queries.js +57 -0
- package/dist/monitor/scanner-queries.js.map +1 -1
- package/dist/monitor/scanner.d.ts +1 -1
- package/dist/monitor/scanner.d.ts.map +1 -1
- package/dist/monitor/scanner.js +10 -2
- package/dist/monitor/scanner.js.map +1 -1
- package/dist/orchestrator/merge-queue-rebase.d.ts +27 -0
- package/dist/orchestrator/merge-queue-rebase.d.ts.map +1 -0
- package/dist/orchestrator/merge-queue-rebase.js +355 -0
- package/dist/orchestrator/merge-queue-rebase.js.map +1 -0
- package/dist/orchestrator/merge-queue.d.ts +40 -0
- package/dist/orchestrator/merge-queue.d.ts.map +1 -0
- package/dist/orchestrator/merge-queue.js +352 -0
- package/dist/orchestrator/merge-queue.js.map +1 -0
- package/dist/orchestrator/task-selector.d.ts +2 -1
- package/dist/orchestrator/task-selector.d.ts.map +1 -1
- package/dist/orchestrator/task-selector.js +20 -5
- package/dist/orchestrator/task-selector.js.map +1 -1
- package/dist/parallel/clone.d.ts +0 -15
- package/dist/parallel/clone.d.ts.map +1 -1
- package/dist/parallel/clone.js +0 -37
- package/dist/parallel/clone.js.map +1 -1
- package/dist/providers/invocation-logger.d.ts +2 -2
- package/dist/providers/invocation-logger.d.ts.map +1 -1
- package/dist/providers/invocation-logger.js +1 -1
- package/dist/providers/invocation-logger.js.map +1 -1
- package/dist/runners/daemon.d.ts.map +1 -1
- package/dist/runners/daemon.js +0 -79
- package/dist/runners/daemon.js.map +1 -1
- package/dist/runners/orchestrator-loop.d.ts.map +1 -1
- package/dist/runners/orchestrator-loop.js +11 -29
- package/dist/runners/orchestrator-loop.js.map +1 -1
- package/dist/runners/wakeup-checks.js +1 -1
- package/dist/runners/wakeup-checks.js.map +1 -1
- package/dist/runners/wakeup-sanitise-recovery.d.ts +21 -0
- package/dist/runners/wakeup-sanitise-recovery.d.ts.map +1 -0
- package/dist/runners/wakeup-sanitise-recovery.js +209 -0
- package/dist/runners/wakeup-sanitise-recovery.js.map +1 -0
- package/dist/runners/wakeup-sanitise.d.ts +1 -1
- package/dist/runners/wakeup-sanitise.d.ts.map +1 -1
- package/dist/runners/wakeup-sanitise.js +58 -179
- package/dist/runners/wakeup-sanitise.js.map +1 -1
- package/dist/workspace/git-helpers.d.ts +8 -0
- package/dist/workspace/git-helpers.d.ts.map +1 -1
- package/dist/workspace/git-helpers.js +34 -0
- package/dist/workspace/git-helpers.js.map +1 -1
- package/dist/workspace/merge-lock.d.ts +5 -3
- package/dist/workspace/merge-lock.d.ts.map +1 -1
- package/dist/workspace/merge-lock.js +16 -15
- package/dist/workspace/merge-lock.js.map +1 -1
- package/migrations/028_add_merge_queue_fields.sql +8 -0
- package/migrations/manifest.json +9 -1
- package/package.json +1 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Orphaned invocation recovery helpers for wakeup sanitisation.
|
|
4
|
+
* Extracted from wakeup-sanitise.ts to stay under file size limits.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.parseReviewerDecisionFromInvocationLogContent = parseReviewerDecisionFromInvocationLogContent;
|
|
8
|
+
exports.parseReviewerDecisionFromLog = parseReviewerDecisionFromLog;
|
|
9
|
+
exports.shouldSkipInvocation = shouldSkipInvocation;
|
|
10
|
+
exports.isRunnerProcessDead = isRunnerProcessDead;
|
|
11
|
+
exports.recoverOrphanedInvocation = recoverOrphanedInvocation;
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_path_1 = require("node:path");
|
|
14
|
+
const node_fs_2 = require("node:fs");
|
|
15
|
+
const reviewer_decision_parser_js_1 = require("../orchestrator/reviewer-decision-parser.js");
|
|
16
|
+
function parseReviewerDecisionFromInvocationLogContent(raw) {
|
|
17
|
+
const stdoutMessages = [];
|
|
18
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
19
|
+
const trimmed = line.trim();
|
|
20
|
+
if (!trimmed)
|
|
21
|
+
continue;
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(trimmed);
|
|
24
|
+
if (parsed.type === 'output' && parsed.stream === 'stdout' && typeof parsed.msg === 'string') {
|
|
25
|
+
stdoutMessages.push(parsed.msg);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Legacy/non-JSON logs handled by fallback below.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const parseCandidates = stdoutMessages.length > 0 ? [stdoutMessages.join('\n'), raw] : [raw];
|
|
33
|
+
for (const candidate of parseCandidates) {
|
|
34
|
+
const decision = (0, reviewer_decision_parser_js_1.parseReviewerDecisionSignal)(candidate).decision;
|
|
35
|
+
if (decision === 'approve')
|
|
36
|
+
return 'approve';
|
|
37
|
+
if (decision === 'reject')
|
|
38
|
+
return 'reject';
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
function parseReviewerDecisionFromLog(projectPath, invocationId) {
|
|
43
|
+
const logPath = (0, node_path_1.join)(projectPath, '.steroids', 'invocations', `${invocationId}.log`);
|
|
44
|
+
if (!(0, node_fs_1.existsSync)(logPath))
|
|
45
|
+
return null;
|
|
46
|
+
try {
|
|
47
|
+
const raw = (0, node_fs_2.readFileSync)(logPath, 'utf-8');
|
|
48
|
+
return parseReviewerDecisionFromInvocationLogContent(raw);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function shouldSkipInvocation(row, activeTaskIds, hasActiveMergeLock, hasActiveParallelRunner, globalDb) {
|
|
55
|
+
if (activeTaskIds.has(row.task_id))
|
|
56
|
+
return true;
|
|
57
|
+
// Merge lock only blocks merge-role recovery; rebase roles don't hold the lock
|
|
58
|
+
if (hasActiveMergeLock && row.role !== 'rebase_coder' && row.role !== 'rebase_reviewer')
|
|
59
|
+
return true;
|
|
60
|
+
if (hasActiveParallelRunner && row.runner_id) {
|
|
61
|
+
const runnerRow = globalDb
|
|
62
|
+
.prepare('SELECT pid FROM runners WHERE id = ?')
|
|
63
|
+
.get(row.runner_id);
|
|
64
|
+
if (runnerRow) {
|
|
65
|
+
if (runnerRow.pid !== null) {
|
|
66
|
+
try {
|
|
67
|
+
process.kill(runnerRow.pid, 0);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
function isRunnerProcessDead(runnerId, globalDb) {
|
|
80
|
+
// No runner_id means no owner to verify — can't confirm dead (protects manual `steroids loop` runs
|
|
81
|
+
// that don't register in the runners table). Pass 1 (30-min timeout) handles these.
|
|
82
|
+
if (!runnerId)
|
|
83
|
+
return false;
|
|
84
|
+
const runnerRow = globalDb
|
|
85
|
+
.prepare('SELECT pid FROM runners WHERE id = ?')
|
|
86
|
+
.get(runnerId);
|
|
87
|
+
if (!runnerRow)
|
|
88
|
+
return true;
|
|
89
|
+
if (runnerRow.pid === null)
|
|
90
|
+
return false;
|
|
91
|
+
try {
|
|
92
|
+
process.kill(runnerRow.pid, 0);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function recoverOrphanedInvocation(projectDb, projectPath, row, dryRun, summary, source) {
|
|
100
|
+
const completedAtMs = Date.now();
|
|
101
|
+
const durationMs = Math.max(0, completedAtMs - row.started_at_ms);
|
|
102
|
+
const reviewerDecision = row.role === 'reviewer' ? parseReviewerDecisionFromLog(projectPath, row.id) : null;
|
|
103
|
+
if (!dryRun) {
|
|
104
|
+
if (reviewerDecision === 'approve' && row.task_status === 'review') {
|
|
105
|
+
projectDb
|
|
106
|
+
.prepare(`UPDATE task_invocations
|
|
107
|
+
SET status = 'completed', success = 1, timed_out = 0, exit_code = 0,
|
|
108
|
+
completed_at_ms = ?, duration_ms = ?,
|
|
109
|
+
error = COALESCE(error, ?)
|
|
110
|
+
WHERE id = ? AND status = 'running'`)
|
|
111
|
+
.run(completedAtMs, durationMs, `Recovered by sanitise [${source}] (review approve token found).`, row.id);
|
|
112
|
+
// Note: approved_sha is not set here because we don't have the commit SHA
|
|
113
|
+
// from the stale invocation data and resolving from remote requires network.
|
|
114
|
+
// The merge queue's handleMergeAttempt checks for missing approved_sha and
|
|
115
|
+
// transitions to blocked_error, which is the safe fallback.
|
|
116
|
+
projectDb
|
|
117
|
+
.prepare(`UPDATE tasks SET status = 'merge_pending', merge_phase = 'queued', updated_at = datetime('now')
|
|
118
|
+
WHERE id = ? AND status = 'review'`)
|
|
119
|
+
.run(row.task_id);
|
|
120
|
+
projectDb
|
|
121
|
+
.prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
|
|
122
|
+
SELECT ?, 'review', 'merge_pending', 'orchestrator', 'orchestrator', ?, datetime('now')
|
|
123
|
+
WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'merge_pending')`)
|
|
124
|
+
.run(row.task_id, `Recovered by sanitise [${source}] (DECISION: APPROVE → merge_pending).`, row.task_id);
|
|
125
|
+
}
|
|
126
|
+
else if (reviewerDecision === 'reject' && row.task_status === 'review') {
|
|
127
|
+
projectDb
|
|
128
|
+
.prepare(`UPDATE task_invocations
|
|
129
|
+
SET status = 'completed', success = 1, timed_out = 0, exit_code = 0,
|
|
130
|
+
completed_at_ms = ?, duration_ms = ?,
|
|
131
|
+
error = COALESCE(error, ?)
|
|
132
|
+
WHERE id = ? AND status = 'running'`)
|
|
133
|
+
.run(completedAtMs, durationMs, `Recovered by sanitise [${source}] (review reject token found).`, row.id);
|
|
134
|
+
const rejectResult = projectDb
|
|
135
|
+
.prepare(`UPDATE tasks
|
|
136
|
+
SET status = 'in_progress', rejection_count = COALESCE(rejection_count, 0) + 1,
|
|
137
|
+
updated_at = datetime('now')
|
|
138
|
+
WHERE id = ? AND status = 'review'`)
|
|
139
|
+
.run(row.task_id);
|
|
140
|
+
if (rejectResult.changes > 0) {
|
|
141
|
+
projectDb
|
|
142
|
+
.prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
|
|
143
|
+
SELECT ?, 'review', 'in_progress', 'orchestrator', 'orchestrator', ?, datetime('now')
|
|
144
|
+
WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'in_progress')`)
|
|
145
|
+
.run(row.task_id, `Recovered by sanitise [${source}] (DECISION: REJECT).`, row.task_id);
|
|
146
|
+
projectDb
|
|
147
|
+
.prepare('DELETE FROM task_locks WHERE task_id = ?')
|
|
148
|
+
.run(row.task_id);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
projectDb
|
|
153
|
+
.prepare(`UPDATE task_invocations
|
|
154
|
+
SET status = 'failed', success = 0, timed_out = 1, exit_code = 1,
|
|
155
|
+
completed_at_ms = ?, duration_ms = ?,
|
|
156
|
+
error = COALESCE(error, ?)
|
|
157
|
+
WHERE id = ? AND status = 'running'`)
|
|
158
|
+
.run(completedAtMs, durationMs, `Sanitise [${source}] closed orphaned running invocation.`, row.id);
|
|
159
|
+
const resetResult = projectDb
|
|
160
|
+
.prepare(`UPDATE tasks SET status = 'pending', updated_at = datetime('now')
|
|
161
|
+
WHERE id = ? AND status = 'in_progress'`)
|
|
162
|
+
.run(row.task_id);
|
|
163
|
+
if (resetResult.changes > 0) {
|
|
164
|
+
projectDb
|
|
165
|
+
.prepare('DELETE FROM task_locks WHERE task_id = ?')
|
|
166
|
+
.run(row.task_id);
|
|
167
|
+
}
|
|
168
|
+
// Merge/rebase role recovery: reset merge_pending tasks with orphaned invocations
|
|
169
|
+
if (row.task_status === 'merge_pending') {
|
|
170
|
+
if (row.role === 'merge' || row.role === 'rebase_coder') {
|
|
171
|
+
// Re-queue for merge attempt (will re-discover conflicts if needed)
|
|
172
|
+
projectDb
|
|
173
|
+
.prepare(`UPDATE tasks SET merge_phase = 'queued', updated_at = datetime('now')
|
|
174
|
+
WHERE id = ? AND status = 'merge_pending'`)
|
|
175
|
+
.run(row.task_id);
|
|
176
|
+
}
|
|
177
|
+
else if (row.role === 'rebase_reviewer') {
|
|
178
|
+
// Parse rebase reviewer decision from log if available
|
|
179
|
+
const rebaseDecision = parseReviewerDecisionFromLog(projectPath, row.id);
|
|
180
|
+
if (rebaseDecision === 'approve') {
|
|
181
|
+
// Approved — re-queue with merge_phase = 'queued'
|
|
182
|
+
// approved_sha not updated here (requires network); merge queue will re-verify
|
|
183
|
+
projectDb
|
|
184
|
+
.prepare(`UPDATE tasks SET merge_phase = 'queued', updated_at = datetime('now')
|
|
185
|
+
WHERE id = ? AND status = 'merge_pending'`)
|
|
186
|
+
.run(row.task_id);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// Rejected or unknown — increment rebase_attempts, re-enter rebasing
|
|
190
|
+
projectDb
|
|
191
|
+
.prepare(`UPDATE tasks SET merge_phase = 'rebasing', rebase_attempts = COALESCE(rebase_attempts, 0) + 1, updated_at = datetime('now')
|
|
192
|
+
WHERE id = ? AND status = 'merge_pending'`)
|
|
193
|
+
.run(row.task_id);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (reviewerDecision === 'approve' && row.task_status === 'review') {
|
|
200
|
+
summary.recoveredApprovals += 1;
|
|
201
|
+
}
|
|
202
|
+
else if (reviewerDecision === 'reject' && row.task_status === 'review') {
|
|
203
|
+
summary.recoveredRejects += 1;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
summary.closedStaleInvocations += 1;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=wakeup-sanitise-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wakeup-sanitise-recovery.js","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise-recovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ export interface SanitiseSummary {
|
|
|
20
20
|
}
|
|
21
21
|
export declare function getSanitiseSettings(projectPath: string): SanitiseSettings;
|
|
22
22
|
export declare function shouldRunPeriodicSanitise(db: ReturnType<typeof openGlobalDatabase>['db'], projectPath: string, intervalMinutes: number): boolean;
|
|
23
|
-
export
|
|
23
|
+
export { parseReviewerDecisionFromInvocationLogContent } from './wakeup-sanitise-recovery.js';
|
|
24
24
|
export declare function runPeriodicSanitiseForProject(globalDb: ReturnType<typeof openGlobalDatabase>['db'], projectDb: ReturnType<typeof openDatabase>['db'], projectPath: string, dryRun: boolean): SanitiseSummary;
|
|
25
25
|
export declare function sanitisedActionCount(summary: SanitiseSummary): number;
|
|
26
26
|
//# sourceMappingURL=wakeup-sanitise.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wakeup-sanitise.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"wakeup-sanitise.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAUpD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAKD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAezE;AAMD,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAC/C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,OAAO,CAkBT;AAYD,OAAO,EAAE,6CAA6C,EAAE,MAAM,+BAA+B,CAAC;AAgM9F,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,IAAI,CAAC,EACrD,SAAS,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,IAAI,CAAC,EAChD,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,eAAe,CAyCjB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CASrE"}
|
|
@@ -3,16 +3,14 @@
|
|
|
3
3
|
* Periodic state sanitisation for projects in wakeup
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseReviewerDecisionFromInvocationLogContent = void 0;
|
|
6
7
|
exports.getSanitiseSettings = getSanitiseSettings;
|
|
7
8
|
exports.shouldRunPeriodicSanitise = shouldRunPeriodicSanitise;
|
|
8
|
-
exports.parseReviewerDecisionFromInvocationLogContent = parseReviewerDecisionFromInvocationLogContent;
|
|
9
9
|
exports.runPeriodicSanitiseForProject = runPeriodicSanitiseForProject;
|
|
10
10
|
exports.sanitisedActionCount = sanitisedActionCount;
|
|
11
|
-
const node_fs_1 = require("node:fs");
|
|
12
|
-
const node_path_1 = require("node:path");
|
|
13
|
-
const node_fs_2 = require("node:fs");
|
|
14
11
|
const loader_js_1 = require("../config/loader.js");
|
|
15
|
-
const
|
|
12
|
+
const wakeup_sanitise_recovery_js_1 = require("./wakeup-sanitise-recovery.js");
|
|
13
|
+
const clone_js_1 = require("../parallel/clone.js");
|
|
16
14
|
const DEFAULT_SANITISE_INTERVAL_MINUTES = 5;
|
|
17
15
|
const DEFAULT_SANITISE_INVOCATION_TIMEOUT_SEC = 1800;
|
|
18
16
|
function getSanitiseSettings(projectPath) {
|
|
@@ -44,52 +42,8 @@ function markPeriodicSanitiseRun(db, projectPath) {
|
|
|
44
42
|
db.prepare(`INSERT INTO _global_schema (key, value) VALUES (?, datetime('now'))
|
|
45
43
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(getSanitiseSchemaKey(projectPath));
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
for (const line of raw.split(/\r?\n/)) {
|
|
50
|
-
const trimmed = line.trim();
|
|
51
|
-
if (!trimmed) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
const parsed = JSON.parse(trimmed);
|
|
56
|
-
if (parsed.type === 'output'
|
|
57
|
-
&& parsed.stream === 'stdout'
|
|
58
|
-
&& typeof parsed.msg === 'string') {
|
|
59
|
-
stdoutMessages.push(parsed.msg);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
// Legacy/non-JSON logs are handled by fallback raw parsing below.
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const parseCandidates = stdoutMessages.length > 0
|
|
67
|
-
? [stdoutMessages.join('\n'), raw]
|
|
68
|
-
: [raw];
|
|
69
|
-
for (const candidate of parseCandidates) {
|
|
70
|
-
const decision = (0, reviewer_decision_parser_js_1.parseReviewerDecisionSignal)(candidate).decision;
|
|
71
|
-
if (decision === 'approve') {
|
|
72
|
-
return 'approve';
|
|
73
|
-
}
|
|
74
|
-
if (decision === 'reject') {
|
|
75
|
-
return 'reject';
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
function parseReviewerDecisionFromLog(projectPath, invocationId) {
|
|
81
|
-
const logPath = (0, node_path_1.join)(projectPath, '.steroids', 'invocations', `${invocationId}.log`);
|
|
82
|
-
if (!(0, node_fs_1.existsSync)(logPath)) {
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
try {
|
|
86
|
-
const raw = (0, node_fs_2.readFileSync)(logPath, 'utf-8');
|
|
87
|
-
return parseReviewerDecisionFromInvocationLogContent(raw);
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
45
|
+
var wakeup_sanitise_recovery_js_2 = require("./wakeup-sanitise-recovery.js");
|
|
46
|
+
Object.defineProperty(exports, "parseReviewerDecisionFromInvocationLogContent", { enumerable: true, get: function () { return wakeup_sanitise_recovery_js_2.parseReviewerDecisionFromInvocationLogContent; } });
|
|
93
47
|
function sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, staleInvocationTimeoutSec) {
|
|
94
48
|
const summary = {
|
|
95
49
|
ran: true,
|
|
@@ -118,18 +72,21 @@ function sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, staleInv
|
|
|
118
72
|
const hasActiveParallelRunner = activeRunnerTaskRows.some((row) => typeof row.parallel_session_id === 'string' && row.parallel_session_id.length > 0);
|
|
119
73
|
let hasActiveMergeLock = false;
|
|
120
74
|
try {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
75
|
+
const STALE_LOCK_TTL_MS = 90_000;
|
|
76
|
+
const projectId = (0, clone_js_1.getProjectHash)(projectPath);
|
|
77
|
+
const mergeLockRows = globalDb
|
|
78
|
+
.prepare('SELECT heartbeat_at FROM workspace_merge_locks WHERE project_id = ?')
|
|
79
|
+
.all(projectId);
|
|
124
80
|
const nowMs = Date.now();
|
|
125
81
|
hasActiveMergeLock = mergeLockRows.some((row) => {
|
|
126
|
-
const
|
|
127
|
-
return Number.isFinite(
|
|
82
|
+
const hbMs = Date.parse(row.heartbeat_at);
|
|
83
|
+
return Number.isFinite(hbMs) && (nowMs - hbMs) < STALE_LOCK_TTL_MS;
|
|
128
84
|
});
|
|
129
85
|
}
|
|
130
86
|
catch {
|
|
131
87
|
hasActiveMergeLock = false;
|
|
132
88
|
}
|
|
89
|
+
// ── Pass 1: Stale invocations (exceeded timeout, any runner state) ──
|
|
133
90
|
const staleInvocations = projectDb
|
|
134
91
|
.prepare(`SELECT i.id, i.task_id, i.role, i.started_at_ms, i.runner_id, t.status AS task_status
|
|
135
92
|
FROM task_invocations i
|
|
@@ -140,139 +97,61 @@ function sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, staleInv
|
|
|
140
97
|
ORDER BY i.started_at_ms ASC`)
|
|
141
98
|
.all(staleCutoffMs);
|
|
142
99
|
for (const row of staleInvocations) {
|
|
143
|
-
if (
|
|
100
|
+
if ((0, wakeup_sanitise_recovery_js_1.shouldSkipInvocation)(row, activeTaskIds, hasActiveMergeLock, hasActiveParallelRunner, globalDb)) {
|
|
144
101
|
continue;
|
|
145
102
|
}
|
|
146
|
-
|
|
147
|
-
|
|
103
|
+
(0, wakeup_sanitise_recovery_js_1.recoverOrphanedInvocation)(projectDb, projectPath, row, dryRun, summary, 'stale timeout');
|
|
104
|
+
}
|
|
105
|
+
// ── Pass 2: Dead-runner orphans (runner process is dead, invocation >2 min old) ──
|
|
106
|
+
// Catches invocations left 'running' by crashed/killed runners without waiting 30 min.
|
|
107
|
+
const deadRunnerCutoffMs = Date.now() - 120_000;
|
|
108
|
+
const recentRunningInvocations = projectDb
|
|
109
|
+
.prepare(`SELECT i.id, i.task_id, i.role, i.started_at_ms, i.runner_id, t.status AS task_status
|
|
110
|
+
FROM task_invocations i
|
|
111
|
+
LEFT JOIN tasks t ON t.id = i.task_id
|
|
112
|
+
WHERE i.status = 'running'
|
|
113
|
+
AND i.started_at_ms IS NOT NULL
|
|
114
|
+
AND i.started_at_ms > ?
|
|
115
|
+
AND i.started_at_ms <= ?
|
|
116
|
+
ORDER BY i.started_at_ms ASC`)
|
|
117
|
+
.all(staleCutoffMs, deadRunnerCutoffMs);
|
|
118
|
+
for (const row of recentRunningInvocations) {
|
|
119
|
+
const isRebaseRole = row.role === 'rebase_coder' || row.role === 'rebase_reviewer';
|
|
120
|
+
if (activeTaskIds.has(row.task_id) || (hasActiveMergeLock && !isRebaseRole)) {
|
|
148
121
|
continue;
|
|
149
122
|
}
|
|
150
|
-
//
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
.prepare('SELECT pid FROM runners WHERE id = ?')
|
|
154
|
-
.get(row.runner_id);
|
|
155
|
-
if (runnerRow) {
|
|
156
|
-
if (runnerRow.pid !== null) {
|
|
157
|
-
try {
|
|
158
|
-
process.kill(runnerRow.pid, 0);
|
|
159
|
-
continue; // Process alive, skip this invocation
|
|
160
|
-
}
|
|
161
|
-
catch {
|
|
162
|
-
// Process dead, fall through to cleanup
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
continue; // No PID to check, assume alive (defensive)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// Runner row missing = runner is dead, proceed with cleanup
|
|
170
|
-
}
|
|
171
|
-
const completedAtMs = Date.now();
|
|
172
|
-
const durationMs = Math.max(0, completedAtMs - row.started_at_ms);
|
|
173
|
-
const reviewerDecision = row.role === 'reviewer'
|
|
174
|
-
? parseReviewerDecisionFromLog(projectPath, row.id)
|
|
175
|
-
: null;
|
|
176
|
-
if (!dryRun) {
|
|
177
|
-
if (reviewerDecision === 'approve' && row.task_status === 'review') {
|
|
178
|
-
projectDb
|
|
179
|
-
.prepare(`UPDATE task_invocations
|
|
180
|
-
SET status = 'completed',
|
|
181
|
-
success = 1,
|
|
182
|
-
timed_out = 0,
|
|
183
|
-
exit_code = 0,
|
|
184
|
-
completed_at_ms = ?,
|
|
185
|
-
duration_ms = ?,
|
|
186
|
-
error = COALESCE(error, 'Recovered by periodic sanitise (review approve token found).')
|
|
187
|
-
WHERE id = ? AND status = 'running'`)
|
|
188
|
-
.run(completedAtMs, durationMs, row.id);
|
|
189
|
-
projectDb
|
|
190
|
-
.prepare(`UPDATE tasks
|
|
191
|
-
SET status = 'completed',
|
|
192
|
-
updated_at = datetime('now')
|
|
193
|
-
WHERE id = ? AND status = 'review'`)
|
|
194
|
-
.run(row.task_id);
|
|
195
|
-
projectDb
|
|
196
|
-
.prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
|
|
197
|
-
SELECT ?, 'review', 'completed', 'orchestrator', 'orchestrator',
|
|
198
|
-
'Recovered by periodic sanitise from reviewer decision log (DECISION: APPROVE).',
|
|
199
|
-
datetime('now')
|
|
200
|
-
WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'completed')`)
|
|
201
|
-
.run(row.task_id, row.task_id);
|
|
202
|
-
}
|
|
203
|
-
else if (reviewerDecision === 'reject' && row.task_status === 'review') {
|
|
204
|
-
projectDb
|
|
205
|
-
.prepare(`UPDATE task_invocations
|
|
206
|
-
SET status = 'completed',
|
|
207
|
-
success = 1,
|
|
208
|
-
timed_out = 0,
|
|
209
|
-
exit_code = 0,
|
|
210
|
-
completed_at_ms = ?,
|
|
211
|
-
duration_ms = ?,
|
|
212
|
-
error = COALESCE(error, 'Recovered by periodic sanitise (review reject token found).')
|
|
213
|
-
WHERE id = ? AND status = 'running'`)
|
|
214
|
-
.run(completedAtMs, durationMs, row.id);
|
|
215
|
-
const rejectResult = projectDb
|
|
216
|
-
.prepare(`UPDATE tasks
|
|
217
|
-
SET status = 'in_progress',
|
|
218
|
-
rejection_count = COALESCE(rejection_count, 0) + 1,
|
|
219
|
-
updated_at = datetime('now')
|
|
220
|
-
WHERE id = ? AND status = 'review'`)
|
|
221
|
-
.run(row.task_id);
|
|
222
|
-
if (rejectResult.changes > 0) {
|
|
223
|
-
projectDb
|
|
224
|
-
.prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
|
|
225
|
-
SELECT ?, 'review', 'in_progress', 'orchestrator', 'orchestrator',
|
|
226
|
-
'Recovered by periodic sanitise from reviewer decision log (DECISION: REJECT).',
|
|
227
|
-
datetime('now')
|
|
228
|
-
WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'in_progress')`)
|
|
229
|
-
.run(row.task_id, row.task_id);
|
|
230
|
-
projectDb
|
|
231
|
-
.prepare('DELETE FROM task_locks WHERE task_id = ?')
|
|
232
|
-
.run(row.task_id);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
projectDb
|
|
237
|
-
.prepare(`UPDATE task_invocations
|
|
238
|
-
SET status = 'failed',
|
|
239
|
-
success = 0,
|
|
240
|
-
timed_out = 1,
|
|
241
|
-
exit_code = 1,
|
|
242
|
-
completed_at_ms = ?,
|
|
243
|
-
duration_ms = ?,
|
|
244
|
-
error = COALESCE(error, 'Periodic sanitise closed stale running invocation.')
|
|
245
|
-
WHERE id = ? AND status = 'running'`)
|
|
246
|
-
.run(completedAtMs, durationMs, row.id);
|
|
247
|
-
// Reset task to pending so the section is unblocked.
|
|
248
|
-
// Defense-in-depth: covers SIGKILL and crash cases where Part 1 (global-db-sessions)
|
|
249
|
-
// cleanup did not fire.
|
|
250
|
-
const resetResult = projectDb
|
|
251
|
-
.prepare(`UPDATE tasks SET status = 'pending', updated_at = datetime('now')
|
|
252
|
-
WHERE id = ? AND status = 'in_progress'`)
|
|
253
|
-
.run(row.task_id);
|
|
254
|
-
if (resetResult.changes > 0) {
|
|
255
|
-
projectDb
|
|
256
|
-
.prepare('DELETE FROM task_locks WHERE task_id = ?')
|
|
257
|
-
.run(row.task_id);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (reviewerDecision === 'approve' && row.task_status === 'review') {
|
|
262
|
-
summary.recoveredApprovals += 1;
|
|
263
|
-
}
|
|
264
|
-
else if (reviewerDecision === 'reject' && row.task_status === 'review') {
|
|
265
|
-
summary.recoveredRejects += 1;
|
|
123
|
+
// Only recover if we can confirm the runner process is dead
|
|
124
|
+
if (!(0, wakeup_sanitise_recovery_js_1.isRunnerProcessDead)(row.runner_id, globalDb)) {
|
|
125
|
+
continue;
|
|
266
126
|
}
|
|
267
|
-
|
|
268
|
-
|
|
127
|
+
(0, wakeup_sanitise_recovery_js_1.recoverOrphanedInvocation)(projectDb, projectPath, row, dryRun, summary, 'dead runner');
|
|
128
|
+
}
|
|
129
|
+
// ── Pass 3: Orphaned task locks (task has no running invocations and no active runner) ──
|
|
130
|
+
if (!dryRun) {
|
|
131
|
+
const orphanedLocks = projectDb
|
|
132
|
+
.prepare(`SELECT tl.task_id FROM task_locks tl
|
|
133
|
+
WHERE NOT EXISTS (
|
|
134
|
+
SELECT 1 FROM task_invocations i
|
|
135
|
+
WHERE i.task_id = tl.task_id AND i.status = 'running'
|
|
136
|
+
)
|
|
137
|
+
AND tl.task_id NOT IN (${activeTaskIds.size > 0
|
|
138
|
+
? [...activeTaskIds].map(() => '?').join(',')
|
|
139
|
+
: "'__none__'"})`)
|
|
140
|
+
.all(...(activeTaskIds.size > 0 ? [...activeTaskIds] : []));
|
|
141
|
+
if (orphanedLocks.length > 0) {
|
|
142
|
+
const taskIds = orphanedLocks.map((r) => r.task_id);
|
|
143
|
+
const placeholders = taskIds.map(() => '?').join(',');
|
|
144
|
+
const released = projectDb
|
|
145
|
+
.prepare(`DELETE FROM task_locks WHERE task_id IN (${placeholders})`)
|
|
146
|
+
.run(...taskIds);
|
|
147
|
+
summary.releasedTaskLocks += released.changes;
|
|
269
148
|
}
|
|
270
149
|
}
|
|
271
150
|
if (!dryRun) {
|
|
272
151
|
const releasedTaskLocks = projectDb
|
|
273
152
|
.prepare(`DELETE FROM task_locks WHERE expires_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`)
|
|
274
153
|
.run();
|
|
275
|
-
summary.releasedTaskLocks
|
|
154
|
+
summary.releasedTaskLocks += releasedTaskLocks.changes;
|
|
276
155
|
const releasedSectionLocks = projectDb
|
|
277
156
|
.prepare(`DELETE FROM section_locks WHERE expires_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`)
|
|
278
157
|
.run();
|
|
@@ -294,7 +173,7 @@ function sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, staleInv
|
|
|
294
173
|
const ids = disputedRows.map((r) => r.id);
|
|
295
174
|
const placeholders = ids.map(() => '?').join(',');
|
|
296
175
|
projectDb
|
|
297
|
-
.prepare(`UPDATE tasks SET status = 'pending', updated_at = datetime('now')
|
|
176
|
+
.prepare(`UPDATE tasks SET status = 'pending', merge_phase = NULL, approved_sha = NULL, rebase_attempts = 0, updated_at = datetime('now')
|
|
298
177
|
WHERE id IN (${placeholders})`)
|
|
299
178
|
.run(...ids);
|
|
300
179
|
const auditStmt = projectDb.prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wakeup-sanitise.js","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":";AAAA;;GAEG
|
|
1
|
+
{"version":3,"file":"wakeup-sanitise.js","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,6 +42,14 @@ export declare function pushWithRetries(cwd: string, remote: string, refspec: st
|
|
|
42
42
|
success: boolean;
|
|
43
43
|
error?: string;
|
|
44
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* Async version of pushWithRetries — uses setTimeout instead of busy-wait
|
|
47
|
+
* so heartbeat timers can fire during backoff delays.
|
|
48
|
+
*/
|
|
49
|
+
export declare function pushWithRetriesAsync(cwd: string, remote: string, refspec: string, retries?: number, backoffMs?: number[], forceWithLease?: boolean): Promise<{
|
|
50
|
+
success: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
}>;
|
|
45
53
|
/**
|
|
46
54
|
* Check if `ancestor` is an ancestor of `descendant`.
|
|
47
55
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../../src/workspace/git-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"git-helpers.d.ts","sourceRoot":"","sources":["../../src/workspace/git-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,GAAG,IAAI,CAef;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMjD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,YAAY,GAAE,MAAM,GAAG,IAAW,GACjC,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAU,EACnB,SAAS,GAAE,MAAM,EAAwB,EACzC,cAAc,GAAE,OAAe,GAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmCtC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAU,EACnB,SAAS,GAAE,MAAM,EAAwB,EACzC,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAQrF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEvE"}
|