@ghostystudio/cli 0.55.0 → 0.56.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 +5 -0
  2. package/dist/index.js +37 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -109,6 +109,11 @@ Every command has its own help with examples: `ghosty <command> --help` or `ghos
109
109
 
110
110
  Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
111
111
 
112
+ ### Changes in 0.56.0
113
+
114
+ - `factory runs why <run> [--refresh]`: why a run got stuck or failed — category, impact, the critical step with its evidence and what to change next time (a healthy run doesn't call the model).
115
+ - `factory runs show --timing` lists stuck patterns (a command open 8+ min, the same command repeated, errors in a row, going back and forth, apt install in a box); `runs stats` counts runs with stuck alerts.
116
+
112
117
  ### Changes in 0.55.0
113
118
 
114
119
  - `factory runs show <run> --timing`: where a run's time and money went — each turn of each role (critic, @plan, @build, @check) with minutes, minutes in tools, model and USD; the clock split into working, waiting for a person and the rest (CI, queues); and the commands that took 60 s or more.
package/dist/index.js CHANGED
@@ -8468,7 +8468,7 @@ async function postLong(path, body, timeoutMs = 9e5) {
8468
8468
  const req = httpsRequest(`${base}${path}`, {
8469
8469
  method: "POST",
8470
8470
  timeout: timeoutMs,
8471
- headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.55.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8471
+ headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.56.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8472
8472
  }, (res) => {
8473
8473
  let buf = "";
8474
8474
  res.on("data", (c) => buf += c);
@@ -8510,7 +8510,7 @@ async function request(path, opts = {}, retried = false) {
8510
8510
  method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
8511
8511
  headers: {
8512
8512
  authorization: `Bearer ${token}`,
8513
- "user-agent": `ghosty-cli/${"0.55.0"}`,
8513
+ "user-agent": `ghosty-cli/${"0.56.0"}`,
8514
8514
  "accept-language": lang(),
8515
8515
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
8516
8516
  ...opts.headers
@@ -10404,7 +10404,7 @@ async function call(path, v, init = {}) {
10404
10404
  "x-ghosty-ts": ts,
10405
10405
  "x-ghosty-sig": sig,
10406
10406
  "content-type": "application/json",
10407
- "user-agent": `ghosty-cli/${"0.55.0"}`
10407
+ "user-agent": `ghosty-cli/${"0.56.0"}`
10408
10408
  },
10409
10409
  body: method === "GET" ? void 0 : raw
10410
10410
  });
@@ -12492,7 +12492,7 @@ var HELPS_ES = {
12492
12492
  ]
12493
12493
  },
12494
12494
  factory: {
12495
- summary: "Los pedidos de la Software Factory de un espacio (viven en su Teams): listarlos con tiempo y costo, ver uno (plan vigente, PR, preview, \xFAltimos eventos, qu\xE9 rol trabaja), ver en qu\xE9 se fue su tiempo y su dinero, los totales del espacio y corregir el t\xEDtulo de un pedido.",
12495
+ summary: "Los pedidos de la Software Factory de un espacio (viven en su Teams): listarlos con tiempo y costo, ver uno (plan vigente, PR, preview, \xFAltimos eventos, qu\xE9 rol trabaja), ver en qu\xE9 se fue su tiempo y su dinero y por qu\xE9 se ator\xF3 o fall\xF3, los totales del espacio y corregir el t\xEDtulo de un pedido.",
12496
12496
  replace: [['"Title"', '"T\xEDtulo"']],
12497
12497
  flags: [
12498
12498
  ["--workspace SLUG", "el espacio (default: el de ghosty use)"],
@@ -12501,6 +12501,7 @@ var HELPS_ES = {
12501
12501
  ["--limit N", "ls: cu\xE1ntos (default 30)"],
12502
12502
  ["--full", "show: imprime el plan vigente"],
12503
12503
  ["--timing", "show: cada turno de cada rol (cr\xEDtico, @plan, @build, @check) con minutos, minutos en tools, modelo y USD; el reloj del pedido partido en trabajando, esperando a una persona (plan o PR por aprobar) y lo dem\xE1s (CI, colas); y los comandos de 60 s o m\xE1s"],
12504
+ ["--refresh", "why: rehace el an\xE1lisis (se guarda la primera vez)"],
12504
12505
  ["--since 30d", "stats: cu\xE1nto hacia atr\xE1s (d\xEDas, default 30)"],
12505
12506
  ["--repo OWNER/REPO", "stats: s\xF3lo ese repo (due\xF1o/repo)"],
12506
12507
  ["-n, --dry-run", "rename: ense\xF1a el cambio, no cambia nada"],
@@ -12510,7 +12511,9 @@ var HELPS_ES = {
12510
12511
  "Leer pide ser miembro del espacio; renombrar, ser due\xF1o, admin o staff de Ghosty, y queda en bit\xE1cora (factory.run_rename). La tarjeta del room toma el t\xEDtulo nuevo en su siguiente refresco.",
12511
12512
  "Qui\xE9n es @plan o @build: ghosty agents ls --handle plan --workspace SLUG.",
12512
12513
  "stats: pedidos, % mezclados, mediana de minutos hasta el PR y hasta el merge, vueltas @check\u2192@build y CI rojo por pedido, y costo por pedido y por PR mezclado. El costo incluye el primer turno de @plan en el hilo, antes de que naciera el pedido.",
12513
- "--timing lee la transcripci\xF3n de cada rol: los motores sin una (ACP) salen con minutos y costo, pero sin comandos."
12514
+ "--timing lee la transcripci\xF3n de cada rol: los motores sin una (ACP) salen con minutos y costo, pero sin comandos. Tambi\xE9n lista los atascos: un comando abierto 8+ min, el mismo comando 4 veces, el mismo error 3 veces, ir y venir entre dos acciones, o apt install dentro de una caja.",
12515
+ "why: si el pedido no fue sano (atascos, @build de m\xE1s de 30 min, vueltas, CI rojo, escalado), una categor\xEDa (missing_service, unresolved_build_or_tests, fixed_strategy\u2026), el paso cr\xEDtico con su evidencia y qu\xE9 cambiar la pr\xF3xima vez. Un pedido sano no llama al modelo. Cuando un pedido cierra sin ser sano, el room recibe este resumen en su hilo.",
12516
+ "Mientras un rol trabaja, si se atora el room recibe un \u23F3 en el hilo y al rol se le dice qu\xE9 revisar; desde la segunda vez en el mismo pedido, quien lo pidi\xF3 recibe un push."
12514
12517
  ]
12515
12518
  }
12516
12519
  };
@@ -13244,11 +13247,12 @@ HELPS.audit = {
13244
13247
  learn: `${REF}#bitacora`
13245
13248
  };
13246
13249
  HELPS.factory = {
13247
- summary: "A workspace's Software Factory runs (they live in its Teams): list them with time and cost, see one (current plan, PR, preview, latest events, which role is working), see where its time and money went, totals for the workspace, and fix a run's title.",
13250
+ summary: "A workspace's Software Factory runs (they live in its Teams): list them with time and cost, see one (current plan, PR, preview, latest events, which role is working), see where its time and money went and why it got stuck or failed, totals for the workspace, and fix a run's title.",
13248
13251
  usage: [
13249
13252
  "ghosty factory runs ls [--workspace SLUG] [--room R] [--status S] [--limit 30]",
13250
13253
  "ghosty factory runs show <run> [--workspace SLUG] [--full]",
13251
13254
  "ghosty factory runs show <run> --timing [--workspace SLUG]",
13255
+ "ghosty factory runs why <run> [--refresh] [--workspace SLUG]",
13252
13256
  "ghosty factory runs stats [--since 30d] [--repo OWNER/REPO] [--workspace SLUG]",
13253
13257
  'ghosty factory runs rename <run> "Title" [--workspace SLUG] [--dry-run] [--yes]'
13254
13258
  ],
@@ -13259,13 +13263,14 @@ HELPS.factory = {
13259
13263
  ["--limit N", "ls: how many (default 30)"],
13260
13264
  ["--full", "show: print the current plan"],
13261
13265
  ["--timing", "show: each turn of each role (critic, @plan, @build, @check) with minutes, minutes in tools, model and USD; the run's clock split into working, waiting for a person (plan or PR to approve) and the rest (CI, queues); and the commands that took 60 s or more"],
13266
+ ["--refresh", "why: redo the analysis (it's saved the first time)"],
13262
13267
  ["--since 30d", "stats: how far back (days, default 30)"],
13263
13268
  ["--repo OWNER/REPO", "stats: only that repo"],
13264
13269
  ["-n, --dry-run", "rename: show the change, change nothing"],
13265
13270
  ["--yes", "rename: skip the confirmation (required without a terminal)"]
13266
13271
  ],
13267
- examples: ["ghosty factory runs ls --workspace business --room mailmask", "ghosty factory runs show 15 --workspace business", "ghosty factory runs show 31 --timing --workspace mercadito-verde", "ghosty factory runs stats --since 7d --workspace mercadito-verde", 'ghosty factory runs rename 15 "Docs del CLI al d\xEDa" --workspace business --dry-run'],
13268
- notes: ["Reading needs membership in the workspace; rename needs owner, admin or Ghosty staff, and is logged (factory.run_rename). The room's card picks the new title up on its next refresh.", "Who is @plan or @build: ghosty agents ls --handle plan --workspace SLUG.", "stats: runs, % merged, median minutes to PR and to merge, @check\u2192@build loops and red CI per run, and cost per run and per merged PR. The cost counts @plan's first turn in the thread, before the run existed.", "--timing reads each role's transcript: engines without one (ACP) show minutes and cost but no commands."],
13272
+ examples: ["ghosty factory runs ls --workspace business --room mailmask", "ghosty factory runs show 15 --workspace business", "ghosty factory runs show 13 --timing --workspace mercadito-verde", "ghosty factory runs why 13 --workspace mercadito-verde", "ghosty factory runs stats --since 7d --workspace mercadito-verde", 'ghosty factory runs rename 15 "Docs del CLI al d\xEDa" --workspace business --dry-run'],
13273
+ notes: ["Reading needs membership in the workspace; rename needs owner, admin or Ghosty staff, and is logged (factory.run_rename). The room's card picks the new title up on its next refresh.", "Who is @plan or @build: ghosty agents ls --handle plan --workspace SLUG.", "stats: runs, % merged, median minutes to PR and to merge, @check\u2192@build loops and red CI per run, and cost per run and per merged PR. The cost counts @plan's first turn in the thread, before the run existed.", "--timing reads each role's transcript: engines without one (ACP) show minutes and cost but no commands. It also lists stuck patterns: a command open 8+ min, the same command 4 times, the same error 3 times, going back and forth, or apt install inside a box.", "why: if the run wasn't healthy (stuck patterns, @build over 30 min, loops, red CI, escalated), a category (missing_service, unresolved_build_or_tests, fixed_strategy\u2026), the critical step with its evidence and what to change next time. A healthy run doesn't call the model. When a run closes unhealthy, the room gets this summary in its thread.", "While a role works, if it gets stuck the room gets a \u23F3 message in the thread and the role is told what to check; from the second time in the same run, whoever asked gets a push."],
13269
13274
  learn: `${REF}#fabrica`
13270
13275
  };
13271
13276
  function helpText(cmd) {
@@ -14125,7 +14130,7 @@ var mins = (n) => n === null || n === void 0 ? "\u2014" : n >= 120 ? `${(n / 60)
14125
14130
  var hhmm = (iso) => new Date(iso).toLocaleTimeString("es-MX", { hour: "2-digit", minute: "2-digit", hour12: false });
14126
14131
  var short2 = (s2) => (s2 ?? "").slice(0, 16).replace("T", " ");
14127
14132
  async function factoryCmd(sub, verb, ref, title, v, context) {
14128
- if (sub !== "runs") throw usage(t(`Unknown factory subcommand: ${sub ?? "(none)"}.`, `Subcomando de factory desconocido: ${sub ?? "(ninguno)"}.`), "ghosty factory runs ls|show|stats|rename \u2026");
14133
+ if (sub !== "runs") throw usage(t(`Unknown factory subcommand: ${sub ?? "(none)"}.`, `Subcomando de factory desconocido: ${sub ?? "(ninguno)"}.`), "ghosty factory runs ls|show|why|stats|rename \u2026");
14129
14134
  const ws = v.workspace ?? context;
14130
14135
  if (!ws) throw usage(t("Which workspace?", "\xBFQu\xE9 espacio?"), t("Add --workspace SLUG (or set one with ghosty use SLUG).", "Agrega --workspace SLUG (o fija uno con ghosty use SLUG)."));
14131
14136
  const base = `/api/v2/workspaces/${enc12(ws)}/factory/runs`;
@@ -14145,7 +14150,7 @@ ${dim(`${t("Detail", "Detalle")}: ghosty factory runs show <run> --workspace ${r
14145
14150
  bold(t(`${workspace} \xB7 last ${s2.sinceDays} days${s2.repo ? ` \xB7 ${s2.repo}` : ""}`, `${workspace} \xB7 \xFAltimos ${s2.sinceDays} d\xEDas${s2.repo ? ` \xB7 ${s2.repo}` : ""}`)),
14146
14151
  `${t("runs", "pedidos")}: ${s2.runs} \xB7 ${t("merged", "mezclados")}: ${s2.merged} (${s2.mergedPct ?? "\u2014"} %) ${dim(s2.byStatus.map((b) => `${b.status} ${b.runs}`).join(" \xB7 "))}`,
14147
14152
  `${t("median to PR", "mediana hasta el PR")}: ${mins(s2.medianMinutesToPr)} \xB7 ${t("to merge", "hasta el merge")}: ${mins(s2.medianMinutesToMerge)}`,
14148
- `${t("@check\u2192@build loops per run", "vueltas @check\u2192@build por pedido")}: ${s2.avgLoops ?? "\u2014"} \xB7 ${t("red CI per run", "CI rojo por pedido")}: ${s2.avgCiFails ?? "\u2014"}`,
14153
+ `${t("@check\u2192@build loops per run", "vueltas @check\u2192@build por pedido")}: ${s2.avgLoops ?? "\u2014"} \xB7 ${t("red CI per run", "CI rojo por pedido")}: ${s2.avgCiFails ?? "\u2014"}${s2.runsWithStuck !== void 0 ? ` \xB7 ${t("runs with stuck alerts", "pedidos con atascos")}: ${s2.runsWithStuck}` : ""}`,
14149
14154
  `${t("cost", "costo")}: ${money(s2.usd)} USD \xB7 ${t("per run", "por pedido")} ${money(s2.usdPerRun)} \xB7 ${bold(t(`per merged PR ${money(s2.usdPerMergedPr)}`, `por PR mezclado ${money(s2.usdPerMergedPr)}`))}`,
14150
14155
  ...s2.byRepo.length > 1 ? ["", table(s2.byRepo.map((b) => ({ repo: b.repo, runs: b.runs, merged: b.merged, usd: money(b.usd) })), ["repo", "runs", "merged", "usd"])] : []
14151
14156
  ].join("\n");
@@ -14178,10 +14183,26 @@ ${dim(`${t("Detail", "Detalle")}: ghosty factory runs show <run> --workspace ${r
14178
14183
  ...head,
14179
14184
  rows.length ? table(rows, cols) : dim(t("No turns found for this run.", "No hay turnos de este pedido.")),
14180
14185
  ...slow.length ? ["", bold(t("Slowest commands (\u2265 60 s)", "Comandos m\xE1s lentos (\u2265 60 s)")), ...slow.map((x) => ` ${hhmm(x.at)} @${x.role} ${x.secs === null ? red(t("no result", "sin resultado")) : mins(Math.round(x.secs / 6) / 10)} ${dim(`${x.tool}: ${x.input}`)}`)] : [],
14186
+ ...tm.steps.some((s2) => s2.flags?.length) ? ["", bold(t("Stuck patterns", "Atascos")), ...tm.steps.flatMap((s2) => (s2.flags ?? []).map((f) => ` ${hhmm(f.at)} @${s2.role} ${red(f.rule)}${f.count > 1 ? ` \xD7${f.count}` : ""}${f.secs ? ` ${mins(Math.round(f.secs / 6) / 10)}` : ""} ${dim(f.detail.slice(0, 120))}`)), dim(t(`Why: ghosty factory runs why ${tm.run} --workspace ${workspace}`, `Por qu\xE9: ghosty factory runs why ${tm.run} --workspace ${workspace}`))] : [],
14181
14187
  ...tm.steps.filter((s2) => s2.why).map((s2) => dim(` @${s2.role}: ${t("no timeline", "sin l\xEDnea de tiempo")} (${s2.why})`))
14182
14188
  ].join("\n");
14183
14189
  });
14184
14190
  }
14191
+ if (verb === "why") {
14192
+ const { why: w, workspace } = await api(`${path}/why`, v.refresh ? { body: { refresh: true } } : void 0);
14193
+ return out({ workspace, why: w }, () => {
14194
+ if (w.healthy) return `${lavender("\u2713")} #${w.runId} ${t("was healthy: no stuck patterns, no long @build, no loops, no red CI.", "fue sano: sin atascos, sin @build largo, sin vueltas ni CI rojo.")}`;
14195
+ const impact = { high: t("high", "alto"), medium: t("medium", "medio"), low: t("low", "bajo") }[w.impact] ?? w.impact;
14196
+ return [
14197
+ `${bold(`#${w.runId}`)} ${red(w.category)} ${dim(`\xB7 ${t("impact", "impacto")} ${impact} \xB7 ${w.source === "model" ? w.model ?? "model" : t("rules", "reglas")} \xB7 ${short2(w.createdAt)}`)}`,
14198
+ w.summary,
14199
+ dim(`${t("signals", "se\xF1ales")}: ${w.reasons.join("; ")}`),
14200
+ ...w.criticalStep ? ["", bold(t("Critical step", "Paso cr\xEDtico")), ` ${w.criticalStep.at ? hhmm(w.criticalStep.at) : "\u2014"} @${w.criticalStep.role ?? "?"} ${dim(w.criticalStep.command ?? "")}`, ` ${w.criticalStep.evidence}`] : [],
14201
+ ...w.actions.length ? ["", bold(t("Next time", "Para la pr\xF3xima")), ...w.actions.map((a) => ` ${lavender(a.type)} ${a.text}`)] : [],
14202
+ ...v.refresh ? [] : ["", dim(t("Saved analysis; --refresh redoes it.", "An\xE1lisis guardado; --refresh lo rehace."))]
14203
+ ].join("\n");
14204
+ });
14205
+ }
14185
14206
  if (verb === "show") {
14186
14207
  const { run: r } = await api(path);
14187
14208
  const lines = [
@@ -14209,7 +14230,7 @@ ${dim(t("Dry run: nothing changed.", "Simulacro: no se cambi\xF3 nada."))}`);
14209
14230
  const r = await api(path, { body: { title } });
14210
14231
  return out(r, () => `${lavender("\u2713")} ${line2} ${dim(t("(logged; the room card picks it up on its next refresh)", "(queda en bit\xE1cora; la tarjeta del room lo toma en su siguiente refresco)"))}`);
14211
14232
  }
14212
- throw usage(t(`Unknown runs subcommand: ${verb}.`, `Subcomando de runs desconocido: ${verb}.`), 'ghosty factory runs ls | show <run> [--timing] | stats [--since 30d] | rename <run> "title"');
14233
+ throw usage(t(`Unknown runs subcommand: ${verb}.`, `Subcomando de runs desconocido: ${verb}.`), 'ghosty factory runs ls | show <run> [--timing] | why <run> [--refresh] | stats [--since 30d] | rename <run> "title"');
14213
14234
  }
14214
14235
  async function agentsByHandle(handle, workspace) {
14215
14236
  const qs = new URLSearchParams({ handle, ...workspace ? { workspace } : {} });
@@ -14501,7 +14522,7 @@ ${bold("Workspaces")} ${dim("(changing them: Ghosty staff)")}
14501
14522
  staff ls [staff-email] [client-email] Ghosty staff assigned to client accounts (staff) [--all: also revoked]
14502
14523
  staff assign|unassign <staff> <client> Staff sees and runs that account's agents, documents, databases and boards as themselves (no keys, billing or transfers; logged) [--reason]
14503
14524
  audit ls The audit log: who changed what (agent page, channels, pauses, replies, transfers, "log in as") [--workspace SLUG] [--agent ID] [--actor EMAIL] [--action A] [--since 24h] [--limit N]
14504
- factory runs ls|show|stats|rename A workspace's Software Factory runs: list (time and cost), detail (plan, PR, preview, who is working), where the time and money went, totals, fix a title [--workspace SLUG] [--room R] [--status S] [show --timing] [stats --since 30d --repo R]
14525
+ factory runs ls|show|why|stats|rename A workspace's Software Factory runs: list (time and cost), detail (plan, PR, preview, who is working), where the time and money went, why it got stuck or failed, totals, fix a title [--workspace SLUG] [--room R] [--status S] [show --timing] [why --refresh] [stats --since 30d --repo R]
14505
14526
 
14506
14527
  ${bold("Agents")}
14507
14528
  agents ls List your agents [--engine E] [--ids: only ids, for xargs] \xB7 --user EMAIL --app all|android|ios|desktop: as their app sees it (staff)
@@ -14665,7 +14686,7 @@ ${bold("Espacios")} ${dim("(cambiarlos: staff de Ghosty)")}
14665
14686
  staff ls [correo-staff] [correo-cliente] Staff de Ghosty asignado a cuentas cliente (staff) [--all: tambi\xE9n revocadas]
14666
14687
  staff assign|unassign <staff> <cliente> El staff ve y opera agentes, documentos, bases y tableros de esa cuenta como s\xED mismo (sin llaves, cobro ni traspasos; queda en bit\xE1cora) [--reason]
14667
14688
  audit ls La bit\xE1cora: qui\xE9n cambi\xF3 qu\xE9 (ficha, canales, pausas, respuestas, traspasos, \xABentrar como\xBB) [--workspace SLUG] [--agent ID] [--actor CORREO] [--action A] [--since 24h] [--limit N]
14668
- factory runs ls|show|stats|rename Los pedidos de la Software Factory de un espacio: lista (tiempo y costo), detalle (plan, PR, preview, qui\xE9n trabaja), en qu\xE9 se fue el tiempo y el dinero, totales, corregir un t\xEDtulo [--workspace SLUG] [--room R] [--status S] [show --timing] [stats --since 30d --repo R]
14689
+ factory runs ls|show|why|stats|rename Los pedidos de la Software Factory de un espacio: lista (tiempo y costo), detalle (plan, PR, preview, qui\xE9n trabaja), en qu\xE9 se fue el tiempo y el dinero, por qu\xE9 se ator\xF3 o fall\xF3, totales, corregir un t\xEDtulo [--workspace SLUG] [--room R] [--status S] [show --timing] [why --refresh] [stats --since 30d --repo R]
14669
14690
 
14670
14691
  ${bold("Agentes")}
14671
14692
  agents ls Lista tus agentes [--engine E] [--ids: s\xF3lo ids, para xargs] \xB7 --user CORREO --app all|android|ios|desktop: como lo ve su app (staff)
@@ -14926,6 +14947,7 @@ async function main() {
14926
14947
  verbose: { type: "boolean" },
14927
14948
  full: { type: "boolean" },
14928
14949
  timing: { type: "boolean" },
14950
+ refresh: { type: "boolean" },
14929
14951
  repo: { type: "string" },
14930
14952
  "as-formmy": { type: "boolean" },
14931
14953
  "key-column": { type: "string" },
@@ -15063,7 +15085,7 @@ async function main() {
15063
15085
  const tokens = splitTokens(pos, v);
15064
15086
  globals.token = tokens.session;
15065
15087
  globals.profile = v.profile;
15066
- if (v.version) return out({ version: "0.55.0" }, () => "0.55.0");
15088
+ if (v.version) return out({ version: "0.56.0" }, () => "0.56.0");
15067
15089
  for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
15068
15090
  const context = (await readConfig()).workspace;
15069
15091
  if (!explicitToken()?.startsWith("gat_")) {
@@ -15229,7 +15251,7 @@ async function main() {
15229
15251
  throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
15230
15252
  }
15231
15253
  }
15232
- var notice = updateNotice("0.55.0").catch(() => null);
15254
+ var notice = updateNotice("0.56.0").catch(() => null);
15233
15255
  main().then(
15234
15256
  async () => {
15235
15257
  const n = await notice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.55.0",
3
+ "version": "0.56.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": {