@oisincoveney/pipeline 1.2.0 → 1.2.2
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/index.d.ts +1 -0
- package/dist/index.js +119 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ interface PipeOptions {
|
|
|
12
12
|
export declare function pipe(description: string, options?: PipeOptions): Promise<void>;
|
|
13
13
|
export declare function createCliProgram(): Command;
|
|
14
14
|
export declare function runCli(argv: string[]): Promise<void>;
|
|
15
|
+
export declare function isCliEntrypoint(argv: string[]): boolean;
|
|
15
16
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -13010,6 +13010,8 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
13010
13010
|
});
|
|
13011
13011
|
|
|
13012
13012
|
// src/index.ts
|
|
13013
|
+
import { existsSync as existsSync7, realpathSync } from "node:fs";
|
|
13014
|
+
import { resolve } from "node:path";
|
|
13013
13015
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
13014
13016
|
|
|
13015
13017
|
// node_modules/commander/esm.mjs
|
|
@@ -36880,6 +36882,7 @@ async function runJscpd(worktreePath) {
|
|
|
36880
36882
|
}
|
|
36881
36883
|
|
|
36882
36884
|
// src/pipeline-runtime.ts
|
|
36885
|
+
var LINE_RE = /\r?\n/;
|
|
36883
36886
|
async function runPipelineFromConfig(options2) {
|
|
36884
36887
|
const worktreePath = options2.worktreePath ?? process.cwd();
|
|
36885
36888
|
const config2 = options2.config ?? loadPipelineConfig(worktreePath);
|
|
@@ -37035,16 +37038,74 @@ async function executeAgentNode(node, context) {
|
|
|
37035
37038
|
});
|
|
37036
37039
|
context.agentInvocations.push(plan);
|
|
37037
37040
|
const result = await context.executor(plan);
|
|
37041
|
+
const normalized = normalizeAgentOutput(plan, result.stdout);
|
|
37038
37042
|
return {
|
|
37039
37043
|
evidence: [
|
|
37040
37044
|
`agent boundary node=${node.id} profile=${node.profile} runner=${plan.runnerId} strategy=${plan.strategy}`,
|
|
37045
|
+
...normalized.evidence,
|
|
37041
37046
|
...result.stderr ? [`stderr: ${result.stderr}`] : [],
|
|
37042
37047
|
...result.timedOut ? ["agent timed out"] : []
|
|
37043
37048
|
],
|
|
37044
37049
|
exitCode: result.exitCode,
|
|
37045
|
-
output:
|
|
37050
|
+
output: normalized.output
|
|
37046
37051
|
};
|
|
37047
37052
|
}
|
|
37053
|
+
function normalizeAgentOutput(plan, stdout) {
|
|
37054
|
+
if (plan.type === "codex") {
|
|
37055
|
+
const text = lastJsonLineValue(stdout, (value) => {
|
|
37056
|
+
if (!isRecord(value)) {
|
|
37057
|
+
return;
|
|
37058
|
+
}
|
|
37059
|
+
const item = value.item;
|
|
37060
|
+
if (isRecord(item) && item.type === "agent_message") {
|
|
37061
|
+
return typeof item.text === "string" ? item.text : undefined;
|
|
37062
|
+
}
|
|
37063
|
+
if (value.type === "agent_message") {
|
|
37064
|
+
return typeof value.text === "string" ? value.text : undefined;
|
|
37065
|
+
}
|
|
37066
|
+
});
|
|
37067
|
+
if (text) {
|
|
37068
|
+
return {
|
|
37069
|
+
evidence: ["normalized runner output from codex JSONL"],
|
|
37070
|
+
output: text
|
|
37071
|
+
};
|
|
37072
|
+
}
|
|
37073
|
+
}
|
|
37074
|
+
if (plan.type === "opencode") {
|
|
37075
|
+
const text = lastJsonLineValue(stdout, (value) => {
|
|
37076
|
+
if (!isRecord(value)) {
|
|
37077
|
+
return;
|
|
37078
|
+
}
|
|
37079
|
+
const part = value.part;
|
|
37080
|
+
if (isRecord(part) && part.type === "text") {
|
|
37081
|
+
return typeof part.text === "string" ? part.text : undefined;
|
|
37082
|
+
}
|
|
37083
|
+
});
|
|
37084
|
+
if (text) {
|
|
37085
|
+
return {
|
|
37086
|
+
evidence: ["normalized runner output from opencode JSON events"],
|
|
37087
|
+
output: text
|
|
37088
|
+
};
|
|
37089
|
+
}
|
|
37090
|
+
}
|
|
37091
|
+
return { evidence: [], output: stdout };
|
|
37092
|
+
}
|
|
37093
|
+
function lastJsonLineValue(text, extract) {
|
|
37094
|
+
let latest;
|
|
37095
|
+
for (const line of text.split(LINE_RE)) {
|
|
37096
|
+
const trimmed = line.trim();
|
|
37097
|
+
if (!trimmed) {
|
|
37098
|
+
continue;
|
|
37099
|
+
}
|
|
37100
|
+
try {
|
|
37101
|
+
const extracted = extract(JSON.parse(trimmed));
|
|
37102
|
+
if (extracted) {
|
|
37103
|
+
latest = extracted;
|
|
37104
|
+
}
|
|
37105
|
+
} catch {}
|
|
37106
|
+
}
|
|
37107
|
+
return latest;
|
|
37108
|
+
}
|
|
37048
37109
|
function renderAgentPrompt(node, context) {
|
|
37049
37110
|
const profile = node.profile ? context.config.profiles[node.profile] : undefined;
|
|
37050
37111
|
const instructions = profile ? readInstructions(context.worktreePath, profile.instructions) : "";
|
|
@@ -37438,6 +37499,7 @@ function formatConfigError(err) {
|
|
|
37438
37499
|
|
|
37439
37500
|
// src/index.ts
|
|
37440
37501
|
var PATH_SEPARATOR_RE = /[\\/]/;
|
|
37502
|
+
var LINE_RE2 = /\r?\n/;
|
|
37441
37503
|
function pipe2(description, options2 = {}) {
|
|
37442
37504
|
try {
|
|
37443
37505
|
if (!description.trim()) {
|
|
@@ -37464,11 +37526,7 @@ async function runConfiguredPipeline(inputs) {
|
|
|
37464
37526
|
});
|
|
37465
37527
|
console.log(formatRuntimeResult(result));
|
|
37466
37528
|
if (result.outcome === "FAIL") {
|
|
37467
|
-
throw new Error(
|
|
37468
|
-
"Pipeline failed.",
|
|
37469
|
-
...result.failureDetails.map((failure) => failure.nodeId ? `- ${failure.nodeId}: ${failure.reason}` : `- ${failure.reason}`)
|
|
37470
|
-
].join(`
|
|
37471
|
-
`));
|
|
37529
|
+
throw new Error(formatRuntimeFailure(result));
|
|
37472
37530
|
}
|
|
37473
37531
|
}
|
|
37474
37532
|
function formatRuntimeResult(result) {
|
|
@@ -37480,6 +37538,50 @@ function formatRuntimeResult(result) {
|
|
|
37480
37538
|
].join(`
|
|
37481
37539
|
`);
|
|
37482
37540
|
}
|
|
37541
|
+
function formatRuntimeFailure(result) {
|
|
37542
|
+
const lines = ["Pipeline failed."];
|
|
37543
|
+
for (const failure of result.failureDetails) {
|
|
37544
|
+
lines.push(failure.nodeId ? `- ${failure.nodeId}: ${failure.reason}` : `- ${failure.reason}`);
|
|
37545
|
+
appendIndentedSection(lines, "Evidence", failure.evidence);
|
|
37546
|
+
const node = failure.nodeId ? result.nodes.find((item) => item.nodeId === failure.nodeId) : undefined;
|
|
37547
|
+
if (node) {
|
|
37548
|
+
lines.push(` Node: status=${node.status} attempts=${node.attempts} exit=${node.exitCode}`);
|
|
37549
|
+
appendIndentedSection(lines, "Node evidence", node.evidence);
|
|
37550
|
+
appendIndentedSection(lines, "Node output", [node.output]);
|
|
37551
|
+
}
|
|
37552
|
+
}
|
|
37553
|
+
if (result.gates.length > 0) {
|
|
37554
|
+
lines.push("Gates:");
|
|
37555
|
+
for (const gate of result.gates) {
|
|
37556
|
+
lines.push(` - ${gate.nodeId}/${gate.gateId}: ${gate.passed ? "PASS" : "FAIL"}${gate.reason ? ` (${gate.reason})` : ""}`);
|
|
37557
|
+
appendIndentedSection(lines, "Gate evidence", gate.evidence);
|
|
37558
|
+
}
|
|
37559
|
+
}
|
|
37560
|
+
return lines.join(`
|
|
37561
|
+
`);
|
|
37562
|
+
}
|
|
37563
|
+
function appendIndentedSection(lines, label, values) {
|
|
37564
|
+
const text = values.filter(Boolean).join(`
|
|
37565
|
+
`).trim();
|
|
37566
|
+
if (!text) {
|
|
37567
|
+
return;
|
|
37568
|
+
}
|
|
37569
|
+
lines.push(` ${label}:`);
|
|
37570
|
+
lines.push(indent(truncateMiddle(text, 4000), " "));
|
|
37571
|
+
}
|
|
37572
|
+
function indent(text, prefix) {
|
|
37573
|
+
return text.split(LINE_RE2).map((line) => `${prefix}${line}`).join(`
|
|
37574
|
+
`);
|
|
37575
|
+
}
|
|
37576
|
+
function truncateMiddle(text, maxLength) {
|
|
37577
|
+
if (text.length <= maxLength) {
|
|
37578
|
+
return text;
|
|
37579
|
+
}
|
|
37580
|
+
const keep = Math.floor((maxLength - 32) / 2);
|
|
37581
|
+
return `${text.slice(0, keep)}
|
|
37582
|
+
... truncated ...
|
|
37583
|
+
${text.slice(-keep)}`;
|
|
37584
|
+
}
|
|
37483
37585
|
function createCliProgram() {
|
|
37484
37586
|
const program2 = new Command;
|
|
37485
37587
|
program2.name("@oisincoveney/pipeline").description("Run and install the oisin pipeline").exitOverride();
|
|
@@ -37540,7 +37642,16 @@ function scriptName(argv) {
|
|
|
37540
37642
|
}
|
|
37541
37643
|
function isCliEntrypoint(argv) {
|
|
37542
37644
|
const name = scriptName(argv);
|
|
37543
|
-
|
|
37645
|
+
const entrypoint = normalizeEntrypointPath(argv[1]);
|
|
37646
|
+
const modulePath = normalizeEntrypointPath(fileURLToPath3(import.meta.url));
|
|
37647
|
+
return entrypoint === modulePath || name === "pipe" || name === "oisin-pipeline";
|
|
37648
|
+
}
|
|
37649
|
+
function normalizeEntrypointPath(path7) {
|
|
37650
|
+
if (!path7) {
|
|
37651
|
+
return;
|
|
37652
|
+
}
|
|
37653
|
+
const resolved = resolve(path7);
|
|
37654
|
+
return existsSync7(resolved) ? realpathSync(resolved) : resolved;
|
|
37544
37655
|
}
|
|
37545
37656
|
if (isCliEntrypoint(process.argv)) {
|
|
37546
37657
|
runCli(process.argv).catch((err) => {
|
|
@@ -37613,5 +37724,6 @@ function formatList(label, items) {
|
|
|
37613
37724
|
export {
|
|
37614
37725
|
runCli,
|
|
37615
37726
|
pipe2 as pipe,
|
|
37727
|
+
isCliEntrypoint,
|
|
37616
37728
|
createCliProgram
|
|
37617
37729
|
};
|