nolo-cli 0.1.52 → 0.1.53

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/index.js +188 -19
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -70008,10 +70008,12 @@ ${this.text}
70008
70008
  // packages/cli/agentRunControl.ts
70009
70009
  var agentRunControl_exports = {};
70010
70010
  __export(agentRunControl_exports, {
70011
+ checkStaleRun: () => checkStaleRun,
70011
70012
  defaultGenerateRunId: () => defaultGenerateRunId,
70012
70013
  finalizeRunRecord: () => finalizeRunRecord,
70013
70014
  findRunRecord: () => findRunRecord,
70014
70015
  findRunRecordByPid: () => findRunRecordByPid,
70016
+ isPidGone: () => isPidGone,
70015
70017
  listRunRecords: () => listRunRecords,
70016
70018
  readRunRecord: () => readRunRecord,
70017
70019
  resolveNoloHome: () => resolveNoloHome2,
@@ -70054,7 +70056,7 @@ function defaultGenerateRunId() {
70054
70056
  function writeRunRecord(record, deps = {}) {
70055
70057
  const fs5 = deps.fs ?? nodeFs;
70056
70058
  const path8 = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
70057
- fs5.mkdirSync(join9(path8, ".."), { recursive: true });
70059
+ fs5.mkdirSync(resolveRunsDir(deps.env, deps.homedir), { recursive: true });
70058
70060
  fs5.writeFileSync(path8, JSON.stringify(record, null, 2));
70059
70061
  }
70060
70062
  function readRunRecord(runId, deps = {}) {
@@ -70172,6 +70174,29 @@ function finalizeRunRecord(runId, update, deps = {}) {
70172
70174
  record.endedAt = now().toISOString();
70173
70175
  writeRunRecord(record, deps);
70174
70176
  }
70177
+ function isPidGone(pid, deps = {}) {
70178
+ const kill = deps.kill ?? ((p, s) => process.kill(p, s));
70179
+ try {
70180
+ kill(pid, "0");
70181
+ return false;
70182
+ } catch (error) {
70183
+ const code = error.code;
70184
+ return code === "ESRCH";
70185
+ }
70186
+ }
70187
+ function checkStaleRun(runId, deps = {}) {
70188
+ const record = readRunRecord(runId, deps);
70189
+ if (!record) return null;
70190
+ if (record.status !== "running") return record;
70191
+ if (typeof record.pid !== "number") return record;
70192
+ if (!isPidGone(record.pid, deps)) return record;
70193
+ const now = deps.now ?? (() => /* @__PURE__ */ new Date());
70194
+ record.status = "failed";
70195
+ record.note = "process gone: pid no longer exists";
70196
+ record.endedAt = now().toISOString();
70197
+ writeRunRecord(record, deps);
70198
+ return record;
70199
+ }
70175
70200
  function formatDuration(startedAt, endedAt) {
70176
70201
  const start = new Date(startedAt).getTime();
70177
70202
  const end = endedAt ? new Date(endedAt).getTime() : Date.now();
@@ -70213,14 +70238,48 @@ function readLogContent(logPath, tailCount, deps) {
70213
70238
  return "";
70214
70239
  }
70215
70240
  }
70216
- async function runAgentPsCommand(_args, deps) {
70241
+ function isRunningStatus(status) {
70242
+ return RUNNING_STATUSES.has(status);
70243
+ }
70244
+ function parseJsonFlag(args2) {
70245
+ let json = false;
70246
+ const rest = [];
70247
+ for (const arg of args2) {
70248
+ if (arg === "--json") {
70249
+ json = true;
70250
+ continue;
70251
+ }
70252
+ if (arg.startsWith("--json=")) {
70253
+ const value = arg.slice("--json=".length);
70254
+ json = value === "" || value === "true" || value === "1";
70255
+ continue;
70256
+ }
70257
+ rest.push(arg);
70258
+ }
70259
+ return { json, rest };
70260
+ }
70261
+ function defaultSleep2(ms) {
70262
+ return new Promise((resolve8) => setTimeout(resolve8, ms));
70263
+ }
70264
+ async function runAgentPsCommand(args2, deps) {
70265
+ const { json } = parseJsonFlag(args2);
70217
70266
  const records = listRunRecords(deps);
70218
- if (records.length === 0) {
70267
+ for (const record of records) {
70268
+ if (record.status === "running" && typeof record.pid === "number") {
70269
+ checkStaleRun(record.runId, deps);
70270
+ }
70271
+ }
70272
+ const refreshed = records.map((r) => readRunRecord(r.runId, deps)).filter(Boolean);
70273
+ if (json) {
70274
+ deps.output.write(JSON.stringify(refreshed) + "\n");
70275
+ return 0;
70276
+ }
70277
+ if (refreshed.length === 0) {
70219
70278
  deps.output.write("No local runs found.\n");
70220
70279
  return 0;
70221
70280
  }
70222
70281
  deps.output.write("RUN ID STATUS PID AGENT\n");
70223
- for (const record of records) {
70282
+ for (const record of refreshed) {
70224
70283
  const pid = record.pid?.toString() ?? "-";
70225
70284
  deps.output.write(
70226
70285
  `${record.runId.padEnd(32)} ${record.status.padEnd(8)} ${pid.padEnd(8)} ${record.agentKey}
@@ -70229,18 +70288,83 @@ async function runAgentPsCommand(_args, deps) {
70229
70288
  }
70230
70289
  return 0;
70231
70290
  }
70291
+ function parseStatusArgs(args2) {
70292
+ let target = "";
70293
+ let json = false;
70294
+ let watch = false;
70295
+ let intervalMs = 2e3;
70296
+ for (let i = 0; i < args2.length; i++) {
70297
+ const arg = args2[i];
70298
+ if (arg === "--json") {
70299
+ json = true;
70300
+ continue;
70301
+ }
70302
+ if (arg.startsWith("--json=")) {
70303
+ const value = arg.slice("--json=".length);
70304
+ json = value === "" || value === "true" || value === "1";
70305
+ continue;
70306
+ }
70307
+ if (arg === "--watch") {
70308
+ watch = true;
70309
+ continue;
70310
+ }
70311
+ if (arg.startsWith("--watch=")) {
70312
+ const value = arg.slice("--watch=".length);
70313
+ watch = value === "" || value === "true" || value === "1";
70314
+ continue;
70315
+ }
70316
+ if (arg === "--interval-ms") {
70317
+ const next = args2[i + 1];
70318
+ if (next && /^\d+$/.test(next)) {
70319
+ intervalMs = Number(next);
70320
+ i += 1;
70321
+ }
70322
+ continue;
70323
+ }
70324
+ if (arg.startsWith("--interval-ms=")) {
70325
+ const value = arg.slice("--interval-ms=".length);
70326
+ if (/^\d+$/.test(value)) intervalMs = Number(value);
70327
+ continue;
70328
+ }
70329
+ if (!arg.startsWith("-") && !target) {
70330
+ target = arg;
70331
+ }
70332
+ }
70333
+ return { target, json, watch, intervalMs };
70334
+ }
70335
+ function printStatusTick(record, deps) {
70336
+ const elapsed = formatDuration(record.startedAt, record.endedAt);
70337
+ const note = record.note ? ` (${record.note})` : "";
70338
+ deps.output.write(
70339
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] ${record.runId} status=${record.status} elapsed=${elapsed}${note}
70340
+ `
70341
+ );
70342
+ }
70232
70343
  async function runAgentStatusCommand(args2, deps) {
70233
- const target = args2[0];
70344
+ const { target, json, watch, intervalMs } = parseStatusArgs(args2);
70234
70345
  if (!target) {
70235
- deps.output.write("Usage: nolo agent status <runId|pid>\n");
70346
+ deps.output.write("Usage: nolo agent status <runId|pid> [--json] [--watch] [--interval-ms N]\n");
70236
70347
  return 1;
70237
70348
  }
70238
- const record = findRunRecord(target, deps);
70239
- if (!record) {
70349
+ const initial = findRunRecord(target, deps);
70350
+ if (!initial) {
70240
70351
  deps.output.write(`Run not found: ${target}
70241
70352
  `);
70242
70353
  return 1;
70243
70354
  }
70355
+ const reconciled = checkStaleRun(initial.runId, deps) ?? initial;
70356
+ if (json) {
70357
+ const record = readRunRecord(reconciled.runId, deps) ?? reconciled;
70358
+ deps.output.write(JSON.stringify(record) + "\n");
70359
+ return 0;
70360
+ }
70361
+ if (!watch) {
70362
+ const record = readRunRecord(reconciled.runId, deps) ?? reconciled;
70363
+ return printStatusOnce(record, deps);
70364
+ }
70365
+ return runStatusWatch(reconciled.runId, intervalMs, deps);
70366
+ }
70367
+ function printStatusOnce(record, deps) {
70244
70368
  deps.output.write(`runId: ${record.runId}
70245
70369
  `);
70246
70370
  deps.output.write(`status: ${record.status}
@@ -70260,6 +70384,8 @@ async function runAgentStatusCommand(args2, deps) {
70260
70384
  if (typeof record.exitCode === "number") deps.output.write(`exitCode: ${record.exitCode}
70261
70385
  `);
70262
70386
  if (record.dialogId) deps.output.write(`dialog: ${record.dialogId}
70387
+ `);
70388
+ if (record.note) deps.output.write(`note: ${record.note}
70263
70389
  `);
70264
70390
  deps.output.write(`log: ${record.logPath}
70265
70391
  `);
@@ -70273,6 +70399,47 @@ async function runAgentStatusCommand(args2, deps) {
70273
70399
  }
70274
70400
  return 0;
70275
70401
  }
70402
+ async function runStatusWatch(runId, intervalMs, deps) {
70403
+ const sleep7 = deps.sleep ?? defaultSleep2;
70404
+ const now = deps.now ?? (() => /* @__PURE__ */ new Date());
70405
+ let stopped = false;
70406
+ const setSignalHandler = deps.setSignalHandler ?? ((handler) => {
70407
+ process.once("SIGINT", handler);
70408
+ });
70409
+ const clearSignalHandler = deps.clearSignalHandler ?? (() => {
70410
+ process.removeAllListeners("SIGINT");
70411
+ });
70412
+ setSignalHandler(() => {
70413
+ stopped = true;
70414
+ });
70415
+ try {
70416
+ let record = readRunRecord(runId, deps);
70417
+ if (!record) {
70418
+ deps.output.write(`Run not found: ${runId}
70419
+ `);
70420
+ return 1;
70421
+ }
70422
+ printStatusTick(record, deps);
70423
+ while (!stopped && isRunningStatus(record.status)) {
70424
+ await sleep7(intervalMs);
70425
+ if (stopped) break;
70426
+ record = checkStaleRun(runId, deps);
70427
+ if (!record) {
70428
+ deps.output.write(`Run not found: ${runId}
70429
+ `);
70430
+ return 1;
70431
+ }
70432
+ printStatusTick(record, deps);
70433
+ }
70434
+ if (stopped) {
70435
+ deps.output.write(`watch stopped by signal
70436
+ `);
70437
+ }
70438
+ return 0;
70439
+ } finally {
70440
+ clearSignalHandler();
70441
+ }
70442
+ }
70276
70443
  function parseLogsArgs(args2, onTail) {
70277
70444
  let runId = "";
70278
70445
  for (let i = 0; i < args2.length; i++) {
@@ -70364,10 +70531,12 @@ async function runAgentStopCommand(args2, deps) {
70364
70531
  async function runAgentKillCommand(args2, deps) {
70365
70532
  return runSignalCommand(args2, "SIGKILL", "kill", deps);
70366
70533
  }
70534
+ var RUNNING_STATUSES;
70367
70535
  var init_agentRunControl = __esm({
70368
70536
  "packages/cli/agentRunControl.ts"() {
70369
70537
  "use strict";
70370
70538
  init_cliEnvHelpers();
70539
+ RUNNING_STATUSES = /* @__PURE__ */ new Set(["running"]);
70371
70540
  }
70372
70541
  });
70373
70542
 
@@ -77218,7 +77387,7 @@ async function runLoginCommand(args2, deps = {}) {
77218
77387
  serverUrl,
77219
77388
  fetchImpl: deps.fetchImpl ?? fetch,
77220
77389
  openBrowser: deps.openBrowser ?? defaultOpenBrowser,
77221
- sleep: deps.sleep ?? defaultSleep2,
77390
+ sleep: deps.sleep ?? defaultSleep3,
77222
77391
  now: deps.now ?? Date.now,
77223
77392
  output: outputTarget,
77224
77393
  error: errorTarget,
@@ -77286,7 +77455,7 @@ function runLogoutCommand(deps = {}) {
77286
77455
  }
77287
77456
  return 0;
77288
77457
  }
77289
- var LOGIN_HELP_TEXT, LOGOUT_HELP_TEXT, WHOAMI_HELP_TEXT, postJson2, defaultSleep2, defaultOpenBrowser;
77458
+ var LOGIN_HELP_TEXT, LOGOUT_HELP_TEXT, WHOAMI_HELP_TEXT, postJson2, defaultSleep3, defaultOpenBrowser;
77290
77459
  var init_authCommands = __esm({
77291
77460
  "packages/cli/authCommands.ts"() {
77292
77461
  "use strict";
@@ -77326,7 +77495,7 @@ Usage:
77326
77495
  headers: { "Content-Type": "application/json" },
77327
77496
  body: JSON.stringify(body)
77328
77497
  });
77329
- defaultSleep2 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
77498
+ defaultSleep3 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
77330
77499
  defaultOpenBrowser = async (url) => {
77331
77500
  const command2 = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
77332
77501
  const args2 = process.platform === "win32" ? ["/c", "start", "", url] : [url];
@@ -77654,7 +77823,7 @@ ${SYNC_HELP_LINE}
77654
77823
 
77655
77824
  // packages/connector-experimental/heartbeatLoop.ts
77656
77825
  async function runHeartbeatLoop(options) {
77657
- const sleep7 = options.sleep ?? defaultSleep3;
77826
+ const sleep7 = options.sleep ?? defaultSleep4;
77658
77827
  let beats = 0;
77659
77828
  while (!options.signal?.aborted) {
77660
77829
  await options.sendHeartbeat();
@@ -77664,11 +77833,11 @@ async function runHeartbeatLoop(options) {
77664
77833
  await sleep7(options.intervalMs);
77665
77834
  }
77666
77835
  }
77667
- var defaultSleep3;
77836
+ var defaultSleep4;
77668
77837
  var init_heartbeatLoop = __esm({
77669
77838
  "packages/connector-experimental/heartbeatLoop.ts"() {
77670
77839
  "use strict";
77671
- defaultSleep3 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
77840
+ defaultSleep4 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
77672
77841
  }
77673
77842
  });
77674
77843
 
@@ -78281,7 +78450,7 @@ ${text}`);
78281
78450
  return 1;
78282
78451
  }
78283
78452
  const maxAttempts = deps.maxConnectorAttempts ?? Infinity;
78284
- const sleep7 = deps.sleep ?? defaultSleep4;
78453
+ const sleep7 = deps.sleep ?? defaultSleep5;
78285
78454
  const reconnectDelayMs = resolveConnectorReconnectDelayMs(env);
78286
78455
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
78287
78456
  if (deps.signal?.aborted) {
@@ -78351,7 +78520,7 @@ ${text}`);
78351
78520
  sendHeartbeat
78352
78521
  });
78353
78522
  }
78354
- var defaultSleep4;
78523
+ var defaultSleep5;
78355
78524
  var init_machineCommands = __esm({
78356
78525
  "packages/cli/machineCommands.ts"() {
78357
78526
  "use strict";
@@ -78366,7 +78535,7 @@ var init_machineCommands = __esm({
78366
78535
  init_machineWsRunDispatch();
78367
78536
  init_machineWsSession();
78368
78537
  init_machineStatusCommands();
78369
- defaultSleep4 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
78538
+ defaultSleep5 = (ms) => new Promise((resolve8) => setTimeout(resolve8, ms));
78370
78539
  }
78371
78540
  });
78372
78541
 
@@ -80283,11 +80452,11 @@ function getAgentInternalCommandEntries() {
80283
80452
  return runAgentReadCommand2(args2, deps);
80284
80453
  }),
80285
80454
  createAgentRunCommand(["agent", "run"], "Run an agent"),
80286
- createEnvCommand(["agent", "ps"], "List active and recent local agent runs", async (_args, deps) => {
80455
+ createEnvCommand(["agent", "ps"], "List active and recent local agent runs (--json for machine-readable output)", async (_args, deps) => {
80287
80456
  const { runAgentPsCommand: runAgentPsCommand2 } = await Promise.resolve().then(() => (init_agentRunControl(), agentRunControl_exports));
80288
80457
  return runAgentPsCommand2(_args, { ...deps, output: process.stdout });
80289
80458
  }),
80290
- createEnvCommand(["agent", "status"], "Show status of a local agent run", async (args2, deps) => {
80459
+ createEnvCommand(["agent", "status"], "Show status of a local agent run (--json, --watch, --interval-ms N)", async (args2, deps) => {
80291
80460
  const { runAgentStatusCommand: runAgentStatusCommand2 } = await Promise.resolve().then(() => (init_agentRunControl(), agentRunControl_exports));
80292
80461
  return runAgentStatusCommand2(args2, { ...deps, output: process.stdout });
80293
80462
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "type": "module",
5
5
  "description": "Agent-first terminal workspace for Nolo",
6
6
  "bin": {
@@ -47,6 +47,6 @@
47
47
  "serpapi": "^2.2.1"
48
48
  },
49
49
  "optionalDependencies": {
50
- "nolo-cli-darwin-arm64": "0.1.52"
50
+ "nolo-cli-darwin-arm64": "0.1.53"
51
51
  }
52
52
  }