@oisincoveney/pipeline 1.2.1 → 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.
Files changed (2) hide show
  1. package/dist/index.js +106 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -36882,6 +36882,7 @@ async function runJscpd(worktreePath) {
36882
36882
  }
36883
36883
 
36884
36884
  // src/pipeline-runtime.ts
36885
+ var LINE_RE = /\r?\n/;
36885
36886
  async function runPipelineFromConfig(options2) {
36886
36887
  const worktreePath = options2.worktreePath ?? process.cwd();
36887
36888
  const config2 = options2.config ?? loadPipelineConfig(worktreePath);
@@ -37037,16 +37038,74 @@ async function executeAgentNode(node, context) {
37037
37038
  });
37038
37039
  context.agentInvocations.push(plan);
37039
37040
  const result = await context.executor(plan);
37041
+ const normalized = normalizeAgentOutput(plan, result.stdout);
37040
37042
  return {
37041
37043
  evidence: [
37042
37044
  `agent boundary node=${node.id} profile=${node.profile} runner=${plan.runnerId} strategy=${plan.strategy}`,
37045
+ ...normalized.evidence,
37043
37046
  ...result.stderr ? [`stderr: ${result.stderr}`] : [],
37044
37047
  ...result.timedOut ? ["agent timed out"] : []
37045
37048
  ],
37046
37049
  exitCode: result.exitCode,
37047
- output: result.stdout
37050
+ output: normalized.output
37048
37051
  };
37049
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
+ }
37050
37109
  function renderAgentPrompt(node, context) {
37051
37110
  const profile = node.profile ? context.config.profiles[node.profile] : undefined;
37052
37111
  const instructions = profile ? readInstructions(context.worktreePath, profile.instructions) : "";
@@ -37440,6 +37499,7 @@ function formatConfigError(err) {
37440
37499
 
37441
37500
  // src/index.ts
37442
37501
  var PATH_SEPARATOR_RE = /[\\/]/;
37502
+ var LINE_RE2 = /\r?\n/;
37443
37503
  function pipe2(description, options2 = {}) {
37444
37504
  try {
37445
37505
  if (!description.trim()) {
@@ -37466,11 +37526,7 @@ async function runConfiguredPipeline(inputs) {
37466
37526
  });
37467
37527
  console.log(formatRuntimeResult(result));
37468
37528
  if (result.outcome === "FAIL") {
37469
- throw new Error([
37470
- "Pipeline failed.",
37471
- ...result.failureDetails.map((failure) => failure.nodeId ? `- ${failure.nodeId}: ${failure.reason}` : `- ${failure.reason}`)
37472
- ].join(`
37473
- `));
37529
+ throw new Error(formatRuntimeFailure(result));
37474
37530
  }
37475
37531
  }
37476
37532
  function formatRuntimeResult(result) {
@@ -37482,6 +37538,50 @@ function formatRuntimeResult(result) {
37482
37538
  ].join(`
37483
37539
  `);
37484
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
+ }
37485
37585
  function createCliProgram() {
37486
37586
  const program2 = new Command;
37487
37587
  program2.name("@oisincoveney/pipeline").description("Run and install the oisin pipeline").exitOverride();
package/package.json CHANGED
@@ -69,7 +69,7 @@
69
69
  "prepack": "bun run build:cli"
70
70
  },
71
71
  "type": "module",
72
- "version": "1.2.1",
72
+ "version": "1.2.2",
73
73
  "description": "",
74
74
  "main": "index.js",
75
75
  "keywords": [],