rlph-cli 1.2.0 → 1.3.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/agents/base.d.ts +7 -0
- package/dist/agents/base.d.ts.map +1 -1
- package/dist/agents/base.js.map +1 -1
- package/dist/agents/claude.d.ts.map +1 -1
- package/dist/agents/claude.js +11 -1
- package/dist/agents/claude.js.map +1 -1
- package/dist/commands/prd-add.d.ts.map +1 -1
- package/dist/commands/prd-add.js +9 -5
- package/dist/commands/prd-add.js.map +1 -1
- package/dist/commands/prd-list.d.ts.map +1 -1
- package/dist/commands/prd-list.js +10 -2
- package/dist/commands/prd-list.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +139 -33
- package/dist/commands/run.js.map +1 -1
- package/dist/prd/manager.d.ts +5 -4
- package/dist/prd/manager.d.ts.map +1 -1
- package/dist/prd/manager.js +107 -28
- package/dist/prd/manager.js.map +1 -1
- package/dist/prd/types.d.ts +3 -0
- package/dist/prd/types.d.ts.map +1 -1
- package/dist/stream/persister.d.ts +61 -0
- package/dist/stream/persister.d.ts.map +1 -0
- package/dist/stream/persister.js +205 -0
- package/dist/stream/persister.js.map +1 -0
- package/dist/stream/types.d.ts +49 -0
- package/dist/stream/types.d.ts.map +1 -0
- package/dist/stream/types.js +2 -0
- package/dist/stream/types.js.map +1 -0
- package/package.json +1 -1
package/dist/agents/base.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process';
|
|
1
2
|
export interface AgentResult {
|
|
2
3
|
output: string;
|
|
3
4
|
exitCode: number;
|
|
@@ -5,6 +6,12 @@ export interface AgentResult {
|
|
|
5
6
|
}
|
|
6
7
|
export interface ExecuteOptions {
|
|
7
8
|
onOutput?: (chunk: string) => void;
|
|
9
|
+
/** Called for each formatted event for persistence. isEventBoundary signals event completion. */
|
|
10
|
+
onPersist?: (chunk: string, isEventBoundary: boolean) => void;
|
|
11
|
+
/** Called for stderr content */
|
|
12
|
+
onStderr?: (chunk: string) => void;
|
|
13
|
+
/** Called with spawned process for signal handling */
|
|
14
|
+
onProcess?: (proc: ChildProcess) => void;
|
|
8
15
|
}
|
|
9
16
|
export interface Agent {
|
|
10
17
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,iGAAiG;IACjG,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7D,gCAAgC;IAChC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,sDAAsD;IACtD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CACrF;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAA;AAEhC,eAAO,MAAM,gBAAgB,EAAE,SAAS,EAAe,CAAA;AAEvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAE9D"}
|
package/dist/agents/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/agents/base.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAC,MAAM,gBAAgB,GAAgB,CAAC,QAAQ,CAAC,CAAA;AAEvD,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,KAAkB,CAAC,CAAA;AACtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAA+B,MAAM,WAAW,CAAA;AAKnE,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAA+B,MAAM,WAAW,CAAA;AAKnE,eAAO,MAAM,MAAM,EAAE,KAqFpB,CAAA"}
|
package/dist/agents/claude.js
CHANGED
|
@@ -7,6 +7,9 @@ export const claude = {
|
|
|
7
7
|
async execute(prompt, cwd, options) {
|
|
8
8
|
const startTime = Date.now();
|
|
9
9
|
const onOutput = options?.onOutput;
|
|
10
|
+
const onPersist = options?.onPersist;
|
|
11
|
+
const onStderr = options?.onStderr;
|
|
12
|
+
const onProcess = options?.onProcess;
|
|
10
13
|
return new Promise((resolve, reject) => {
|
|
11
14
|
const proc = spawn('claude', [
|
|
12
15
|
'-p',
|
|
@@ -18,6 +21,8 @@ export const claude = {
|
|
|
18
21
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
19
22
|
shell: true,
|
|
20
23
|
});
|
|
24
|
+
// Expose process for signal handling
|
|
25
|
+
onProcess?.(proc);
|
|
21
26
|
let rawOutput = '';
|
|
22
27
|
let textOutput = '';
|
|
23
28
|
let stderr = '';
|
|
@@ -25,6 +30,8 @@ export const claude = {
|
|
|
25
30
|
const formatted = formatEvent(event);
|
|
26
31
|
if (formatted) {
|
|
27
32
|
onOutput?.(formatted + '\n');
|
|
33
|
+
// Persist with event boundary flag (event is complete)
|
|
34
|
+
onPersist?.(formatted + '\n', true);
|
|
28
35
|
}
|
|
29
36
|
// Accumulate text content for completion marker detection
|
|
30
37
|
if (event.type === 'assistant') {
|
|
@@ -35,7 +42,9 @@ export const claude = {
|
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
}, (_error, line) => {
|
|
38
|
-
|
|
45
|
+
const warning = chalk.yellow(`[warn] malformed JSON: ${line.slice(0, 100)}\n`);
|
|
46
|
+
onOutput?.(warning);
|
|
47
|
+
onPersist?.(warning, false);
|
|
39
48
|
});
|
|
40
49
|
proc.stdout.on('data', (data) => {
|
|
41
50
|
const chunk = data.toString();
|
|
@@ -46,6 +55,7 @@ export const claude = {
|
|
|
46
55
|
const chunk = data.toString();
|
|
47
56
|
stderr += chunk;
|
|
48
57
|
onOutput?.(chalk.red(chunk));
|
|
58
|
+
onStderr?.(chunk);
|
|
49
59
|
});
|
|
50
60
|
proc.on('error', (err) => {
|
|
51
61
|
reject(new Error(`Failed to spawn claude: ${err.message}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGnD,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE,QAAQ;IAEd,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,GAAW,EAAE,OAAwB;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agents/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-add.d.ts","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prd-add.d.ts","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Ef"}
|
package/dist/commands/prd-add.js
CHANGED
|
@@ -2,7 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { access, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { getAgent, isValidAgent } from '../agents/index.js';
|
|
5
|
-
import { createPrdFolder, copyMarkdown, getPrdDir, prdExists } from '../prd/index.js';
|
|
5
|
+
import { createPrdFolder, copyMarkdown, getPrdDir, isProjectInitialized, prdExists, } from '../prd/index.js';
|
|
6
6
|
import { ensureTemplates, loadTemplate, substituteVars } from '../templates/index.js';
|
|
7
7
|
export async function prdAdd(path, name, opts) {
|
|
8
8
|
// Validate agent
|
|
@@ -19,12 +19,16 @@ export async function prdAdd(path, name, opts) {
|
|
|
19
19
|
console.error(chalk.red(`File not found: ${path}`));
|
|
20
20
|
process.exit(1);
|
|
21
21
|
}
|
|
22
|
-
// Check if PRD already exists
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Check if PRD already exists in target location
|
|
23
|
+
// For initialized projects, only check local; otherwise check global
|
|
24
|
+
const isInitialized = await isProjectInitialized();
|
|
25
|
+
const checkLocation = isInitialized ? 'local' : 'global';
|
|
26
|
+
if (await prdExists(name, checkLocation)) {
|
|
27
|
+
const locationLabel = isInitialized ? 'local' : 'global';
|
|
28
|
+
console.error(chalk.red(`PRD already exists (${locationLabel}): ${name}`));
|
|
25
29
|
process.exit(1);
|
|
26
30
|
}
|
|
27
|
-
const prdDir = await getPrdDir(name);
|
|
31
|
+
const prdDir = await getPrdDir(name, 'write');
|
|
28
32
|
const prdJsonPath = join(prdDir, 'prd.json');
|
|
29
33
|
const progressPath = join(prdDir, 'progress.txt');
|
|
30
34
|
console.log(chalk.blue(`Creating PRD: ${name}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-add.js","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,
|
|
1
|
+
{"version":3,"file":"prd-add.js","sourceRoot":"","sources":["../../src/commands/prd-add.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-list.d.ts","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prd-list.d.ts","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"AAmBA,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkD7C"}
|
|
@@ -10,6 +10,9 @@ function statusColor(status) {
|
|
|
10
10
|
return chalk.green(status);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
function locationColor(location) {
|
|
14
|
+
return location === 'local' ? chalk.cyan(location) : chalk.gray(location);
|
|
15
|
+
}
|
|
13
16
|
export async function prdList() {
|
|
14
17
|
const prds = await listPrds();
|
|
15
18
|
if (prds.length === 0) {
|
|
@@ -21,6 +24,7 @@ export async function prdList() {
|
|
|
21
24
|
const descWidth = Math.min(40, Math.max(11, ...prds.map((p) => p.description.length)));
|
|
22
25
|
const statusWidth = 11;
|
|
23
26
|
const progressWidth = 8;
|
|
27
|
+
const locationWidth = 6;
|
|
24
28
|
// Header
|
|
25
29
|
console.log(chalk.bold('NAME'.padEnd(nameWidth) +
|
|
26
30
|
' ' +
|
|
@@ -28,7 +32,9 @@ export async function prdList() {
|
|
|
28
32
|
' ' +
|
|
29
33
|
'STATUS'.padEnd(statusWidth) +
|
|
30
34
|
' ' +
|
|
31
|
-
'PROGRESS')
|
|
35
|
+
'PROGRESS'.padStart(progressWidth) +
|
|
36
|
+
' ' +
|
|
37
|
+
'LOCATION'));
|
|
32
38
|
// Rows
|
|
33
39
|
for (const prd of prds) {
|
|
34
40
|
const desc = prd.description.length > descWidth
|
|
@@ -41,7 +47,9 @@ export async function prdList() {
|
|
|
41
47
|
' ' +
|
|
42
48
|
statusColor(prd.status).padEnd(statusWidth + 10) + // extra for ansi codes
|
|
43
49
|
' ' +
|
|
44
|
-
progress.padStart(progressWidth)
|
|
50
|
+
progress.padStart(progressWidth) +
|
|
51
|
+
' ' +
|
|
52
|
+
locationColor(prd.location));
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
//# sourceMappingURL=prd-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd-list.js","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG1C,SAAS,WAAW,CAAC,MAAqB;IACxC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3B,KAAK,aAAa;YAChB,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC7B,KAAK,WAAW;YACd,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAA;IAE7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,0BAA0B;IAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACtF,MAAM,WAAW,GAAG,EAAE,CAAA;IACtB,MAAM,aAAa,GAAG,CAAC,CAAA;IAEvB,SAAS;IACT,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QACtB,IAAI;QACJ,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC;QAC/B,IAAI;QACJ,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC;QAC5B,IAAI;QACJ,UAAU,CACb,CACF,CAAA;IAED,OAAO;IACP,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GACR,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,SAAS;YAChC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK;YACjD,CAAC,CAAC,GAAG,CAAC,WAAW,CAAA;QACrB,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,UAAU,EAAE,CAAA;QAE1D,OAAO,CAAC,GAAG,CACT,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACxB,IAAI;YACJ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACtB,IAAI;YACJ,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC,GAAG,uBAAuB;YAC1E,IAAI;YACJ,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"prd-list.js","sourceRoot":"","sources":["../../src/commands/prd-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAmGD,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4H1E"}
|
package/dist/commands/run.js
CHANGED
|
@@ -1,10 +1,92 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { mkdir
|
|
2
|
+
import { mkdir } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { getAgent, isValidAgent } from '../agents/index.js';
|
|
5
5
|
import { getPrd, getPrdDir, prdExists } from '../prd/index.js';
|
|
6
|
+
import { StreamPersisterImpl } from '../stream/persister.js';
|
|
6
7
|
import { ensureTemplates, loadTemplate, substituteVars } from '../templates/index.js';
|
|
7
8
|
const TASKS_COMPLETE_MARKER = '<tasks>COMPLETE</tasks>';
|
|
9
|
+
const SIGNAL_EXIT_CODES = {
|
|
10
|
+
SIGINT: 130, // 128 + 2
|
|
11
|
+
SIGTERM: 143, // 128 + 15
|
|
12
|
+
SIGHUP: 129, // 128 + 1
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Signal handler manager for graceful interruption
|
|
16
|
+
*/
|
|
17
|
+
class SignalHandlers {
|
|
18
|
+
activePersister = null;
|
|
19
|
+
activeProcess = null;
|
|
20
|
+
handlers = new Map();
|
|
21
|
+
aborted = false;
|
|
22
|
+
handling = false; // re-entrancy guard
|
|
23
|
+
register() {
|
|
24
|
+
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
25
|
+
for (const signal of signals) {
|
|
26
|
+
const handler = () => void this.handleSignal(signal);
|
|
27
|
+
this.handlers.set(signal, handler);
|
|
28
|
+
process.addListener(signal, handler);
|
|
29
|
+
}
|
|
30
|
+
const exceptionHandler = (err) => void this.handleCrash(err instanceof Error ? err : new Error(String(err)));
|
|
31
|
+
this.handlers.set('uncaughtException', exceptionHandler);
|
|
32
|
+
process.addListener('uncaughtException', exceptionHandler);
|
|
33
|
+
}
|
|
34
|
+
unregister() {
|
|
35
|
+
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
36
|
+
for (const signal of signals) {
|
|
37
|
+
const handler = this.handlers.get(signal);
|
|
38
|
+
if (handler)
|
|
39
|
+
process.removeListener(signal, handler);
|
|
40
|
+
}
|
|
41
|
+
const exceptionHandler = this.handlers.get('uncaughtException');
|
|
42
|
+
if (exceptionHandler)
|
|
43
|
+
process.removeListener('uncaughtException', exceptionHandler);
|
|
44
|
+
this.handlers.clear();
|
|
45
|
+
}
|
|
46
|
+
setPersister(persister) {
|
|
47
|
+
this.activePersister = persister;
|
|
48
|
+
}
|
|
49
|
+
setProcess(proc) {
|
|
50
|
+
this.activeProcess = proc;
|
|
51
|
+
}
|
|
52
|
+
wasAborted() {
|
|
53
|
+
return this.aborted;
|
|
54
|
+
}
|
|
55
|
+
async handleSignal(signal) {
|
|
56
|
+
if (this.handling)
|
|
57
|
+
return; // re-entrancy guard
|
|
58
|
+
this.handling = true;
|
|
59
|
+
this.aborted = true;
|
|
60
|
+
// Kill child process first
|
|
61
|
+
if (this.activeProcess && !this.activeProcess.killed) {
|
|
62
|
+
this.activeProcess.kill(signal);
|
|
63
|
+
this.activeProcess = null;
|
|
64
|
+
}
|
|
65
|
+
if (this.activePersister) {
|
|
66
|
+
await this.activePersister.abort(signal);
|
|
67
|
+
this.activePersister = null;
|
|
68
|
+
}
|
|
69
|
+
this.unregister();
|
|
70
|
+
process.exit(SIGNAL_EXIT_CODES[signal]);
|
|
71
|
+
}
|
|
72
|
+
async handleCrash(error) {
|
|
73
|
+
if (this.handling)
|
|
74
|
+
return; // re-entrancy guard
|
|
75
|
+
this.handling = true;
|
|
76
|
+
// Kill child process
|
|
77
|
+
if (this.activeProcess && !this.activeProcess.killed) {
|
|
78
|
+
this.activeProcess.kill();
|
|
79
|
+
this.activeProcess = null;
|
|
80
|
+
}
|
|
81
|
+
if (this.activePersister) {
|
|
82
|
+
await this.activePersister.crash(error);
|
|
83
|
+
this.activePersister = null;
|
|
84
|
+
}
|
|
85
|
+
this.unregister();
|
|
86
|
+
console.error(chalk.red(`Uncaught exception: ${error.message}`));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
8
90
|
export async function run(prdName, opts) {
|
|
9
91
|
// Validate agent
|
|
10
92
|
if (!isValidAgent(opts.agent)) {
|
|
@@ -46,31 +128,67 @@ export async function run(prdName, opts) {
|
|
|
46
128
|
console.log(chalk.gray(`Pending tasks: ${pendingTasks}/${prd.tasks.length}`));
|
|
47
129
|
console.log(chalk.gray(`Iterations: ${iterations}`));
|
|
48
130
|
console.log();
|
|
131
|
+
// Set up signal handlers for graceful interruption
|
|
132
|
+
const signalHandlers = new SignalHandlers();
|
|
133
|
+
signalHandlers.register();
|
|
49
134
|
// Run loop
|
|
50
135
|
let completed = false;
|
|
51
136
|
let actualIterations = 0;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
137
|
+
try {
|
|
138
|
+
for (let i = 0; i < iterations; i++) {
|
|
139
|
+
actualIterations++;
|
|
140
|
+
console.log(chalk.yellow(`[${i + 1}/${iterations}] Running ${agent.name}...`));
|
|
141
|
+
console.log();
|
|
142
|
+
const logPath = join(iterationsDir, `${i}.log`);
|
|
143
|
+
const persister = new StreamPersisterImpl({ logPath });
|
|
144
|
+
signalHandlers.setPersister(persister);
|
|
145
|
+
let result;
|
|
146
|
+
try {
|
|
147
|
+
result = await agent.execute(prompt, process.cwd(), {
|
|
148
|
+
onOutput: (chunk) => process.stdout.write(chunk),
|
|
149
|
+
onPersist: (chunk, isEventBoundary) => {
|
|
150
|
+
void persister.append(chunk, isEventBoundary);
|
|
151
|
+
},
|
|
152
|
+
onStderr: (chunk) => {
|
|
153
|
+
void persister.appendStderr(chunk);
|
|
154
|
+
},
|
|
155
|
+
onProcess: (proc) => signalHandlers.setProcess(proc),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
// Execution failed - persist crash state and re-throw
|
|
160
|
+
await persister.crash(err instanceof Error ? err : new Error(String(err)));
|
|
161
|
+
signalHandlers.setPersister(null);
|
|
162
|
+
signalHandlers.setProcess(null);
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
signalHandlers.setProcess(null);
|
|
166
|
+
// Complete THEN clear persister (fixes race with signal handlers)
|
|
167
|
+
await persister.complete(result.exitCode, result.duration);
|
|
168
|
+
signalHandlers.setPersister(null);
|
|
169
|
+
// Check for persistence errors
|
|
170
|
+
const persistError = persister.getError();
|
|
171
|
+
if (persistError) {
|
|
172
|
+
console.log(chalk.yellow(` Warning: log write error: ${persistError.message}`));
|
|
173
|
+
}
|
|
174
|
+
console.log();
|
|
175
|
+
if (result.exitCode !== 0) {
|
|
176
|
+
console.log(chalk.red(` Exit code: ${result.exitCode}`));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
console.log(chalk.green(` Done (${result.duration}ms)`));
|
|
180
|
+
}
|
|
181
|
+
// Check for completion marker
|
|
182
|
+
if (result.output.includes(TASKS_COMPLETE_MARKER)) {
|
|
183
|
+
console.log(chalk.cyan(` All tasks complete`));
|
|
184
|
+
completed = true;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
72
187
|
}
|
|
73
188
|
}
|
|
189
|
+
finally {
|
|
190
|
+
signalHandlers.unregister();
|
|
191
|
+
}
|
|
74
192
|
console.log();
|
|
75
193
|
if (completed) {
|
|
76
194
|
console.log(chalk.green(`PRD completed after ${actualIterations} iteration(s)`));
|
|
@@ -80,16 +198,4 @@ export async function run(prdName, opts) {
|
|
|
80
198
|
}
|
|
81
199
|
console.log(chalk.gray(`Logs: ${iterationsDir}`));
|
|
82
200
|
}
|
|
83
|
-
async function writeIterationLog(iterationsDir, iteration, result) {
|
|
84
|
-
const logPath = join(iterationsDir, `${iteration}.log`);
|
|
85
|
-
const header = [
|
|
86
|
-
`# Iteration ${iteration}`,
|
|
87
|
-
`Timestamp: ${new Date().toISOString()}`,
|
|
88
|
-
`Duration: ${result.duration}ms`,
|
|
89
|
-
`Exit Code: ${result.exitCode}`,
|
|
90
|
-
'---',
|
|
91
|
-
'',
|
|
92
|
-
].join('\n');
|
|
93
|
-
await writeFile(logPath, header + result.output);
|
|
94
|
-
}
|
|
95
201
|
//# sourceMappingURL=run.js.map
|
package/dist/commands/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
package/dist/prd/manager.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { PrdJson, PrdStatus } from './types.js';
|
|
1
|
+
import type { PrdDirMode, PrdJson, PrdLocation, PrdStatus } from './types.js';
|
|
2
2
|
export declare function getLocalPrdsDir(): string;
|
|
3
3
|
export declare function getGlobalPrdsDir(): string;
|
|
4
4
|
export declare function getPrdsDir(): string;
|
|
5
5
|
export declare function getLocalPrdDir(name: string): string;
|
|
6
6
|
export declare function getGlobalPrdDir(name: string): string;
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
7
|
+
export declare function isProjectInitialized(): Promise<boolean>;
|
|
8
|
+
export declare function getPrdDir(name: string, mode?: PrdDirMode): Promise<string>;
|
|
9
|
+
export declare function prdExists(name: string, location?: 'local' | 'global'): Promise<boolean>;
|
|
10
|
+
export declare function createPrdFolder(name: string, location?: PrdLocation): Promise<void>;
|
|
10
11
|
export declare function copyMarkdown(src: string, name: string): Promise<void>;
|
|
11
12
|
export declare function getPrd(name: string): Promise<PrdJson>;
|
|
12
13
|
export declare function listPrds(): Promise<PrdStatus[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EACP,WAAW,EACX,SAAS,EAEV,MAAM,YAAY,CAAA;AAEnB,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAWD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG7D;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,UAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,GAC5B,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,WAAoB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB3D;AA8BD,wBAAsB,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAiDrD"}
|
package/dist/prd/manager.js
CHANGED
|
@@ -25,32 +25,82 @@ async function dirExists(path) {
|
|
|
25
25
|
return false;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
export async function
|
|
28
|
+
export async function isProjectInitialized() {
|
|
29
|
+
const localRalphDir = join(process.cwd(), '.ralph');
|
|
30
|
+
return dirExists(localRalphDir);
|
|
31
|
+
}
|
|
32
|
+
export async function getPrdDir(name, mode = 'read') {
|
|
29
33
|
const localDir = getLocalPrdDir(name);
|
|
34
|
+
const globalDir = getGlobalPrdDir(name);
|
|
35
|
+
if (mode === 'write') {
|
|
36
|
+
// Write mode: use local if project is initialized, else global
|
|
37
|
+
if (await isProjectInitialized()) {
|
|
38
|
+
return localDir;
|
|
39
|
+
}
|
|
40
|
+
return globalDir;
|
|
41
|
+
}
|
|
42
|
+
// Read mode: local if exists, else global (current behavior)
|
|
30
43
|
if (await dirExists(localDir)) {
|
|
31
44
|
return localDir;
|
|
32
45
|
}
|
|
33
|
-
return
|
|
46
|
+
return globalDir;
|
|
34
47
|
}
|
|
35
|
-
export async function prdExists(name) {
|
|
48
|
+
export async function prdExists(name, location) {
|
|
36
49
|
const localDir = getLocalPrdDir(name);
|
|
37
50
|
const globalDir = getGlobalPrdDir(name);
|
|
51
|
+
if (location === 'local') {
|
|
52
|
+
return dirExists(localDir);
|
|
53
|
+
}
|
|
54
|
+
if (location === 'global') {
|
|
55
|
+
return dirExists(globalDir);
|
|
56
|
+
}
|
|
57
|
+
// Check both when location not specified
|
|
38
58
|
return (await dirExists(localDir)) || (await dirExists(globalDir));
|
|
39
59
|
}
|
|
40
|
-
export async function createPrdFolder(name) {
|
|
41
|
-
|
|
60
|
+
export async function createPrdFolder(name, location = 'auto') {
|
|
61
|
+
let prdDir;
|
|
62
|
+
if (location === 'local') {
|
|
63
|
+
prdDir = getLocalPrdDir(name);
|
|
64
|
+
}
|
|
65
|
+
else if (location === 'global') {
|
|
66
|
+
prdDir = getGlobalPrdDir(name);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// auto: use write mode to get local-first behavior
|
|
70
|
+
prdDir = await getPrdDir(name, 'write');
|
|
71
|
+
}
|
|
42
72
|
await mkdir(prdDir, { recursive: true });
|
|
43
73
|
}
|
|
44
74
|
export async function copyMarkdown(src, name) {
|
|
45
|
-
const prdDir = await getPrdDir(name);
|
|
75
|
+
const prdDir = await getPrdDir(name, 'write');
|
|
46
76
|
const dest = join(prdDir, 'prd.md');
|
|
47
77
|
await copyFile(src, dest);
|
|
48
78
|
}
|
|
49
79
|
export async function getPrd(name) {
|
|
50
80
|
const prdDir = await getPrdDir(name);
|
|
51
81
|
const prdPath = join(prdDir, 'prd.json');
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
let content;
|
|
83
|
+
try {
|
|
84
|
+
content = await readFile(prdPath, 'utf-8');
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (err instanceof Error && 'code' in err) {
|
|
88
|
+
const code = err.code;
|
|
89
|
+
if (code === 'EACCES') {
|
|
90
|
+
throw new Error(`Permission denied: ${prdPath}`);
|
|
91
|
+
}
|
|
92
|
+
if (code === 'ENOENT') {
|
|
93
|
+
throw new Error(`PRD not found: ${name}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(content);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new Error(`Invalid JSON in PRD file: ${prdPath}`);
|
|
103
|
+
}
|
|
54
104
|
}
|
|
55
105
|
function computeStatus(prd) {
|
|
56
106
|
const completed = prd.tasks.filter((t) => t.passes).length;
|
|
@@ -68,28 +118,57 @@ async function readPrdEntries(dir) {
|
|
|
68
118
|
return [];
|
|
69
119
|
}
|
|
70
120
|
}
|
|
121
|
+
async function getPrdFromDir(dir, entry) {
|
|
122
|
+
try {
|
|
123
|
+
const prdPath = join(dir, entry, 'prd.json');
|
|
124
|
+
const content = await readFile(prdPath, 'utf-8');
|
|
125
|
+
return JSON.parse(content);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
71
131
|
export async function listPrds() {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const
|
|
132
|
+
const localDir = getLocalPrdsDir();
|
|
133
|
+
const globalDir = getGlobalPrdsDir();
|
|
134
|
+
const localEntries = await readPrdEntries(localDir);
|
|
135
|
+
const globalEntries = await readPrdEntries(globalDir);
|
|
76
136
|
const results = [];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
137
|
+
const seenNames = new Set();
|
|
138
|
+
// Process local entries first (they take precedence)
|
|
139
|
+
for (const entry of localEntries) {
|
|
140
|
+
const prd = await getPrdFromDir(localDir, entry);
|
|
141
|
+
if (!prd)
|
|
142
|
+
continue;
|
|
143
|
+
const status = computeStatus(prd);
|
|
144
|
+
const tasksCompleted = prd.tasks.filter((t) => t.passes).length;
|
|
145
|
+
seenNames.add(entry);
|
|
146
|
+
results.push({
|
|
147
|
+
name: prd.prdName,
|
|
148
|
+
description: prd.tasks[0]?.description ?? '',
|
|
149
|
+
status,
|
|
150
|
+
tasksTotal: prd.tasks.length,
|
|
151
|
+
tasksCompleted,
|
|
152
|
+
location: 'local',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Process global entries, skip if shadowed by local
|
|
156
|
+
for (const entry of globalEntries) {
|
|
157
|
+
if (seenNames.has(entry))
|
|
158
|
+
continue;
|
|
159
|
+
const prd = await getPrdFromDir(globalDir, entry);
|
|
160
|
+
if (!prd)
|
|
161
|
+
continue;
|
|
162
|
+
const status = computeStatus(prd);
|
|
163
|
+
const tasksCompleted = prd.tasks.filter((t) => t.passes).length;
|
|
164
|
+
results.push({
|
|
165
|
+
name: prd.prdName,
|
|
166
|
+
description: prd.tasks[0]?.description ?? '',
|
|
167
|
+
status,
|
|
168
|
+
tasksTotal: prd.tasks.length,
|
|
169
|
+
tasksCompleted,
|
|
170
|
+
location: 'global',
|
|
171
|
+
});
|
|
93
172
|
}
|
|
94
173
|
return results;
|
|
95
174
|
}
|
package/dist/prd/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/prd/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/prd/types.d.ts
CHANGED
|
@@ -20,11 +20,14 @@ export interface PrdJson {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
export type PrdStatusType = 'pending' | 'in_progress' | 'completed';
|
|
23
|
+
export type PrdLocation = 'local' | 'global' | 'auto';
|
|
24
|
+
export type PrdDirMode = 'read' | 'write';
|
|
23
25
|
export interface PrdStatus {
|
|
24
26
|
name: string;
|
|
25
27
|
description: string;
|
|
26
28
|
status: PrdStatusType;
|
|
27
29
|
tasksTotal: number;
|
|
28
30
|
tasksCompleted: number;
|
|
31
|
+
location: 'local' | 'global';
|
|
29
32
|
}
|
|
30
33
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/prd/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAA;AAEvD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;CACF;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;AAEnE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,aAAa,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAA;AAEvD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;CACF;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;AAEnE,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAErD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;AAEzC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,aAAa,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAA;CAC7B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { StreamPersister, StreamPersisterOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Persists streamed output incrementally with buffering
|
|
4
|
+
*/
|
|
5
|
+
export declare class StreamPersisterImpl implements StreamPersister {
|
|
6
|
+
private buffer;
|
|
7
|
+
private logPath;
|
|
8
|
+
private status;
|
|
9
|
+
private startTime;
|
|
10
|
+
private headerWritten;
|
|
11
|
+
private writeError;
|
|
12
|
+
private fileHandle;
|
|
13
|
+
private flushTimer;
|
|
14
|
+
private flushIntervalMs;
|
|
15
|
+
private flushing;
|
|
16
|
+
private finalized;
|
|
17
|
+
constructor(options: StreamPersisterOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Starts the auto-flush timer if not already running
|
|
20
|
+
*/
|
|
21
|
+
private startFlushTimer;
|
|
22
|
+
/**
|
|
23
|
+
* Stops the auto-flush timer
|
|
24
|
+
*/
|
|
25
|
+
private stopFlushTimer;
|
|
26
|
+
/**
|
|
27
|
+
* Ensures file handle is open and header is written
|
|
28
|
+
*/
|
|
29
|
+
private ensureFile;
|
|
30
|
+
/**
|
|
31
|
+
* Writes the log header with in_progress status
|
|
32
|
+
*/
|
|
33
|
+
private writeHeader;
|
|
34
|
+
/**
|
|
35
|
+
* Writes content to file atomically (complete string only)
|
|
36
|
+
*/
|
|
37
|
+
private writeToFile;
|
|
38
|
+
append(content: string, isEventBoundary?: boolean): Promise<void>;
|
|
39
|
+
appendStderr(content: string): Promise<void>;
|
|
40
|
+
flush(): Promise<void>;
|
|
41
|
+
complete(exitCode: number, duration: number): Promise<void>;
|
|
42
|
+
abort(signal: string): Promise<void>;
|
|
43
|
+
crash(error: Error): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Writes final metadata section
|
|
46
|
+
*/
|
|
47
|
+
private writeMetadata;
|
|
48
|
+
/**
|
|
49
|
+
* Closes the file handle
|
|
50
|
+
*/
|
|
51
|
+
private close;
|
|
52
|
+
/**
|
|
53
|
+
* Cleanup method for cases where persister is abandoned without complete/abort/crash
|
|
54
|
+
*/
|
|
55
|
+
destroy(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Returns any write error that occurred
|
|
58
|
+
*/
|
|
59
|
+
getError(): Error | null;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=persister.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persister.d.ts","sourceRoot":"","sources":["../../src/stream/persister.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAgB,MAAM,YAAY,CAAA;AAElF;;GAEG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,SAAS,CAAQ;gBAEb,OAAO,EAAE,sBAAsB;IAM3C;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;YACW,UAAU;IAwBxB;;OAEG;YACW,WAAW;IAYzB;;OAEG;YACW,WAAW;IAWnB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/D,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3D,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxC;;OAEG;YACW,aAAa;IA2B3B;;OAEG;YACW,KAAK;IAWnB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;OAEG;IACH,QAAQ,IAAI,KAAK,GAAG,IAAI;CAGzB"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Persists streamed output incrementally with buffering
|
|
5
|
+
*/
|
|
6
|
+
export class StreamPersisterImpl {
|
|
7
|
+
buffer = '';
|
|
8
|
+
logPath;
|
|
9
|
+
status = 'in_progress';
|
|
10
|
+
startTime;
|
|
11
|
+
headerWritten = false;
|
|
12
|
+
writeError = null;
|
|
13
|
+
fileHandle = null;
|
|
14
|
+
flushTimer = null;
|
|
15
|
+
flushIntervalMs;
|
|
16
|
+
flushing = false; // mutex for flush
|
|
17
|
+
finalized = false; // guard against double finalization
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.logPath = options.logPath;
|
|
20
|
+
this.startTime = Date.now();
|
|
21
|
+
this.flushIntervalMs = options.flushIntervalMs ?? 100;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Starts the auto-flush timer if not already running
|
|
25
|
+
*/
|
|
26
|
+
startFlushTimer() {
|
|
27
|
+
if (this.flushTimer)
|
|
28
|
+
return;
|
|
29
|
+
this.flushTimer = setInterval(() => {
|
|
30
|
+
void this.flush();
|
|
31
|
+
}, this.flushIntervalMs);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stops the auto-flush timer
|
|
35
|
+
*/
|
|
36
|
+
stopFlushTimer() {
|
|
37
|
+
if (!this.flushTimer)
|
|
38
|
+
return;
|
|
39
|
+
clearInterval(this.flushTimer);
|
|
40
|
+
this.flushTimer = null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Ensures file handle is open and header is written
|
|
44
|
+
*/
|
|
45
|
+
async ensureFile() {
|
|
46
|
+
if (this.writeError)
|
|
47
|
+
return null;
|
|
48
|
+
if (!this.fileHandle) {
|
|
49
|
+
try {
|
|
50
|
+
// Ensure directory exists
|
|
51
|
+
await fs.mkdir(dirname(this.logPath), { recursive: true });
|
|
52
|
+
this.fileHandle = await fs.open(this.logPath, 'w');
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
this.writeError = err instanceof Error ? err : new Error(String(err));
|
|
56
|
+
console.error(`[StreamPersister] Failed to open file: ${this.writeError.message}`);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!this.headerWritten) {
|
|
61
|
+
await this.writeHeader();
|
|
62
|
+
this.headerWritten = true;
|
|
63
|
+
}
|
|
64
|
+
return this.fileHandle;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Writes the log header with in_progress status
|
|
68
|
+
*/
|
|
69
|
+
async writeHeader() {
|
|
70
|
+
const header = [
|
|
71
|
+
`# Iteration Log`,
|
|
72
|
+
`Timestamp: ${new Date(this.startTime).toISOString()}`,
|
|
73
|
+
`Status: ${this.status}`,
|
|
74
|
+
'---',
|
|
75
|
+
'',
|
|
76
|
+
].join('\n');
|
|
77
|
+
await this.writeToFile(header);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Writes content to file atomically (complete string only)
|
|
81
|
+
*/
|
|
82
|
+
async writeToFile(content) {
|
|
83
|
+
if (!this.fileHandle || this.writeError)
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
await this.fileHandle.write(content, null, 'utf8');
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
this.writeError = err instanceof Error ? err : new Error(String(err));
|
|
90
|
+
console.error(`[StreamPersister] Write error: ${this.writeError.message}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async append(content, isEventBoundary = false) {
|
|
94
|
+
this.buffer += content;
|
|
95
|
+
this.startFlushTimer();
|
|
96
|
+
if (isEventBoundary) {
|
|
97
|
+
await this.flush();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async appendStderr(content) {
|
|
101
|
+
// Prefix each line with [stderr]
|
|
102
|
+
const prefixed = content
|
|
103
|
+
.split('\n')
|
|
104
|
+
.map((line) => (line ? `[stderr] ${line}` : line))
|
|
105
|
+
.join('\n');
|
|
106
|
+
this.buffer += prefixed;
|
|
107
|
+
this.startFlushTimer();
|
|
108
|
+
}
|
|
109
|
+
async flush() {
|
|
110
|
+
if (!this.buffer || this.flushing)
|
|
111
|
+
return;
|
|
112
|
+
this.flushing = true;
|
|
113
|
+
try {
|
|
114
|
+
const handle = await this.ensureFile();
|
|
115
|
+
if (!handle)
|
|
116
|
+
return;
|
|
117
|
+
const content = this.buffer;
|
|
118
|
+
this.buffer = '';
|
|
119
|
+
await this.writeToFile(content);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
this.flushing = false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async complete(exitCode, duration) {
|
|
126
|
+
if (this.finalized)
|
|
127
|
+
return;
|
|
128
|
+
this.finalized = true;
|
|
129
|
+
this.stopFlushTimer();
|
|
130
|
+
this.status = 'completed';
|
|
131
|
+
await this.flush();
|
|
132
|
+
await this.writeMetadata({ exitCode, duration });
|
|
133
|
+
await this.close();
|
|
134
|
+
}
|
|
135
|
+
async abort(signal) {
|
|
136
|
+
if (this.finalized)
|
|
137
|
+
return;
|
|
138
|
+
this.finalized = true;
|
|
139
|
+
this.stopFlushTimer();
|
|
140
|
+
this.status = 'aborted';
|
|
141
|
+
await this.flush();
|
|
142
|
+
await this.writeMetadata({ signal });
|
|
143
|
+
await this.close();
|
|
144
|
+
}
|
|
145
|
+
async crash(error) {
|
|
146
|
+
if (this.finalized)
|
|
147
|
+
return;
|
|
148
|
+
this.finalized = true;
|
|
149
|
+
this.stopFlushTimer();
|
|
150
|
+
this.status = 'crashed';
|
|
151
|
+
await this.flush();
|
|
152
|
+
await this.writeMetadata({ error: error.message });
|
|
153
|
+
await this.close();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Writes final metadata section
|
|
157
|
+
*/
|
|
158
|
+
async writeMetadata(info) {
|
|
159
|
+
const handle = await this.ensureFile();
|
|
160
|
+
if (!handle)
|
|
161
|
+
return;
|
|
162
|
+
const parts = ['\n---', `Status: ${this.status}`];
|
|
163
|
+
if (info.exitCode !== undefined) {
|
|
164
|
+
parts.push(`Exit Code: ${info.exitCode}`);
|
|
165
|
+
}
|
|
166
|
+
if (info.duration !== undefined) {
|
|
167
|
+
parts.push(`Duration: ${info.duration}ms`);
|
|
168
|
+
}
|
|
169
|
+
if (info.signal) {
|
|
170
|
+
parts.push(`Interrupted: ${info.signal}`);
|
|
171
|
+
}
|
|
172
|
+
if (info.error) {
|
|
173
|
+
parts.push(`Error: ${info.error}`);
|
|
174
|
+
}
|
|
175
|
+
await this.writeToFile(parts.join('\n') + '\n');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Closes the file handle
|
|
179
|
+
*/
|
|
180
|
+
async close() {
|
|
181
|
+
if (!this.fileHandle)
|
|
182
|
+
return;
|
|
183
|
+
try {
|
|
184
|
+
await this.fileHandle.close();
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Ignore close errors
|
|
188
|
+
}
|
|
189
|
+
this.fileHandle = null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Cleanup method for cases where persister is abandoned without complete/abort/crash
|
|
193
|
+
*/
|
|
194
|
+
async destroy() {
|
|
195
|
+
this.stopFlushTimer();
|
|
196
|
+
await this.close();
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Returns any write error that occurred
|
|
200
|
+
*/
|
|
201
|
+
getError() {
|
|
202
|
+
return this.writeError;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=persister.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persister.js","sourceRoot":"","sources":["../../src/stream/persister.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status of a stream persistence log
|
|
3
|
+
*/
|
|
4
|
+
export type StreamStatus = 'in_progress' | 'completed' | 'aborted' | 'crashed';
|
|
5
|
+
/**
|
|
6
|
+
* Options for creating a StreamPersister
|
|
7
|
+
*/
|
|
8
|
+
export interface StreamPersisterOptions {
|
|
9
|
+
/** Path to the log file */
|
|
10
|
+
logPath: string;
|
|
11
|
+
/** Interval in ms for auto-flush (default: 100) */
|
|
12
|
+
flushIntervalMs?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Interface for persisting streamed output incrementally
|
|
16
|
+
*/
|
|
17
|
+
export interface StreamPersister {
|
|
18
|
+
/**
|
|
19
|
+
* Append formatted content to buffer
|
|
20
|
+
* Called for each formatted event
|
|
21
|
+
* @param isEventBoundary If true, triggers immediate flush
|
|
22
|
+
*/
|
|
23
|
+
append(content: string, isEventBoundary?: boolean): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Append stderr content with [stderr] prefix
|
|
26
|
+
*/
|
|
27
|
+
appendStderr(content: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Force flush buffer to disk
|
|
30
|
+
*/
|
|
31
|
+
flush(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Called on normal completion
|
|
34
|
+
*/
|
|
35
|
+
complete(exitCode: number, duration: number): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Called on interruption (SIGINT, SIGTERM, SIGHUP)
|
|
38
|
+
*/
|
|
39
|
+
abort(signal: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Called on crash (uncaughtException)
|
|
42
|
+
*/
|
|
43
|
+
crash(error: Error): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Returns any write error that occurred during persistence
|
|
46
|
+
*/
|
|
47
|
+
getError(): Error | null;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjE;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5C;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3D;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElC;;OAEG;IACH,QAAQ,IAAI,KAAK,GAAG,IAAI,CAAA;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":""}
|