@ghostystudio/cli 0.16.0 → 0.17.0

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 +9 -0
  2. package/dist/index.js +132 -24
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -87,6 +87,15 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
87
87
  - `try --replay FILE --out DIR`: replays real conversations from your machine. The report is written after every step, survives Ghosty deploys (it honors `Retry-After`), and `--resume` continues a partial run.
88
88
  - `agents doctor` speaks English like the rest of the CLI; `channels whatsapp ls` returns a full URL.
89
89
 
90
+ ### Changes in 0.17.0
91
+
92
+ - Agents by **name** everywhere: `ghosty agents get pia-0`, `ghosty try "Ghosty Ventas" "hola"` (ids still work). Same-name agents: the one in the `ghosty use` workspace wins, otherwise the CLI lists their ids.
93
+ - `ghosty use <workspace>`: default workspace for `boards`, `agents create` and `agents ls` (`--all`, `--workspace none`, `use --clear`).
94
+
95
+ ### Changes in 0.16.1
96
+
97
+ - `agents create --like`: `--board same|main|new|NAME` (`new` = its own board with the source's columns, one per number) and `--no-notify` (shared with the same people, no email).
98
+
90
99
  ### Changes in 0.16.0
91
100
 
92
101
  - `agents create --like <agent> [--copy-dbs] [--dry-run]`: a new agent with another's setup (skills and their switches, toolsets, connectors, voice, databases, documents, board, shares), never its prompt, env or channels.
package/dist/index.js CHANGED
@@ -288,7 +288,7 @@ async function postLong(path, body, timeoutMs = 9e5) {
288
288
  const req = httpsRequest(`${base}${path}`, {
289
289
  method: "POST",
290
290
  timeout: timeoutMs,
291
- headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.16.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
291
+ headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.17.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
292
292
  }, (res) => {
293
293
  let buf = "";
294
294
  res.on("data", (c) => buf += c);
@@ -330,7 +330,7 @@ async function request(path, opts = {}, retried = false) {
330
330
  method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
331
331
  headers: {
332
332
  authorization: `Bearer ${token}`,
333
- "user-agent": `ghosty-cli/${"0.16.0"}`,
333
+ "user-agent": `ghosty-cli/${"0.17.0"}`,
334
334
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
335
335
  ...opts.headers
336
336
  },
@@ -529,17 +529,21 @@ var need = (v, what, example) => {
529
529
  if (!v) throw usage(`Missing ${what}.`, `Example: ${example}`);
530
530
  return v;
531
531
  };
532
- async function agentsLs() {
532
+ async function agentsLs(workspace) {
533
533
  const r = await api("/api/v2/me/agents?client=cli");
534
- const rows = r.agentes.map((a) => ({
534
+ const list = workspace ? r.agentes.filter((a) => a.espacio?.nombre === workspace) : r.agentes;
535
+ const spaceOf = (a) => a.espacio?.tipo === "workspace" ? a.espacio.nombre : a.espacio?.tipo ?? "";
536
+ const rows = list.map((a) => ({
535
537
  id: a.id,
536
538
  name: a.nombre,
537
539
  engine: a.motor ?? a.origen,
538
540
  source: a.origen,
541
+ workspace: spaceOf(a),
539
542
  lastActivity: a.ultimaActividad ?? null,
540
543
  ...a.compartidoPor ? { sharedBy: a.compartidoPor } : {}
541
544
  }));
542
- out(rows, () => table(rows, ["id", "name", "engine", "lastActivity"]));
545
+ out(rows, () => `${table(rows, ["id", "name", "engine", "workspace", "lastActivity"])}${workspace ? `
546
+ ${dim(`only ${workspace} (ghosty use) \xB7 all: --all`)}` : ""}`);
543
547
  }
544
548
  function parseEnv(raw) {
545
549
  if (!raw) return void 0;
@@ -573,8 +577,8 @@ async function agentsCreate(v) {
573
577
  if (v.workspace) body.workspace = v.workspace;
574
578
  const channels = parseChannels(v.channels);
575
579
  if (channels) body.channels = channels;
576
- if (v.like) Object.assign(body, { like: v.like, ...v["copy-dbs"] ? { copyDbs: true } : {}, ...v["dry-run"] ? { dryRun: true } : {} });
577
- else if (v["dry-run"]) throw usage("--dry-run goes with --like (it lists what would be copied).");
580
+ if (v.like) Object.assign(body, { like: v.like, ...v["copy-dbs"] ? { copyDbs: true } : {}, ...v["dry-run"] ? { dryRun: true } : {}, ...v.board ? { board: v.board } : {}, ...v["no-notify"] ? { notify: false } : {} });
581
+ else if (v["dry-run"] || v.board || v["no-notify"]) throw usage("--dry-run, --board and --no-notify go with --like.");
578
582
  if (v.like && v["dry-run"]) {
579
583
  const p = await api("/api/v2/me/agents", { method: "POST", body });
580
584
  return out(p, () => `${dim(`like ${v.like} \xB7 ${p.engine ?? "?"} \xB7 ${p.model ?? "default"}${p.workspace ? ` \xB7 workspace ${p.workspace}` : ""}`)}
@@ -1269,7 +1273,7 @@ async function call(path, v, init = {}) {
1269
1273
  "x-ghosty-ts": ts,
1270
1274
  "x-ghosty-sig": sig,
1271
1275
  "content-type": "application/json",
1272
- "user-agent": `ghosty-cli/${"0.16.0"}`
1276
+ "user-agent": `ghosty-cli/${"0.17.0"}`
1273
1277
  },
1274
1278
  body: method === "GET" ? void 0 : raw
1275
1279
  });
@@ -2002,7 +2006,11 @@ Archive ${plan.matched} card(s) on \xAB${plan.board}\xBB? (reversible: a new mes
2002
2006
 
2003
2007
  // src/commands/boards.ts
2004
2008
  var enc8 = encodeURIComponent;
2005
- async function boardsCmd(sub, a1, a2, v) {
2009
+ async function boardsCmd(sub, a1, a2, v, context) {
2010
+ if (context && sub !== "assign") {
2011
+ if ((sub === "ls" || sub === "list" || !sub || sub === "move-cards") && !a1) a1 = context;
2012
+ else if ((sub === "create" || sub === "rm") && a1 && !a2) [a1, a2] = [context, a1];
2013
+ }
2006
2014
  switch (sub ?? "ls") {
2007
2015
  case "ls":
2008
2016
  case "list": {
@@ -2059,7 +2067,7 @@ var HELPS = {
2059
2067
  summary: "Create, inspect, change, check and delete agents.",
2060
2068
  usage: [
2061
2069
  "ghosty agents ls",
2062
- "ghosty agents create --name NAME [--engine E] [--model M] [--prompt TEXT | --prompt-file FILE] [--env K=V,\u2026] [--workspace SLUG] [--channels teams=off,\u2026] [--like AGENT [--copy-dbs] [--dry-run]]",
2070
+ "ghosty agents create --name NAME [--engine E] [--model M] [--prompt TEXT | --prompt-file FILE] [--env K=V,\u2026] [--workspace SLUG] [--channels teams=off,\u2026] [--like AGENT [--copy-dbs] [--board same|main|new|NAME] [--no-notify] [--dry-run]]",
2063
2071
  "ghosty agents get <agent-id> [--fields name,model,prompt] [--prompt-out FILE]",
2064
2072
  "ghosty agents set <agent-id> [--name] [--engine] [--model] [--prompt | --prompt-file] [--env K=V,\u2026] [--connect ID,\u2026] [--disconnect ID,\u2026] [--voice E:ID] [--voice-replies auto|off] [--auto-stage on|off] [--toolsets crm,sales | +crm,-sales]",
2065
2073
  "ghosty agents set <agent-id> --prompt-base <base-agent-id> --prompt-overlay overlay.json [--dry-run [--out FILE]] | --prompt-base none",
@@ -2079,6 +2087,8 @@ var HELPS = {
2079
2087
  ["--prompt-out FILE", "get: write the prompt to FILE (edit it and come back with set --prompt-file)"],
2080
2088
  ["--like AGENT", "create: copy that agent's setup (skills and their switches, toolsets, connectors, voice, databases, documents, board, shares) \u2014 not its prompt, env or channels. docs grant: the same documents"],
2081
2089
  ["--copy-dbs", "create --like: duplicate its databases with their rows instead of granting the same ones"],
2090
+ ["--board B", "create --like: same (the source's board, default) \xB7 main \xB7 new (a board named like the agent, with the source's columns: one board per number) \xB7 or an existing board"],
2091
+ ["--no-notify", "create --like: share it with the same people WITHOUT emailing them"],
2082
2092
  ["--workspace SLUG", "create: born in that workspace (you own or administer it), owned by its owner and active in its Teams"],
2083
2093
  ["--channels k=on|off,\u2026", "create/set: turn channels on/off: teams, web, whatsapp, messenger, wa (personal WhatsApp)"],
2084
2094
  ["--toolsets LIST", "set: gs tool groups it gets (crm, sales\u2026): a list replaces; +x / -x add or remove"],
@@ -2120,7 +2130,7 @@ var HELPS = {
2120
2130
  "ghosty agents share <id> ana@empresa.com --role admin",
2121
2131
  "ghosty agents get <id> --prompt-out PROMPT.md",
2122
2132
  "ghosty agents get <id> --fields toolsets,connectors # what it really has: effective toolsets, connectors connected + granted",
2123
- "ghosty agents create --name tania-mkt --like <pia-id> --dry-run",
2133
+ "ghosty agents create --name tania-mkt --like <pia-id> --board new --no-notify --dry-run",
2124
2134
  'ghosty agents docs grant <id> "Cat\xE1logo.pdf" "Precios.xlsx" \xB7 ghosty agents docs grant <id> --like <other-id>',
2125
2135
  "ghosty agents set <pia-id> --prompt-base <tania-id> --prompt-overlay capa.json --dry-run --out /tmp/pia.md",
2126
2136
  'ghosty agents demo <id> --slug guardias --on --vence "2026-10-15T20:00" --starter "Ens\xE9\xF1ame c\xF3mo empezar"',
@@ -2337,6 +2347,14 @@ HELPS.channels = {
2337
2347
  ],
2338
2348
  learn: `${REF}#canales-de-whatsapp`
2339
2349
  };
2350
+ HELPS.use = {
2351
+ summary: "A default workspace for this session (profile): boards take it without typing it, agents create is born there and agents ls lists only its agents.",
2352
+ usage: ["ghosty use # which one", "ghosty use <workspace>", "ghosty use --clear"],
2353
+ flags: [["--clear", "no default workspace"]],
2354
+ examples: ["ghosty use siiqtec", "ghosty boards ls", "ghosty agents create --name tania-mkt --like pia-0 --board new", "ghosty agents ls --all"],
2355
+ notes: ["Agents can be named instead of using their id anywhere; with several of the same name, the one in this workspace wins.", "agents create --workspace none makes a personal agent even with a default workspace."],
2356
+ learn: `${REF}#sesion`
2357
+ };
2340
2358
  HELPS.boards = {
2341
2359
  summary: "A WORKSPACE's sales boards: list them, create one (copying another's columns), choose where an agent sends its cards, and move cards between boards.",
2342
2360
  usage: [
@@ -2412,28 +2430,56 @@ function newer(a, b) {
2412
2430
  }
2413
2431
  async function latestVersion() {
2414
2432
  if (process.env.GHOSTY_NO_UPDATE_CHECK || process.env.CI) return null;
2415
- let cache = {};
2433
+ let cache2 = {};
2416
2434
  try {
2417
- cache = JSON.parse(await readFile9(FILE, "utf8"));
2435
+ cache2 = JSON.parse(await readFile9(FILE, "utf8"));
2418
2436
  } catch {
2419
2437
  }
2420
- if (!cache.checkedAt || Date.now() - cache.checkedAt > DAY) {
2438
+ if (!cache2.checkedAt || Date.now() - cache2.checkedAt > DAY) {
2421
2439
  try {
2422
2440
  const r = await fetch("https://registry.npmjs.org/@ghostystudio/cli/latest", { signal: AbortSignal.timeout(1500) });
2423
2441
  const latest = (await r.json()).version;
2424
- if (latest) cache = { latest, checkedAt: Date.now() };
2442
+ if (latest) cache2 = { latest, checkedAt: Date.now() };
2425
2443
  await mkdir4(dirname3(FILE), { recursive: true });
2426
- await writeFile4(FILE, JSON.stringify(cache));
2444
+ await writeFile4(FILE, JSON.stringify(cache2));
2427
2445
  } catch {
2428
2446
  }
2429
2447
  }
2430
- return cache.latest ?? null;
2448
+ return cache2.latest ?? null;
2431
2449
  }
2432
2450
  async function updateNotice(current) {
2433
2451
  const latest = await latestVersion();
2434
2452
  return latest && newer(latest, current) ? `Update available: ${current} \u2192 ${latest}. Run: ${UPGRADE}` : null;
2435
2453
  }
2436
2454
 
2455
+ // src/resolve.ts
2456
+ var looksLikeId = (s) => /^c[a-z0-9]{20,}$/.test(s) || /^[0-9a-f]{24}$/.test(s);
2457
+ function pickAgent(list, ref, workspace) {
2458
+ const want = ref.trim().toLowerCase();
2459
+ let hits = list.filter((a) => a.nombre.trim().toLowerCase() === want);
2460
+ if (hits.length > 1 && workspace) {
2461
+ const here = hits.filter((a) => a.espacio?.nombre === workspace);
2462
+ if (here.length) hits = here;
2463
+ }
2464
+ if (hits.length === 1) return hits[0].id;
2465
+ if (!hits.length) {
2466
+ const near = list.filter((a) => a.nombre.toLowerCase().includes(want)).slice(0, 5);
2467
+ throw new CliError(`No agent named "${ref}".`, EXIT.USAGE, near.length ? `Did you mean: ${near.map((a) => `${a.nombre} (${a.id})`).join(", ")}?` : "List them: ghosty agents ls");
2468
+ }
2469
+ const where = (a) => a.espacio?.tipo === "workspace" ? a.espacio.nombre : a.espacio?.tipo ?? "?";
2470
+ throw new CliError(`${hits.length} agents are named "${ref}".`, EXIT.USAGE, `Use the id:
2471
+ ${hits.map((a) => ` ${a.id} ${a.motor ?? ""} ${where(a)}`).join("\n")}`);
2472
+ }
2473
+ var cache = null;
2474
+ function listAgents() {
2475
+ cache ??= api("/api/v2/me/agents?client=cli").then((r) => r.agentes);
2476
+ return cache;
2477
+ }
2478
+ async function resolveAgent(ref, workspace) {
2479
+ if (!ref || looksLikeId(ref)) return ref;
2480
+ return pickAgent(await listAgents(), ref, workspace);
2481
+ }
2482
+
2437
2483
  // src/index.ts
2438
2484
  var HELP = `${bold("Usage:")} ghosty <command> [options]
2439
2485
 
@@ -2442,13 +2488,14 @@ ${bold("Session")}
2442
2488
  --device Sign in from another device with a link + code (auto over SSH/CI)
2443
2489
  logout Sign out and revoke this device's session
2444
2490
  whoami Show who you are signed in as
2491
+ use [workspace] Default workspace for boards, agents create and agents ls [--clear]
2445
2492
  usage Your plan and how much you've used this week and month
2446
2493
 
2447
2494
  ${bold("Agents")}
2448
2495
  agents ls List your agents
2449
2496
  agents create Create an agent --name [--engine] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
2450
2497
  [--workspace SLUG] [--channels teams=off,\u2026] born in a workspace, active in its Teams
2451
- [--like AGENT [--copy-dbs] [--dry-run]] with another agent's setup (not its prompt, env or channels)
2498
+ [--like AGENT [--copy-dbs] [--board same|main|new|NAME] [--no-notify] [--dry-run]] with another agent's setup (not its prompt, env or channels)
2452
2499
  agents get <id> Show an agent's config [--fields name,model,prompt] [--prompt-out FILE]
2453
2500
  agents set <id> Change identity or engine [--name] [--engine] [--model] [--prompt | --prompt-file FILE] [--env K=V,\u2026]
2454
2501
  [--connect google-drive,\u2026] [--disconnect \u2026] give/remove access to your connectors
@@ -2511,6 +2558,7 @@ ${bold("Your account")}
2511
2558
  docs [topic] Open the docs
2512
2559
 
2513
2560
  ${bold("Global options")}
2561
+ <agent> Everywhere: an agent's NAME (case-insensitive) or its id
2514
2562
  --json Machine-readable output (stdout is JSON only)
2515
2563
  --token <token> Use this token (or env GHOSTY_TOKEN). A gat_\u2026 agent token reaches only that agent.
2516
2564
  --profile <name> Use a separate saved session (or env GHOSTY_PROFILE), e.g. one per account
@@ -2521,7 +2569,7 @@ ${bold("Global options")}
2521
2569
  ${bold("Exit codes")} 0 ok \xB7 1 API error \xB7 2 usage error \xB7 3 not signed in
2522
2570
  ${dim("Note: `ghosty` may collide with another binary on your PATH (e.g. the Ghosty TUI). Check with `which -a ghosty`; run `npx @ghostystudio/cli` to be sure.")}
2523
2571
  ${dim("Docs: https://www.ghosty.studio/docs/cli")}`;
2524
- var COMMANDS = ["login", "logout", "whoami", "usage", "agents", "files", "skills", "mcp", "dbs", "turns", "try", "chat", "conversations", "schedule", "partner", "me", "channels", "board", "boards", "credentials", "docs", "help"];
2572
+ var COMMANDS = ["login", "logout", "whoami", "usage", "use", "agents", "files", "skills", "mcp", "dbs", "turns", "try", "chat", "conversations", "schedule", "partner", "me", "channels", "board", "boards", "credentials", "docs", "help"];
2525
2573
  var AGENTS_SUBS = ["ls", "create", "get", "set", "doctor", "docs", "share", "unshare", "shares", "rm", "restart", "demo", "box"];
2526
2574
  function unknown(what, input, known, helpCmd) {
2527
2575
  const s = suggest(input, known);
@@ -2531,6 +2579,45 @@ function showHelp() {
2531
2579
  if (process.stdout.isTTY && !process.env.NO_COLOR && !globals.json) process.stdout.write(BANNER + "\n\n");
2532
2580
  process.stdout.write(HELP + "\n");
2533
2581
  }
2582
+ function agentArgIndex(pos) {
2583
+ const [cmd, sub] = pos;
2584
+ switch (cmd) {
2585
+ case "agents":
2586
+ if (sub === "docs" || sub === "documents") return 3;
2587
+ return sub && !["ls", "list", "create", "new"].includes(sub) ? 2 : null;
2588
+ case "files":
2589
+ case "skills":
2590
+ case "mcp":
2591
+ case "dbs":
2592
+ case "db":
2593
+ case "turns":
2594
+ case "board":
2595
+ case "conversations":
2596
+ case "schedule":
2597
+ return 2;
2598
+ case "try":
2599
+ case "chat":
2600
+ return 1;
2601
+ case "channels":
2602
+ return pos[2] === "groups" ? 4 : 3;
2603
+ case "boards":
2604
+ return sub === "assign" ? 2 : null;
2605
+ default:
2606
+ return null;
2607
+ }
2608
+ }
2609
+ async function useCmd(slug, v) {
2610
+ const cfg = await readConfig();
2611
+ if (v.clear) {
2612
+ delete cfg.workspace;
2613
+ await writeConfig(cfg);
2614
+ return out({ workspace: null }, () => `${lavender("\u2713")} No default workspace.`);
2615
+ }
2616
+ if (!slug) return out({ workspace: cfg.workspace ?? null }, () => cfg.workspace ? `Workspace: ${bold(cfg.workspace)}` : dim("No default workspace. Set one: ghosty use <workspace>"));
2617
+ await api(`/api/v2/workspaces/${encodeURIComponent(slug)}/boards`);
2618
+ await writeConfig({ ...cfg, workspace: slug });
2619
+ return out({ workspace: slug }, () => `${lavender("\u2713")} Using ${bold(slug)}: boards, agents create and agents ls default to it. ${dim("(ghosty use --clear to stop)")}`);
2620
+ }
2534
2621
  async function main() {
2535
2622
  const { values: v, positionals: pos } = parseArgs({
2536
2623
  allowPositionals: true,
@@ -2604,12 +2691,15 @@ async function main() {
2604
2691
  "as-formmy": { type: "boolean" },
2605
2692
  like: { type: "string" },
2606
2693
  "copy-dbs": { type: "boolean" },
2694
+ "no-notify": { type: "boolean" },
2695
+ board: { type: "string" },
2607
2696
  only: { type: "string" },
2608
2697
  enable: { type: "string" },
2609
2698
  disable: { type: "string" },
2610
2699
  "columns-from": { type: "string" },
2611
2700
  to: { type: "string" },
2612
2701
  all: { type: "boolean" },
2702
+ clear: { type: "boolean" },
2613
2703
  q: { type: "string" },
2614
2704
  "prompt-out": { type: "string" },
2615
2705
  toolsets: { type: "string" },
@@ -2650,7 +2740,16 @@ async function main() {
2650
2740
  const tokens = splitTokens(pos, v);
2651
2741
  globals.token = tokens.session;
2652
2742
  globals.profile = v.profile;
2653
- if (v.version) return out({ version: "0.16.0" }, () => "0.16.0");
2743
+ if (v.version) return out({ version: "0.17.0" }, () => "0.17.0");
2744
+ const context = (await readConfig()).workspace;
2745
+ if (!explicitToken()?.startsWith("gat_")) {
2746
+ const at = agentArgIndex(pos);
2747
+ if (at !== null && pos[at]) pos[at] = await resolveAgent(pos[at], context);
2748
+ for (const f of ["like", "prompt-base"]) {
2749
+ const val = v[f];
2750
+ if (typeof val === "string" && val !== "none") v[f] = await resolveAgent(val, context);
2751
+ }
2752
+ }
2654
2753
  const [cmd, sub, a1, a2] = pos;
2655
2754
  if (cmd === "partner" && (v.help || !sub || sub === "help")) return out({ help: PARTNER_HELP }, () => PARTNER_HELP);
2656
2755
  const topic = cmd === "help" ? sub : v.help ? cmd : void 0;
@@ -2676,9 +2775,18 @@ async function main() {
2676
2775
  const me = await api("/api/v2/me");
2677
2776
  return out(me, () => `${bold(me.email)}${dim(` \xB7 ${new URL(process.env.GHOSTY_URL || "https://www.ghosty.studio").host}`)}`);
2678
2777
  }
2778
+ case "use":
2779
+ return useCmd(sub, v);
2679
2780
  case "agents":
2680
- if (sub === "ls" || sub === "list" || !sub) return agentsLs();
2681
- if (sub === "create" || sub === "new") return agentsCreate(v);
2781
+ if (sub === "ls" || sub === "list" || !sub) return agentsLs(v.all ? void 0 : context);
2782
+ if (sub === "create" || sub === "new") {
2783
+ if (v.workspace === "none") delete v.workspace;
2784
+ else if (!v.workspace && context) {
2785
+ v.workspace = context;
2786
+ if (!globals.json) info(dim(`workspace ${context} (from ghosty use; --workspace none for a personal agent)`));
2787
+ }
2788
+ return agentsCreate(v);
2789
+ }
2682
2790
  if (sub === "get") return agentsGet(a1, v.fields, v["prompt-out"]);
2683
2791
  if (sub === "share" || sub === "unshare" || sub === "shares") return agentsShare(sub, a1, a2, v);
2684
2792
  if (sub === "set") return agentsSet(a1, v);
@@ -2703,7 +2811,7 @@ async function main() {
2703
2811
  case "board":
2704
2812
  return boardCmd(sub, a1, v, a2);
2705
2813
  case "boards":
2706
- return boardsCmd(sub, a1, a2, v);
2814
+ return boardsCmd(sub, a1, a2, v, context);
2707
2815
  case "channels":
2708
2816
  if (a1 === "groups") return groupsCmd(pos.slice(3).filter((x) => x !== void 0), v);
2709
2817
  return channelsCmd(sub, a1, a2, pos.slice(4).join(" ") || void 0, v);
@@ -2738,7 +2846,7 @@ async function main() {
2738
2846
  throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
2739
2847
  }
2740
2848
  }
2741
- var notice = updateNotice("0.16.0").catch(() => null);
2849
+ var notice = updateNotice("0.17.0").catch(() => null);
2742
2850
  main().then(
2743
2851
  async () => {
2744
2852
  const n = await notice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Official Ghosty Studio CLI — configure, test and chat with your agents from the terminal. Built for humans and coding agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "scripts": {
17
17
  "build": "esbuild src/index.ts --bundle --platform=node --format=esm --target=node22 --outfile=dist/index.js --banner:js='#!/usr/bin/env node' --define:__VERSION__=\\\"$npm_package_version\\\"",
18
18
  "prepack": "npm run build",
19
- "test": "for t in flags prompt api rows wa-auth; do esbuild src/$t.test.ts --bundle --platform=node --format=esm --outfile=/tmp/ghosty-cli-$t.test.mjs --log-level=error || exit 1; done && node --test /tmp/ghosty-cli-*.test.mjs"
19
+ "test": "for t in flags prompt api rows wa-auth resolve; do esbuild src/$t.test.ts --bundle --platform=node --format=esm --outfile=/tmp/ghosty-cli-$t.test.mjs --log-level=error || exit 1; done && node --test /tmp/ghosty-cli-*.test.mjs"
20
20
  },
21
21
  "keywords": [
22
22
  "ghosty",