@tagma/sdk 0.6.0 → 0.6.1
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/LICENSE +21 -21
- package/README.md +573 -573
- package/dist/drivers/opencode.d.ts.map +1 -1
- package/dist/drivers/opencode.js +47 -17
- package/dist/drivers/opencode.js.map +1 -1
- package/package.json +2 -2
- package/src/bootstrap.ts +37 -37
- package/src/completions/output-check.ts +92 -92
- package/src/dag.ts +245 -245
- package/src/drivers/opencode.ts +410 -371
- package/src/engine.ts +1220 -1220
- package/src/hooks.ts +193 -193
- package/src/middlewares/static-context.ts +49 -49
- package/src/pipeline-runner.ts +173 -173
- package/src/prompt-doc.ts +49 -49
- package/src/registry.ts +267 -267
- package/src/runner.ts +460 -460
- package/src/schema.test.ts +101 -101
- package/src/schema.ts +338 -338
- package/src/sdk.ts +118 -118
- package/src/task-ref.test.ts +401 -401
- package/src/task-ref.ts +120 -120
- package/src/validate-raw.ts +412 -412
- package/dist/drivers/claude-code.d.ts +0 -3
- package/dist/drivers/claude-code.d.ts.map +0 -1
- package/dist/drivers/claude-code.js +0 -225
- package/dist/drivers/claude-code.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/drivers/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAOb,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/drivers/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EAOb,MAAM,UAAU,CAAC;AA+NlB,eAAO,MAAM,cAAc,EAAE,YAkL5B,CAAC"}
|
package/dist/drivers/opencode.js
CHANGED
|
@@ -18,7 +18,12 @@ const EFFORT_TO_VARIANT = {
|
|
|
18
18
|
medium: null,
|
|
19
19
|
high: 'high',
|
|
20
20
|
};
|
|
21
|
+
// Memoize BOTH success and failure. On failure we stash the message so every
|
|
22
|
+
// subsequent ensureOpencodeInstalled() throws the identical error — re-running
|
|
23
|
+
// the bun-install probe for each task of a failed run would just be slow and
|
|
24
|
+
// produce confusing interleaved stderr.
|
|
21
25
|
let opencodeReady;
|
|
26
|
+
let opencodeReadyError;
|
|
22
27
|
let cachedDefaultModel;
|
|
23
28
|
async function runCapture(args) {
|
|
24
29
|
try {
|
|
@@ -34,14 +39,35 @@ async function runCapture(args) {
|
|
|
34
39
|
return { code: -1, stdout: '', stderr: '' };
|
|
35
40
|
}
|
|
36
41
|
}
|
|
42
|
+
// Shared tail for every failure message — the Tagma desktop app exposes a
|
|
43
|
+
// one-click installer at the same npm source path this driver would reach
|
|
44
|
+
// for, so point users there first. Users running the SDK as a library still
|
|
45
|
+
// see the manual bun/npm hint.
|
|
46
|
+
const SETUP_HINT = 'If you are using the Tagma desktop app, open Editor Settings → OpenCode CLI to install or update the bundled binary. ' +
|
|
47
|
+
'Otherwise install it manually: `bun install -g opencode-ai` or `npm install -g opencode-ai`.';
|
|
37
48
|
async function ensureOpencodeInstalled() {
|
|
38
|
-
if (opencodeReady
|
|
39
|
-
return
|
|
40
|
-
|
|
49
|
+
if (opencodeReady === true)
|
|
50
|
+
return;
|
|
51
|
+
if (opencodeReady === false && opencodeReadyError) {
|
|
52
|
+
throw new Error(opencodeReadyError);
|
|
53
|
+
}
|
|
54
|
+
// Probe existing install first — this is the hot path for desktop users
|
|
55
|
+
// (bundled binary in PATH) and for anyone who already has opencode.
|
|
41
56
|
const probe = await runCapture(['opencode', '--version']);
|
|
42
57
|
if (probe.code === 0) {
|
|
43
58
|
opencodeReady = true;
|
|
44
|
-
return
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Distinguish "bun is missing" from "bun is here but install failed" so
|
|
62
|
+
// the error we surface points at the right next step. If bun is absent we
|
|
63
|
+
// skip the install attempt entirely — spawning with `bun` as argv[0]
|
|
64
|
+
// would just ENOENT inside runCapture's catch and look identical to a
|
|
65
|
+
// failed install.
|
|
66
|
+
const bunProbe = await runCapture(['bun', '--version']);
|
|
67
|
+
if (bunProbe.code !== 0) {
|
|
68
|
+
opencodeReady = false;
|
|
69
|
+
opencodeReadyError = `OpenCode CLI is not available and \`bun\` is not installed. ${SETUP_HINT}`;
|
|
70
|
+
throw new Error(opencodeReadyError);
|
|
45
71
|
}
|
|
46
72
|
console.error('[driver:opencode] opencode CLI not found — installing via `bun install -g opencode-ai`... (this may take up to a minute)');
|
|
47
73
|
// Use inherit here so the user sees bun's own progress during the one-time
|
|
@@ -52,9 +78,9 @@ async function ensureOpencodeInstalled() {
|
|
|
52
78
|
});
|
|
53
79
|
const installCode = await install.exited;
|
|
54
80
|
if (installCode !== 0) {
|
|
55
|
-
console.error('[driver:opencode] install failed — opencode run will likely fail below.');
|
|
56
81
|
opencodeReady = false;
|
|
57
|
-
|
|
82
|
+
opencodeReadyError = `\`bun install -g opencode-ai\` failed (exit code ${installCode}). ${SETUP_HINT}`;
|
|
83
|
+
throw new Error(opencodeReadyError);
|
|
58
84
|
}
|
|
59
85
|
// Bun installs globals under `~/.bun/bin` (or `%USERPROFILE%\.bun\bin`),
|
|
60
86
|
// which isn't on this process's cached PATH unless the user already has
|
|
@@ -70,11 +96,14 @@ async function ensureOpencodeInstalled() {
|
|
|
70
96
|
}
|
|
71
97
|
}
|
|
72
98
|
const verify = await runCapture(['opencode', '--version']);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
99
|
+
if (verify.code !== 0) {
|
|
100
|
+
opencodeReady = false;
|
|
101
|
+
opencodeReadyError =
|
|
102
|
+
'`opencode` is not resolvable after `bun install -g opencode-ai` completed. ' +
|
|
103
|
+
"Bun's global bin directory is probably not on PATH — add it manually or restart the app.";
|
|
104
|
+
throw new Error(opencodeReadyError);
|
|
76
105
|
}
|
|
77
|
-
|
|
106
|
+
opencodeReady = true;
|
|
78
107
|
}
|
|
79
108
|
// `opencode models --verbose` emits "<provider>/<id>\n{...json...}\n" pairs.
|
|
80
109
|
// Walk balanced braces rather than split on newlines so we survive any
|
|
@@ -134,11 +163,11 @@ function pickFreeModel(models) {
|
|
|
134
163
|
async function resolveDefaultModel() {
|
|
135
164
|
if (cachedDefaultModel !== undefined)
|
|
136
165
|
return cachedDefaultModel;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
166
|
+
// ensureOpencodeInstalled now throws with an actionable message when the
|
|
167
|
+
// CLI can't be provisioned, so we let the error bubble up to the task
|
|
168
|
+
// runner instead of silently falling back to DEFAULT_MODEL (which would
|
|
169
|
+
// produce a second confusing ENOENT a few lines later in `opencode run`).
|
|
170
|
+
await ensureOpencodeInstalled();
|
|
142
171
|
console.error('[driver:opencode] resolving free opencode model...');
|
|
143
172
|
const { code, stdout } = await runCapture(['opencode', 'models', '--verbose']);
|
|
144
173
|
if (code !== 0) {
|
|
@@ -163,8 +192,9 @@ export const OpenCodeDriver = {
|
|
|
163
192
|
async buildCommand(task, track, ctx) {
|
|
164
193
|
const explicitModel = task.model ?? track.model;
|
|
165
194
|
// Always make sure the opencode CLI is usable before we spawn it — even
|
|
166
|
-
// when the user pinned a model.
|
|
167
|
-
//
|
|
195
|
+
// when the user pinned a model. ensureOpencodeInstalled throws with an
|
|
196
|
+
// actionable message when the binary is neither present on PATH (desktop
|
|
197
|
+
// bundles it there via runtime-paths.ts) nor installable via bun.
|
|
168
198
|
if (explicitModel)
|
|
169
199
|
await ensureOpencodeInstalled();
|
|
170
200
|
// Otherwise resolveDefaultModel both ensures the CLI and picks a free
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/drivers/opencode.ts"],"names":[],"mappings":"AAUA,MAAM,aAAa,GAAG,qBAAqB,CAAC;AAE5C,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,yEAAyE;AACzE,yDAAyD;AAEzD,8EAA8E;AAC9E,2EAA2E;AAC3E,wDAAwD;AACxD,uCAAuC;AACvC,yCAAyC;AACzC,sCAAsC;AACtC,uEAAuE;AACvE,4CAA4C;AAC5C,MAAM,iBAAiB,GAAkC;IACvD,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,MAAM;CACb,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/drivers/opencode.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tagma/sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Local AI task orchestration engine — core SDK for tagma pipelines",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"release:publish": "bun scripts/release.ts --publish"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@tagma/types": "0.4.
|
|
45
|
+
"@tagma/types": "0.4.1",
|
|
46
46
|
"js-yaml": "^4.1.0",
|
|
47
47
|
"chokidar": "^4.0.0"
|
|
48
48
|
},
|
package/src/bootstrap.ts
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { registerPlugin } from './registry';
|
|
2
|
-
|
|
3
|
-
// Built-in Drivers
|
|
4
|
-
// Only opencode is built in. Other drivers (codex, claude-code) ship as
|
|
5
|
-
// workspace plugins under packages/ and must be declared in pipeline.yaml
|
|
6
|
-
// via the `plugins` field, e.g.:
|
|
7
|
-
// plugins: ["@tagma/driver-codex", "@tagma/driver-claude-code"]
|
|
8
|
-
import { OpenCodeDriver } from './drivers/opencode';
|
|
9
|
-
|
|
10
|
-
// Built-in Triggers
|
|
11
|
-
import { FileTrigger } from './triggers/file';
|
|
12
|
-
import { ManualTrigger } from './triggers/manual';
|
|
13
|
-
|
|
14
|
-
// Built-in Completions
|
|
15
|
-
import { ExitCodeCompletion } from './completions/exit-code';
|
|
16
|
-
import { FileExistsCompletion } from './completions/file-exists';
|
|
17
|
-
import { OutputCheckCompletion } from './completions/output-check';
|
|
18
|
-
|
|
19
|
-
// Built-in Middleware
|
|
20
|
-
import { StaticContextMiddleware } from './middlewares/static-context';
|
|
21
|
-
|
|
22
|
-
export function bootstrapBuiltins(): void {
|
|
23
|
-
// Drivers
|
|
24
|
-
registerPlugin('drivers', 'opencode', OpenCodeDriver);
|
|
25
|
-
|
|
26
|
-
// Triggers
|
|
27
|
-
registerPlugin('triggers', 'file', FileTrigger);
|
|
28
|
-
registerPlugin('triggers', 'manual', ManualTrigger);
|
|
29
|
-
|
|
30
|
-
// Completions
|
|
31
|
-
registerPlugin('completions', 'exit_code', ExitCodeCompletion);
|
|
32
|
-
registerPlugin('completions', 'file_exists', FileExistsCompletion);
|
|
33
|
-
registerPlugin('completions', 'output_check', OutputCheckCompletion);
|
|
34
|
-
|
|
35
|
-
// Middlewares
|
|
36
|
-
registerPlugin('middlewares', 'static_context', StaticContextMiddleware);
|
|
37
|
-
}
|
|
1
|
+
import { registerPlugin } from './registry';
|
|
2
|
+
|
|
3
|
+
// Built-in Drivers
|
|
4
|
+
// Only opencode is built in. Other drivers (codex, claude-code) ship as
|
|
5
|
+
// workspace plugins under packages/ and must be declared in pipeline.yaml
|
|
6
|
+
// via the `plugins` field, e.g.:
|
|
7
|
+
// plugins: ["@tagma/driver-codex", "@tagma/driver-claude-code"]
|
|
8
|
+
import { OpenCodeDriver } from './drivers/opencode';
|
|
9
|
+
|
|
10
|
+
// Built-in Triggers
|
|
11
|
+
import { FileTrigger } from './triggers/file';
|
|
12
|
+
import { ManualTrigger } from './triggers/manual';
|
|
13
|
+
|
|
14
|
+
// Built-in Completions
|
|
15
|
+
import { ExitCodeCompletion } from './completions/exit-code';
|
|
16
|
+
import { FileExistsCompletion } from './completions/file-exists';
|
|
17
|
+
import { OutputCheckCompletion } from './completions/output-check';
|
|
18
|
+
|
|
19
|
+
// Built-in Middleware
|
|
20
|
+
import { StaticContextMiddleware } from './middlewares/static-context';
|
|
21
|
+
|
|
22
|
+
export function bootstrapBuiltins(): void {
|
|
23
|
+
// Drivers
|
|
24
|
+
registerPlugin('drivers', 'opencode', OpenCodeDriver);
|
|
25
|
+
|
|
26
|
+
// Triggers
|
|
27
|
+
registerPlugin('triggers', 'file', FileTrigger);
|
|
28
|
+
registerPlugin('triggers', 'manual', ManualTrigger);
|
|
29
|
+
|
|
30
|
+
// Completions
|
|
31
|
+
registerPlugin('completions', 'exit_code', ExitCodeCompletion);
|
|
32
|
+
registerPlugin('completions', 'file_exists', FileExistsCompletion);
|
|
33
|
+
registerPlugin('completions', 'output_check', OutputCheckCompletion);
|
|
34
|
+
|
|
35
|
+
// Middlewares
|
|
36
|
+
registerPlugin('middlewares', 'static_context', StaticContextMiddleware);
|
|
37
|
+
}
|
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import type { CompletionPlugin, CompletionContext, TaskResult } from '../types';
|
|
2
|
-
import { shellArgs, parseDuration } from '../utils';
|
|
3
|
-
|
|
4
|
-
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
5
|
-
|
|
6
|
-
export const OutputCheckCompletion: CompletionPlugin = {
|
|
7
|
-
name: 'output_check',
|
|
8
|
-
schema: {
|
|
9
|
-
description:
|
|
10
|
-
'Pipe the task output into a shell command; mark success when that command exits 0. For AI driver tasks the driver-normalized text is piped (not the raw NDJSON); command tasks see their raw stdout.',
|
|
11
|
-
fields: {
|
|
12
|
-
check: {
|
|
13
|
-
type: 'string',
|
|
14
|
-
required: true,
|
|
15
|
-
description:
|
|
16
|
-
'Shell command to run. The task output is piped to its stdin — normalizedOutput when the driver provides one, otherwise raw stdout.',
|
|
17
|
-
placeholder: "grep -q 'PASS'",
|
|
18
|
-
},
|
|
19
|
-
timeout: {
|
|
20
|
-
type: 'duration',
|
|
21
|
-
default: '30s',
|
|
22
|
-
description: 'Maximum time to wait for the check command.',
|
|
23
|
-
placeholder: '30s',
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
async check(
|
|
29
|
-
config: Record<string, unknown>,
|
|
30
|
-
result: TaskResult,
|
|
31
|
-
ctx: CompletionContext,
|
|
32
|
-
): Promise<boolean> {
|
|
33
|
-
const checkCmd = config.check as string;
|
|
34
|
-
if (!checkCmd) throw new Error('output_check completion: "check" is required');
|
|
35
|
-
|
|
36
|
-
const timeoutMs =
|
|
37
|
-
config.timeout != null ? parseDuration(String(config.timeout)) : DEFAULT_TIMEOUT_MS;
|
|
38
|
-
|
|
39
|
-
const controller = new AbortController();
|
|
40
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
41
|
-
|
|
42
|
-
// Wire pipeline abort signal into the check process so external abort
|
|
43
|
-
// terminates the child instead of leaving it running undetected.
|
|
44
|
-
const onAbort = () => controller.abort();
|
|
45
|
-
if (ctx.signal) {
|
|
46
|
-
if (ctx.signal.aborted) {
|
|
47
|
-
controller.abort();
|
|
48
|
-
} else {
|
|
49
|
-
ctx.signal.addEventListener('abort', onAbort, { once: true });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const proc = Bun.spawn(shellArgs(checkCmd) as string[], {
|
|
54
|
-
cwd: ctx.workDir,
|
|
55
|
-
stdin: 'pipe',
|
|
56
|
-
stdout: 'pipe',
|
|
57
|
-
stderr: 'pipe',
|
|
58
|
-
signal: controller.signal,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
if (proc.stdin) {
|
|
63
|
-
try {
|
|
64
|
-
// Prefer driver-normalized text (e.g. concatenated message text for
|
|
65
|
-
// AI drivers that emit NDJSON). Falling back to raw stdout keeps
|
|
66
|
-
// command tasks and drivers without parseResult working.
|
|
67
|
-
const payload = result.normalizedOutput ?? result.stdout;
|
|
68
|
-
proc.stdin.write(payload);
|
|
69
|
-
proc.stdin.end(); // no await — consistent with runner.ts; proc.exited handles sync
|
|
70
|
-
} catch (err: unknown) {
|
|
71
|
-
// EPIPE is expected when the check process exits before reading all of stdin
|
|
72
|
-
// (e.g. `grep -q` exits on first match). Anything else is a real failure.
|
|
73
|
-
const code = (err as NodeJS.ErrnoException)?.code;
|
|
74
|
-
if (code !== 'EPIPE') throw err;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Consume stderr concurrently with waiting for exit to prevent pipe-buffer
|
|
79
|
-
// deadlock when check script emits more than ~64 KB of stderr output.
|
|
80
|
-
const [exitCode, stderr] = await Promise.all([proc.exited, new Response(proc.stderr).text()]);
|
|
81
|
-
|
|
82
|
-
if (exitCode !== 0 && stderr.trim()) {
|
|
83
|
-
console.warn(`[output_check] "${checkCmd}" exit=${exitCode}: ${stderr.trim()}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return exitCode === 0;
|
|
87
|
-
} finally {
|
|
88
|
-
clearTimeout(timer);
|
|
89
|
-
if (ctx.signal) ctx.signal.removeEventListener('abort', onAbort);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
};
|
|
1
|
+
import type { CompletionPlugin, CompletionContext, TaskResult } from '../types';
|
|
2
|
+
import { shellArgs, parseDuration } from '../utils';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
5
|
+
|
|
6
|
+
export const OutputCheckCompletion: CompletionPlugin = {
|
|
7
|
+
name: 'output_check',
|
|
8
|
+
schema: {
|
|
9
|
+
description:
|
|
10
|
+
'Pipe the task output into a shell command; mark success when that command exits 0. For AI driver tasks the driver-normalized text is piped (not the raw NDJSON); command tasks see their raw stdout.',
|
|
11
|
+
fields: {
|
|
12
|
+
check: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
required: true,
|
|
15
|
+
description:
|
|
16
|
+
'Shell command to run. The task output is piped to its stdin — normalizedOutput when the driver provides one, otherwise raw stdout.',
|
|
17
|
+
placeholder: "grep -q 'PASS'",
|
|
18
|
+
},
|
|
19
|
+
timeout: {
|
|
20
|
+
type: 'duration',
|
|
21
|
+
default: '30s',
|
|
22
|
+
description: 'Maximum time to wait for the check command.',
|
|
23
|
+
placeholder: '30s',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
async check(
|
|
29
|
+
config: Record<string, unknown>,
|
|
30
|
+
result: TaskResult,
|
|
31
|
+
ctx: CompletionContext,
|
|
32
|
+
): Promise<boolean> {
|
|
33
|
+
const checkCmd = config.check as string;
|
|
34
|
+
if (!checkCmd) throw new Error('output_check completion: "check" is required');
|
|
35
|
+
|
|
36
|
+
const timeoutMs =
|
|
37
|
+
config.timeout != null ? parseDuration(String(config.timeout)) : DEFAULT_TIMEOUT_MS;
|
|
38
|
+
|
|
39
|
+
const controller = new AbortController();
|
|
40
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
41
|
+
|
|
42
|
+
// Wire pipeline abort signal into the check process so external abort
|
|
43
|
+
// terminates the child instead of leaving it running undetected.
|
|
44
|
+
const onAbort = () => controller.abort();
|
|
45
|
+
if (ctx.signal) {
|
|
46
|
+
if (ctx.signal.aborted) {
|
|
47
|
+
controller.abort();
|
|
48
|
+
} else {
|
|
49
|
+
ctx.signal.addEventListener('abort', onAbort, { once: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const proc = Bun.spawn(shellArgs(checkCmd) as string[], {
|
|
54
|
+
cwd: ctx.workDir,
|
|
55
|
+
stdin: 'pipe',
|
|
56
|
+
stdout: 'pipe',
|
|
57
|
+
stderr: 'pipe',
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
if (proc.stdin) {
|
|
63
|
+
try {
|
|
64
|
+
// Prefer driver-normalized text (e.g. concatenated message text for
|
|
65
|
+
// AI drivers that emit NDJSON). Falling back to raw stdout keeps
|
|
66
|
+
// command tasks and drivers without parseResult working.
|
|
67
|
+
const payload = result.normalizedOutput ?? result.stdout;
|
|
68
|
+
proc.stdin.write(payload);
|
|
69
|
+
proc.stdin.end(); // no await — consistent with runner.ts; proc.exited handles sync
|
|
70
|
+
} catch (err: unknown) {
|
|
71
|
+
// EPIPE is expected when the check process exits before reading all of stdin
|
|
72
|
+
// (e.g. `grep -q` exits on first match). Anything else is a real failure.
|
|
73
|
+
const code = (err as NodeJS.ErrnoException)?.code;
|
|
74
|
+
if (code !== 'EPIPE') throw err;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Consume stderr concurrently with waiting for exit to prevent pipe-buffer
|
|
79
|
+
// deadlock when check script emits more than ~64 KB of stderr output.
|
|
80
|
+
const [exitCode, stderr] = await Promise.all([proc.exited, new Response(proc.stderr).text()]);
|
|
81
|
+
|
|
82
|
+
if (exitCode !== 0 && stderr.trim()) {
|
|
83
|
+
console.warn(`[output_check] "${checkCmd}" exit=${exitCode}: ${stderr.trim()}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return exitCode === 0;
|
|
87
|
+
} finally {
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
if (ctx.signal) ctx.signal.removeEventListener('abort', onAbort);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|