@great-arrow/cli 0.1.55 → 0.1.57

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 (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +162 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -227,6 +227,7 @@ and MCP reachability.
227
227
  ### Agents
228
228
 
229
229
  ```bash
230
+ gad agents # who is working right now, and where
230
231
  gad agent list
231
232
  gad agent invoke research-analyst --task "Summarize Q2 metrics"
232
233
  gad ask "What did we decide about the caching layer?"
package/dist/index.js CHANGED
@@ -9402,7 +9402,7 @@ function isNodeError(value) {
9402
9402
 
9403
9403
  // src/lib/version.ts
9404
9404
  var CLI_PACKAGE_NAME = "@great-arrow/cli";
9405
- var CLI_VERSION = "0.1.55";
9405
+ var CLI_VERSION = "0.1.57";
9406
9406
  var GAD_INSTALL_VERSION = "2026.08.08";
9407
9407
  var GAD_INSTALL_MIN_VERSION = "2026.06.22";
9408
9408
  var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
@@ -10129,6 +10129,9 @@ async function confirm(message) {
10129
10129
  });
10130
10130
  });
10131
10131
  }
10132
+ function stripControlChars(s) {
10133
+ return String(s).replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
10134
+ }
10132
10135
 
10133
10136
  // src/lib/formatter.ts
10134
10137
  var Formatter = class {
@@ -11828,7 +11831,9 @@ var TODO_COLUMNS = [
11828
11831
  if (Number.isNaN(date.getTime())) return str;
11829
11832
  return date.toLocaleDateString();
11830
11833
  }
11831
- }
11834
+ },
11835
+ // Every card the CLI lists is clickable (owner rule 2026-10-06).
11836
+ { key: "url", header: "Link" }
11832
11837
  ];
11833
11838
  var listCommand2 = new Command("list").description("List open todos sorted by priority").option(
11834
11839
  "--status <status>",
@@ -17221,6 +17226,68 @@ agentCommand.command("invoke <agent-id>").description("Execute an agent with a t
17221
17226
  }
17222
17227
  });
17223
17228
 
17229
+ // src/commands/agents.ts
17230
+ function groupTitle(where, rawMachine) {
17231
+ const machine = rawMachine ? stripControlChars(String(rawMachine)) : "";
17232
+ switch (where) {
17233
+ case "this_computer":
17234
+ return machine ? `On ${machine}` : "On your computers";
17235
+ case "remote_machine":
17236
+ return machine ? `On ${machine} (remote)` : "On a remote machine";
17237
+ case "vendor_cloud":
17238
+ return "In the cloud";
17239
+ case "great_arrow":
17240
+ return "Great Arrow agents";
17241
+ default:
17242
+ return "Location not reported";
17243
+ }
17244
+ }
17245
+ function itemLine(item) {
17246
+ const name = stripControlChars(String(item.who ?? ""));
17247
+ const who = typeof item.sessions === "number" && item.sessions > 1 ? `${name} (${item.sessions} sessions)` : name;
17248
+ const detail = item.detail ? stripControlChars(String(item.detail)) : "";
17249
+ return detail ? ` ${who} \u2014 ${detail}` : ` ${who}`;
17250
+ }
17251
+ function count(n) {
17252
+ return typeof n === "number" && Number.isFinite(n) ? n : 0;
17253
+ }
17254
+ function renderAgentsNow(payload) {
17255
+ const safe = payload && typeof payload === "object" ? payload : {};
17256
+ const groups = (Array.isArray(safe.working) ? safe.working : []).filter(
17257
+ (g) => g && Array.isArray(g.items) && g.items.length > 0
17258
+ );
17259
+ const counts = safe.counts ?? {};
17260
+ const lines = [];
17261
+ if (groups.length === 0) {
17262
+ lines.push("No agent is working right now.");
17263
+ } else {
17264
+ for (const g of groups) {
17265
+ lines.push(groupTitle(g.where, g.machine));
17266
+ for (const item of g.items) lines.push(itemLine(item));
17267
+ lines.push("");
17268
+ }
17269
+ if (lines[lines.length - 1] === "") lines.pop();
17270
+ }
17271
+ lines.push("");
17272
+ lines.push(
17273
+ `${count(counts.connected)} connected, idle \xB7 ${count(count(counts.working) + count(counts.connected) + count(counts.recent))} seen in 24h`
17274
+ );
17275
+ return lines.join("\n");
17276
+ }
17277
+ var agentsCommand = new Command("agents").description(
17278
+ "Agents working right now \u2014 this computer, the cloud and Great Arrow"
17279
+ ).option("--json", "Output as JSON").action(async (_opts, command) => {
17280
+ const g = globalOutputOpts(command);
17281
+ const auth = await resolveAuth();
17282
+ const client = new GadClient({ token: auth.token, apiUrl: auth.apiUrl });
17283
+ const result = await client.mcpCall("agents_now", {});
17284
+ if (g.json) {
17285
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
17286
+ return;
17287
+ }
17288
+ process.stdout.write(renderAgentsNow(result) + "\n");
17289
+ });
17290
+
17224
17291
  // src/commands/ask.ts
17225
17292
  var ORCHESTRATOR_TIMEOUT_MS = 9e4;
17226
17293
  var ANSWER_FIELDS = [
@@ -19266,7 +19333,9 @@ var NEXT_COLUMNS = [
19266
19333
  { key: "priority", header: "Priority", width: 8 },
19267
19334
  { key: "id", header: "ID", width: 36 },
19268
19335
  { key: "title", header: "Title", width: 40 },
19269
- { key: "context", header: "Next" }
19336
+ { key: "context", header: "Next" },
19337
+ // Every card the CLI lists is clickable (owner rule 2026-10-06).
19338
+ { key: "url", header: "Link" }
19270
19339
  ];
19271
19340
  function dueRank(value) {
19272
19341
  if (typeof value !== "string" || !value) return Number.POSITIVE_INFINITY;
@@ -19400,6 +19469,94 @@ function discoverCommand() {
19400
19469
  });
19401
19470
  }
19402
19471
 
19472
+ // src/lib/call-args.ts
19473
+ var AUTH_ERROR_CODES = /* @__PURE__ */ new Set([
19474
+ "unauthorized",
19475
+ "forbidden",
19476
+ "insufficient_scope",
19477
+ "auth_required"
19478
+ ]);
19479
+ function parseCallArgs(raw) {
19480
+ if (raw === void 0 || raw.trim() === "") return {};
19481
+ let parsed;
19482
+ try {
19483
+ parsed = JSON.parse(raw);
19484
+ } catch {
19485
+ throw new CliError(
19486
+ "--args is not valid JSON.",
19487
+ 3 /* VALIDATION_ERROR */,
19488
+ `Pass an object, e.g. --args '{"query":"pricing"}'.`
19489
+ );
19490
+ }
19491
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
19492
+ throw new CliError(
19493
+ "--args must be a JSON object.",
19494
+ 3 /* VALIDATION_ERROR */,
19495
+ `Pass an object, e.g. --args '{"query":"pricing"}'.`
19496
+ );
19497
+ }
19498
+ return parsed;
19499
+ }
19500
+ function callFailure(result) {
19501
+ if (typeof result !== "object" || result === null) return null;
19502
+ const record = result;
19503
+ const message = typeof record.message === "string" ? record.message : "";
19504
+ if (typeof record.error === "string" && record.error.trim() !== "") {
19505
+ return {
19506
+ code: record.error,
19507
+ message: message || `Request failed: ${record.error}`
19508
+ };
19509
+ }
19510
+ if (typeof record.error === "object" && record.error !== null) {
19511
+ const inner = record.error;
19512
+ const code = typeof inner.code === "string" ? inner.code : "error";
19513
+ const innerMessage = typeof inner.message === "string" ? inner.message : message;
19514
+ return { code, message: innerMessage || `Request failed: ${code}` };
19515
+ }
19516
+ if (record.ok === false || record.isError === true) {
19517
+ return {
19518
+ code: "error",
19519
+ message: message || "The tool reported a failure."
19520
+ };
19521
+ }
19522
+ return null;
19523
+ }
19524
+ function gadCallArgs(tool, args) {
19525
+ return { tool_name: tool, args };
19526
+ }
19527
+
19528
+ // src/commands/call.ts
19529
+ function callCommand() {
19530
+ return new Command("call").description("Call any Great Arrow tool by name (see 'gad discover')").argument("<tool>", "Tool name, e.g. memory_search").option("--args <json>", "Tool arguments as a JSON object").option("--json", "Output as JSON").action(async (tool, opts, command) => {
19531
+ const g = globalOutputOpts(command);
19532
+ const args = parseCallArgs(opts.args);
19533
+ const auth = await resolveAuth();
19534
+ const client = new GadClient({
19535
+ token: auth.token,
19536
+ getToken: auth.getToken,
19537
+ apiUrl: auth.apiUrl
19538
+ });
19539
+ const result = await client.mcpCall("gad_call", gadCallArgs(tool, args));
19540
+ const failure = callFailure(result);
19541
+ if (failure) {
19542
+ throw new CliError(
19543
+ `${tool}: ${failure.message}`,
19544
+ AUTH_ERROR_CODES.has(failure.code) ? 1 /* AUTH_ERROR */ : 3 /* VALIDATION_ERROR */,
19545
+ failure.code === "unknown_tool" ? `Find the exact name with 'gad discover' or 'gad call tools_discover --args '{"query":"..."}''.` : void 0
19546
+ );
19547
+ }
19548
+ if (typeof result === "string") {
19549
+ process.stdout.write(result.endsWith("\n") ? result : `${result}
19550
+ `);
19551
+ return;
19552
+ }
19553
+ process.stdout.write(
19554
+ `${g.json ? JSON.stringify(result) : JSON.stringify(result, null, 2)}
19555
+ `
19556
+ );
19557
+ });
19558
+ }
19559
+
19403
19560
  // src/lib/completions.ts
19404
19561
  var COMMANDS = [
19405
19562
  "login",
@@ -23042,6 +23199,7 @@ program2.addCommand(workspace_default);
23042
23199
  program2.addCommand(todo_default);
23043
23200
  program2.addCommand(nextCommand());
23044
23201
  program2.addCommand(discoverCommand());
23202
+ program2.addCommand(callCommand());
23045
23203
  program2.addCommand(claim_default);
23046
23204
  program2.addCommand(work_default());
23047
23205
  program2.addCommand(worktree_default);
@@ -23052,6 +23210,7 @@ program2.addCommand(doctorCommand());
23052
23210
  program2.addCommand(integrations_default);
23053
23211
  program2.addCommand(mcp_default);
23054
23212
  program2.addCommand(agentCommand);
23213
+ program2.addCommand(agentsCommand);
23055
23214
  program2.addCommand(askCommand());
23056
23215
  program2.addCommand(localCommand());
23057
23216
  program2.addCommand(smokeCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@great-arrow/cli",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "GreatArrow.ai CLI tool",
5
5
  "type": "module",
6
6
  "bin": {