@vendian/cli 0.0.14 → 0.0.16

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/cli-wrapper.mjs +199 -10
  2. package/package.json +1 -1
package/cli-wrapper.mjs CHANGED
@@ -36779,7 +36779,7 @@ import fs12 from "node:fs";
36779
36779
  import readlinePromises from "node:readline/promises";
36780
36780
 
36781
36781
  // src/version.js
36782
- var CLI_VERSION = true ? "0.0.14" : process.env.npm_package_version || "0.0.0-dev";
36782
+ var CLI_VERSION = true ? "0.0.16" : process.env.npm_package_version || "0.0.0-dev";
36783
36783
 
36784
36784
  // src/npm-update.js
36785
36785
  var NPM_CHECK_INTERVAL_MS = 30 * 60 * 1e3;
@@ -37153,11 +37153,12 @@ function serveProcessExitMessage({ stderr = "", code = 0, signal = "" } = {}) {
37153
37153
  if (/unrecognized arguments:\s*--event-stream/i.test(text)) {
37154
37154
  return "Managed Vendian runtime is too old for the local serve dashboard. Run `vendian update`, then start Serve Agents again.";
37155
37155
  }
37156
+ const detail = textTail(text);
37156
37157
  if (code && code !== 0) {
37157
- return `Local serve exited with code ${code}. Toggle details for stderr.`;
37158
+ return `Local serve exited with code ${code}${detail ? `: ${detail}` : ""}`;
37158
37159
  }
37159
37160
  if (signal && signal !== "SIGINT" && signal !== "SIGTERM") {
37160
- return `Local serve exited from ${signal}. Toggle details for stderr.`;
37161
+ return `Local serve exited from ${signal}${detail ? `: ${detail}` : ""}`;
37161
37162
  }
37162
37163
  return "";
37163
37164
  }
@@ -37296,6 +37297,22 @@ function applyServeEvent(state, event) {
37296
37297
  jobsRun: Number(event.jobsRun ?? state.jobsRun)
37297
37298
  };
37298
37299
  }
37300
+ if (event.type === "process_exit" || event.type === "daemon_exit") {
37301
+ const timestamp = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
37302
+ const message = stringValue(event.message || processExitMessage(event));
37303
+ const relativePath = stringValue(event.relativePath || "");
37304
+ const runState = failRunningAgents(state.agentRunState, message, timestamp, relativePath);
37305
+ return {
37306
+ ...next,
37307
+ stopped: true,
37308
+ connected: false,
37309
+ currentJob: null,
37310
+ activity: "Process exited",
37311
+ agentLogs: appendProcessExitAgentLogs(state.agentLogs, event, state.agentRunState, relativePath),
37312
+ agentRunState: runState,
37313
+ errors: appendError(state.errors, "Local daemon", message)
37314
+ };
37315
+ }
37299
37316
  if (event.type === "run_log") {
37300
37317
  const entry = serveEventAgentLogEntry(event);
37301
37318
  const nextRunState = entry && entry.entry.eventType === "completion" ? setAgentRunState(state.agentRunState, entry.relativePath, {
@@ -37498,6 +37515,30 @@ function serveEventAgentLogEntry(event) {
37498
37515
  }
37499
37516
  };
37500
37517
  }
37518
+ if (type === "process_exit" || type === "daemon_exit") {
37519
+ const message = stringValue(event.message || processExitMessage(event));
37520
+ return {
37521
+ relativePath,
37522
+ entry: {
37523
+ timestamp,
37524
+ runId: stringValue(event.runId || event.sessionId || "daemon"),
37525
+ eventType: type,
37526
+ level: "error",
37527
+ message,
37528
+ stepId: null,
37529
+ current: null,
37530
+ total: null,
37531
+ success: false,
37532
+ error: {
37533
+ message,
37534
+ code: event.code ?? null,
37535
+ signal: event.signal ?? null,
37536
+ stderrTail: event.stderrTail ?? null
37537
+ },
37538
+ jobType: event.jobType ? stringValue(event.jobType) : null
37539
+ }
37540
+ };
37541
+ }
37501
37542
  return null;
37502
37543
  }
37503
37544
  function agentRuntimeStatus(agent, agentRunState = {}) {
@@ -37540,6 +37581,46 @@ function setAgentRunState(agentRunState, relativePath, patch) {
37540
37581
  }
37541
37582
  };
37542
37583
  }
37584
+ function failRunningAgents(agentRunState, message, timestamp, relativePath = "") {
37585
+ let next = agentRunState || {};
37586
+ for (const [path8, run2] of Object.entries(agentRunState || {})) {
37587
+ if (run2?.status !== "running") continue;
37588
+ next = setAgentRunState(next, path8, {
37589
+ status: "error",
37590
+ completedAt: timestamp,
37591
+ lastEventAt: timestamp,
37592
+ errorMessage: message
37593
+ });
37594
+ }
37595
+ if (relativePath) {
37596
+ next = setAgentRunState(next, relativePath, {
37597
+ status: "error",
37598
+ completedAt: timestamp,
37599
+ lastEventAt: timestamp,
37600
+ errorMessage: message
37601
+ });
37602
+ }
37603
+ return next;
37604
+ }
37605
+ function appendProcessExitAgentLogs(agentLogs, event, agentRunState, relativePath = "") {
37606
+ const paths = /* @__PURE__ */ new Set();
37607
+ if (relativePath) {
37608
+ paths.add(relativePath);
37609
+ }
37610
+ for (const [path8, run2] of Object.entries(agentRunState || {})) {
37611
+ if (run2?.status === "running") {
37612
+ paths.add(path8);
37613
+ }
37614
+ }
37615
+ if (paths.size === 0) {
37616
+ return appendAgentLog(agentLogs, event);
37617
+ }
37618
+ let next = agentLogs || {};
37619
+ for (const path8 of paths) {
37620
+ next = appendAgentLog(next, { ...event, relativePath: path8 });
37621
+ }
37622
+ return next;
37623
+ }
37543
37624
  function reconcileInventoryRunState(agentRunState, agents, timestamp) {
37544
37625
  let next = agentRunState || {};
37545
37626
  for (const agent of agents || []) {
@@ -37612,6 +37693,19 @@ function jobLabel(event) {
37612
37693
  function stringValue(value) {
37613
37694
  return value == null ? "" : String(value);
37614
37695
  }
37696
+ function processExitMessage(event) {
37697
+ if (event?.code && Number(event.code) !== 0) {
37698
+ return `Agent serve exited with code ${event.code}`;
37699
+ }
37700
+ if (event?.signal) {
37701
+ return `Agent serve exited from ${event.signal}`;
37702
+ }
37703
+ return "Agent serve exited";
37704
+ }
37705
+ function textTail(value, limit = 800) {
37706
+ const text = String(value || "").trim().replace(/\s+/g, " ");
37707
+ return text.length > limit ? text.slice(-limit) : text;
37708
+ }
37615
37709
  function formatSeconds(value) {
37616
37710
  const numeric = Number(value);
37617
37711
  return Number.isFinite(numeric) ? `${numeric.toFixed(1)}s` : "";
@@ -38733,6 +38827,64 @@ function runtimeStatusIcon(status) {
38733
38827
  if (status === "error") return fig.cross;
38734
38828
  return fig.dotEmpty;
38735
38829
  }
38830
+ function agentStatusReason(agent) {
38831
+ const status = agent.status?.status;
38832
+ if (status === "error") {
38833
+ const msg = agent.status?.run?.errorMessage || agent.status?.run?.disabledReason || "";
38834
+ return msg || "Setup failed";
38835
+ }
38836
+ if (status === "disabled") {
38837
+ const msg = agent.status?.disabledReason || agent.status?.run?.disabledReason || "";
38838
+ return msg || "Deps not met locally";
38839
+ }
38840
+ return "";
38841
+ }
38842
+ function agentDetailStatusBlock(runtime, agent, agentRunState, relativePath) {
38843
+ const runState = (agentRunState || {})[relativePath];
38844
+ const lines = [];
38845
+ if (runtime.status === "error") {
38846
+ const errorMsg = runState?.errorMessage || agent?.errorMessage || "Unknown error during agent setup";
38847
+ lines.push(
38848
+ h(
38849
+ Text2,
38850
+ { key: "err-header", color: colors.error, bold: true },
38851
+ ` ${fig.cross} Error: Agent failed to prepare`
38852
+ )
38853
+ );
38854
+ lines.push(
38855
+ h(
38856
+ Text2,
38857
+ { key: "err-msg", color: colors.error },
38858
+ ` ${errorMsg}`
38859
+ )
38860
+ );
38861
+ lines.push(h(Text2, { key: "err-spacer" }, ""));
38862
+ } else if (runtime.status === "disabled") {
38863
+ const reason = runState?.disabledReason || runtime.disabledReason || agent?.disabledReason || "System dependency not met locally";
38864
+ const hints = runState?.resolutionHints || runtime.resolutionHints || agent?.resolutionHints || [];
38865
+ lines.push(
38866
+ h(
38867
+ Text2,
38868
+ { key: "dis-header", color: colors.warning, bold: true },
38869
+ ` ${fig.warning} Disabled: ${reason}`
38870
+ )
38871
+ );
38872
+ if (hints.length > 0) {
38873
+ for (let i = 0; i < Math.min(hints.length, 3); i++) {
38874
+ lines.push(
38875
+ h(
38876
+ Text2,
38877
+ { key: `dis-hint-${i}`, color: colors.muted },
38878
+ ` ${fig.arrowRight} ${hints[i]}`
38879
+ )
38880
+ );
38881
+ }
38882
+ }
38883
+ lines.push(h(Text2, { key: "dis-spacer" }, ""));
38884
+ }
38885
+ if (lines.length === 0) return null;
38886
+ return h(Box2, { flexDirection: "column" }, ...lines);
38887
+ }
38736
38888
  function FooterBar({ items }) {
38737
38889
  if (!items || !items.length) return null;
38738
38890
  return h(
@@ -38819,7 +38971,8 @@ function AgentLogPicker({ agents, agentLogs, agentRunState = {}, onSelectAgent,
38819
38971
  ...agentList.map((agent, i) => {
38820
38972
  const isActive = i === selectedIndex;
38821
38973
  const logCountColor = agent.hasErrors ? colors.error : agent.logCount > 0 ? colors.success : colors.muted;
38822
- const lastEvent = agent.lastLog ? formatAgentLogEntry(agent.lastLog) : "No logs";
38974
+ const lastEvent = agent.lastLog ? formatAgentLogEntry(agent.lastLog) : agentStatusReason(agent) || "No logs";
38975
+ const lastEventColor = agent.lastLog ? colors.muted : agent.status.status === "error" ? colors.error : agent.status.status === "disabled" ? colors.warning : colors.muted;
38823
38976
  return h(
38824
38977
  Text2,
38825
38978
  { key: agent.path },
@@ -38827,7 +38980,7 @@ function AgentLogPicker({ agents, agentLogs, agentRunState = {}, onSelectAgent,
38827
38980
  h(Text2, { bold: isActive }, clip(agent.name, nameW - 2).padEnd(nameW)),
38828
38981
  h(Text2, { color: runtimeStatusColor(agent.status.status) }, `${runtimeStatusIcon(agent.status.status)} ${agent.status.label}`.padEnd(statusW)),
38829
38982
  h(Text2, { color: logCountColor }, String(agent.logCount).padEnd(6)),
38830
- h(Text2, { color: colors.muted }, clip(lastEvent, 36))
38983
+ h(Text2, { color: lastEventColor }, clip(lastEvent, 36))
38831
38984
  );
38832
38985
  }),
38833
38986
  h(Text2, null, ""),
@@ -38873,7 +39026,12 @@ function AgentLogDetail({ relativePath, agentLogs, agentRunState = {}, agents, o
38873
39026
  h(Text2, { color: runtimeStatusColor(runtime.status) }, `${runtimeStatusIcon(runtime.status)} ${runtime.label}`)
38874
39027
  ),
38875
39028
  h(Text2, null, ""),
38876
- logs.length === 0 ? h(Text2, { color: colors.muted }, " No logs recorded yet for this agent. Logs appear during runs.") : h(
39029
+ logs.length === 0 ? h(
39030
+ Box2,
39031
+ { flexDirection: "column" },
39032
+ agentDetailStatusBlock(runtime, agent, agentRunState, relativePath),
39033
+ h(Text2, { color: colors.muted }, " No run logs recorded yet. Logs appear during runs.")
39034
+ ) : h(
38877
39035
  Box2,
38878
39036
  { flexDirection: "column" },
38879
39037
  ...visibleRows.map((row, i) => {
@@ -39146,13 +39304,44 @@ function attachServeChild(child, setState, setStartupError, onExit, logStore = n
39146
39304
  });
39147
39305
  child.on("error", (error) => setStartupError(errorMessage2(error)));
39148
39306
  child.on("exit", (code, signal) => {
39149
- try {
39150
- logStore?.compact();
39151
- } catch {
39152
- }
39153
39307
  const message = serveProcessExitMessage({ stderr: stderrChunks.join("\n"), code, signal });
39154
39308
  if (message) {
39155
39309
  setStartupError(message);
39310
+ setState((current) => {
39311
+ const currentJob = current?.currentJob || {};
39312
+ const event = {
39313
+ type: "process_exit",
39314
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
39315
+ code,
39316
+ signal,
39317
+ message,
39318
+ stderrTail: stderrChunks.join("\n").slice(-2e3),
39319
+ relativePath: currentJob.relativePath || currentJob.localPath || currentJob.path || "",
39320
+ runId: currentJob.runId || currentJob.deployRequestId || currentJob.testRunId || "",
39321
+ sessionId: currentJob.sessionId || "",
39322
+ jobType: currentJob.jobType || ""
39323
+ };
39324
+ try {
39325
+ const runningPaths = Object.entries(current?.agentRunState || {}).filter(([, run2]) => run2?.status === "running").map(([path8]) => path8).filter(Boolean);
39326
+ const paths = new Set(runningPaths);
39327
+ if (event.relativePath) {
39328
+ paths.add(event.relativePath);
39329
+ }
39330
+ if (paths.size === 0) {
39331
+ logStore?.append(event);
39332
+ } else {
39333
+ for (const relativePath of paths) {
39334
+ logStore?.append({ ...event, relativePath });
39335
+ }
39336
+ }
39337
+ } catch {
39338
+ }
39339
+ return applyServeEvent(current, event);
39340
+ });
39341
+ }
39342
+ try {
39343
+ logStore?.compact();
39344
+ } catch {
39156
39345
  }
39157
39346
  onExit({ code, signal, message });
39158
39347
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vendian/cli",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Public Vendian CLI bootstrapper and launcher",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,