@bradygaster/squad-cli 0.9.3-insider.1 → 0.9.4
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 +33 -0
- package/dist/cli/commands/cast.d.ts.map +1 -1
- package/dist/cli/commands/cast.js +9 -2
- package/dist/cli/commands/cast.js.map +1 -1
- package/dist/cli/commands/externalize.d.ts +27 -0
- package/dist/cli/commands/externalize.d.ts.map +1 -0
- package/dist/cli/commands/externalize.js +209 -0
- package/dist/cli/commands/externalize.js.map +1 -0
- package/dist/cli/commands/loop.d.ts +6 -1
- package/dist/cli/commands/loop.d.ts.map +1 -1
- package/dist/cli/commands/loop.js +13 -13
- package/dist/cli/commands/loop.js.map +1 -1
- package/dist/cli/commands/migrate.js +2 -2
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts.map +1 -1
- package/dist/cli/commands/plugin.js +2 -1
- package/dist/cli/commands/plugin.js.map +1 -1
- package/dist/cli/commands/rc.js +2 -2
- package/dist/cli/commands/rc.js.map +1 -1
- package/dist/cli/commands/skill.d.ts +31 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +497 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +31 -5
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/watch/agent-spawn.d.ts +62 -0
- package/dist/cli/commands/watch/agent-spawn.d.ts.map +1 -0
- package/dist/cli/commands/watch/agent-spawn.js +127 -0
- package/dist/cli/commands/watch/agent-spawn.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/decision-hygiene.js +3 -3
- package/dist/cli/commands/watch/capabilities/decision-hygiene.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/execute.d.ts.map +1 -1
- package/dist/cli/commands/watch/capabilities/execute.js +15 -5
- package/dist/cli/commands/watch/capabilities/execute.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/monitor-email.js +3 -3
- package/dist/cli/commands/watch/capabilities/monitor-email.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/monitor-teams.js +3 -3
- package/dist/cli/commands/watch/capabilities/monitor-teams.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/retro.js +3 -3
- package/dist/cli/commands/watch/capabilities/retro.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/wave-dispatch.js +3 -3
- package/dist/cli/commands/watch/capabilities/wave-dispatch.js.map +1 -1
- package/dist/cli/commands/watch/config.d.ts +10 -8
- package/dist/cli/commands/watch/config.d.ts.map +1 -1
- package/dist/cli/commands/watch/config.js +27 -5
- package/dist/cli/commands/watch/config.js.map +1 -1
- package/dist/cli/commands/watch/external-loader.d.ts +14 -0
- package/dist/cli/commands/watch/external-loader.d.ts.map +1 -0
- package/dist/cli/commands/watch/external-loader.js +85 -0
- package/dist/cli/commands/watch/external-loader.js.map +1 -0
- package/dist/cli/commands/watch/health.js +10 -9
- package/dist/cli/commands/watch/health.js.map +1 -1
- package/dist/cli/commands/watch/index.d.ts +10 -0
- package/dist/cli/commands/watch/index.d.ts.map +1 -1
- package/dist/cli/commands/watch/index.js +53 -7
- package/dist/cli/commands/watch/index.js.map +1 -1
- package/dist/cli/commands/watch/pid-tracker.d.ts +35 -0
- package/dist/cli/commands/watch/pid-tracker.d.ts.map +1 -0
- package/dist/cli/commands/watch/pid-tracker.js +127 -0
- package/dist/cli/commands/watch/pid-tracker.js.map +1 -0
- package/dist/cli/commands/watch/types.d.ts +5 -0
- package/dist/cli/commands/watch/types.d.ts.map +1 -1
- package/dist/cli/core/email-scrub.js +2 -2
- package/dist/cli/core/email-scrub.js.map +1 -1
- package/dist/cli/core/gh-cli.d.ts +2 -1
- package/dist/cli/core/gh-cli.d.ts.map +1 -1
- package/dist/cli/core/gh-cli.js +3 -2
- package/dist/cli/core/gh-cli.js.map +1 -1
- package/dist/cli/core/init.d.ts.map +1 -1
- package/dist/cli/core/init.js +26 -31
- package/dist/cli/core/init.js.map +1 -1
- package/dist/cli/core/migrations.js +1 -1
- package/dist/cli/core/migrations.js.map +1 -1
- package/dist/cli/core/nap.js +2 -2
- package/dist/cli/core/nap.js.map +1 -1
- package/dist/cli/core/project-type.js +1 -1
- package/dist/cli/core/project-type.js.map +1 -1
- package/dist/cli/core/templates.d.ts.map +1 -1
- package/dist/cli/core/templates.js +48 -0
- package/dist/cli/core/templates.js.map +1 -1
- package/dist/cli/core/upgrade.d.ts +4 -2
- package/dist/cli/core/upgrade.d.ts.map +1 -1
- package/dist/cli/core/upgrade.js +46 -21
- package/dist/cli/core/upgrade.js.map +1 -1
- package/dist/cli/shell/index.d.ts.map +1 -1
- package/dist/cli/shell/index.js +22 -0
- package/dist/cli/shell/index.js.map +1 -1
- package/dist/cli/shell/session-store.js +2 -2
- package/dist/cli/shell/session-store.js.map +1 -1
- package/dist/cli-entry.js +101 -83
- package/dist/cli-entry.js.map +1 -1
- package/package.json +6 -2
- package/templates/casting-reference.md +104 -104
- package/templates/ceremonies.md +28 -28
- package/templates/fact-checker-charter.md +83 -0
- package/templates/mcp-config.md +0 -2
- package/templates/scribe-charter.md +1 -1
- package/templates/skills/external-comms/SKILL.md +329 -329
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
- package/templates/skills/humanizer/SKILL.md +105 -105
- package/templates/skills/pr-review-response/SKILL.md +268 -0
- package/templates/skills/pr-screenshots/SKILL.md +149 -149
- package/templates/skills/versioning-policy/SKILL.md +119 -0
- package/templates/squad.agent.md.template +13 -6
- package/dist/cli/commands/watch/capabilities/budget-check.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/budget-check.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/budget-check.js +0 -38
- package/dist/cli/commands/watch/capabilities/budget-check.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts +0 -52
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/circuit-breaker.js +0 -152
- package/dist/cli/commands/watch/capabilities/circuit-breaker.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/health-check.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/health-check.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/health-check.js +0 -139
- package/dist/cli/commands/watch/capabilities/health-check.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts +0 -48
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/heartbeat.js +0 -115
- package/dist/cli/commands/watch/capabilities/heartbeat.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts +0 -30
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/lockfile.js +0 -100
- package/dist/cli/commands/watch/capabilities/lockfile.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts +0 -30
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/machine-capabilities.js +0 -103
- package/dist/cli/commands/watch/capabilities/machine-capabilities.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/post-failure.d.ts +0 -19
- package/dist/cli/commands/watch/capabilities/post-failure.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/post-failure.js +0 -58
- package/dist/cli/commands/watch/capabilities/post-failure.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/priority.d.ts +0 -59
- package/dist/cli/commands/watch/capabilities/priority.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/priority.js +0 -101
- package/dist/cli/commands/watch/capabilities/priority.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts +0 -67
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/rate-pool.js +0 -187
- package/dist/cli/commands/watch/capabilities/rate-pool.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts +0 -23
- package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/stale-reclaim.js +0 -87
- package/dist/cli/commands/watch/capabilities/stale-reclaim.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js +0 -114
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js.map +0 -1
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Health-check capability — pre-round watchdog.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Invoke-RalphHealthCheck`.
|
|
5
|
-
* Runs in the `pre-scan` phase and verifies:
|
|
6
|
-
* 1. gh CLI authenticated
|
|
7
|
-
* 2. Circuit breaker state file is valid
|
|
8
|
-
* 3. Disk space above threshold (configurable, default 500 MB)
|
|
9
|
-
* 4. Git branch matches expected (optional)
|
|
10
|
-
*
|
|
11
|
-
* Config (via squad.config.ts → watch.capabilities["health-check"]):
|
|
12
|
-
* diskThresholdMB – minimum free disk in MB (default: 500)
|
|
13
|
-
* expectedBranch – warn if not on this branch (optional)
|
|
14
|
-
*/
|
|
15
|
-
import { execFile } from 'node:child_process';
|
|
16
|
-
import { promisify } from 'node:util';
|
|
17
|
-
import path from 'node:path';
|
|
18
|
-
import fs from 'node:fs';
|
|
19
|
-
const execFileAsync = promisify(execFile);
|
|
20
|
-
export class HealthCheckCapability {
|
|
21
|
-
name = 'health-check';
|
|
22
|
-
description = 'Pre-round watchdog: verify auth, disk space, branch, CB state';
|
|
23
|
-
configShape = 'object';
|
|
24
|
-
requires = ['gh'];
|
|
25
|
-
phase = 'pre-scan';
|
|
26
|
-
async preflight(_context) {
|
|
27
|
-
return { ok: true };
|
|
28
|
-
}
|
|
29
|
-
async execute(context) {
|
|
30
|
-
const healed = [];
|
|
31
|
-
const warnings = [];
|
|
32
|
-
const config = context.config;
|
|
33
|
-
const diskThresholdMB = config['diskThresholdMB'] ?? 500;
|
|
34
|
-
const expectedBranch = config['expectedBranch'];
|
|
35
|
-
// 1. Verify gh auth
|
|
36
|
-
try {
|
|
37
|
-
await execFileAsync('gh', ['auth', 'status'], { timeout: 10_000 });
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
// Try extracting auth info from git remote (P3 auth fallback)
|
|
41
|
-
const patFromRemote = await extractPatFromRemote(context.teamRoot);
|
|
42
|
-
if (patFromRemote) {
|
|
43
|
-
healed.push('Detected PAT in git remote URL — gh auth may need refresh');
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
warnings.push('gh auth: not authenticated — run "gh auth login"');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// 2. Validate circuit breaker state file
|
|
50
|
-
const cbPath = path.join(context.teamRoot, '.squad', 'ralph-circuit-breaker.json');
|
|
51
|
-
try {
|
|
52
|
-
if (fs.existsSync(cbPath)) {
|
|
53
|
-
const rawContent = fs.readFileSync(cbPath, 'utf-8');
|
|
54
|
-
const parsed = JSON.parse(rawContent);
|
|
55
|
-
// Check for nested schema (legacy)
|
|
56
|
-
if (!parsed.preferredModel && parsed.model_fallback) {
|
|
57
|
-
healed.push('CB schema: would convert nested→flat on next use');
|
|
58
|
-
}
|
|
59
|
-
// Check for empty model
|
|
60
|
-
if (parsed.currentModel === '' || parsed.currentModel === null) {
|
|
61
|
-
warnings.push('CB state has empty currentModel — circuit-breaker will auto-reset');
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
// No CB file is fine — will be created on demand
|
|
67
|
-
}
|
|
68
|
-
// 3. Disk space check
|
|
69
|
-
try {
|
|
70
|
-
const freeBytes = await getFreeDiskSpace(context.teamRoot);
|
|
71
|
-
const freeMB = Math.floor(freeBytes / (1024 * 1024));
|
|
72
|
-
if (freeMB < diskThresholdMB) {
|
|
73
|
-
warnings.push(`Low disk space: ${freeMB} MB free (threshold: ${diskThresholdMB} MB)`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// Disk check failed — non-blocking
|
|
78
|
-
}
|
|
79
|
-
// 4. Branch drift check
|
|
80
|
-
if (expectedBranch) {
|
|
81
|
-
try {
|
|
82
|
-
const { stdout } = await execFileAsync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
83
|
-
cwd: context.teamRoot,
|
|
84
|
-
timeout: 5_000,
|
|
85
|
-
});
|
|
86
|
-
const current = stdout.trim();
|
|
87
|
-
if (current && current !== expectedBranch) {
|
|
88
|
-
warnings.push(`Branch drift: on "${current}" (expected "${expectedBranch}")`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch { /* not a git repo or other error */ }
|
|
92
|
-
}
|
|
93
|
-
const summary = healed.length > 0 || warnings.length > 0
|
|
94
|
-
? `healed: ${healed.length}, warnings: ${warnings.length}`
|
|
95
|
-
: 'all checks passed';
|
|
96
|
-
return {
|
|
97
|
-
success: warnings.length === 0,
|
|
98
|
-
summary,
|
|
99
|
-
data: { healed, warnings },
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/** Try extracting a PAT from git remote URL (https://<pat>@github.com/...) */
|
|
104
|
-
async function extractPatFromRemote(cwd) {
|
|
105
|
-
try {
|
|
106
|
-
const { stdout } = await execFileAsync('git', ['config', '--get', 'remote.origin.url'], {
|
|
107
|
-
cwd,
|
|
108
|
-
timeout: 5_000,
|
|
109
|
-
});
|
|
110
|
-
const url = stdout.trim();
|
|
111
|
-
// Pattern: https://<token>@github.com/...
|
|
112
|
-
const match = url.match(/https:\/\/([^@]+)@github\.com/);
|
|
113
|
-
if (match && match[1] && match[1] !== 'oauth2') {
|
|
114
|
-
return match[1];
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
catch { /* not available */ }
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
/** Get free disk space in bytes for the drive containing the given path. */
|
|
121
|
-
async function getFreeDiskSpace(dirPath) {
|
|
122
|
-
const platform = process.platform;
|
|
123
|
-
if (platform === 'win32') {
|
|
124
|
-
const drive = path.parse(path.resolve(dirPath)).root;
|
|
125
|
-
const { stdout } = await execFileAsync('wmic', [
|
|
126
|
-
'logicaldisk', 'where', `DeviceID='${drive.replace('\\', '')}'`,
|
|
127
|
-
'get', 'FreeSpace', '/value',
|
|
128
|
-
], { timeout: 5_000 });
|
|
129
|
-
const match = stdout.match(/FreeSpace=(\d+)/);
|
|
130
|
-
return match ? parseInt(match[1], 10) : Infinity;
|
|
131
|
-
}
|
|
132
|
-
// Unix: use df
|
|
133
|
-
const { stdout } = await execFileAsync('df', ['--output=avail', '-B1', dirPath], {
|
|
134
|
-
timeout: 5_000,
|
|
135
|
-
});
|
|
136
|
-
const lines = stdout.trim().split('\n');
|
|
137
|
-
return parseInt(lines[lines.length - 1].trim(), 10) || Infinity;
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=health-check.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/health-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat capability — write status JSON every round.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Update-Heartbeat`.
|
|
5
|
-
* Writes to `.squad/ralph-heartbeat.json` every round with:
|
|
6
|
-
* - round number, status, PID, timestamp
|
|
7
|
-
* - consecutive failures counter
|
|
8
|
-
* - duration of last round
|
|
9
|
-
*
|
|
10
|
-
* Also maintains a structured log at `.squad/ralph-watch.log` with rotation.
|
|
11
|
-
*
|
|
12
|
-
* Runs in the `housekeeping` phase.
|
|
13
|
-
*
|
|
14
|
-
* Config (via squad.config.ts → watch.capabilities["heartbeat"]):
|
|
15
|
-
* heartbeatPath – override heartbeat file location (default: .squad/ralph-heartbeat.json)
|
|
16
|
-
* logPath – override log file location (default: .squad/ralph-watch.log)
|
|
17
|
-
* maxLogEntries – max log lines before rotation (default: 500)
|
|
18
|
-
* maxLogBytes – max log file size before rotation (default: 1MB)
|
|
19
|
-
*/
|
|
20
|
-
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
21
|
-
export interface HeartbeatData {
|
|
22
|
-
lastRun: string;
|
|
23
|
-
lastHeartbeat: string;
|
|
24
|
-
round: number;
|
|
25
|
-
status: string;
|
|
26
|
-
exitCode: number;
|
|
27
|
-
durationSeconds: number;
|
|
28
|
-
consecutiveFailures: number;
|
|
29
|
-
pid: number;
|
|
30
|
-
}
|
|
31
|
-
export declare class HeartbeatCapability implements WatchCapability {
|
|
32
|
-
readonly name = "heartbeat";
|
|
33
|
-
readonly description = "Write heartbeat JSON and structured log every round";
|
|
34
|
-
readonly configShape: "object";
|
|
35
|
-
readonly requires: never[];
|
|
36
|
-
readonly phase: "housekeeping";
|
|
37
|
-
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
38
|
-
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
39
|
-
}
|
|
40
|
-
/** Increment consecutive failure counter (called by the main loop on error). */
|
|
41
|
-
export declare function recordFailure(): void;
|
|
42
|
-
/** Reset consecutive failure counter (called by the main loop on success). */
|
|
43
|
-
export declare function recordSuccess(): void;
|
|
44
|
-
/** Get current consecutive failure count. */
|
|
45
|
-
export declare function getConsecutiveFailures(): number;
|
|
46
|
-
/** Mark round start time for duration tracking. */
|
|
47
|
-
export declare function markRoundStart(): void;
|
|
48
|
-
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpG,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAMD,qBAAa,mBAAoB,YAAW,eAAe;IACzD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,yDAAyD;IAC7E,QAAQ,CAAC,WAAW,EAAG,QAAQ,CAAU;IACzC,QAAQ,CAAC,QAAQ,UAAM;IACvB,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA2ChE;AAED,gFAAgF;AAChF,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,mDAAmD;AACnD,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat capability — write status JSON every round.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Update-Heartbeat`.
|
|
5
|
-
* Writes to `.squad/ralph-heartbeat.json` every round with:
|
|
6
|
-
* - round number, status, PID, timestamp
|
|
7
|
-
* - consecutive failures counter
|
|
8
|
-
* - duration of last round
|
|
9
|
-
*
|
|
10
|
-
* Also maintains a structured log at `.squad/ralph-watch.log` with rotation.
|
|
11
|
-
*
|
|
12
|
-
* Runs in the `housekeeping` phase.
|
|
13
|
-
*
|
|
14
|
-
* Config (via squad.config.ts → watch.capabilities["heartbeat"]):
|
|
15
|
-
* heartbeatPath – override heartbeat file location (default: .squad/ralph-heartbeat.json)
|
|
16
|
-
* logPath – override log file location (default: .squad/ralph-watch.log)
|
|
17
|
-
* maxLogEntries – max log lines before rotation (default: 500)
|
|
18
|
-
* maxLogBytes – max log file size before rotation (default: 1MB)
|
|
19
|
-
*/
|
|
20
|
-
import path from 'node:path';
|
|
21
|
-
import fs from 'node:fs';
|
|
22
|
-
// Module-level state tracked across rounds
|
|
23
|
-
let consecutiveFailures = 0;
|
|
24
|
-
let lastRoundStart = Date.now();
|
|
25
|
-
export class HeartbeatCapability {
|
|
26
|
-
name = 'heartbeat';
|
|
27
|
-
description = 'Write heartbeat JSON and structured log every round';
|
|
28
|
-
configShape = 'object';
|
|
29
|
-
requires = [];
|
|
30
|
-
phase = 'housekeeping';
|
|
31
|
-
async preflight(_context) {
|
|
32
|
-
return { ok: true };
|
|
33
|
-
}
|
|
34
|
-
async execute(context) {
|
|
35
|
-
const config = context.config;
|
|
36
|
-
const squadDir = path.join(context.teamRoot, '.squad');
|
|
37
|
-
const heartbeatPath = config['heartbeatPath'] ?? path.join(squadDir, 'ralph-heartbeat.json');
|
|
38
|
-
const logPath = config['logPath'] ?? path.join(squadDir, 'ralph-watch.log');
|
|
39
|
-
const maxLogEntries = config['maxLogEntries'] ?? 500;
|
|
40
|
-
const maxLogBytes = config['maxLogBytes'] ?? 1_048_576; // 1 MB
|
|
41
|
-
const now = new Date();
|
|
42
|
-
const durationSeconds = Math.round((Date.now() - lastRoundStart) / 1000 * 100) / 100;
|
|
43
|
-
lastRoundStart = Date.now();
|
|
44
|
-
// Write heartbeat
|
|
45
|
-
const heartbeat = {
|
|
46
|
-
lastRun: now.toISOString(),
|
|
47
|
-
lastHeartbeat: now.toISOString(),
|
|
48
|
-
round: context.round,
|
|
49
|
-
status: 'idle',
|
|
50
|
-
exitCode: 0,
|
|
51
|
-
durationSeconds,
|
|
52
|
-
consecutiveFailures,
|
|
53
|
-
pid: process.pid,
|
|
54
|
-
};
|
|
55
|
-
try {
|
|
56
|
-
ensureDir(path.dirname(heartbeatPath));
|
|
57
|
-
fs.writeFileSync(heartbeatPath, JSON.stringify(heartbeat, null, 2), 'utf-8');
|
|
58
|
-
}
|
|
59
|
-
catch { /* best-effort */ }
|
|
60
|
-
// Append structured log entry
|
|
61
|
-
const logEntry = `${now.toISOString()} | Round=${context.round} | Duration=${durationSeconds}s | Failures=${consecutiveFailures} | Status=idle`;
|
|
62
|
-
try {
|
|
63
|
-
ensureDir(path.dirname(logPath));
|
|
64
|
-
fs.appendFileSync(logPath, logEntry + '\n', 'utf-8');
|
|
65
|
-
rotateLog(logPath, maxLogEntries, maxLogBytes);
|
|
66
|
-
}
|
|
67
|
-
catch { /* best-effort */ }
|
|
68
|
-
return {
|
|
69
|
-
success: true,
|
|
70
|
-
summary: `heartbeat written (round ${context.round})`,
|
|
71
|
-
data: { heartbeatPath, durationSeconds },
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/** Increment consecutive failure counter (called by the main loop on error). */
|
|
76
|
-
export function recordFailure() {
|
|
77
|
-
consecutiveFailures++;
|
|
78
|
-
}
|
|
79
|
-
/** Reset consecutive failure counter (called by the main loop on success). */
|
|
80
|
-
export function recordSuccess() {
|
|
81
|
-
consecutiveFailures = 0;
|
|
82
|
-
}
|
|
83
|
-
/** Get current consecutive failure count. */
|
|
84
|
-
export function getConsecutiveFailures() {
|
|
85
|
-
return consecutiveFailures;
|
|
86
|
-
}
|
|
87
|
-
/** Mark round start time for duration tracking. */
|
|
88
|
-
export function markRoundStart() {
|
|
89
|
-
lastRoundStart = Date.now();
|
|
90
|
-
}
|
|
91
|
-
function ensureDir(dir) {
|
|
92
|
-
if (!fs.existsSync(dir)) {
|
|
93
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function rotateLog(logPath, maxEntries, maxBytes) {
|
|
97
|
-
try {
|
|
98
|
-
const stat = fs.statSync(logPath);
|
|
99
|
-
let needsRotation = stat.size > maxBytes;
|
|
100
|
-
if (!needsRotation) {
|
|
101
|
-
const content = fs.readFileSync(logPath, 'utf-8');
|
|
102
|
-
const lines = content.split('\n').filter(Boolean);
|
|
103
|
-
needsRotation = lines.length > maxEntries;
|
|
104
|
-
}
|
|
105
|
-
if (needsRotation) {
|
|
106
|
-
const content = fs.readFileSync(logPath, 'utf-8');
|
|
107
|
-
const lines = content.split('\n').filter(Boolean);
|
|
108
|
-
const kept = lines.slice(-Math.max(maxEntries - 1, 1));
|
|
109
|
-
const header = `# Ralph Watch Log — Rotated ${new Date().toISOString()} (kept last ${kept.length} entries)`;
|
|
110
|
-
fs.writeFileSync(logPath, [header, ...kept].join('\n') + '\n', 'utf-8');
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch { /* best-effort */ }
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lockfile utility — per-repo lock with PID, timestamp, and stale detection.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 lockfile logic.
|
|
5
|
-
* Written BEFORE a round (status=running) and AFTER (status=idle/error).
|
|
6
|
-
* External tools (e.g., squad-monitor) can read this file to know if
|
|
7
|
-
* a watch process is active.
|
|
8
|
-
*
|
|
9
|
-
* This is a utility module — not a WatchCapability.
|
|
10
|
-
*/
|
|
11
|
-
export interface LockfileData {
|
|
12
|
-
pid: number;
|
|
13
|
-
status: 'running' | 'idle' | 'error';
|
|
14
|
-
round: number;
|
|
15
|
-
lastRun: string;
|
|
16
|
-
exitCode: number;
|
|
17
|
-
consecutiveFailures: number;
|
|
18
|
-
started: string;
|
|
19
|
-
directory: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Acquire a lockfile for this watch process.
|
|
23
|
-
* Returns false if another non-stale process holds the lock.
|
|
24
|
-
*/
|
|
25
|
-
export declare function acquireLock(teamRoot: string): boolean;
|
|
26
|
-
/** Update the lockfile with current round state. */
|
|
27
|
-
export declare function updateLock(teamRoot: string, status: 'running' | 'idle' | 'error', round: number, exitCode?: number, consecutiveFailures?: number): void;
|
|
28
|
-
/** Release the lockfile on shutdown. */
|
|
29
|
-
export declare function releaseLock(teamRoot: string): void;
|
|
30
|
-
//# sourceMappingURL=lockfile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAiCrD;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,EACpC,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAU,EACpB,mBAAmB,GAAE,MAAU,GAC9B,IAAI,CAiBN;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAUlD"}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lockfile utility — per-repo lock with PID, timestamp, and stale detection.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 lockfile logic.
|
|
5
|
-
* Written BEFORE a round (status=running) and AFTER (status=idle/error).
|
|
6
|
-
* External tools (e.g., squad-monitor) can read this file to know if
|
|
7
|
-
* a watch process is active.
|
|
8
|
-
*
|
|
9
|
-
* This is a utility module — not a WatchCapability.
|
|
10
|
-
*/
|
|
11
|
-
import path from 'node:path';
|
|
12
|
-
import fs from 'node:fs';
|
|
13
|
-
const STALE_THRESHOLD_MS = 30 * 60 * 1000; // 30 minutes
|
|
14
|
-
/**
|
|
15
|
-
* Acquire a lockfile for this watch process.
|
|
16
|
-
* Returns false if another non-stale process holds the lock.
|
|
17
|
-
*/
|
|
18
|
-
export function acquireLock(teamRoot) {
|
|
19
|
-
const lockPath = getLockPath(teamRoot);
|
|
20
|
-
if (fs.existsSync(lockPath)) {
|
|
21
|
-
try {
|
|
22
|
-
const existing = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
23
|
-
// Check if the PID is still alive
|
|
24
|
-
if (isProcessAlive(existing.pid)) {
|
|
25
|
-
// Check if it's stale
|
|
26
|
-
const age = Date.now() - new Date(existing.lastRun).getTime();
|
|
27
|
-
if (age < STALE_THRESHOLD_MS) {
|
|
28
|
-
return false; // Another active process holds the lock
|
|
29
|
-
}
|
|
30
|
-
// Stale — we can take over
|
|
31
|
-
}
|
|
32
|
-
// Dead or stale PID — safe to overwrite
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Corrupt lockfile — overwrite
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
writeLock(teamRoot, {
|
|
39
|
-
pid: process.pid,
|
|
40
|
-
status: 'running',
|
|
41
|
-
round: 0,
|
|
42
|
-
lastRun: new Date().toISOString(),
|
|
43
|
-
exitCode: 0,
|
|
44
|
-
consecutiveFailures: 0,
|
|
45
|
-
started: new Date().toISOString(),
|
|
46
|
-
directory: teamRoot,
|
|
47
|
-
});
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
/** Update the lockfile with current round state. */
|
|
51
|
-
export function updateLock(teamRoot, status, round, exitCode = 0, consecutiveFailures = 0) {
|
|
52
|
-
const lockPath = getLockPath(teamRoot);
|
|
53
|
-
let existing = {};
|
|
54
|
-
try {
|
|
55
|
-
existing = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
56
|
-
}
|
|
57
|
-
catch { /* use defaults */ }
|
|
58
|
-
writeLock(teamRoot, {
|
|
59
|
-
pid: process.pid,
|
|
60
|
-
status,
|
|
61
|
-
round,
|
|
62
|
-
lastRun: new Date().toISOString(),
|
|
63
|
-
exitCode,
|
|
64
|
-
consecutiveFailures,
|
|
65
|
-
started: existing.started ?? new Date().toISOString(),
|
|
66
|
-
directory: teamRoot,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
/** Release the lockfile on shutdown. */
|
|
70
|
-
export function releaseLock(teamRoot) {
|
|
71
|
-
const lockPath = getLockPath(teamRoot);
|
|
72
|
-
try {
|
|
73
|
-
if (fs.existsSync(lockPath)) {
|
|
74
|
-
const data = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
75
|
-
if (data.pid === process.pid) {
|
|
76
|
-
fs.unlinkSync(lockPath);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
catch { /* best-effort */ }
|
|
81
|
-
}
|
|
82
|
-
function getLockPath(teamRoot) {
|
|
83
|
-
return path.join(teamRoot, '.ralph-watch.lock');
|
|
84
|
-
}
|
|
85
|
-
function writeLock(teamRoot, data) {
|
|
86
|
-
try {
|
|
87
|
-
fs.writeFileSync(getLockPath(teamRoot), JSON.stringify(data, null, 2), 'utf-8');
|
|
88
|
-
}
|
|
89
|
-
catch { /* best-effort */ }
|
|
90
|
-
}
|
|
91
|
-
function isProcessAlive(pid) {
|
|
92
|
-
try {
|
|
93
|
-
process.kill(pid, 0);
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=lockfile.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/lockfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Machine capability checking — match issue needs:* labels to local machine.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Test-MachineCapability`.
|
|
5
|
-
* Reads `needs:*` labels from issues and compares against a local
|
|
6
|
-
* capabilities list provided via:
|
|
7
|
-
* 1. CLI flag: --capabilities gpu,browser,docker
|
|
8
|
-
* 2. Config: watch.capabilities["machine-capabilities"].list
|
|
9
|
-
* 3. Auto-detect: probe for common tools (nvidia-smi, playwright, docker)
|
|
10
|
-
*
|
|
11
|
-
* This is a utility module — not a WatchCapability.
|
|
12
|
-
*/
|
|
13
|
-
export interface MachineCapabilityResult {
|
|
14
|
-
canHandle: boolean;
|
|
15
|
-
reason: string;
|
|
16
|
-
missing?: string[];
|
|
17
|
-
}
|
|
18
|
-
export interface MachineCapabilityConfig {
|
|
19
|
-
/** Explicit list of capabilities this machine has. */
|
|
20
|
-
list?: string[];
|
|
21
|
-
/** Whether to auto-detect capabilities (default: true). */
|
|
22
|
-
autoDetect?: boolean;
|
|
23
|
-
}
|
|
24
|
-
/** Detect capabilities available on this machine. */
|
|
25
|
-
export declare function detectCapabilities(config?: MachineCapabilityConfig): Promise<string[]>;
|
|
26
|
-
/**
|
|
27
|
-
* Check if this machine can handle an issue based on its needs:* labels.
|
|
28
|
-
*/
|
|
29
|
-
export declare function checkMachineCapability(issueLabels: string[], machineCaps: string[]): MachineCapabilityResult;
|
|
30
|
-
//# sourceMappingURL=machine-capabilities.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"machine-capabilities.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/machine-capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAyCD,qDAAqD;AACrD,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAW5F;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,EAAE,GACpB,uBAAuB,CAqBzB"}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Machine capability checking — match issue needs:* labels to local machine.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Test-MachineCapability`.
|
|
5
|
-
* Reads `needs:*` labels from issues and compares against a local
|
|
6
|
-
* capabilities list provided via:
|
|
7
|
-
* 1. CLI flag: --capabilities gpu,browser,docker
|
|
8
|
-
* 2. Config: watch.capabilities["machine-capabilities"].list
|
|
9
|
-
* 3. Auto-detect: probe for common tools (nvidia-smi, playwright, docker)
|
|
10
|
-
*
|
|
11
|
-
* This is a utility module — not a WatchCapability.
|
|
12
|
-
*/
|
|
13
|
-
import { execFile } from 'node:child_process';
|
|
14
|
-
import { promisify } from 'node:util';
|
|
15
|
-
const execFileAsync = promisify(execFile);
|
|
16
|
-
/** Probes for common capabilities on the local machine. */
|
|
17
|
-
const CAPABILITY_PROBES = {
|
|
18
|
-
gpu: async () => {
|
|
19
|
-
try {
|
|
20
|
-
await execFileAsync('nvidia-smi', ['--query-gpu=name', '--format=csv,noheader'], { timeout: 5_000 });
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
browser: async () => {
|
|
28
|
-
try {
|
|
29
|
-
await execFileAsync('npx', ['playwright', '--version'], { timeout: 10_000 });
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
docker: async () => {
|
|
37
|
-
try {
|
|
38
|
-
await execFileAsync('docker', ['info'], { timeout: 5_000 });
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
node: async () => {
|
|
46
|
-
try {
|
|
47
|
-
await execFileAsync('node', ['--version'], { timeout: 5_000 });
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
python: async () => {
|
|
55
|
-
try {
|
|
56
|
-
await execFileAsync('python3', ['--version'], { timeout: 5_000 });
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
try {
|
|
61
|
-
await execFileAsync('python', ['--version'], { timeout: 5_000 });
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
/** Detect capabilities available on this machine. */
|
|
71
|
-
export async function detectCapabilities(config) {
|
|
72
|
-
const caps = new Set(config?.list ?? []);
|
|
73
|
-
if (config?.autoDetect !== false) {
|
|
74
|
-
const probes = Object.entries(CAPABILITY_PROBES).map(async ([name, probe]) => {
|
|
75
|
-
if (await probe())
|
|
76
|
-
caps.add(name);
|
|
77
|
-
});
|
|
78
|
-
await Promise.all(probes);
|
|
79
|
-
}
|
|
80
|
-
return [...caps];
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Check if this machine can handle an issue based on its needs:* labels.
|
|
84
|
-
*/
|
|
85
|
-
export function checkMachineCapability(issueLabels, machineCaps) {
|
|
86
|
-
const needsLabels = issueLabels
|
|
87
|
-
.filter(l => l.startsWith('needs:'))
|
|
88
|
-
.map(l => l.replace(/^needs:/, ''));
|
|
89
|
-
if (needsLabels.length === 0) {
|
|
90
|
-
return { canHandle: true, reason: 'No needs:* labels on issue' };
|
|
91
|
-
}
|
|
92
|
-
const capSet = new Set(machineCaps.map(c => c.toLowerCase()));
|
|
93
|
-
const missing = needsLabels.filter(need => !capSet.has(need.toLowerCase()));
|
|
94
|
-
if (missing.length === 0) {
|
|
95
|
-
return { canHandle: true, reason: 'All required capabilities present' };
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
canHandle: false,
|
|
99
|
-
reason: `Missing capabilities: ${missing.join(', ')}`,
|
|
100
|
-
missing,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=machine-capabilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"machine-capabilities.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/machine-capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Post-failure remediation — tiered self-healing response.
|
|
3
|
-
*
|
|
4
|
-
* Ported from ralph-watch.ps1 `Invoke-PostFailureRemediation`.
|
|
5
|
-
* Tiered response based on consecutive failure count:
|
|
6
|
-
* Tier 1 (≥3): Reset circuit breaker state
|
|
7
|
-
* Tier 2 (≥6): Re-verify auth
|
|
8
|
-
* Tier 3 (≥9): Git pull to get latest fixes
|
|
9
|
-
* Tier 4 (≥15): Extended pause + webhook alert
|
|
10
|
-
*
|
|
11
|
-
* This is a utility module — called from the main watch loop on errors.
|
|
12
|
-
*/
|
|
13
|
-
import type { ModelCircuitBreaker } from './circuit-breaker.js';
|
|
14
|
-
export interface RemediationResult {
|
|
15
|
-
actions: string[];
|
|
16
|
-
pauseSeconds: number;
|
|
17
|
-
}
|
|
18
|
-
export declare function runPostFailureRemediation(consecutiveFailures: number, round: number, teamRoot: string, circuitBreaker?: ModelCircuitBreaker): Promise<RemediationResult>;
|
|
19
|
-
//# sourceMappingURL=post-failure.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"post-failure.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/post-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,yBAAyB,CAC7C,mBAAmB,EAAE,MAAM,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,mBAAmB,GACnC,OAAO,CAAC,iBAAiB,CAAC,CA4C5B"}
|