@ghostystudio/cli 0.17.0 → 0.18.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 +12 -6
  2. package/dist/index.js +70 -27
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -24,7 +24,8 @@ ghosty agents share|unshare <id> <email> [--role editor|admin] # share without
24
24
  ghosty agents rm <id> [--yes]
25
25
  ghosty agents restart <id>
26
26
  ghosty agents box <id> [--check PATH]… [--contains PATH=TEXT]… [--recycle] # is its machine on the new image?
27
- ghosty agents demo <id> [--slug NAME] [--on | --off] [--vence "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N]
27
+ ghosty agents demo enable|disable <id>
28
+ ghosty agents demo <id> [--slug NAME] [--expires "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N]
28
29
  [--welcome TEXT] [--starter TEXT] [--chips "a|b|c"] [--sponsor on|off] [--rotate] # public /p/ link, no account needed
29
30
  ghosty agents doctor <id> [--verbose] # exits 1 when it finds a problem
30
31
  ghosty agents docs ls|grant|revoke <id> [doc] [--write] [--no-deliver]
@@ -33,7 +34,7 @@ ghosty agents set <id> --voice elevenlabs:ID --voice-replies auto --auto-stage o
33
34
 
34
35
  ghosty files ls|get|put|rm <id> [path] [--file LOCAL] [--out LOCAL]
35
36
  ghosty skills ls|get|add|rm <id> [slug] [--file SKILL.md | --dir FOLDER] [--out DIR] # get without --out only lists
36
- ghosty skills on|off <id> <slug> # turn one of its skills (or one of Ghosty's) on or off
37
+ ghosty skills enable|disable <id> <slug> # turn one of its skills (or one of Ghosty's) on or off
37
38
  ghosty skills templates <id> # pdf-doc templates: its own and Ghosty's, and which folder wins
38
39
  ghosty dbs ls|tables|query|import|grant|revoke <id> [db] [--write] [--arg V]… [--external-write t1,t2] [--external-rows t:col+col] [--from easybits:ID --tables a,b --append --dry-run]
39
40
  ghosty turns ls <id> [--errors | --status running|done|stopped|error] [--since 1h] [--limit N]
@@ -43,11 +44,11 @@ ghosty channels whatsapp link|unlink <id> --integration ID --answer on|off [--
43
44
  ghosty channels whatsapp history <id> --integration ID [--days 7] [--dry-run] # its recent cards, messages and orders (no duplicates)
44
45
  ghosty channels wa import <id> --from-file F | --from-dir DIR --own-number yes|no [--dry-run] # personal WhatsApp session, no QR
45
46
  ghosty channels wa pair|status|pause <id> [--phone N]
46
- ghosty channels wa groups ls|set|create <id> [group] [--role equipo|cliente] [--on|--off] [--dry-run] # personal WhatsApp groups
47
+ ghosty channels wa groups ls|enable|disable|set|create <id> [group] [--role equipo|cliente] [--dry-run] # personal WhatsApp groups
47
48
  ghosty boards ls|create|assign|move-cards|rm <workspace|agent> … [--columns-from main] [--from A --to B --integration X --dry-run]
48
- ghosty board ls <id> [--q TEXT] [--limit 20] # recent cards on its sales board
49
- ghosty board show <id> <folio|phone|id> [--limit 20] # a card's thread, attachments and whether gs kept a copy
50
- ghosty board archive <id> --integration X | --column X | --before 30d [--dry-run]
49
+ ghosty cards ls <id> [--q TEXT] [--limit 20] # recent cards on its sales board
50
+ ghosty cards show <id> <folio|phone|id> [--limit 20] # a card's thread, attachments and whether gs kept a copy
51
+ ghosty cards archive <id> --integration X | --column X | --before 30d [--dry-run]
51
52
  ghosty mcp get|set <id> [--file servers.json]
52
53
 
53
54
  ghosty try <id> "message" [--session] [--reset]
@@ -87,6 +88,11 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
87
88
  - `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
89
  - `agents doctor` speaks English like the rest of the CLI; `channels whatsapp ls` returns a full URL.
89
90
 
91
+ ### Changes in 0.18.0
92
+
93
+ - One naming rule (like `gh`): noun then verb; turning things on/off is `enable|disable`; `on|off` only as a flag value. `ghosty cards` (an agent's board cards; `board` still works), `skills enable|disable`, `agents demo enable|disable <agent>`, `channels wa groups enable|disable <agent> <group>`, `--expires` (was `--vence`). Old forms still work and print the new one.
94
+ - Help for `login`, `logout`, `whoami`, `docs`, `use` and `cards`.
95
+
90
96
  ### Changes in 0.17.0
91
97
 
92
98
  - 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.
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.17.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
291
+ headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.18.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.17.0"}`,
333
+ "user-agent": `ghosty-cli/${"0.18.0"}`,
334
334
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
335
335
  ...opts.headers
336
336
  },
@@ -1273,7 +1273,7 @@ async function call(path, v, init = {}) {
1273
1273
  "x-ghosty-ts": ts,
1274
1274
  "x-ghosty-sig": sig,
1275
1275
  "content-type": "application/json",
1276
- "user-agent": `ghosty-cli/${"0.17.0"}`
1276
+ "user-agent": `ghosty-cli/${"0.18.0"}`
1277
1277
  },
1278
1278
  body: method === "GET" ? void 0 : raw
1279
1279
  });
@@ -2079,7 +2079,8 @@ var HELPS = {
2079
2079
  "ghosty agents shares <agent-id>",
2080
2080
  "ghosty agents restart <agent-id>",
2081
2081
  "ghosty agents box <agent-id> [--check PATH]\u2026 [--contains PATH=TEXT]\u2026 [--recycle]",
2082
- 'ghosty agents demo <agent-id> [--slug NAME] [--on | --off] [--vence "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N] [--welcome TEXT] [--starter TEXT] [--chips "a|b|c"] [--sponsor on|off] [--rotate]',
2082
+ "ghosty agents demo enable|disable <agent-id>",
2083
+ 'ghosty agents demo <agent-id> [--slug NAME] [--expires "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N] [--welcome TEXT] [--starter TEXT] [--chips "a|b|c"] [--sponsor on|off] [--rotate]',
2083
2084
  "ghosty agents rm <agent-id> [--yes]"
2084
2085
  ],
2085
2086
  flags: [
@@ -2105,8 +2106,7 @@ var HELPS = {
2105
2106
  ["--role R", "share: editor (configures and uses it) or admin (also shares it); again on a shared email changes the role"],
2106
2107
  ["--yes", "rm: skip the confirmation (required without a terminal)"],
2107
2108
  ["--slug NAME", "demo: link name; a 6-char code is appended (/p/NAME-CODE)"],
2108
- ["--on | --off", "demo: turn the public link on or off"],
2109
- ["--vence DATE|no", `demo: fixed expiry in your machine's time ("2026-10-15T20:00"); no = never`],
2109
+ ["--expires DATE|no", `demo: fixed expiry in your machine's time ("2026-10-15T20:00"); no = never`],
2110
2110
  ["--turns N", "demo: messages per visitor (default 150)"],
2111
2111
  ["--per-ip N", "demo: messages per IP per day (default 30)"],
2112
2112
  ["--welcome TEXT", "demo: chat greeting (empty = default)"],
@@ -2133,7 +2133,8 @@ var HELPS = {
2133
2133
  "ghosty agents create --name tania-mkt --like <pia-id> --board new --no-notify --dry-run",
2134
2134
  'ghosty agents docs grant <id> "Cat\xE1logo.pdf" "Precios.xlsx" \xB7 ghosty agents docs grant <id> --like <other-id>',
2135
2135
  "ghosty agents set <pia-id> --prompt-base <tania-id> --prompt-overlay capa.json --dry-run --out /tmp/pia.md",
2136
- 'ghosty agents demo <id> --slug guardias --on --vence "2026-10-15T20:00" --starter "Ens\xE9\xF1ame c\xF3mo empezar"',
2136
+ "ghosty agents demo enable <id>",
2137
+ 'ghosty agents demo <id> --slug guardias --expires "2026-10-15T20:00" --starter "Ens\xE9\xF1ame c\xF3mo empezar"',
2137
2138
  "ghosty agents box <id> --contains /opt/claude-worker/skills/pdf-doc/render-doc.mjs=pdf-templates"
2138
2139
  ],
2139
2140
  notes: ["doctor exits 1 when it finds a problem, so it can gate a script or CI.", "A derived prompt can't be edited directly (409): change the base or the overlay, or unlink it with --prompt-base none.", "demo with no flags only prints its status: link, expiry, caps and numbers."],
@@ -2143,7 +2144,7 @@ var HELPS = {
2143
2144
  summary: "Skills of an agent (agentskills.io format: a folder with SKILL.md).",
2144
2145
  usage: [
2145
2146
  "ghosty skills ls <agent-id>",
2146
- "ghosty skills on|off <agent-id> <slug>",
2147
+ "ghosty skills enable|disable <agent-id> <slug>",
2147
2148
  "ghosty skills house <agent-id> [--only a,b | --enable a,b | --disable a,b] [--dry-run]",
2148
2149
  "ghosty skills get <agent-id> <slug> [--out DIR]",
2149
2150
  "ghosty skills templates <agent-id>",
@@ -2308,14 +2309,14 @@ HELPS.channels = {
2308
2309
  "ghosty channels wa pair <agent-id> --phone 5215512345678",
2309
2310
  "ghosty channels wa status|pause <agent-id>",
2310
2311
  "ghosty channels wa groups ls <agent-id> [--cached]",
2311
- "ghosty channels wa groups set <agent-id> <group> [--role equipo|cliente] [--on | --off] [--dry-run] [--yes]",
2312
+ "ghosty channels wa groups enable|disable <agent-id> <group> [--role equipo|cliente] [--dry-run] [--yes]",
2313
+ "ghosty channels wa groups set <agent-id> <group> --role equipo|cliente [--dry-run]",
2312
2314
  'ghosty channels wa groups create <agent-id> "Name" [--role equipo|cliente]'
2313
2315
  ],
2314
2316
  flags: [
2315
2317
  ["-n, --dry-run", "print the plan (+ starts answering, - stops) and change nothing"],
2316
- ["--yes", "enable / groups set --on: skip the confirmation (required without a terminal)"],
2318
+ ["--yes", "enable / groups enable: skip the confirmation (required without a terminal)"],
2317
2319
  ["--role R", "groups: equipo (the team: writes to databases, admin tools) or cliente (like any customer)"],
2318
- ["--on | --off", "groups set: the agent answers in that group, or stops"],
2319
2320
  ["--cached", "groups ls: don't ask WhatsApp for the live list (faster; may miss new groups)"],
2320
2321
  ["--integration ID", "link/unlink/history: the WhatsApp Business number's Integration id in Formmy"],
2321
2322
  ["--days N", "history: conversations active in the last N days (1-30, default 7)"],
@@ -2332,7 +2333,7 @@ HELPS.channels = {
2332
2333
  "ghosty channels whatsapp enable <id> 5512345678 --dry-run",
2333
2334
  "ghosty channels whatsapp disable <id> 5512345678",
2334
2335
  "ghosty channels wa groups ls <id>",
2335
- 'ghosty channels wa groups set <id> "Pia-cotizadora" --role equipo --on --dry-run',
2336
+ 'ghosty channels wa groups enable <id> "Pia-cotizadora" --role equipo --dry-run',
2336
2337
  "ghosty channels whatsapp link <id> --integration 6a3af395\u2026 --answer off --dry-run",
2337
2338
  "ghosty channels whatsapp history <id> --integration 6a3af395\u2026 --days 7 --dry-run",
2338
2339
  "ghosty channels wa import <id> --from-file pia-wa.json --own-number no --dry-run"
@@ -2347,6 +2348,16 @@ HELPS.channels = {
2347
2348
  ],
2348
2349
  learn: `${REF}#canales-de-whatsapp`
2349
2350
  };
2351
+ HELPS.login = {
2352
+ summary: "Sign in with your browser (OAuth2, no password here). An agent can run it for you: it prints the URL and waits.",
2353
+ usage: ["ghosty login", "ghosty login --device"],
2354
+ flags: [["--device", "sign in from another device with a link + code (automatic over SSH or CI)"], ["--profile NAME", "a separate saved session, e.g. one per account"]],
2355
+ examples: ["ghosty login", "ghosty login --profile cliente", "GHOSTY_TOKEN=gat_\u2026 ghosty agents get <id> # no login: an agent token"],
2356
+ learn: `${REF}#sesion`
2357
+ };
2358
+ HELPS.logout = { summary: "Sign out and revoke this device's session on the server.", usage: ["ghosty logout [--profile NAME]"], examples: ["ghosty logout"], learn: `${REF}#sesion` };
2359
+ HELPS.whoami = { summary: "Who you are signed in as (with --json, also your account's plan).", usage: ["ghosty whoami [--json]"], examples: ["ghosty whoami"], learn: `${REF}#sesion` };
2360
+ HELPS.docs = { summary: "Open the docs in your browser (with --json, just print the URL).", usage: ["ghosty docs [topic]"], examples: ["ghosty docs", "ghosty docs cli"], learn: REF };
2350
2361
  HELPS.use = {
2351
2362
  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
2363
  usage: ["ghosty use # which one", "ghosty use <workspace>", "ghosty use --clear"],
@@ -2375,12 +2386,12 @@ HELPS.boards = {
2375
2386
  notes: ["assign changes where NEW cards go; move-cards brings the existing ones (thread, orders, activity) with a new folio. A card whose conversation is already on the target board is skipped.", "Reading needs membership; changing needs owner or staff of the workspace.", "rm only deletes an empty board that is not the main one."],
2376
2387
  learn: `${REF}#tablero`
2377
2388
  };
2378
- HELPS.board = {
2379
- summary: "The agent's sales board. It belongs to the WORKSPACE: you must be a member, a shared agent is not enough.",
2389
+ HELPS.cards = {
2390
+ summary: "The cards on an agent's sales board (its board belongs to the WORKSPACE: you must be a member, a shared agent is not enough). The workspace's boards themselves: ghosty boards.",
2380
2391
  usage: [
2381
- "ghosty board ls <agent-id> [--q TEXT] [--limit 20]",
2382
- "ghosty board show <agent-id> <folio|phone|session|id> [--limit 20]",
2383
- "ghosty board archive <agent-id> [--integration ID] [--column NAME] [--before 30d|ISO] [--dry-run] [--yes]"
2392
+ "ghosty cards ls <agent-id> [--q TEXT] [--limit 20]",
2393
+ "ghosty cards show <agent-id> <folio|phone|session|id> [--limit 20]",
2394
+ "ghosty cards archive <agent-id> [--integration ID] [--column NAME] [--before 30d|ISO] [--dry-run] [--yes]"
2384
2395
  ],
2385
2396
  flags: [
2386
2397
  ["--q TEXT", "ls: cards whose name, phone or last message contains TEXT"],
@@ -2391,10 +2402,11 @@ HELPS.board = {
2391
2402
  ["-n, --dry-run", "count and show a sample, change nothing"],
2392
2403
  ["--yes", "skip the confirmation (required without a terminal)"]
2393
2404
  ],
2394
- examples: ["ghosty board ls <id> --q 7712", 'ghosty board show <id> "#12"', "ghosty board show <id> 5210000009922 --limit 50", "ghosty board archive <id> --integration prueba --dry-run", "ghosty board archive <id> --column Perdido --before 30d --yes"],
2405
+ examples: ["ghosty cards ls <id> --q 7712", 'ghosty cards show <id> "#12"', "ghosty cards show <id> 5210000009922 --limit 50", "ghosty cards archive <id> --integration prueba --dry-run", "ghosty cards archive <id> --column Perdido --before 30d --yes"],
2395
2406
  notes: ["show prints each message with who wrote it (customer, agent, operator), its attachment and whether gs keeps a copy of it.", "Archiving is reversible: when the customer writes again the card comes back. At least one filter is required."],
2396
2407
  learn: `${REF}#tablero`
2397
2408
  };
2409
+ HELPS.board = HELPS.cards;
2398
2410
  HELPS.conversations = HELPS.chat;
2399
2411
  HELPS.usage = { ...HELPS.me, summary: "Your plan and how much you've used this week and month.", usage: ["ghosty usage", "ghosty me usage"], examples: ["ghosty usage", "ghosty usage --json"], learn: `${REF}#uso` };
2400
2412
  function helpText(cmd) {
@@ -2480,6 +2492,34 @@ async function resolveAgent(ref, workspace) {
2480
2492
  return pickAgent(await listAgents(), ref, workspace);
2481
2493
  }
2482
2494
 
2495
+ // src/aliases.ts
2496
+ function normalizeArgs(pos, v) {
2497
+ const notes = [];
2498
+ const [cmd, sub] = pos;
2499
+ if (cmd === "cards") pos[0] = "board";
2500
+ else if (cmd === "board") notes.push("`ghosty board` is now `ghosty cards` (same subcommands).");
2501
+ if (cmd === "skills") {
2502
+ if (sub === "enable") pos[1] = "on";
2503
+ else if (sub === "disable") pos[1] = "off";
2504
+ else if (sub === "on" || sub === "off") notes.push(`\`skills ${sub}\` is now \`skills ${sub === "on" ? "enable" : "disable"}\`.`);
2505
+ }
2506
+ if (cmd === "agents" && sub === "demo") {
2507
+ if (pos[2] === "enable" || pos[2] === "disable") {
2508
+ v[pos[2] === "enable" ? "on" : "off"] = true;
2509
+ pos.splice(2, 1);
2510
+ } else if (v.on || v.off) notes.push(`\`agents demo <agent> --${v.on ? "on" : "off"}\` is now \`agents demo ${v.on ? "enable" : "disable"} <agent>\`.`);
2511
+ if (v.expires !== void 0) v.vence = v.expires;
2512
+ else if (v.vence !== void 0) notes.push("`--vence` is now `--expires`.");
2513
+ }
2514
+ if (cmd === "channels" && pos[2] === "groups") {
2515
+ if (pos[3] === "enable" || pos[3] === "disable") {
2516
+ v[pos[3] === "enable" ? "on" : "off"] = true;
2517
+ pos[3] = "set";
2518
+ } else if (pos[3] === "set" && (v.on || v.off)) notes.push(`\`groups set \u2026 --${v.on ? "on" : "off"}\` is now \`groups ${v.on ? "enable" : "disable"} <agent> <group>\` (set keeps --role).`);
2519
+ }
2520
+ return notes;
2521
+ }
2522
+
2483
2523
  // src/index.ts
2484
2524
  var HELP = `${bold("Usage:")} ghosty <command> [options]
2485
2525
 
@@ -2511,12 +2551,13 @@ ${bold("Agents")}
2511
2551
  agents rm <id> Delete an agent (owner only; asks you to type its name, or --yes)
2512
2552
  agents restart <id> Restart an ACP agent (needsRestart) so it loads new skills
2513
2553
  agents box <id> The machine serving it: is it on the new image? [--check PATH]\u2026 [--contains PATH=TEXT]\u2026 [--recycle]
2554
+ agents demo enable|disable <id> Turn its public demo link on or off
2514
2555
  agents demo <id> Public demo link /p/<slug>: anyone tries it without an account, "Keep it" clones it to theirs
2515
- [--slug NAME] [--on | --off] [--vence "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N] [--welcome TEXT] [--chips "a|b|c"] [--starter TEXT] [--sponsor on|off] [--rotate]
2556
+ [--slug NAME] [--expires "YYYY-MM-DDTHH:MM"|no] [--turns N] [--per-ip N] [--welcome TEXT] [--chips "a|b|c"] [--starter TEXT] [--sponsor on|off] [--rotate]
2516
2557
 
2517
2558
  ${bold("Configure an agent")}
2518
2559
  files ls|get|put|rm <id> [path] Files in the agent's machine [--file LOCAL] [--out LOCAL]
2519
- skills on|off <id> <slug> Turn one of its skills (or one of Ghosty's) on or off
2560
+ skills enable|disable <id> <slug> Turn one of its skills (or one of Ghosty's) on or off
2520
2561
  skills house <id> Ghosty's skills in bulk [--only a,b | --enable a,b | --disable a,b] [--dry-run]
2521
2562
  skills ls|get|add|rm <id> [slug] Skills (add from catalog, --file SKILL.md or --dir FOLDER; get lists, --out DIR saves; rm keeps a copy)
2522
2563
  skills templates <id> pdf-doc templates it sees: its own and Ghosty's, and which folder wins
@@ -2528,11 +2569,11 @@ ${bold("Configure an agent")}
2528
2569
  channels wa import <id> --from-file F | --from-dir DIR --own-number yes|no Move a personal WhatsApp session here, no QR [--dry-run] [--replace] [--no-connect]
2529
2570
  channels wa pair <id> --phone N Pair a personal WhatsApp by code (no QR)
2530
2571
  channels wa status|pause <id> Personal WhatsApp: how it is / pause it (keeps the session)
2531
- channels wa groups ls|set|create <id> [group] Personal WhatsApp groups it answers, and as whom [--role equipo|cliente] [--on|--off] [--dry-run]
2572
+ channels wa groups ls|enable|disable|set|create <id> [group] Personal WhatsApp groups it answers, and as whom [--role equipo|cliente] [--dry-run]
2532
2573
  boards ls|create|assign|move-cards|rm A workspace's boards: create (--columns-from), where an agent sends cards, move cards
2533
- board ls <id> Recent cards on its sales board [--q TEXT] [--limit 20]
2534
- board show <id> <card> A card's thread: who wrote, text, attachments and whether gs kept a copy (folio, phone or id)
2535
- board archive <id> Archive cards in bulk (reversible) --integration X | --column X | --before 30d [--dry-run]
2574
+ cards ls <id> Recent cards on its sales board [--q TEXT] [--limit 20]
2575
+ cards show <id> <card> A card's thread: who wrote, text, attachments and whether gs kept a copy (folio, phone or id)
2576
+ cards archive <id> Archive cards in bulk (reversible) --integration X | --column X | --before 30d [--dry-run]
2536
2577
 
2537
2578
  ${bold("Talk to an agent")}
2538
2579
  try <id> "message" One test turn, prints the full answer [--session] [--reset]
@@ -2569,7 +2610,7 @@ ${bold("Global options")}
2569
2610
  ${bold("Exit codes")} 0 ok \xB7 1 API error \xB7 2 usage error \xB7 3 not signed in
2570
2611
  ${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.")}
2571
2612
  ${dim("Docs: https://www.ghosty.studio/docs/cli")}`;
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"];
2613
+ var COMMANDS = ["login", "logout", "whoami", "usage", "use", "cards", "agents", "files", "skills", "mcp", "dbs", "turns", "try", "chat", "conversations", "schedule", "partner", "me", "channels", "board", "boards", "credentials", "docs", "help"];
2573
2614
  var AGENTS_SUBS = ["ls", "create", "get", "set", "doctor", "docs", "share", "unshare", "shares", "rm", "restart", "demo", "box"];
2574
2615
  function unknown(what, input, known, helpCmd) {
2575
2616
  const s = suggest(input, known);
@@ -2700,6 +2741,7 @@ async function main() {
2700
2741
  to: { type: "string" },
2701
2742
  all: { type: "boolean" },
2702
2743
  clear: { type: "boolean" },
2744
+ expires: { type: "string" },
2703
2745
  q: { type: "string" },
2704
2746
  "prompt-out": { type: "string" },
2705
2747
  toolsets: { type: "string" },
@@ -2740,7 +2782,8 @@ async function main() {
2740
2782
  const tokens = splitTokens(pos, v);
2741
2783
  globals.token = tokens.session;
2742
2784
  globals.profile = v.profile;
2743
- if (v.version) return out({ version: "0.17.0" }, () => "0.17.0");
2785
+ if (v.version) return out({ version: "0.18.0" }, () => "0.18.0");
2786
+ for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
2744
2787
  const context = (await readConfig()).workspace;
2745
2788
  if (!explicitToken()?.startsWith("gat_")) {
2746
2789
  const at = agentArgIndex(pos);
@@ -2846,7 +2889,7 @@ async function main() {
2846
2889
  throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
2847
2890
  }
2848
2891
  }
2849
- var notice = updateNotice("0.17.0").catch(() => null);
2892
+ var notice = updateNotice("0.18.0").catch(() => null);
2850
2893
  main().then(
2851
2894
  async () => {
2852
2895
  const n = await notice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.17.0",
3
+ "version": "0.18.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 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"
19
+ "test": "for t in flags prompt api rows wa-auth resolve aliases; 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",