@ghostystudio/cli 0.47.0 → 0.48.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 +4 -0
  2. package/dist/index.js +29 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -103,6 +103,10 @@ Every command has its own help with examples: `ghosty <command> --help` or `ghos
103
103
 
104
104
  Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
105
105
 
106
+ ### Changes in 0.48.0
107
+
108
+ - `agents teams on <id> <workspace> --factory plan,build,check`: make an agent those Software Factory roles in that workspace (same as «Team» in /factory; each role keeps its name and avatar). `agents teams ls` shows the roles it holds.
109
+
106
110
  ### Changes in 0.47.0
107
111
 
108
112
  - `agents set --quote` takes VAT rules for the house `cotizar` tool: `iva-incluido=true` (prices already include VAT), `iva.CATEGORY=16` (VAT for that category), `solo-factura=true` (VAT only when the customer asks for an invoice).
package/dist/index.js CHANGED
@@ -7462,6 +7462,13 @@ var SERVER_MESSAGES = [
7462
7462
  ["@{} ya est\xE1 ocupado por otro agente en este espacio: dale un handle propio", "@{} is already taken by another agent in this workspace: give it its own handle"],
7463
7463
  // — Activar en equipos de Teams (`agents teams`)
7464
7464
  ["@{} ya est\xE1 ocupado en {}", "@{} is already taken in {}"],
7465
+ ["la f\xE1brica no est\xE1 instalada en {}: inst\xE1lala desde /factory en Teams", "the Software Factory isn't installed in {}: install it from /factory in Teams"],
7466
+ ["la f\xE1brica no tiene el rol {}: usa {}", "the Software Factory has no role {}: use {}"],
7467
+ ["faltan los roles: {}", "missing the roles: {}"],
7468
+ ["@eval no existe en {}: act\xEDvalo desde /factory en Teams", "@eval doesn't exist in {}: turn it on from /factory in Teams"],
7469
+ ["@{} no existe en {}: reinstala la f\xE1brica desde /factory en Teams", "@{} doesn't exist in {}: reinstall the Software Factory from /factory in Teams"],
7470
+ ["@{} en {} es de otro agente, no de la f\xE1brica", "@{} in {} belongs to another agent, not to the Software Factory"],
7471
+ ["factory: lista de roles (plan, build, check, eval)", "factory: a list of roles (plan, build, check, eval)"],
7465
7472
  ["@{} est\xE1 reservado", "@{} is reserved"],
7466
7473
  ["los @handle {} a {}5 ya est\xE1n ocupados en {}", "handles @{} to @{}5 are already taken in {}"],
7467
7474
  ["no administras el equipo {}", "you don't administer the workspace {}"],
@@ -8422,7 +8429,7 @@ async function postLong(path, body, timeoutMs = 9e5) {
8422
8429
  const req = httpsRequest(`${base}${path}`, {
8423
8430
  method: "POST",
8424
8431
  timeout: timeoutMs,
8425
- headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.47.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8432
+ headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.48.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
8426
8433
  }, (res) => {
8427
8434
  let buf = "";
8428
8435
  res.on("data", (c) => buf += c);
@@ -8464,7 +8471,7 @@ async function request(path, opts = {}, retried = false) {
8464
8471
  method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
8465
8472
  headers: {
8466
8473
  authorization: `Bearer ${token}`,
8467
- "user-agent": `ghosty-cli/${"0.47.0"}`,
8474
+ "user-agent": `ghosty-cli/${"0.48.0"}`,
8468
8475
  "accept-language": lang(),
8469
8476
  ...opts.body !== void 0 ? { "content-type": "application/json" } : {},
8470
8477
  ...opts.headers
@@ -8965,7 +8972,7 @@ ${rows.length ? table(rows, ["email", "role", "accepted"]) : dim(t("Not shared w
8965
8972
  out(r, () => `${lavender("\u2713")} ${r.already ? t(`Already shared with ${r.email}`, `Ya estaba compartido con ${r.email}`) : t(`Shared with ${r.email}; they got an email`, `Compartido con ${r.email}; le lleg\xF3 un correo`)} ${dim(`(${r.role})`)}.`);
8966
8973
  }
8967
8974
  async function agentsTeams(sub, id, ws, v) {
8968
- const ex = "ghosty agents teams ls <agent-id> \xB7 on <agent-id> <workspace> [--handle x] \xB7 off <agent-id> <workspace> \xB7 rm <agent-id> <workspace> [--yes]";
8975
+ const ex = "ghosty agents teams ls <agent-id> \xB7 on <agent-id> <workspace> [--handle x | --factory plan,build,check] \xB7 off <agent-id> <workspace> \xB7 rm <agent-id> <workspace> [--yes]";
8969
8976
  if (sub !== "ls" && sub !== "on" && sub !== "off" && sub !== "rm") throw usage(t("Use ls, on, off or rm.", "Usa ls, on, off o rm."), ex);
8970
8977
  id = need(id, "agent id", ex);
8971
8978
  if (sub === "ls") {
@@ -8975,7 +8982,7 @@ async function agentsTeams(sub, id, ws, v) {
8975
8982
  const state = x.state ?? (x.active ? "on" : "off");
8976
8983
  return {
8977
8984
  workspace: x.slug,
8978
- handle: state === "off" ? dim(`(@${x.suggested})`) : `@${x.handle}`,
8985
+ handle: state === "off" ? dim(`(@${x.suggested})`) : `@${x.handle}` + (x.roles?.filter((h) => h !== x.handle).length ? dim(` + ${x.roles.filter((h) => h !== x.handle).map((h) => `@${h}`).join(" ")}`) : ""),
8979
8986
  state: !x.confirmed ? t("unconfirmed", "sin confirmar") : label[state] + (x.editable === false ? dim(t(" \xB7 not yours to change", " \xB7 no lo administras")) : "")
8980
8987
  };
8981
8988
  });
@@ -8992,6 +8999,13 @@ async function agentsTeams(sub, id, ws, v) {
8992
8999
  const r2 = await api(agentPath(id, `/teams?workspace=${encodeURIComponent(workspace)}`), { method: "DELETE", body: { workspace } });
8993
9000
  return out(r2, () => `${lavender("\u2713")} ${r2.wasActive ? t(`Paused in ${workspace}; it keeps its @handle.`, `En pausa en ${workspace}; conserva su @handle.`) : t(`It wasn't answering in ${workspace}.`, `No estaba contestando en ${workspace}.`)}`);
8994
9001
  }
9002
+ if (v.factory !== void 0) {
9003
+ if (v.handle) throw usage(t("Use --handle or --factory, not both.", "Usa --handle o --factory, no los dos."), ex);
9004
+ const roles = v.factory.split(",").map((x) => x.trim().replace(/^@/, "")).filter(Boolean);
9005
+ if (!roles.length) throw usage(t("--factory needs roles: plan,build,check (or eval).", "--factory necesita roles: plan,build,check (o eval)."), ex);
9006
+ const r2 = await api(agentPath(id, "/teams"), { method: "POST", body: { workspace, factory: roles } });
9007
+ return out(r2, () => `${lavender("\u2713")} ${t(`In ${workspace} it now is`, `En ${workspace} ahora es`)} ${r2.roles.map((x) => `@${x.handle}`).join(", ")}${dim(t(` (before: ${r2.roles.map((x) => x.previous ?? "\u2014").join(", ")})`, ` (antes: ${r2.roles.map((x) => x.previous ?? "\u2014").join(", ")})`))}. ${t("The next turn of each role runs on it.", "El siguiente turno de cada rol ya corre en \xE9l.")}`);
9008
+ }
8995
9009
  const r = await api(agentPath(id, "/teams"), { method: "POST", body: { workspace, ...v.handle ? { handle: v.handle } : {} } });
8996
9010
  out(r, () => `${lavender("\u2713")} ${r.changed ? t(`Answers in ${workspace} as @${r.handle}.`, `Contesta en ${workspace} como @${r.handle}.`) : t(`Already answering in ${workspace} as @${r.handle}.`, `Ya contestaba en ${workspace} como @${r.handle}.`)}`);
8997
9011
  }
@@ -9781,7 +9795,7 @@ async function call(path, v, init = {}) {
9781
9795
  "x-ghosty-ts": ts,
9782
9796
  "x-ghosty-sig": sig,
9783
9797
  "content-type": "application/json",
9784
- "user-agent": `ghosty-cli/${"0.47.0"}`
9798
+ "user-agent": `ghosty-cli/${"0.48.0"}`
9785
9799
  },
9786
9800
  body: method === "GET" ? void 0 : raw
9787
9801
  });
@@ -11269,7 +11283,7 @@ var HELPS_ES = {
11269
11283
  ["--voice-replies M", "set: auto = contesta con nota de voz cuando el cliente manda o pide audio; off = siempre texto"],
11270
11284
  ["--auto-stage on|off", "set: mueve solo las tarjetas del tablero tras cada turno del cliente (una llamada extra al modelo por turno)"],
11271
11285
  ["--quote k=v,\u2026", "set: config de la tool de casa `cotizar` \u2014 iva (0-100), iva-incluido=true (los precios del cat\xE1logo ya traen IVA), iva.CATEGORIA=16 (IVA de esa categor\xEDa del cat\xE1logo; iva.CATEGORIA= la quita), solo-factura=true (IVA s\xF3lo si el cliente pide factura), vigencia (d\xEDas), prefix (folio), moneda, empresa, rfc, telefono, correo, direccion, notas, color. Vac\xEDo lo borra (rfc=). El contador de folio no se toca"],
11272
- ["--catalog ARCHIVO", "set: el cat\xE1logo de la tool de casa `cotizar` desde un CSV (sku,nombre,precio[,unidad,categoria,descripcion]) o una lista JSON; reemplaza al anterior. Su `categoria` decide las reglas de IVA"],
11286
+ ["--catalog FILE", "set: el cat\xE1logo de la tool de casa `cotizar` desde un CSV (sku,nombre,precio[,unidad,categoria,descripcion]) o una lista JSON; reemplaza al anterior. Su `categoria` decide las reglas de IVA"],
11273
11287
  ["--verbose", "doctor: lista tambi\xE9n las revisiones que pasaron"],
11274
11288
  ["--user EMAIL", "doctor (staff de Ghosty): los agentes de esa persona \u2014 doctor, \xFAltimos turnos (estado, segundos, error y \xABfetched\xBB: si su app pidi\xF3 el hilo despu\xE9s de que termin\xF3 el turno), plan/bolsa y cajas (marca duplicadas); queda en bit\xE1cora"],
11275
11289
  ["--turns N", "doctor --user: cu\xE1ntos turnos recientes por agente (default 8, m\xE1x. 50)"],
@@ -11280,6 +11294,7 @@ var HELPS_ES = {
11280
11294
  ["--note TEXT", "docs replace/restore: por qu\xE9 cambi\xF3 (sale en docs history)"],
11281
11295
  ["--role R", "share: editor (lo configura y lo usa) o admin (adem\xE1s lo comparte); repetirlo sobre un correo ya compartido cambia el rol"],
11282
11296
  ["--handle NAME", "teams on: su @handle en ese equipo (default: sacado de su nombre, con sufijo si est\xE1 ocupado; @ghosty est\xE1 reservado). Sobre un equipo donde ya est\xE1, le cambia el handle"],
11297
+ ["--factory ROLES", "teams on: le pasa esos roles de la Software Factory del equipo (plan, build, check, eval; separados por comas) \u2014 lo mismo que \xABEquipo\xBB en /factory. Cada rol conserva su nombre y avatar; su siguiente turno ya corre en \xE9l. La f\xE1brica tiene que estar instalada ah\xED"],
11283
11298
  ["--yes", "rm: se salta la confirmaci\xF3n (obligatorio sin terminal)"],
11284
11299
  ["--slug NAME", "demo: nombre de la liga; se le agrega un c\xF3digo de 6 caracteres (/p/NAME-CODE)"],
11285
11300
  ["--expires DATE|no", 'demo: caducidad fija en la hora de tu m\xE1quina ("2026-10-15T20:00"); no = nunca'],
@@ -11684,6 +11699,7 @@ var HELPS = {
11684
11699
  "ghosty agents shares <agent-id>",
11685
11700
  "ghosty agents teams ls <agent-id> # Teams workspaces you administer: where it answers, is paused, and with which @handle",
11686
11701
  "ghosty agents teams on <agent-id> <workspace> [--handle NAME] # turn it on there (or change its @handle)",
11702
+ "ghosty agents teams on <agent-id> <workspace> --factory plan,build,check # make it the workspace's Software Factory roles",
11687
11703
  "ghosty agents teams off <agent-id> <workspace> # pause it there; it keeps its @handle",
11688
11704
  "ghosty agents teams rm <agent-id> <workspace> [--yes] # remove it from there; the agent stays",
11689
11705
  "ghosty agents restart <agent-id>",
@@ -11720,6 +11736,7 @@ var HELPS = {
11720
11736
  ["--note TEXT", "docs replace/restore: why it changed (shown in docs history)"],
11721
11737
  ["--role R", "share: editor (configures and uses it) or admin (also shares it); again on a shared email changes the role"],
11722
11738
  ["--handle NAME", "teams on: its @handle in that workspace (default: from its name, with a suffix if taken; @ghosty is reserved). On an active workspace it changes the handle"],
11739
+ ["--factory ROLES", "teams on: give it those Software Factory roles in that workspace (plan, build, check, eval; comma-separated) \u2014 the same as \xABTeam\xBB in /factory. Keeps each role's name and avatar; the next turn of each role runs on it. The factory must be installed there"],
11723
11740
  ["--yes", "rm: skip the confirmation (required without a terminal)"],
11724
11741
  ["--slug NAME", "demo: link name; a 6-char code is appended (/p/NAME-CODE)"],
11725
11742
  ["--expires DATE|no", `demo: fixed expiry in your machine's time ("2026-10-15T20:00"); no = never`],
@@ -11757,6 +11774,7 @@ var HELPS = {
11757
11774
  "ghosty agents set <id> --toolsets +crm",
11758
11775
  "ghosty agents share <id> ana@empresa.com --role admin",
11759
11776
  "ghosty agents teams on <id> abogados --handle licenciado",
11777
+ "ghosty agents teams on <id> mercadito-verde --factory plan,build,check",
11760
11778
  "ghosty agents get <id> --prompt-out PROMPT.md",
11761
11779
  "ghosty agents get <id> --fields toolsets,connectors # what it really has: effective toolsets, connectors connected + granted",
11762
11780
  "ghosty agents create --name tania-mkt --like <pia-id> --board new --no-notify --dry-run",
@@ -13429,7 +13447,7 @@ ${bold("Agents")}
13429
13447
  agents docs replace <id> <doc> New version (keeps name and access) --url URL | --file PATH [--note]
13430
13448
  agents docs history|restore <id> <doc> [n] Its versions; restore n as a new version
13431
13449
  agents share|unshare <id> <email> Share it without handing it over [--role editor|admin] \xB7 agents shares <id> lists them
13432
- agents teams ls|on|off|rm <id> [ws] Which Teams workspaces it answers in, and its @handle there [--handle x]
13450
+ agents teams ls|on|off|rm <id> [ws] Which Teams workspaces it answers in, and its @handle there [--handle x] [--factory plan,build,check: its Software Factory roles]
13433
13451
  agents rm <id> Delete an agent (owner only; asks you to type its name, or --yes) [--from-workspace: turn it off in Teams first]
13434
13452
  agents restart <id> Restart an ACP agent (needsRestart) so it loads new skills
13435
13453
  agents box <id> The machine serving it: is it on the new image? [--check PATH]\u2026 [--contains PATH=TEXT]\u2026 [--recycle [--reenv] [--force]]
@@ -13575,7 +13593,7 @@ ${bold("Agentes")}
13575
13593
  agents docs replace <id> <doc> Versi\xF3n nueva (conserva nombre y accesos) --url URL | --file RUTA [--note]
13576
13594
  agents docs history|restore <id> <doc> [n] Sus versiones; restaura la n como versi\xF3n nueva
13577
13595
  agents share|unshare <id> <correo> Comp\xE1rtelo sin cederlo [--role editor|admin] \xB7 agents shares <id> los lista
13578
- agents teams ls|on|off|rm <id> [equipo] En qu\xE9 equipos de Teams contesta y con qu\xE9 @handle [--handle x]
13596
+ agents teams ls|on|off|rm <id> [equipo] En qu\xE9 equipos de Teams contesta y con qu\xE9 @handle [--handle x] [--factory plan,build,check: sus roles de la Software Factory]
13579
13597
  agents rm <id> Borra un agente (s\xF3lo el due\xF1o; te pide escribir su nombre, o --yes) [--from-workspace: antes lo desactiva en Teams]
13580
13598
  agents restart <id> Reinicia un agente ACP (needsRestart) para que cargue skills nuevas
13581
13599
  agents box <id> La m\xE1quina que lo atiende: \xBFya trae la imagen nueva? [--check RUTA]\u2026 [--contains RUTA=TEXTO]\u2026 [--recycle [--reenv] [--force]]
@@ -13825,6 +13843,7 @@ async function main() {
13825
13843
  recycle: { type: "boolean" },
13826
13844
  role: { type: "string" },
13827
13845
  handle: { type: "string" },
13846
+ factory: { type: "string" },
13828
13847
  wake: { type: "string" },
13829
13848
  text: { type: "string" },
13830
13849
  sender: { type: "string" },
@@ -13898,7 +13917,7 @@ async function main() {
13898
13917
  const tokens = splitTokens(pos, v);
13899
13918
  globals.token = tokens.session;
13900
13919
  globals.profile = v.profile;
13901
- if (v.version) return out({ version: "0.47.0" }, () => "0.47.0");
13920
+ if (v.version) return out({ version: "0.48.0" }, () => "0.48.0");
13902
13921
  for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
13903
13922
  const context = (await readConfig()).workspace;
13904
13923
  if (!explicitToken()?.startsWith("gat_")) {
@@ -14058,7 +14077,7 @@ async function main() {
14058
14077
  throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
14059
14078
  }
14060
14079
  }
14061
- var notice = updateNotice("0.47.0").catch(() => null);
14080
+ var notice = updateNotice("0.48.0").catch(() => null);
14062
14081
  main().then(
14063
14082
  async () => {
14064
14083
  const n = await notice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghostystudio/cli",
3
- "version": "0.47.0",
3
+ "version": "0.48.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": {