@ghostystudio/cli 0.54.0 → 0.55.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.
- package/README.md +7 -1
- package/dist/index.js +77 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,12 @@ 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.55.0
|
|
113
|
+
|
|
114
|
+
- `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.
|
|
115
|
+
- `factory runs stats [--since 30d] [--repo owner/repo]`: runs, % merged, median minutes to PR and to merge, @check→@build loops, red CI per run, and cost per run and per merged PR.
|
|
116
|
+
- `factory runs ls` shows each run's time and cost.
|
|
117
|
+
|
|
112
118
|
### Changes in 0.54.0
|
|
113
119
|
|
|
114
120
|
- `agents embed <id> --copy '{json}'|none` and `--copy-file texts.json`: the phrases the web widget shows while the agent works (`waking`, `connecting`, `thinking` — 1–8 that rotate —, `stillWorking`, `cantStart`, `interrupted`, `retryLabel`, plain text ≤ 80 chars) and whether it shows the duration and the Copy button (`showDuration`, `showCopyButton`). Patch per key; `null` = Ghosty's phrase. `agents embed <id> theme` exports `copy` too, and `--out` bakes it into the component.
|
|
@@ -134,7 +140,7 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
|
|
|
134
140
|
- `channels whatsapp integrations` shows who answered each number last; `--orphans` and `channels messenger ls [--orphans]` list numbers/pages nobody answers today that had turns.
|
|
135
141
|
- `agents set --prompt-patch overlay.json` / `--prompt-append FILE [--dry-run]`: change one piece of the prompt on the server's current copy (dry run prints the diff).
|
|
136
142
|
- `audit ls [--workspace] [--agent] [--actor] [--action] [--since]`: the audit log. The agent page's Save and channel changes are logged now.
|
|
137
|
-
- `factory runs ls|show|rename` (a workspace's Software Factory runs) and `agents ls --handle build`.
|
|
143
|
+
- `factory runs ls|show|rename` (a workspace's Software Factory runs) and `agents ls --handle build`. Since 0.55: `show --timing` and `stats`.
|
|
138
144
|
|
|
139
145
|
### Changes in 0.49.0
|
|
140
146
|
|
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.
|
|
8471
|
+
headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.55.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.
|
|
8513
|
+
"user-agent": `ghosty-cli/${"0.55.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.
|
|
10407
|
+
"user-agent": `ghosty-cli/${"0.55.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, ver uno (plan vigente, PR, preview, \xFAltimos eventos, qu\xE9 rol trabaja) 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, 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)"],
|
|
@@ -12500,12 +12500,17 @@ var HELPS_ES = {
|
|
|
12500
12500
|
["--status S", "ls: s\xF3lo esa etapa (planning, building, checking, pr_review, merged\u2026)"],
|
|
12501
12501
|
["--limit N", "ls: cu\xE1ntos (default 30)"],
|
|
12502
12502
|
["--full", "show: imprime el plan vigente"],
|
|
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
|
+
["--since 30d", "stats: cu\xE1nto hacia atr\xE1s (d\xEDas, default 30)"],
|
|
12505
|
+
["--repo OWNER/REPO", "stats: s\xF3lo ese repo (due\xF1o/repo)"],
|
|
12503
12506
|
["-n, --dry-run", "rename: ense\xF1a el cambio, no cambia nada"],
|
|
12504
12507
|
["--yes", "rename: se salta la confirmaci\xF3n (obligatorio sin terminal)"]
|
|
12505
12508
|
],
|
|
12506
12509
|
notes: [
|
|
12507
12510
|
"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.",
|
|
12508
|
-
"Qui\xE9n es @plan o @build: ghosty agents ls --handle plan --workspace SLUG."
|
|
12511
|
+
"Qui\xE9n es @plan o @build: ghosty agents ls --handle plan --workspace SLUG.",
|
|
12512
|
+
"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."
|
|
12509
12514
|
]
|
|
12510
12515
|
}
|
|
12511
12516
|
};
|
|
@@ -13239,10 +13244,12 @@ HELPS.audit = {
|
|
|
13239
13244
|
learn: `${REF}#bitacora`
|
|
13240
13245
|
};
|
|
13241
13246
|
HELPS.factory = {
|
|
13242
|
-
summary: "A workspace's Software Factory runs (they live in its Teams): list them, see one (current plan, PR, preview, latest events, which role is working) and fix a run's title.",
|
|
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.",
|
|
13243
13248
|
usage: [
|
|
13244
13249
|
"ghosty factory runs ls [--workspace SLUG] [--room R] [--status S] [--limit 30]",
|
|
13245
13250
|
"ghosty factory runs show <run> [--workspace SLUG] [--full]",
|
|
13251
|
+
"ghosty factory runs show <run> --timing [--workspace SLUG]",
|
|
13252
|
+
"ghosty factory runs stats [--since 30d] [--repo OWNER/REPO] [--workspace SLUG]",
|
|
13246
13253
|
'ghosty factory runs rename <run> "Title" [--workspace SLUG] [--dry-run] [--yes]'
|
|
13247
13254
|
],
|
|
13248
13255
|
flags: [
|
|
@@ -13251,11 +13258,14 @@ HELPS.factory = {
|
|
|
13251
13258
|
["--status S", "ls: only that stage (planning, building, checking, pr_review, merged\u2026)"],
|
|
13252
13259
|
["--limit N", "ls: how many (default 30)"],
|
|
13253
13260
|
["--full", "show: print the current plan"],
|
|
13261
|
+
["--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"],
|
|
13262
|
+
["--since 30d", "stats: how far back (days, default 30)"],
|
|
13263
|
+
["--repo OWNER/REPO", "stats: only that repo"],
|
|
13254
13264
|
["-n, --dry-run", "rename: show the change, change nothing"],
|
|
13255
13265
|
["--yes", "rename: skip the confirmation (required without a terminal)"]
|
|
13256
13266
|
],
|
|
13257
|
-
examples: ["ghosty factory runs ls --workspace business --room mailmask", "ghosty factory runs show 15 --workspace business", 'ghosty factory runs rename 15 "Docs del CLI al d\xEDa" --workspace business --dry-run'],
|
|
13258
|
-
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."],
|
|
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."],
|
|
13259
13269
|
learn: `${REF}#fabrica`
|
|
13260
13270
|
};
|
|
13261
13271
|
function helpText(cmd) {
|
|
@@ -13613,11 +13623,11 @@ async function planCmd(sub, slug, v, context) {
|
|
|
13613
13623
|
if (!slug) throw usage(t("Missing workspace.", "Falta el espacio."), "ghosty plan apply <workspace> [--dry-run] (or ghosty use <workspace>)");
|
|
13614
13624
|
const path = `/api/v2/workspaces/${encodeURIComponent(slug)}/plan/apply`;
|
|
13615
13625
|
const plan = await api(path, { method: "POST", body: { dryRun: true } });
|
|
13616
|
-
const
|
|
13626
|
+
const money2 = (n) => `$${n.toLocaleString("es-MX")} MXN`;
|
|
13617
13627
|
const text = [
|
|
13618
13628
|
`${bold(plan.workspace)} ${dim(plan.scheduledFor ? t(`scheduled for ${plan.scheduledFor.slice(0, 10)}`, `programado para el ${plan.scheduledFor.slice(0, 10)}`) : "")}`,
|
|
13619
13629
|
...plan.changes.map((c) => ` ~ ${c.label}: ${String(c.from)} \u2192 ${String(c.to)}`),
|
|
13620
|
-
` ${t("monthly", "al mes")}: ${
|
|
13630
|
+
` ${t("monthly", "al mes")}: ${money2(plan.monthlyTotal.from)} \u2192 ${money2(plan.monthlyTotal.to)}`
|
|
13621
13631
|
].join("\n");
|
|
13622
13632
|
if (v["dry-run"]) return out(plan, () => `${text}
|
|
13623
13633
|
${dim(t("Dry run: nothing applied.", "Simulaci\xF3n: no se aplic\xF3 nada."))}`);
|
|
@@ -14110,21 +14120,68 @@ ${dim(t("Times in UTC. --full for the whole detail; --json for everything.", "Ho
|
|
|
14110
14120
|
|
|
14111
14121
|
// src/commands/factory.ts
|
|
14112
14122
|
var enc12 = encodeURIComponent;
|
|
14123
|
+
var money = (n) => n === null || n === void 0 ? "\u2014" : `$${n.toFixed(2)}`;
|
|
14124
|
+
var mins = (n) => n === null || n === void 0 ? "\u2014" : n >= 120 ? `${(n / 60).toFixed(1)} h` : `${n} min`;
|
|
14125
|
+
var hhmm = (iso) => new Date(iso).toLocaleTimeString("es-MX", { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
14113
14126
|
var short2 = (s2) => (s2 ?? "").slice(0, 16).replace("T", " ");
|
|
14114
14127
|
async function factoryCmd(sub, verb, ref, title, v, context) {
|
|
14115
|
-
if (sub !== "runs") throw usage(t(`Unknown factory subcommand: ${sub ?? "(none)"}.`, `Subcomando de factory desconocido: ${sub ?? "(ninguno)"}.`), "ghosty factory runs ls|show|rename \u2026");
|
|
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");
|
|
14116
14129
|
const ws = v.workspace ?? context;
|
|
14117
14130
|
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)."));
|
|
14118
14131
|
const base = `/api/v2/workspaces/${enc12(ws)}/factory/runs`;
|
|
14119
14132
|
if (!verb || verb === "ls" || verb === "list") {
|
|
14120
14133
|
const qs = new URLSearchParams({ ...v.room ? { room: v.room } : {}, ...v.status ? { status: v.status } : {}, ...v.limit ? { limit: v.limit } : {} });
|
|
14121
14134
|
const r = await api(`${base}?${qs}`);
|
|
14122
|
-
const rows = r.runs.map((x) => ({ run: `#${x.id}`, title: x.title.slice(0, 60), status: x.status, room: x.room ? `#${x.room}` : "", pr: x.pr ? x.pr.replace(/^https:\/\/github\.com\//, "") : "", updated: short2(x.updatedAt) }));
|
|
14123
|
-
return out(r, () => rows.length ? `${table(rows, ["run", "title", "status", "room", "pr", "updated"])}
|
|
14135
|
+
const rows = r.runs.map((x) => ({ run: `#${x.id}`, title: x.title.slice(0, 60), status: x.status, room: x.room ? `#${x.room}` : "", pr: x.pr ? x.pr.replace(/^https:\/\/github\.com\//, "") : "", time: mins(x.durationMin), usd: money(x.usd), updated: short2(x.updatedAt) }));
|
|
14136
|
+
return out(r, () => rows.length ? `${table(rows, ["run", "title", "status", "room", "pr", "time", "usd", "updated"])}
|
|
14124
14137
|
${dim(`${t("Detail", "Detalle")}: ghosty factory runs show <run> --workspace ${r.workspace}`)}` : dim(t(`No factory runs in ${r.workspace}.`, `No hay pedidos de la f\xE1brica en ${r.workspace}.`)));
|
|
14125
14138
|
}
|
|
14139
|
+
if (verb === "stats") {
|
|
14140
|
+
const qs = new URLSearchParams({ since: v.since ?? "30d", ...v.repo ? { repo: v.repo } : {} });
|
|
14141
|
+
const { stats: s2, workspace } = await api(`/api/v2/workspaces/${enc12(ws)}/factory/stats?${qs}`);
|
|
14142
|
+
return out({ workspace, stats: s2 }, () => {
|
|
14143
|
+
if (!s2.runs) return dim(t(`No factory runs in ${workspace} in the last ${s2.sinceDays} days.`, `No hay pedidos de la f\xE1brica en ${workspace} en los \xFAltimos ${s2.sinceDays} d\xEDas.`));
|
|
14144
|
+
return [
|
|
14145
|
+
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
|
+
`${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
|
+
`${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"}`,
|
|
14149
|
+
`${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
|
+
...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
|
+
].join("\n");
|
|
14152
|
+
});
|
|
14153
|
+
}
|
|
14126
14154
|
if (!ref) throw usage(t("Missing run.", "Falta el pedido."), `ghosty factory runs ${verb} <run> --workspace ${ws}`);
|
|
14127
14155
|
const path = `${base}/${enc12(ref.replace(/^#/, ""))}`;
|
|
14156
|
+
if (verb === "show" && v.timing) {
|
|
14157
|
+
const { timing: tm, workspace } = await api(`${path}/timing`);
|
|
14158
|
+
return out({ workspace, timing: tm }, () => {
|
|
14159
|
+
const c = tm.clock;
|
|
14160
|
+
const head = [
|
|
14161
|
+
`${bold(`#${tm.run}`)} ${dim(`\xB7 ${tm.status} \xB7 ${t("loops", "vueltas")} ${tm.loops} \xB7 ${t("red CI", "CI rojo")} ${tm.ciFails}`)} \xB7 ${bold(money(tm.usd))} USD`,
|
|
14162
|
+
`${t("clock", "reloj")}: ${mins(c.totalMinutes)} = ${t("working", "trabajando")} ${mins(c.workingMinutes)} \xB7 ${t("waiting for a person", "esperando a una persona")} ${mins(c.waitingHumanMinutes)} \xB7 ${t("other (CI, queues)", "lo dem\xE1s (CI, colas)")} ${mins(c.otherMinutes)}`,
|
|
14163
|
+
dim(c.byState.map((b) => `${b.state} ${mins(b.minutes)}`).join(" \u2192 ")),
|
|
14164
|
+
""
|
|
14165
|
+
];
|
|
14166
|
+
const rows = tm.steps.map((s2) => ({
|
|
14167
|
+
[t("at", "hora")]: hhmm(s2.startedAt),
|
|
14168
|
+
[t("step", "paso")]: `@${s2.role ?? "?"}${s2.critic ? t(" (critic)", " (cr\xEDtico)") : ""}${s2.prePlan ? t(" (thread)", " (hilo)") : ""}`,
|
|
14169
|
+
[t("time", "tiempo")]: s2.state === "running" ? `${mins(s2.minutes)} \u2026` : mins(s2.minutes),
|
|
14170
|
+
[t("in tools", "en tools")]: mins(s2.toolMinutes),
|
|
14171
|
+
model: (s2.model ?? "\u2014").replace(/^claude-/, ""),
|
|
14172
|
+
usd: money(s2.usd),
|
|
14173
|
+
[t("state", "estado")]: s2.state === "error" ? red(s2.state) : s2.state
|
|
14174
|
+
}));
|
|
14175
|
+
const cols = Object.keys(rows[0] ?? {});
|
|
14176
|
+
const slow = tm.steps.flatMap((s2) => s2.slow.map((x) => ({ ...x, role: s2.role })));
|
|
14177
|
+
return [
|
|
14178
|
+
...head,
|
|
14179
|
+
rows.length ? table(rows, cols) : dim(t("No turns found for this run.", "No hay turnos de este pedido.")),
|
|
14180
|
+
...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}`)}`)] : [],
|
|
14181
|
+
...tm.steps.filter((s2) => s2.why).map((s2) => dim(` @${s2.role}: ${t("no timeline", "sin l\xEDnea de tiempo")} (${s2.why})`))
|
|
14182
|
+
].join("\n");
|
|
14183
|
+
});
|
|
14184
|
+
}
|
|
14128
14185
|
if (verb === "show") {
|
|
14129
14186
|
const { run: r } = await api(path);
|
|
14130
14187
|
const lines = [
|
|
@@ -14152,7 +14209,7 @@ ${dim(t("Dry run: nothing changed.", "Simulacro: no se cambi\xF3 nada."))}`);
|
|
|
14152
14209
|
const r = await api(path, { body: { title } });
|
|
14153
14210
|
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)"))}`);
|
|
14154
14211
|
}
|
|
14155
|
-
throw usage(t(`Unknown runs subcommand: ${verb}.`, `Subcomando de runs desconocido: ${verb}.`), 'ghosty factory runs ls | show <run> | rename <run> "title"');
|
|
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"');
|
|
14156
14213
|
}
|
|
14157
14214
|
async function agentsByHandle(handle, workspace) {
|
|
14158
14215
|
const qs = new URLSearchParams({ handle, ...workspace ? { workspace } : {} });
|
|
@@ -14444,7 +14501,7 @@ ${bold("Workspaces")} ${dim("(changing them: Ghosty staff)")}
|
|
|
14444
14501
|
staff ls [staff-email] [client-email] Ghosty staff assigned to client accounts (staff) [--all: also revoked]
|
|
14445
14502
|
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]
|
|
14446
14503
|
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]
|
|
14447
|
-
factory runs ls|show|rename
|
|
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]
|
|
14448
14505
|
|
|
14449
14506
|
${bold("Agents")}
|
|
14450
14507
|
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)
|
|
@@ -14608,7 +14665,7 @@ ${bold("Espacios")} ${dim("(cambiarlos: staff de Ghosty)")}
|
|
|
14608
14665
|
staff ls [correo-staff] [correo-cliente] Staff de Ghosty asignado a cuentas cliente (staff) [--all: tambi\xE9n revocadas]
|
|
14609
14666
|
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]
|
|
14610
14667
|
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]
|
|
14611
|
-
factory runs ls|show|rename
|
|
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]
|
|
14612
14669
|
|
|
14613
14670
|
${bold("Agentes")}
|
|
14614
14671
|
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)
|
|
@@ -14868,6 +14925,8 @@ async function main() {
|
|
|
14868
14925
|
action: { type: "string" },
|
|
14869
14926
|
verbose: { type: "boolean" },
|
|
14870
14927
|
full: { type: "boolean" },
|
|
14928
|
+
timing: { type: "boolean" },
|
|
14929
|
+
repo: { type: "string" },
|
|
14871
14930
|
"as-formmy": { type: "boolean" },
|
|
14872
14931
|
"key-column": { type: "string" },
|
|
14873
14932
|
"unset-env": { type: "string" },
|
|
@@ -15004,7 +15063,7 @@ async function main() {
|
|
|
15004
15063
|
const tokens = splitTokens(pos, v);
|
|
15005
15064
|
globals.token = tokens.session;
|
|
15006
15065
|
globals.profile = v.profile;
|
|
15007
|
-
if (v.version) return out({ version: "0.
|
|
15066
|
+
if (v.version) return out({ version: "0.55.0" }, () => "0.55.0");
|
|
15008
15067
|
for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
|
|
15009
15068
|
const context = (await readConfig()).workspace;
|
|
15010
15069
|
if (!explicitToken()?.startsWith("gat_")) {
|
|
@@ -15170,7 +15229,7 @@ async function main() {
|
|
|
15170
15229
|
throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
|
|
15171
15230
|
}
|
|
15172
15231
|
}
|
|
15173
|
-
var notice = updateNotice("0.
|
|
15232
|
+
var notice = updateNotice("0.55.0").catch(() => null);
|
|
15174
15233
|
main().then(
|
|
15175
15234
|
async () => {
|
|
15176
15235
|
const n = await notice;
|
package/package.json
CHANGED