@nk070281sjv/cli 2.3.5 → 2.3.6

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 +150 -14
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -30779,7 +30779,7 @@ ${hint}
30779
30779
  }
30780
30780
 
30781
30781
  // src/lib/version.ts
30782
- var CLI_VERSION = true ? "2.3.5" : createRequire(import.meta.url)("../../package.json").version;
30782
+ var CLI_VERSION = true ? "2.3.6" : createRequire(import.meta.url)("../../package.json").version;
30783
30783
 
30784
30784
  // src/lib/deps.ts
30785
30785
  init_src();
@@ -37516,6 +37516,9 @@ function buildOpenCodeRunArgs(input) {
37516
37516
  if (input.attachUrl) {
37517
37517
  base.push("--attach", input.attachUrl, "--dir", input.cwd);
37518
37518
  }
37519
+ if (input.pure) {
37520
+ base.push("--pure");
37521
+ }
37519
37522
  const limit = input.promptArgvLimit ?? DEFAULT_PROMPT_ARGV_LIMIT;
37520
37523
  if (input.prompt.length <= limit) {
37521
37524
  return [...base, input.prompt];
@@ -37534,15 +37537,25 @@ function parseOpenCodeJsonEvents(stdout) {
37534
37537
  }
37535
37538
  return events;
37536
37539
  }
37540
+ function extractOpenCodeText(events) {
37541
+ return events.map((event) => {
37542
+ if (!isRecord(event)) return "";
37543
+ const part = event.part;
37544
+ if (!isRecord(part) || part.type !== "text") return "";
37545
+ return typeof part.text === "string" ? part.text : "";
37546
+ }).join("").trimStart();
37547
+ }
37537
37548
  var OpenCodeProcessRunner = class {
37538
37549
  spawn;
37539
37550
  promptArgvLimit;
37540
37551
  serveReadyTimeoutMs;
37552
+ pure;
37541
37553
  server;
37542
37554
  constructor(options = {}) {
37543
37555
  this.spawn = options.spawn ?? spawnBinary;
37544
37556
  this.promptArgvLimit = options.promptArgvLimit ?? DEFAULT_PROMPT_ARGV_LIMIT;
37545
37557
  this.serveReadyTimeoutMs = options.serveReadyTimeoutMs ?? 15e3;
37558
+ this.pure = options.pure ?? true;
37546
37559
  }
37547
37560
  async run(request, signal) {
37548
37561
  const prompt = await readFile2(request.promptPath, "utf-8");
@@ -37555,7 +37568,8 @@ var OpenCodeProcessRunner = class {
37555
37568
  exitCode: -1,
37556
37569
  stdout: "",
37557
37570
  stderr: error instanceof Error ? error.message : "Failed to start OpenCode server.",
37558
- ndjsonEvents: []
37571
+ ndjsonEvents: [],
37572
+ outputText: ""
37559
37573
  };
37560
37574
  }
37561
37575
  const args = buildOpenCodeRunArgs({
@@ -37565,6 +37579,7 @@ var OpenCodeProcessRunner = class {
37565
37579
  promptPath: request.promptPath,
37566
37580
  cwd: request.cwd,
37567
37581
  attachUrl,
37582
+ pure: this.pure,
37568
37583
  promptArgvLimit: this.promptArgvLimit
37569
37584
  });
37570
37585
  return new Promise((resolve4) => {
@@ -37574,7 +37589,8 @@ var OpenCodeProcessRunner = class {
37574
37589
  exitCode: -1,
37575
37590
  stdout: "",
37576
37591
  stderr: "OpenCode process aborted before spawn.",
37577
- ndjsonEvents: []
37592
+ ndjsonEvents: [],
37593
+ outputText: ""
37578
37594
  });
37579
37595
  return;
37580
37596
  }
@@ -37604,21 +37620,25 @@ var OpenCodeProcessRunner = class {
37604
37620
  stderr += chunk;
37605
37621
  });
37606
37622
  child.on("error", (err) => {
37623
+ const ndjsonEvents = parseOpenCodeJsonEvents(stdout);
37607
37624
  settle({
37608
37625
  id: request.id,
37609
37626
  exitCode: -1,
37610
37627
  stdout,
37611
37628
  stderr: stderr || err.message,
37612
- ndjsonEvents: parseOpenCodeJsonEvents(stdout)
37629
+ ndjsonEvents,
37630
+ outputText: extractOpenCodeText(ndjsonEvents)
37613
37631
  });
37614
37632
  });
37615
37633
  child.on("close", (code) => {
37634
+ const ndjsonEvents = parseOpenCodeJsonEvents(stdout);
37616
37635
  settle({
37617
37636
  id: request.id,
37618
37637
  exitCode: code ?? -1,
37619
37638
  stdout,
37620
37639
  stderr,
37621
- ndjsonEvents: parseOpenCodeJsonEvents(stdout)
37640
+ ndjsonEvents,
37641
+ outputText: extractOpenCodeText(ndjsonEvents)
37622
37642
  });
37623
37643
  });
37624
37644
  });
@@ -37656,7 +37676,14 @@ var OpenCodeProcessRunner = class {
37656
37676
  }
37657
37677
  const child = this.spawn(
37658
37678
  "opencode",
37659
- ["serve", "--hostname", "127.0.0.1", "--port", "0"],
37679
+ [
37680
+ "serve",
37681
+ "--hostname",
37682
+ "127.0.0.1",
37683
+ "--port",
37684
+ "0",
37685
+ ...this.pure ? ["--pure"] : []
37686
+ ],
37660
37687
  {
37661
37688
  cwd,
37662
37689
  stdio: ["ignore", "pipe", "pipe"]
@@ -37731,6 +37758,9 @@ ${server.stderr}`);
37731
37758
  function parseServeUrl(output) {
37732
37759
  return output.match(/opencode server listening on (https?:\/\/\S+)/)?.[1];
37733
37760
  }
37761
+ function isRecord(value) {
37762
+ return typeof value === "object" && value !== null;
37763
+ }
37734
37764
 
37735
37765
  // src/lib/agent-orchestrator/prompt-writer.ts
37736
37766
  import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
@@ -37889,6 +37919,7 @@ function schemaHint(stage) {
37889
37919
  // src/lib/agent-orchestrator/review-orchestrator.ts
37890
37920
  async function runReviewerPhase(input) {
37891
37921
  const journal = input.journal ?? new NoopAgentLifecycleJournal();
37922
+ const emit = input.emit ?? (() => void 0);
37892
37923
  const controller = new AbortController();
37893
37924
  const reviewerRequests = input.resolvedTeam.reviewers.map((reviewer) => {
37894
37925
  if (!reviewer.model.trim()) {
@@ -37917,7 +37948,26 @@ async function runReviewerPhase(input) {
37917
37948
  phase: "reviews"
37918
37949
  });
37919
37950
  await journal.beat(agentSessionId);
37951
+ const startLogPaths = await writeProcessStartLog(input.context.roundDir, request);
37952
+ emit({
37953
+ event: "agent:start",
37954
+ phase: "reviews",
37955
+ id: request.id,
37956
+ model: request.model,
37957
+ prompt_path: request.promptPath,
37958
+ meta_log: startLogPaths.meta
37959
+ });
37920
37960
  const result = await input.runner.run(request, controller.signal);
37961
+ const logPaths = await writeProcessLogs(input.context.roundDir, request, result);
37962
+ emit({
37963
+ event: "agent:complete",
37964
+ phase: "reviews",
37965
+ id: request.id,
37966
+ exit_code: result.exitCode,
37967
+ stdout_log: logPaths.stdout,
37968
+ stderr_log: logPaths.stderr,
37969
+ meta_log: logPaths.meta
37970
+ });
37921
37971
  const vendorId = extractVendorSessionId(result.ndjsonEvents);
37922
37972
  if (vendorId) await journal.bindVendorId(agentSessionId, vendorId);
37923
37973
  await journal.endInstance(agentSessionId, {
@@ -37988,7 +38038,7 @@ async function runReviewerPhase(input) {
37988
38038
  for (const result of sortResults(results, requests)) {
37989
38039
  const reviewer = byId.get(result.id);
37990
38040
  if (!reviewer) continue;
37991
- await writeRoundArtifact(input.context.roundDir, reviewer.reviewPath, result.stdout);
38041
+ await writeRoundArtifact(input.context.roundDir, reviewer.reviewPath, processOutput(result));
37992
38042
  }
37993
38043
  return { ok: true, results: sortResults(results, requests) };
37994
38044
  }
@@ -38021,7 +38071,8 @@ async function runOpenCodeProcessAgentReview(input) {
38021
38071
  resolvedTeam: snapshot.resolvedTeam,
38022
38072
  cwd: input.cwd,
38023
38073
  runner,
38024
- journal
38074
+ journal,
38075
+ emit
38025
38076
  });
38026
38077
  if (!reviewerResult.ok) {
38027
38078
  emit({
@@ -38042,7 +38093,8 @@ async function runOpenCodeProcessAgentReview(input) {
38042
38093
  resolvedTeam: snapshot.resolvedTeam,
38043
38094
  cwd: input.cwd,
38044
38095
  runner,
38045
- journal
38096
+ journal,
38097
+ emit
38046
38098
  });
38047
38099
  if (!pipelineResult.ok) {
38048
38100
  emit({
@@ -38069,6 +38121,7 @@ async function runOpenCodeProcessAgentReview(input) {
38069
38121
  }
38070
38122
  async function runPipelineStages(input) {
38071
38123
  const journal = input.journal ?? new NoopAgentLifecycleJournal();
38124
+ const emit = input.emit ?? (() => void 0);
38072
38125
  const missingReviews = input.resolvedTeam.reviewers.map((reviewer) => reviewer.reviewPath).filter((reviewPath) => !isNonEmptyFile(join27(input.context.roundDir, reviewPath)));
38073
38126
  if (missingReviews.length > 0) {
38074
38127
  return {
@@ -38097,7 +38150,26 @@ async function runPipelineStages(input) {
38097
38150
  cwd: input.cwd,
38098
38151
  phase: stage
38099
38152
  };
38153
+ const startLogPaths = await writeProcessStartLog(input.context.roundDir, request);
38154
+ emit({
38155
+ event: "agent:start",
38156
+ phase: stage,
38157
+ id: request.id,
38158
+ model: request.model,
38159
+ prompt_path: request.promptPath,
38160
+ meta_log: startLogPaths.meta
38161
+ });
38100
38162
  const result = await input.runner.run(request, new AbortController().signal);
38163
+ const logPaths = await writeProcessLogs(input.context.roundDir, request, result);
38164
+ emit({
38165
+ event: "agent:complete",
38166
+ phase: stage,
38167
+ id: request.id,
38168
+ exit_code: result.exitCode,
38169
+ stdout_log: logPaths.stdout,
38170
+ stderr_log: logPaths.stderr,
38171
+ meta_log: logPaths.meta
38172
+ });
38101
38173
  results.push(result);
38102
38174
  const vendorId = extractVendorSessionId(result.ndjsonEvents);
38103
38175
  if (vendorId) await journal.bindVendorId(agentSessionId, vendorId);
@@ -38123,7 +38195,7 @@ async function runPipelineStages(input) {
38123
38195
  results
38124
38196
  };
38125
38197
  }
38126
- await writeRoundArtifact(input.context.roundDir, ref.artifactPath, result.stdout);
38198
+ await writeRoundArtifact(input.context.roundDir, ref.artifactPath, processOutput(result));
38127
38199
  const validationErrors = validateStageArtifact(input.context.roundDir, stage, ref.artifactPath);
38128
38200
  if (validationErrors.length > 0) {
38129
38201
  await journal.endInstance(agentSessionId, {
@@ -38156,6 +38228,70 @@ function validateStageArtifact(roundDir, stage, artifactPath) {
38156
38228
  function isNonEmptyFile(path2) {
38157
38229
  return existsSync22(path2) && statSync5(path2).isFile() && statSync5(path2).size > 0;
38158
38230
  }
38231
+ async function writeProcessStartLog(roundDir, request) {
38232
+ const metaPath = `process-logs/${request.id}.meta.json`;
38233
+ await writeRoundArtifact(
38234
+ roundDir,
38235
+ metaPath,
38236
+ JSON.stringify(
38237
+ {
38238
+ schema_version: 1,
38239
+ id: request.id,
38240
+ phase: request.phase,
38241
+ model: request.model,
38242
+ prompt_path: request.promptPath,
38243
+ status: "running",
38244
+ started_at: (/* @__PURE__ */ new Date()).toISOString()
38245
+ },
38246
+ null,
38247
+ 2
38248
+ )
38249
+ );
38250
+ return { meta: metaPath };
38251
+ }
38252
+ async function writeProcessLogs(roundDir, request, result) {
38253
+ const prefix = `process-logs/${request.id}`;
38254
+ const stdoutPath = `${prefix}.stdout.ndjson`;
38255
+ const stderrPath = `${prefix}.stderr.log`;
38256
+ const metaPath = `${prefix}.meta.json`;
38257
+ await writeRoundArtifact(roundDir, stdoutPath, result.stdout);
38258
+ await writeRoundArtifact(roundDir, stderrPath, result.stderr);
38259
+ await writeRoundArtifact(
38260
+ roundDir,
38261
+ metaPath,
38262
+ JSON.stringify(
38263
+ {
38264
+ schema_version: 1,
38265
+ id: request.id,
38266
+ phase: request.phase,
38267
+ model: request.model,
38268
+ prompt_path: request.promptPath,
38269
+ status: "completed",
38270
+ completed_at: (/* @__PURE__ */ new Date()).toISOString(),
38271
+ exit_code: result.exitCode,
38272
+ output_text_bytes: Buffer.byteLength(processOutput(result), "utf-8"),
38273
+ stdout_bytes: Buffer.byteLength(result.stdout, "utf-8"),
38274
+ stderr_bytes: Buffer.byteLength(result.stderr, "utf-8"),
38275
+ opencode_session_ids: extractUniqueSessionIds(result.ndjsonEvents)
38276
+ },
38277
+ null,
38278
+ 2
38279
+ )
38280
+ );
38281
+ return { stdout: stdoutPath, stderr: stderrPath, meta: metaPath };
38282
+ }
38283
+ function processOutput(result) {
38284
+ return result.outputText ?? result.stdout;
38285
+ }
38286
+ function extractUniqueSessionIds(events) {
38287
+ const ids = /* @__PURE__ */ new Set();
38288
+ for (const event of events) {
38289
+ if (!isRecord2(event)) continue;
38290
+ const sessionID = event.sessionID;
38291
+ if (typeof sessionID === "string") ids.add(sessionID);
38292
+ }
38293
+ return [...ids];
38294
+ }
38159
38295
  async function writePipelineFailure(roundDir, stage, result, results, validationErrors = [], diagnostic = buildFailureDiagnostic(result)) {
38160
38296
  await writeRoundArtifact(
38161
38297
  roundDir,
@@ -38217,11 +38353,11 @@ function buildFailureDiagnostic(result, request) {
38217
38353
  }
38218
38354
  function extractOpenCodeErrorMessage(events) {
38219
38355
  for (const event of events) {
38220
- if (!isRecord(event) || event.type !== "error") continue;
38356
+ if (!isRecord2(event) || event.type !== "error") continue;
38221
38357
  const error = event.error;
38222
- if (!isRecord(error)) continue;
38358
+ if (!isRecord2(error)) continue;
38223
38359
  const data = error.data;
38224
- if (isRecord(data) && typeof data.message === "string") return data.message;
38360
+ if (isRecord2(data) && typeof data.message === "string") return data.message;
38225
38361
  if (typeof error.message === "string") return error.message;
38226
38362
  }
38227
38363
  return void 0;
@@ -38234,7 +38370,7 @@ function excerpt(value, limit = 1200) {
38234
38370
  function stripAnsi2(value) {
38235
38371
  return value.replace(/\u001b\[[0-9;]*m/g, "");
38236
38372
  }
38237
- function isRecord(value) {
38373
+ function isRecord2(value) {
38238
38374
  return typeof value === "object" && value !== null;
38239
38375
  }
38240
38376
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nk070281sjv/cli",
3
- "version": "2.3.5",
3
+ "version": "2.3.6",
4
4
  "description": "CLI for Open Code Review - Multi-environment setup and progress tracking",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@inquirer/prompts": "^7.2.0",
40
- "@nk070281sjv/agents": "2.3.5",
40
+ "@nk070281sjv/agents": "2.3.6",
41
41
  "chalk": "^5.4.1",
42
42
  "chokidar": "^4.0.3",
43
43
  "commander": "^13.0.0",