@ghostystudio/cli 0.60.0 → 0.62.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 +8 -0
  2. package/dist/index.js +111 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -110,6 +110,14 @@ Every command has its own help with examples: `ghosty <command> --help` or `ghos
110
110
 
111
111
  Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
112
112
 
113
+ ### Changes in 0.62.0
114
+
115
+ - `support link <id> <owner/repo#12 | URL>` (staff): ties a case to the GitHub issue or PR that fixes it; when it closes, every tied customer gets "fixed" by email.
116
+
117
+ ### Changes in 0.61.0
118
+
119
+ - `support open --title T --body TEXT`: ask Ghosty for help; we answer by email and replying to that email adds to the case. `support ls | show <id> | reply <id>` follow your cases. Staff: `support ls|show|reply --all`, `support resolve|reopen <id>`.
120
+
113
121
  ### Changes in 0.60.0
114
122
 
115
123
  - `agents archive <id>` / `agents restore <id>`: archive an agent (it stops answering on every channel and leaves the lists; deleted automatically after 7 days) or bring it back as it was. `agents ls --archived` lists archived agents and when they get deleted.
package/dist/index.js CHANGED
@@ -8478,7 +8478,7 @@ async function postLong(path, body, timeoutMs = 9e5) {
8478
8478
  const req = httpsRequest(`${base}${path}`, {
8479
8479
  method: "POST",
8480
8480
  timeout: timeoutMs,
8481
- headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.60.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8481
+ headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.62.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8482
8482
  }, (res) => {
8483
8483
  let buf = "";
8484
8484
  res.on("data", (c) => buf += c);
@@ -8520,7 +8520,7 @@ async function request(path, opts = {}, retried = false) {
8520
8520
  method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
8521
8521
  headers: {
8522
8522
  authorization: `Bearer ${token}`,
8523
- "user-agent": `ghosty-cli/${"0.60.0"}`,
8523
+ "user-agent": `ghosty-cli/${"0.62.0"}`,
8524
8524
  "accept-language": lang(),
8525
8525
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
8526
8526
  ...opts.headers
@@ -10432,7 +10432,7 @@ async function call(path, v, init = {}) {
10432
10432
  "x-ghosty-ts": ts,
10433
10433
  "x-ghosty-sig": sig,
10434
10434
  "content-type": "application/json",
10435
- "user-agent": `ghosty-cli/${"0.60.0"}`
10435
+ "user-agent": `ghosty-cli/${"0.62.0"}`
10436
10436
  },
10437
10437
  body: method === "GET" ? void 0 : raw
10438
10438
  });
@@ -10933,6 +10933,16 @@ ${table(rows, ["table", "rows", "customer writes", "customer sees", "columns"])}
10933
10933
  ${dim(`${t(`${rows.length} row(s)`, `${rows.length} fila(s)`)} \xB7 ${Math.round(r.ms)} ms`)}`;
10934
10934
  });
10935
10935
  }
10936
+ case "origin": {
10937
+ db = need2(db, t("database (id or name)", "la base (id o nombre)"), "ghosty dbs origin <agent-id> <db> [--table T] [--since 2026-10-10] [--limit N]");
10938
+ const q = new URLSearchParams();
10939
+ if (v.table) q.set("table", v.table);
10940
+ if (v.since) q.set("since", v.since);
10941
+ if (v.limit) q.set("limit", v.limit);
10942
+ const r = await api(agentPath2(id, `/dbs/${enc6(db)}/origin${q.size ? `?${q}` : ""}`));
10943
+ const rows = r.writes.map((w) => ({ when: w.created_at, agent: w.agent_id.slice(0, 10), channel: w.canal ?? "", what: `${w.op} ${w.table_name}${w.row_id != null ? ` #${w.row_id}` : ""}`, customer: w.phone10 ?? "", why: w.reason ?? "" }));
10944
+ return out(r, () => rows.length ? table(rows, ["when", "agent", "channel", "what", "customer", "why"]) : dim(t("No agent writes recorded yet in this database.", "Todav\xEDa no hay escrituras de agentes registradas en esta base.")));
10945
+ }
10936
10946
  case "grant": {
10937
10947
  db = need2(db, t("database (id or name)", "la base (id o nombre)"), "ghosty dbs grant <agent-id> <db> [--external-write t1,t2] [--external-rows t:col+col]");
10938
10948
  let rowScope;
@@ -12230,6 +12240,7 @@ var HELPS_ES = {
12230
12240
  ["--rehost-images t.col,\u2026", "import: copia las ligas de imagen de esas columnas al almacenamiento p\xFAblico de Ghosty (ligas permanentes en img.ghosty.studio)"],
12231
12241
  ["--table T --column C", "rehost: la columna de ligas de imagen (p. ej. catalogo imagen_url) que se pasa a ligas permanentes en img.ghosty.studio; idempotente, una liga que falla se queda como estaba"],
12232
12242
  ["--key-column K --dir DIR", "photos put: cada archivo de DIR se llama como la clave de su fila (SKU-123.jpg \u2192 la fila donde K = SKU-123); va al almacenamiento permanente y su liga a --column (default imagen_url)"],
12243
+ ["--since DATE --limit N", "origin: escrituras de agentes desde esa fecha (p. ej. 2026-10-10), hasta N (default 50)"],
12233
12244
  ["-n, --dry-run", "import: imprime el plan (+ crear, ~ reemplazar N \u2192 M filas) y las filas que s\xF3lo existen en gs, no cambia nada \xB7 photos put: lista las claves sin fila y los archivos que no son imagen \xB7 rename: lista los prompts, env y skills que la nombran \xB7 rm: tablas, filas y agentes que la perder\xEDan"],
12234
12245
  ["--yes", "import, rm: se salta la confirmaci\xF3n (obligatorio sin terminal)"]
12235
12246
  ],
@@ -12516,6 +12527,16 @@ var HELPS_ES = {
12516
12527
  summary: "Staff de Ghosty: qu\xE9 avisos (push) se le mandaron a alguien (fin de turno, permiso, escalar, documento\u2026), a qu\xE9 dispositivo y qu\xE9 contest\xF3 Apple/Google. Se registran desde el 1-oct y se guardan 30 d\xEDas.",
12517
12528
  notes: ["thread ense\xF1a la clase de la conversaci\xF3n: un \xABchannel\xBB ah\xED es que le lleg\xF3 el aviso de un cliente.", "Tambi\xE9n salen los push de las novedades (kind novedad)."]
12518
12529
  },
12530
+ support: {
12531
+ summary: "Pide ayuda a Ghosty. Soporte es por correo: cada caso tiene su propia direcci\xF3n de respuesta, as\xED que contestar el correo (o escribir aqu\xED) cae en el mismo caso. Tambi\xE9n te lo abre tu agente: \xABrep\xF3rtalo a soporte\xBB.",
12532
+ notes: [
12533
+ "El caso lleva tu cuenta, tus agentes y sus errores recientes: no hace falta repetirlos.",
12534
+ "Contestar un caso resuelto lo reabre.",
12535
+ "El staff contesta desde su correo: /resuelto en la primera l\xEDnea cierra el caso.",
12536
+ "link liga un caso al issue o PR de GitHub que lo arregla; varios casos al mismo funcionan como tracker. Al cerrarse el issue como completado (o mergearse el PR) a cada cliente le llega \xABya qued\xF3\xBB y su caso se resuelve.",
12537
+ "Solo: al staff le llega un recordatorio tras 4 h sin respuesta; un caso esperando al cliente se cierra solo a los 7 d\xEDas (si contesta, se reabre)."
12538
+ ]
12539
+ },
12519
12540
  novedades: {
12520
12541
  summary: "Staff de Ghosty: las novedades de la app Android. Cada una con su ilustraci\xF3n; mismos frenos que el admin: pru\xE9bala en tu tel\xE9fono primero, push de 9 a 21 h CDMX, 72 h entre env\xEDos a todos.",
12521
12542
  notes: ["ls dice, de una ya enviada, cu\xE1ntos entreg\xF3 y rechaz\xF3 FCM (del push log, desde el 1-oct).", "--image se publica en img.ghosty.studio (WebP 1200 px). --to vac\xEDo = todos. send sin --at la manda ya (pregunta); --at '' quita la programaci\xF3n.", "--min-version N (versionCode de Android): si la app del tester es m\xE1s vieja, el bot\xF3n dice \xABActualizar\xBB y lanza la actualizaci\xF3n de Play desde la app; '' la quita."]
@@ -12806,6 +12827,7 @@ var HELPS = {
12806
12827
  "ghosty dbs ls <agent-id> [--orphans]",
12807
12828
  "ghosty dbs tables <agent-id> <db>",
12808
12829
  'ghosty dbs query <agent-id> <db> "SQL" [--arg V]\u2026 [--write]',
12830
+ "ghosty dbs origin <agent-id> <db> [--table T] [--since 2026-10-10] [--limit N]",
12809
12831
  "ghosty dbs export <agent-id> <db> [--table T] [--out FILE]",
12810
12832
  "ghosty dbs import <agent-id> <db> --from easybits:<db-id> [--tables a,b] [--append] [--rehost-images t.col,\u2026] [--dry-run] [--yes]",
12811
12833
  "ghosty dbs rehost <agent-id> <db> --table T --column C [--dry-run]",
@@ -12829,6 +12851,7 @@ var HELPS = {
12829
12851
  ["--rehost-images t.col,\u2026", "import: copy the image links in those columns to Ghosty's public storage (permanent links at img.ghosty.studio)"],
12830
12852
  ["--table T --column C", "rehost: the column of image links (e.g. catalogo imagen_url) to move to permanent links at img.ghosty.studio; idempotent, a link that fails stays as it was"],
12831
12853
  ["--key-column K --dir DIR", "photos put: each file in DIR is named after its row's key (SKU-123.jpg \u2192 the row where K = SKU-123); it goes to permanent storage and its link to --column (default imagen_url)"],
12854
+ ["--since DATE --limit N", "origin: agent writes since that date (e.g. 2026-10-10), up to N (default 50)"],
12832
12855
  ["-n, --dry-run", "import: print the plan (+ create, ~ replace N \u2192 M rows) and the rows that exist only in gs, change nothing \xB7 photos put: list keys with no row and files that aren't images \xB7 rename: list the prompts, env and skills that name it \xB7 rm: tables, rows and agents that would lose it"],
12833
12856
  ["--yes", "import, rm: skip the confirmation (required when not interactive)"]
12834
12857
  ],
@@ -13260,6 +13283,22 @@ HELPS.push = {
13260
13283
  notes: ["thread shows the conversation's kind: a \xABchannel\xBB there means a customer's push reached them.", "Announcement pushes appear too (kind novedad)."],
13261
13284
  learn: `${REF}#soporte`
13262
13285
  };
13286
+ HELPS.support = {
13287
+ summary: "Ask Ghosty for help. Support is by email: each case has its own reply address, so answering the email (or writing here) lands in the same case. Your agent can open one too: \xABreport it to support\xBB.",
13288
+ usage: [
13289
+ "ghosty support open --title T --body TEXT",
13290
+ "ghosty support ls",
13291
+ "ghosty support show <id>",
13292
+ "ghosty support reply <id> --body TEXT",
13293
+ "ghosty support ls|show --all [--status open|waiting_customer|resolved] (staff)",
13294
+ "ghosty support reply <id> --all --body TEXT [--resolve] (staff: emails the customer)",
13295
+ "ghosty support resolve|reopen <id> (staff)",
13296
+ "ghosty support link <id> <owner/repo#12 | issue/PR URL> (staff)"
13297
+ ],
13298
+ examples: ['ghosty support open --title "My agent stopped answering on WhatsApp" --body "Since yesterday 6 pm\u2026"', "ghosty support ls --all", 'ghosty support reply <id> --all --body "Fixed, try again" --resolve'],
13299
+ notes: ["The case carries your account, agents and recent errors, so you don't have to repeat them.", "Replying to a resolved case reopens it.", "Staff answer from their own inbox too: /resuelto on the first line closes the case.", "link ties a case to the GitHub issue or PR that fixes it; several cases on the same one act as a tracker. When the issue closes as completed (or the PR merges) each customer gets \xABya qued\xF3\xBB and the case resolves.", "Automatic: staff get a reminder after 4 h without an answer; a case waiting on the customer closes itself after 7 days (replying reopens it)."],
13300
+ learn: `${REF}#soporte`
13301
+ };
13263
13302
  HELPS.novedades = {
13264
13303
  summary: "Ghosty staff: the Android app's announcements (what's new). Each one needs its own illustration; same brakes as the admin: test on your phone first, push 9\u201321 h CDMX, 72 h between pushes to everyone.",
13265
13304
  usage: [
@@ -14661,6 +14700,59 @@ async function userDoctor(email, agent, v) {
14661
14700
  return lines.join("\n");
14662
14701
  });
14663
14702
  }
14703
+ var STATUS = (s2) => s2 === "open" ? t("open", "abierto") : s2 === "waiting_customer" ? t("waiting on customer", "esperando al cliente") : s2 === "resolved" ? t("resolved", "resuelto") : s2;
14704
+ async function supportCmd(sub, id, v) {
14705
+ if (!sub || sub === "ls" || sub === "list") {
14706
+ const q = new URLSearchParams({ ...v.status ? { status: v.status } : {}, ...v.limit ? { limit: v.limit } : {} });
14707
+ const r = v.all ? await api(`/api/v2/support/cases?${q}`) : await api("/api/v2/me/support");
14708
+ const rows = r.cases.map((c) => ({ id: c.id, code: c.code, status: STATUS(c.status), title: c.title.slice(0, 50), ...v.all ? { email: c.email } : {}, last: cdmx(c.lastMessageAt) }));
14709
+ return out(r, () => rows.length ? table(rows, v.all ? ["id", "code", "status", "title", "email", "last"] : ["id", "code", "status", "title", "last"]) : dim(t("No cases.", "Sin casos.")));
14710
+ }
14711
+ if (sub === "open") {
14712
+ if (!v.body) throw usage(t("Missing --body.", "Falta --body."), 'ghosty support open --title "\u2026" --body "\u2026"');
14713
+ const r = await api("/api/v2/me/support", { method: "POST", body: { title: v.title ?? "", body: v.body } });
14714
+ return out(r, () => `${lavender("\u2713")} ${t("Case", "Caso")} ${bold(r.case.code)} ${t("opened. We'll answer by email at", "abierto. Te contestamos por correo a")} ${r.case.email}.
14715
+ ${dim(r.case.id)}`);
14716
+ }
14717
+ if (!id) throw usage(t("Missing the case id.", "Falta el id del caso."), "ghosty support ls");
14718
+ if (sub === "show") {
14719
+ const r = v.all ? await api(`/api/v2/support/cases/${enc13(id)}`) : await api(`/api/v2/me/support/${enc13(id)}`);
14720
+ const c = r.case;
14721
+ return out(r, () => {
14722
+ const who2 = (a) => a === "staff" ? "Ghosty" : a === "agent" ? t("agent", "agente") : a === "customer" ? t("customer", "cliente") : a;
14723
+ const ctx = c.context;
14724
+ const lines = [
14725
+ `${bold(c.code)} ${c.title} ${dim(`\xB7 ${STATUS(c.status)} \xB7 ${c.email} \xB7 ${c.channel}`)}`,
14726
+ ...ctx?.plan ? [dim(` plan ${ctx.plan}`)] : [],
14727
+ ...(ctx?.agents ?? []).map((a) => dim(` ${a.name ?? a.id} ${a.engine}/${a.model ?? ""}`) + (a.failedTurns ? red(` \xB7 ${a.failedTurns} ${t("failed turns", "turnos con error")}`) : "")),
14728
+ ...ctx?.thread ? [dim(` ghosty conversations show ${ctx.thread.agentId} ${ctx.thread.sessionId} --why`)] : [],
14729
+ "",
14730
+ ...c.thread.map((m) => `${dim(cdmx(m.createdAt))} ${bold(who2(m.author))}${m.authorEmail ? dim(` ${m.authorEmail}`) : ""} ${dim(`(${m.via})`)}
14731
+ ${m.body}${m.attachments.length ? dim(`
14732
+ \u{1F4CE} ${m.attachments.map((a) => a.name).join(", ")}`) : ""}
14733
+ `)
14734
+ ];
14735
+ return lines.join("\n");
14736
+ });
14737
+ }
14738
+ if (sub === "reply") {
14739
+ if (!v.body && !v.resolve) throw usage(t("Missing --body.", "Falta --body."), 'ghosty support reply <id> --body "\u2026" [--resolve]');
14740
+ const r = v.all || v.resolve ? await api(`/api/v2/support/cases/${enc13(id)}`, { method: "POST", body: { intent: "reply", body: v.body ?? "", resolve: Boolean(v.resolve) } }) : await api(`/api/v2/me/support/${enc13(id)}`, { method: "POST", body: { body: v.body } });
14741
+ return out(r, () => `${lavender("\u2713")} ${r.case.code} \xB7 ${STATUS(r.case.status)}`);
14742
+ }
14743
+ if (sub === "link") {
14744
+ const ref = v.ref;
14745
+ if (!ref) throw usage(t("Missing the issue or PR.", "Falta el issue o PR."), "ghosty support link <id> owner/repo#12 (or the issue/PR URL)");
14746
+ const r = await api(`/api/v2/support/cases/${enc13(id)}`, { method: "POST", body: { intent: "link", ref } });
14747
+ return out(r, () => `${lavender("\u2713")} ${r.case.code} \u2192 ${bold(r.ref)} ${dim(`(${r.github.title})`)}${r.alsoWaiting ? `
14748
+ ${dim(t(`${r.alsoWaiting} more cases wait for the same fix: all get "fixed" when it closes.`, `Otros ${r.alsoWaiting} casos esperan el mismo arreglo: a todos les llega \xABya qued\xF3\xBB al cerrarse.`))}` : ""}`);
14749
+ }
14750
+ if (sub === "resolve" || sub === "reopen") {
14751
+ const r = await api(`/api/v2/support/cases/${enc13(id)}`, { method: "POST", body: { intent: sub } });
14752
+ return out(r, () => `${lavender("\u2713")} ${r.case.code} \xB7 ${STATUS(r.case.status)}`);
14753
+ }
14754
+ throw usage(t(`Unknown support subcommand: ${sub}.`, `Subcomando de support desconocido: ${sub}.`), "ghosty support ls | open | show | reply | resolve | reopen | link");
14755
+ }
14664
14756
 
14665
14757
  // src/index.ts
14666
14758
  var HELP_EN = `${bold("Usage:")} ghosty <command> [options]
@@ -14770,6 +14862,9 @@ ${bold("Support")} ${dim("(Ghosty staff)")}
14770
14862
  conversations show <id> <conv> --why A conversation: who sees it in their list / by link, and why
14771
14863
  turns stats Real failure rate by engine and error [--since 14d] [--all]
14772
14864
  push log --user EMAIL Pushes sent to someone and what Apple/Google answered [--since 2d]
14865
+ support ls|show|reply --all The support inbox; reply goes to the customer by email [--status open|waiting_customer|resolved] [--resolve]
14866
+ support resolve|reopen <id> Close a case (emails the customer) or reopen it
14867
+ support link <id> <issue|PR> Tie it to the GitHub fix: when it closes, every tied case gets "fixed" by email
14773
14868
  novedades ls|create|set|test|send|rm Android app announcements [--title] [--body] [--image FILE] [--link] [--to] [--min-version N] [--publish] [--at]
14774
14869
 
14775
14870
  ${bold("Sites")} ${dim("(sites your agents publish at <slug>.ghosty.page)")}
@@ -14816,6 +14911,8 @@ ${bold("Your account")}
14816
14911
  me memories ls|add|edit|rm What your agents remember about you (personal chats only) add "text" \xB7 edit <id> "text" \xB7 rm <id>
14817
14912
  credentials ls|set|rm [provider] Provider keys in your vault (hidden prompt, stdin or --from-env VAR; never as an argument)
14818
14913
  connectors ls|connect|disconnect [id] Your connectors (Shopify, Stripe, monday\u2026): connect opens the browser or asks for the key
14914
+ support open --title T --body TEXT Ask Ghosty for help; we answer by email (or ask your agent: "report it to support")
14915
+ support ls | show <id> | reply <id> --body TEXT Your support cases (replying to the email works too)
14819
14916
  docs [topic] Open the docs
14820
14917
 
14821
14918
  ${bold("Global options")}
@@ -14938,6 +15035,9 @@ ${bold("Soporte")} ${dim("(staff de Ghosty)")}
14938
15035
  conversations show <id> <conv> --why Una conversaci\xF3n: qui\xE9n la ve en su lista / por liga, y por qu\xE9
14939
15036
  turns stats Tasa real de fallos por motor y por error [--since 14d] [--all]
14940
15037
  push log --user CORREO Avisos que se le mandaron a alguien y qu\xE9 contest\xF3 Apple/Google [--since 2d]
15038
+ support ls|show|reply --all La bandeja de soporte; la respuesta le llega al cliente por correo [--status open|waiting_customer|resolved] [--resolve]
15039
+ support resolve|reopen <id> Cerrar un caso (le avisa al cliente) o reabrirlo
15040
+ support link <id> <issue|PR> Ligarlo al arreglo en GitHub: al cerrarse, a todos los casos ligados les llega \xABya qued\xF3\xBB
14941
15041
  novedades ls|create|set|test|send|rm Novedades de la app Android [--title] [--body] [--image ARCHIVO] [--link] [--to] [--min-version N] [--publish] [--at]
14942
15042
 
14943
15043
  ${bold("Sitios")} ${dim("(los sitios que publican tus agentes en <slug>.ghosty.page)")}
@@ -14984,6 +15084,8 @@ ${bold("Tu cuenta")}
14984
15084
  me memories ls|add|edit|rm Lo que tus agentes recuerdan de ti (s\xF3lo chats personales) add "texto" \xB7 edit <id> "texto" \xB7 rm <id>
14985
15085
  credentials ls|set|rm [proveedor] Llaves de proveedor en tu b\xF3veda (prompt oculto, stdin o --from-env VAR; nunca como argumento)
14986
15086
  connectors ls|connect|disconnect [id] Tus conectores (Shopify, Stripe, monday\u2026): connect abre el navegador o pide la llave
15087
+ support open --title T --body TEXTO Pide ayuda a Ghosty; te contestamos por correo (o dile a tu agente \xABrep\xF3rtalo a soporte\xBB)
15088
+ support ls | show <id> | reply <id> --body TEXTO Tus casos de soporte (contestar el correo tambi\xE9n sirve)
14987
15089
  docs [tema] Abre la documentaci\xF3n
14988
15090
 
14989
15091
  ${bold("Opciones globales")}
@@ -14999,7 +15101,7 @@ ${bold("Opciones globales")}
14999
15101
  ${bold("C\xF3digos de salida")} 0 bien \xB7 1 error de la API \xB7 2 uso incorrecto \xB7 3 sin sesi\xF3n
15000
15102
  ${dim("Nota: `ghosty` puede chocar con otro binario en tu PATH (p. ej. la TUI de Ghosty). Rev\xEDsalo con `which -a ghosty`; corre `npx @ghostystudio/cli` para ir a la segura.")}
15001
15103
  ${dim("Documentaci\xF3n: https://www.ghosty.studio/docs/cli")}`;
15002
- var COMMANDS = ["login", "logout", "whoami", "usage", "use", "apply", "plan", "engines", "bags", "spaces", "workspaces", "staff", "audit", "factory", "demos", "sites", "push", "novedades", "completion", "cards", "agents", "files", "skills", "mcp", "dbs", "turns", "try", "chat", "conversations", "schedule", "partner", "me", "channels", "board", "boards", "credentials", "connectors", "browser", "docs", "help"];
15104
+ var COMMANDS = ["login", "logout", "whoami", "usage", "use", "apply", "plan", "engines", "bags", "spaces", "workspaces", "staff", "audit", "factory", "demos", "sites", "push", "novedades", "completion", "cards", "agents", "files", "skills", "mcp", "dbs", "turns", "try", "chat", "conversations", "schedule", "partner", "me", "channels", "board", "boards", "credentials", "connectors", "browser", "support", "docs", "help"];
15003
15105
  var AGENTS_SUBS = ["ls", "create", "get", "set", "export", "doctor", "docs", "share", "unshare", "shares", "teams", "rm", "restart", "demo", "embed", "box"];
15004
15106
  function unknown(what, input, known, helpCmd) {
15005
15107
  const s2 = suggest(input, known);
@@ -15152,6 +15254,7 @@ async function main() {
15152
15254
  "columns-from": { type: "string" },
15153
15255
  to: { type: "string" },
15154
15256
  all: { type: "boolean" },
15257
+ resolve: { type: "boolean" },
15155
15258
  clear: { type: "boolean" },
15156
15259
  expires: { type: "string" },
15157
15260
  lang: { type: "string" },
@@ -15268,7 +15371,7 @@ async function main() {
15268
15371
  const tokens = splitTokens(pos, v);
15269
15372
  globals.token = tokens.session;
15270
15373
  globals.profile = v.profile;
15271
- if (v.version) return out({ version: "0.60.0" }, () => "0.60.0");
15374
+ if (v.version) return out({ version: "0.62.0" }, () => "0.62.0");
15272
15375
  for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
15273
15376
  const context = (await readConfig()).workspace;
15274
15377
  if (!explicitToken()?.startsWith("gat_")) {
@@ -15355,6 +15458,8 @@ async function main() {
15355
15458
  if (v["quota-hits"]) return workspaceUsage(v.workspace ?? context, v);
15356
15459
  if (sub === "stats") return turnStats(v);
15357
15460
  return turnsCmd(sub, a1, a2, v);
15461
+ case "support":
15462
+ return supportCmd(sub, a1, { ...v, ref: a2 });
15358
15463
  case "push":
15359
15464
  if (sub !== "log") throw usage(t("Unknown push subcommand.", "Subcomando de push desconocido."), "ghosty push log --user <email> [--since 2d]");
15360
15465
  return pushLog(v.user, v);
@@ -15435,7 +15540,7 @@ async function main() {
15435
15540
  throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
15436
15541
  }
15437
15542
  }
15438
- var notice = updateNotice("0.60.0").catch(() => null);
15543
+ var notice = updateNotice("0.62.0").catch(() => null);
15439
15544
  main().then(
15440
15545
  async () => {
15441
15546
  const n = await notice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.60.0",
3
+ "version": "0.62.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": {