@ghostystudio/cli 0.100.0 → 0.103.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 +10 -3
- package/dist/index.js +85 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ ghosty files ls|get|put|rm <id> [path] [--file LOCAL] [--out LOCAL]
|
|
|
64
64
|
ghosty skills ls|get|add|rm <id> [slug] [--file SKILL.md | --dir FOLDER] [--out DIR] # get without --out only lists
|
|
65
65
|
ghosty skills enable|disable <id> <slug> # turn one of its skills (or one of Ghosty's) on or off
|
|
66
66
|
ghosty skills templates <id> # pdf-doc templates: its own and Ghosty's, and which folder wins
|
|
67
|
-
ghosty dbs ls|tables|query|export|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]
|
|
67
|
+
ghosty dbs ls|create|tables|query|export|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]
|
|
68
68
|
ghosty turns ls <id> [--errors | --status running|done|stopped|error] [--since 1h] [--limit N]
|
|
69
69
|
ghosty turns ls --workspace SLUG --quota-hits [--days 14] # messages that got no turn because the balance ran out
|
|
70
70
|
ghosty turns show <id> [turn-id|last] # what came in, what it answered, where the time went [--full]
|
|
@@ -79,7 +79,7 @@ ghosty channels messenger on|off <id> <page> [--take] # this agent answers the
|
|
|
79
79
|
ghosty channels mteams connect <id> --app-id <guid> --tenant <guid> # Microsoft Teams bot (secret in GHOSTY_MTEAMS_SECRET); ls shows endpoint and last problem
|
|
80
80
|
ghosty channels wa import <id> --from-file F | --from-dir DIR --own-number yes|no [--dry-run] # personal WhatsApp session, no QR
|
|
81
81
|
ghosty channels wa pair|status|pause <id> [--phone N]
|
|
82
|
-
ghosty channels wa groups ls|enable|disable|set|create <id> [group] [--role equipo|cliente] [--wake mention|all] [--dry-run] # personal WhatsApp groups
|
|
82
|
+
ghosty channels wa groups ls|enable|disable|set|create <id> [group] [--role equipo|cliente] [--wake mention|name|all] [--dry-run] # personal WhatsApp groups
|
|
83
83
|
ghosty boards ls|create|assign|move-cards|access|rm <workspace|agent> … [--columns-from main] [--from A --to B --integration X --dry-run] [--add|--remove EMAIL --until 14d]
|
|
84
84
|
ghosty spaces members ls|add|rm <workspace> [email] [--role member|admin] [--until 2026-10-28|14d]
|
|
85
85
|
ghosty access why <email> <agent-id> | --workspace W --board B
|
|
@@ -157,6 +157,12 @@ Every command has its own help with examples: `ghosty <command> --help` or `ghos
|
|
|
157
157
|
|
|
158
158
|
Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
|
|
159
159
|
|
|
160
|
+
### Changes in 0.103.0
|
|
161
|
+
|
|
162
|
+
- `agents set --quote catalogo_base=DB:TABLE`: the house `cotizar` tool reads its catalog from a table of a granted database, so the owner edits prices on the web, by CSV or by chatting with the agent (`catalogo_base=` goes back to the `--catalog` list, which stays as the fallback).
|
|
163
|
+
- New `dbs create <id> <name> [--description] [--read] [--no-grant]` and `dbs import <id> <db> --from csv:FILE --table T [--append] [--dry-run]`.
|
|
164
|
+
- `agents set --quote plantilla=@quote.html,logo=…,comercial=…,numeros=es`: your own PDF template for quotes.
|
|
165
|
+
|
|
160
166
|
### Changes in 0.100.0
|
|
161
167
|
|
|
162
168
|
- `app ls | suggest <build> | min <build> --yes [--platform ios|android|notch]` (staff): the apps' version gates without opening /admin/settings. `suggest` raises the dismissible "update" notice (do it once the build is live in the store); `min` stops older builds and asks for confirmation; `min` can never be above `suggest`. Only that number changes; the emergency flags stay in the panel. Logged as `platform.app-config`.
|
|
@@ -297,6 +303,7 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
|
|
|
297
303
|
|
|
298
304
|
### Changes in 0.57.1 (0.57.0 + the 0.56.1 factory fix)
|
|
299
305
|
|
|
306
|
+
- `sites rm <slug> [--yes]`: delete one of your sites (stops being served, files removed, slot freed if pinned; can't be undone).
|
|
300
307
|
- `sites pin <slug>` / `sites unpin <slug>` / `sites pins [--cancel|--resume]`: «Pinned sites» — $49 USD/yr or $5 USD/mo ($990 / $99 MXN), includes up to 3 sites per pack; a pinned site never pauses and has no banner. `--interval year|month`, `--currency usd|mxn`, `--add-pack`.
|
|
301
308
|
- `sites ls` shows each site's state (pinned, paused, pauses on…).
|
|
302
309
|
|
|
@@ -407,7 +414,7 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
|
|
|
407
414
|
- `agents ls --user --app` also lists their phones with the app build. `novedades ls` shows how many FCM delivered and rejected; announcement pushes show up in `push log`.
|
|
408
415
|
- `novedades create|set --min-version N`: if the app is older, its button reads «Actualizar». `turns stats` breaks down by channel (Teams and A2A included).
|
|
409
416
|
- `schedule add --conversation wa:<jid>` answers in that WhatsApp group/chat. `channels wa pair` warns that in Mexico `52…` and `521…` are different accounts.
|
|
410
|
-
- `channels wa groups set <agent> <group> --wake mention|all`: in `mention` (default when you turn a group on) the agent only answers when @-mentioned, named or replied to; the rest reaches it as context. `ls` shows the column.
|
|
417
|
+
- `channels wa groups set <agent> <group> --wake mention|name|all`: in `mention` (default when you turn a group on) the agent only answers when @-mentioned, named or replied to; the rest reaches it as context. `ls` shows the column. `--alias "tilin"` adds other names that wake it in that group (comma-separated, `""` clears).
|
|
411
418
|
- `channels wa groups enable|disable` now work (they were in the help but got rejected).
|
|
412
419
|
|
|
413
420
|
### Changes in 0.31.0
|
package/dist/index.js
CHANGED
|
@@ -1190,7 +1190,7 @@ async function postLong(path2, body, timeoutMs = 9e5) {
|
|
|
1190
1190
|
const req = httpsRequest(`${base}${path2}`, {
|
|
1191
1191
|
method: "POST",
|
|
1192
1192
|
timeout: timeoutMs,
|
|
1193
|
-
headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.
|
|
1193
|
+
headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.103.0"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
|
|
1194
1194
|
}, (res) => {
|
|
1195
1195
|
let buf = "";
|
|
1196
1196
|
res.on("data", (c) => buf += c);
|
|
@@ -1232,7 +1232,7 @@ async function request(path2, opts = {}, retried = false) {
|
|
|
1232
1232
|
method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
|
|
1233
1233
|
headers: {
|
|
1234
1234
|
authorization: `Bearer ${token}`,
|
|
1235
|
-
"user-agent": `ghosty-cli/${"0.
|
|
1235
|
+
"user-agent": `ghosty-cli/${"0.103.0"}`,
|
|
1236
1236
|
"accept-language": lang(),
|
|
1237
1237
|
...opts.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
1238
1238
|
...opts.headers
|
|
@@ -9920,11 +9920,11 @@ ${dim(t(`${r3.beforeChars} \u2192 ${r3.chars} chars. Dry run: nothing changed.`,
|
|
|
9920
9920
|
const emailAny = parseSwitch("--email-any", v["email-any"]);
|
|
9921
9921
|
if (emailAny !== void 0) body.email = { anyFromClients: emailAny };
|
|
9922
9922
|
if (v.quote) {
|
|
9923
|
-
const alias = { iva: "ivaPct", vigencia: "vigenciaDias", prefix: "folioPrefijo", prefijo: "folioPrefijo", currency: "moneda", company: "empresa", phone: "telefono", email: "correo", address: "direccion", notes: "notas", "iva-incluido": "ivaIncluido", "solo-factura": "ivaSoloConFactura" };
|
|
9923
|
+
const alias = { "catalogo-base": "catalogoBase", catalogo_base: "catalogoBase", "catalog-db": "catalogoBase", catalog_db: "catalogoBase", iva: "ivaPct", vigencia: "vigenciaDias", prefix: "folioPrefijo", prefijo: "folioPrefijo", currency: "moneda", company: "empresa", phone: "telefono", email: "correo", address: "direccion", notes: "notas", "iva-incluido": "ivaIncluido", "solo-factura": "ivaSoloConFactura", template: "plantilla", numbers: "numeros", seller: "comercial" };
|
|
9924
9924
|
const cot = {};
|
|
9925
9925
|
let cats = null;
|
|
9926
|
-
for (const part of v.quote.split(/,(?=\s*[a-zA-
|
|
9927
|
-
const m = /^\s*([a-zA-
|
|
9926
|
+
for (const part of v.quote.split(/,(?=\s*[a-zA-Z_-]+(?:\.[^=,]+)?=)/)) {
|
|
9927
|
+
const m = /^\s*([a-zA-Z_-]+)(?:\.([^=]+))?=(.*)$/.exec(part);
|
|
9928
9928
|
if (!m) throw usage(t(`Bad --quote: ${part}.`, `--quote inv\xE1lido: ${part}.`), "--quote iva=0,prefix=SFI,vigencia=15");
|
|
9929
9929
|
const [, rawKey, category, rawVal] = m;
|
|
9930
9930
|
const val = rawVal.trim().replace(/^"(.*)"$/, "$1");
|
|
@@ -9935,6 +9935,10 @@ ${dim(t(`${r3.beforeChars} \u2192 ${r3.chars} chars. Dry run: nothing changed.`,
|
|
|
9935
9935
|
continue;
|
|
9936
9936
|
}
|
|
9937
9937
|
const key = alias[rawKey] ?? rawKey;
|
|
9938
|
+
if (key === "plantilla" && val.startsWith("@")) {
|
|
9939
|
+
cot[key] = await readFile3(resolve(val.slice(1)), "utf8");
|
|
9940
|
+
continue;
|
|
9941
|
+
}
|
|
9938
9942
|
cot[key] = key === "ivaPct" || key === "vigenciaDias" ? Number(val) : key === "ivaIncluido" || key === "ivaSoloConFactura" ? /^(true|on|yes|si|sí|1)$/i.test(val) : val;
|
|
9939
9943
|
}
|
|
9940
9944
|
if (cats) cot.ivaPorCategoria = cats;
|
|
@@ -11293,7 +11297,7 @@ async function call(path2, v, init = {}) {
|
|
|
11293
11297
|
"x-ghosty-ts": ts,
|
|
11294
11298
|
"x-ghosty-sig": sig,
|
|
11295
11299
|
"content-type": "application/json",
|
|
11296
|
-
"user-agent": `ghosty-cli/${"0.
|
|
11300
|
+
"user-agent": `ghosty-cli/${"0.103.0"}`
|
|
11297
11301
|
},
|
|
11298
11302
|
body: method === "GET" ? void 0 : raw
|
|
11299
11303
|
});
|
|
@@ -11909,8 +11913,29 @@ ${dim(t("Is the source the right database? Leave those tables out with --tables.
|
|
|
11909
11913
|
function planText(plan) {
|
|
11910
11914
|
return plan.map((p) => p.action === "create" ? t(` + ${p.table} create, ${p.sourceRows} row(s)`, ` + ${p.table} crear, ${p.sourceRows} fila(s)`) : t(` ~ ${p.table} ${p.action} ${p.targetRows} \u2192 ${p.resultRows} row(s)`, ` ~ ${p.table} ${p.action === "replace" ? "reemplazar" : "agregar"} ${p.targetRows} \u2192 ${p.resultRows} fila(s)`)).join("\n");
|
|
11911
11915
|
}
|
|
11916
|
+
async function dbsImportCsv(id, db, file, v) {
|
|
11917
|
+
const ex = "ghosty dbs import <agent-id> <db> --from csv:products.csv --table products [--append] [--dry-run]";
|
|
11918
|
+
if (!v.table) throw usage(t("Missing --table.", "Falta --table."), `${t("Example", "Ejemplo")}: ${ex}`);
|
|
11919
|
+
const csvText = await readFile6(file, "utf8");
|
|
11920
|
+
const body = { from: "csv", table: v.table, csv: csvText, mode: v.append ? "append" : "replace" };
|
|
11921
|
+
const path2 = agentPath2(id, `/dbs/${enc9(db)}/import`);
|
|
11922
|
+
const dry = await api(path2, { body: { ...body, dryRun: true } });
|
|
11923
|
+
const cols = dim(` ${t("columns", "columnas")}: ${dry.columns.join(", ")}`);
|
|
11924
|
+
if (v["dry-run"]) return out(dry, () => `${dry.db} \u2190 ${basename3(file)}
|
|
11925
|
+
${planText(dry.plan)}
|
|
11926
|
+
${cols}
|
|
11927
|
+
${dim(t("Dry run: nothing changed.", "Simulaci\xF3n: no cambi\xF3 nada."))}`);
|
|
11928
|
+
if (dry.plan.some((p) => p.action === "replace" && p.targetRows > 0)) await confirm(`${planText(dry.plan)}${shrinkWarnings(dry.plan)}
|
|
11929
|
+
${t(`Replace the rows of ${v.table} in ${dry.db}?`, `\xBFReemplazar las filas de ${v.table} en ${dry.db}?`)}`, { yes: v.yes, retry: ex });
|
|
11930
|
+
const r = await api(path2, { body });
|
|
11931
|
+
return out(r, () => `${planText(r.plan)}
|
|
11932
|
+
${cols}
|
|
11933
|
+
${lavender("\u2713")} ${t(`${r.imported} row(s) imported into ${r.db}.${v.table}${r.created ? " (new table)" : ""}.`, `${r.imported} fila(s) importadas en ${r.db}.${v.table}${r.created ? " (tabla nueva)" : ""}.`)}`);
|
|
11934
|
+
}
|
|
11912
11935
|
async function dbsImport(id, db, v) {
|
|
11913
|
-
const ex = "ghosty dbs import <agent-id> <db> --from easybits:<db-id> [--tables a,b] [--dry-run]";
|
|
11936
|
+
const ex = "ghosty dbs import <agent-id> <db> --from easybits:<db-id> [--tables a,b] [--dry-run] | --from csv:file.csv --table T";
|
|
11937
|
+
const csvFile = /^csv:(.+)$/.exec(v.from ?? "");
|
|
11938
|
+
if (csvFile) return dbsImportCsv(id, db, csvFile[1], v);
|
|
11914
11939
|
const m = /^easybits:(.+)$/.exec(v.from ?? "");
|
|
11915
11940
|
if (!m) throw usage(t("Missing or bad --from.", "Falta --from o no es v\xE1lido."), `${t("Example", "Ejemplo")}: ${ex}`);
|
|
11916
11941
|
const easybitsKey = process.env.EASYBITS_API_KEY;
|
|
@@ -12029,6 +12054,13 @@ async function dbsCmd(sub, id, db, rest, v) {
|
|
|
12029
12054
|
${dim(`${t("Delete one", "Borrar una")}: ghosty dbs rm ${id} <db> --dry-run`)}` : dim(t("No orphan databases: every one is granted to some agent.", "Sin bases hu\xE9rfanas: todas est\xE1n concedidas a alg\xFAn agente.")));
|
|
12030
12055
|
return out(dbs, () => rows.length ? table(rows, ["name", "access", "agents", "writes from customers", "own rows", "id"]) : dim(t("This account has no databases yet: create one at /app/dbs.", "Esta cuenta todav\xEDa no tiene bases: crea una en /app/dbs.")));
|
|
12031
12056
|
}
|
|
12057
|
+
case "create":
|
|
12058
|
+
case "new": {
|
|
12059
|
+
const name = need2(db, t("database name", "el nombre de la base"), "ghosty dbs create <agent-id> <name> [--description TEXT] [--read]");
|
|
12060
|
+
const r = await api(agentPath2(id, "/dbs"), { body: { name, ...v.description ? { description: v.description } : {}, grant: v["no-grant"] ? false : v.read ? "read" : "write" } });
|
|
12061
|
+
return out(r, () => `${lavender("\u2713")} ${t(`Database ${bold(r.name)} created${r.granted ? " and granted to the agent" : ""}.`, `Base ${bold(r.name)} creada${r.granted ? " y concedida al agente" : ""}.`)}
|
|
12062
|
+
${dim(`${t("Fill it", "Ll\xE9nala")}: ghosty dbs import ${id} ${r.name} --from csv:file.csv --table T`)}`);
|
|
12063
|
+
}
|
|
12032
12064
|
case "tables": {
|
|
12033
12065
|
db = need2(db, t("database (id or name)", "la base (id o nombre)"), "ghosty dbs tables <agent-id> <db>");
|
|
12034
12066
|
const r = await api(agentPath2(id, `/dbs/${enc9(db)}`));
|
|
@@ -12800,15 +12832,15 @@ async function groupsCmd(args, v) {
|
|
|
12800
12832
|
const sub = rawSub === "enable" || rawSub === "disable" ? "set" : rawSub;
|
|
12801
12833
|
if (rawSub === "enable") v = { ...v, on: true };
|
|
12802
12834
|
if (rawSub === "disable") v = { ...v, off: true };
|
|
12803
|
-
const ex = 'ghosty channels wa groups ls <agent-id> | set <agent-id> <group> [--role equipo|cliente] [--wake mention|all] [--on|--off] [--name "New name"] | create <agent-id> "Name" | inject <agent-id> <group> --text "\u2026" [--sender NAME]';
|
|
12835
|
+
const ex = 'ghosty channels wa groups ls <agent-id> | set <agent-id> <group> [--role equipo|cliente] [--wake mention|name|all] [--alias "tilin,ghos"] [--on|--off] [--name "New name"] | create <agent-id> "Name" | inject <agent-id> <group> --text "\u2026" [--sender NAME]';
|
|
12804
12836
|
if (!id) throw usage(t("Missing agent id.", "Falta el id del agente."), `${t("Example", "Ejemplo")}: ${ex}`);
|
|
12805
12837
|
const path2 = `/api/v2/agents/${enc11(id)}/wa/groups`;
|
|
12806
12838
|
if (v.role !== void 0 && v.role !== "equipo" && v.role !== "cliente") throw usage(t("--role takes equipo or cliente.", "--role acepta equipo o cliente."));
|
|
12807
|
-
if (v.wake !== void 0 && v.wake !== "mention" && v.wake !== "all") throw usage(t("--wake takes mention or all.", "--wake acepta mention o all."));
|
|
12839
|
+
if (v.wake !== void 0 && v.wake !== "mention" && v.wake !== "name" && v.wake !== "all") throw usage(t("--wake takes mention, name or all.", "--wake acepta mention, name o all."));
|
|
12808
12840
|
if (!sub || sub === "ls" || sub === "list") {
|
|
12809
12841
|
const r2 = await api(`${path2}${v.cached ? "?live=0" : ""}`);
|
|
12810
|
-
const rows = r2.groups.map((g2) => ({ name: g2.name, on: g2.enabled ? lavender("on") : dim("off"), role: g2.role, wake: g2.wake ?? "all", jid: g2.jid }));
|
|
12811
|
-
return out(r2, () => rows.length ? table(rows, ["name", "on", "role", "wake", "jid"]) : dim(t('No groups. Pair its personal WhatsApp in the web, or: ghosty channels wa groups create <agent-id> "Name"', 'Sin grupos. Parea su WhatsApp personal en la web, o: ghosty channels wa groups create <agent-id> "Nombre"')));
|
|
12842
|
+
const rows = r2.groups.map((g2) => ({ name: g2.name, on: g2.enabled ? lavender("on") : dim("off"), role: g2.role, wake: g2.wake ?? "all", alias: (g2.alias ?? []).join(", "), jid: g2.jid }));
|
|
12843
|
+
return out(r2, () => rows.length ? table(rows, ["name", "on", "role", "wake", "alias", "jid"]) : dim(t('No groups. Pair its personal WhatsApp in the web, or: ghosty channels wa groups create <agent-id> "Name"', 'Sin grupos. Parea su WhatsApp personal en la web, o: ghosty channels wa groups create <agent-id> "Nombre"')));
|
|
12812
12844
|
}
|
|
12813
12845
|
if (sub === "create") {
|
|
12814
12846
|
const name2 = rest.join(" ").trim();
|
|
@@ -12835,16 +12867,18 @@ async function groupsCmd(args, v) {
|
|
|
12835
12867
|
const role = v.role ?? g.role;
|
|
12836
12868
|
const name = v.name?.trim() || void 0;
|
|
12837
12869
|
const wake = v.wake;
|
|
12838
|
-
const
|
|
12870
|
+
const alias = v.alias === void 0 ? void 0 : v.alias.split(",").map((x) => x.trim()).filter(Boolean);
|
|
12871
|
+
const aliasChanged = alias !== void 0 && alias.join(",") !== (g.alias ?? []).join(",");
|
|
12872
|
+
const changes = [...aliasChanged ? [`alias [${(g.alias ?? []).join(", ")}]\u2192[${alias.join(", ")}]`] : [], ...wake && wake !== g.wake ? [`wake ${g.wake ?? "all"}\u2192${wake}`] : [], ...enabled !== g.enabled ? [`${g.enabled ? "on" : "off"}\u2192${enabled ? "on" : "off"}`] : [], ...role !== g.role ? [`${g.role}\u2192${role}`] : [], ...name && name !== g.name ? [`\xAB${g.name}\xBB\u2192\xAB${name}\xBB`] : []];
|
|
12839
12873
|
if (!changes.length) return out({ changed: 0, group: g }, () => dim(t(`Nothing to do: ${g.name} is already ${g.enabled ? "on" : "off"} as ${g.role}.`, `Nada que hacer: ${g.name} ya est\xE1 ${g.enabled ? "encendido" : "apagado"} como ${g.role}.`)));
|
|
12840
12874
|
const plan = `~ ${g.name}: ${changes.join(", ")}`;
|
|
12841
12875
|
if (v["dry-run"]) return out({ dryRun: true, plan: [plan] }, () => `${plan}
|
|
12842
12876
|
${dim(t("Dry run: nothing changed.", "Simulacro: no se cambi\xF3 nada."))}`);
|
|
12843
12877
|
if (enabled && !g.enabled) await confirm(`${bold(plan)}
|
|
12844
12878
|
${t(`The agent will start answering in this group as ${role}.`, `El agente empezar\xE1 a contestar en este grupo como ${role}.`)}`, { yes: v.yes, retry: `ghosty channels wa groups set ${id} "${ref}"${v.role ? ` --role ${v.role}` : ""} --on` });
|
|
12845
|
-
const r = await api(path2, { method: "POST", body: { jid: g.jid, enabled, role, ...wake ? { wake } : {}, ...name ? { name } : {} } });
|
|
12879
|
+
const r = await api(path2, { method: "POST", body: { jid: g.jid, enabled, role, ...wake ? { wake } : {}, ...alias ? { alias } : {}, ...name ? { name } : {} } });
|
|
12846
12880
|
const now = r.groups.find((x) => x.jid === g.jid);
|
|
12847
|
-
return out({ group: now ?? null, plan: [plan] }, () => `${lavender("\u2713")} ${now?.name ?? g.name}: ${now?.enabled ? "on" : "off"} ${t("as", "como")} ${now?.role ?? role} \xB7 wake ${now?.wake ?? wake ?? "all"}`);
|
|
12881
|
+
return out({ group: now ?? null, plan: [plan] }, () => `${lavender("\u2713")} ${now?.name ?? g.name}: ${now?.enabled ? "on" : "off"} ${t("as", "como")} ${now?.role ?? role} \xB7 wake ${now?.wake ?? wake ?? "all"}${now?.alias?.length ? ` \xB7 alias ${now.alias.join(", ")}` : ""}`);
|
|
12848
12882
|
}
|
|
12849
12883
|
var EB_EXPORT = (agentId) => `${(process.env.EASYBITS_URL ?? "https://www.easybits.cloud").replace(/\/+$/, "")}/api/v2/fleet-agents/${enc11(agentId)}/baileys/export`;
|
|
12850
12884
|
async function easybitsSession(agentId, keys) {
|
|
@@ -13514,7 +13548,7 @@ var HELPS_ES = {
|
|
|
13514
13548
|
["--channel-roles k=role,\u2026", "set: qui\xE9n habla en teams y en programado (turnos programados): equipo (escribe en bases, tools admin) o cliente. chat siempre es el equipo; WhatsApp Business, Messenger, demo y widget son clientes; el WhatsApp personal va por grupo (channels wa groups set --role)"],
|
|
13515
13549
|
["--extensions name=on|off,\u2026", "set: prende o apaga extensiones del config.yaml de su caja (developer, memory\u2026; Ghosty \xB7 Lite y Goose); se funden con lo guardado. L\xEDstalas: get (configuraci\xF3n completa)"],
|
|
13516
13550
|
["--email-any on|off", "set: on = enviar_correo puede escribir a CUALQUIER direcci\xF3n desde canales de cliente; off (default) = s\xF3lo a quien escribe. S\xF3lo el due\xF1o"],
|
|
13517
|
-
["--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"],
|
|
13551
|
+
["--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 \xB7 plantilla=@cotizacion.html (tu propia plantilla del PDF: {{folio}}, {{cliente}}, {{#items}}\u2026{{/items}}), logo=https://\u2026, comercial=NOMBRE, numeros=es (1.234,56) \xB7 catalogo_base=BASE:TABLA (el cat\xE1logo sale de esa tabla de una base concedida, editable en la web o platicando con el agente; catalogo_base= regresa a la lista de la ficha)"],
|
|
13518
13552
|
["--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"],
|
|
13519
13553
|
["--verbose", "doctor: lista tambi\xE9n las revisiones que pasaron"],
|
|
13520
13554
|
["--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"],
|
|
@@ -13838,7 +13872,8 @@ var HELPS_ES = {
|
|
|
13838
13872
|
["-n, --dry-run", "imprime el plan (+ empieza a contestar, - deja de contestar) y no cambia nada"],
|
|
13839
13873
|
["--yes", "enable / groups enable: se salta la confirmaci\xF3n (obligatorio sin terminal)"],
|
|
13840
13874
|
["--role R", "groups: equipo (el equipo: escribe en bases de datos, tools de admin) o cliente (como cualquier cliente)"],
|
|
13841
|
-
["--wake mention|all", "groups set/enable: contesta todo,
|
|
13875
|
+
["--wake mention|name|all", "groups set/enable: contesta todo (all), s\xF3lo si lo mencionan con @, lo nombran o le responden (mention), o s\xF3lo si escriben su nombre o un alias (name: sin @ ni respuestas)"],
|
|
13876
|
+
['--alias "a,b"', 'groups set: otros nombres que lo despiertan en ese grupo adem\xE1s del suyo (el apodo con que le dicen ah\xED); "" los quita'],
|
|
13842
13877
|
["--text T / --sender N", "groups inject (staff): un mensaje que se perdi\xF3 (grupo apagado, deploy) entra como si N lo hubiera escrito ah\xED, y el agente contesta en el grupo"],
|
|
13843
13878
|
["--cached", "groups ls: no le pide a WhatsApp la lista en vivo (m\xE1s r\xE1pido; puede faltar alg\xFAn grupo nuevo)"],
|
|
13844
13879
|
["--ads-only on|off", "link: s\xF3lo las conversaciones que vienen de un anuncio abren tarjeta (tambi\xE9n solo, para cambiarlo en un n\xFAmero ya ligado)"],
|
|
@@ -14045,6 +14080,7 @@ var HELPS_ES = {
|
|
|
14045
14080
|
["--interval I", "pin: year (default, 2 meses gratis) o month \u2014 el periodo del cobro si hay que pagar"],
|
|
14046
14081
|
["--currency C", "pin: usd (default) o mxn \u2014 la moneda del cobro si hay que pagar"],
|
|
14047
14082
|
["--add-pack", "pin: ya usas tus lugares \u2014 suma 3 m\xE1s (mismo periodo y moneda de tu suscripci\xF3n) y fija \xE9ste"],
|
|
14083
|
+
["--yes", "rm: sin confirmaci\xF3n (obligatorio sin terminal)"],
|
|
14048
14084
|
["--cancel / --resume", "pins: cancela al final del periodo (los sitios vuelven a Gratis con aviso), o lo deshace"],
|
|
14049
14085
|
["--days N", "search: la ventana de Search Console en d\xEDas (default 28; Google reporta con 2\u20133 d\xEDas de retraso)"],
|
|
14050
14086
|
["--since S / --kind K / --req-id ID", "errors: ventana (30m, 6h, 7d; default 24h), un tipo de evento, o todo lo de una petici\xF3n (su x-request-id)"],
|
|
@@ -14271,7 +14307,7 @@ var HELPS = {
|
|
|
14271
14307
|
["--channel-roles k=role,\u2026", "set: who talks on teams and programado (scheduled turns): equipo (team: writes to databases, admin tools) or cliente (customer). chat is always the team; WhatsApp Business, Messenger, demo and widget are customers; personal WhatsApp goes per group (channels wa groups set --role)"],
|
|
14272
14308
|
["--extensions name=on|off,\u2026", "set: turn its box's config.yaml extensions on or off (developer, memory\u2026; Ghosty \xB7 Lite and Goose); merged with what's saved. List them: get (full config)"],
|
|
14273
14309
|
["--email-any on|off", "set: on = enviar_correo may write to ANY address from customer channels; off (default) = only to the person writing. Owner only"],
|
|
14274
|
-
["--quote k=v,\u2026", "set: config of the house `cotizar` tool \u2014 iva (0-100), iva-incluido=true (catalog prices already include VAT), iva.CATEGORY=16 (VAT for that catalog category; iva.CATEGORY= removes it), solo-factura=true (VAT only when the customer asks for an invoice), vigencia (days), prefix (folio), moneda, empresa, rfc, telefono, correo, direccion, notas, color. Empty value clears it (rfc=). The folio counter is never touched"],
|
|
14310
|
+
["--quote k=v,\u2026", "set: config of the house `cotizar` tool \u2014 iva (0-100), iva-incluido=true (catalog prices already include VAT), iva.CATEGORY=16 (VAT for that catalog category; iva.CATEGORY= removes it), solo-factura=true (VAT only when the customer asks for an invoice), vigencia (days), prefix (folio), moneda, empresa, rfc, telefono, correo, direccion, notas, color. Empty value clears it (rfc=). The folio counter is never touched \xB7 plantilla=@quote.html (your own PDF template: {{folio}}, {{cliente}}, {{#items}}\u2026{{/items}}), logo=https://\u2026, comercial=NAME, numeros=es (1.234,56) \xB7 catalogo_base=DB:TABLE (the catalog comes from that table of a granted database, editable on the web or by chatting with the agent; catalogo_base= goes back to the agent's own list)"],
|
|
14275
14311
|
["--catalog FILE", "set: the house `cotizar` tool's catalog from a CSV (sku,nombre,precio[,unidad,categoria,descripcion]) or JSON list; replaces the previous one. Its `categoria` drives the VAT rules"],
|
|
14276
14312
|
["--verbose", "doctor: also list the checks that passed"],
|
|
14277
14313
|
["--user EMAIL", "doctor (Ghosty staff): that person's agents \u2014 doctor, latest turns (state, seconds, error, and \xABfetched\xBB: whether their app asked for the thread after the turn ended), plan/bag and boxes (duplicates flagged); logged"],
|
|
@@ -14403,6 +14439,7 @@ var HELPS = {
|
|
|
14403
14439
|
summary: "Databases an agent can use, and what it may write from customer channels.",
|
|
14404
14440
|
usage: [
|
|
14405
14441
|
"ghosty dbs ls <agent-id> [--orphans]",
|
|
14442
|
+
"ghosty dbs create <agent-id> <name> [--description TEXT] [--read] [--no-grant]",
|
|
14406
14443
|
"ghosty dbs tables <agent-id> <db>",
|
|
14407
14444
|
'ghosty dbs query <agent-id> <db> "SQL" [--arg V]\u2026 [--write]',
|
|
14408
14445
|
"ghosty dbs origin <agent-id> <db> [--table T] [--since 2026-10-10] [--limit N]",
|
|
@@ -14410,6 +14447,7 @@ var HELPS = {
|
|
|
14410
14447
|
"ghosty dbs restore <agent-id> <db> <checkpoint-id> [--yes]",
|
|
14411
14448
|
"ghosty dbs export <agent-id> <db> [--table T] [--out FILE]",
|
|
14412
14449
|
"ghosty dbs import <agent-id> <db> --from easybits:<db-id> [--tables a,b] [--append] [--rehost-images t.col,\u2026] [--dry-run] [--yes]",
|
|
14450
|
+
"ghosty dbs import <agent-id> <db> --from csv:FILE --table T [--append] [--dry-run] [--yes]",
|
|
14413
14451
|
"ghosty dbs rehost <agent-id> <db> --table T --column C [--dry-run]",
|
|
14414
14452
|
"ghosty dbs photos put <agent-id> <db> --table T --key-column K --dir DIR [--column C] [--dry-run]",
|
|
14415
14453
|
"ghosty dbs grant <agent-id> <db> [--external-write t1,t2] [--external-rows t:col+col,\u2026]",
|
|
@@ -14761,7 +14799,8 @@ HELPS.channels = {
|
|
|
14761
14799
|
["-n, --dry-run", "print the plan (+ starts answering, - stops) and change nothing"],
|
|
14762
14800
|
["--yes", "enable / groups enable: skip the confirmation (required without a terminal)"],
|
|
14763
14801
|
["--role R", "groups: equipo (the team: writes to databases, admin tools) or cliente (like any customer)"],
|
|
14764
|
-
["--wake mention|all", "groups set/enable: answer every message,
|
|
14802
|
+
["--wake mention|name|all", "groups set/enable: answer every message (all), only when it's @-mentioned, named or replied to (mention), or only when its name or an alias is written (name: no @, no replies)"],
|
|
14803
|
+
['--alias "a,b"', 'groups set: other names that wake it in that group besides its own (the nickname people use there); "" clears them'],
|
|
14765
14804
|
["--text T / --sender N", "groups inject (staff): a message that got lost (group off, deploy) enters as if N wrote it there, and the agent answers in the group"],
|
|
14766
14805
|
["--cached", "groups ls: don't ask WhatsApp for the live list (faster; may miss new groups)"],
|
|
14767
14806
|
["--ads-only on|off", "link: only conversations that come from an ad open a card (also alone, to change it on a linked number)"],
|
|
@@ -15083,6 +15122,7 @@ HELPS.sites = {
|
|
|
15083
15122
|
"ghosty sites agent <slug> [create] [--agent id] [--model m] [--prompt p]",
|
|
15084
15123
|
"ghosty sites pin <slug|id> [--interval year|month] [--currency usd|mxn] [--add-pack]",
|
|
15085
15124
|
"ghosty sites unpin <slug|id>",
|
|
15125
|
+
"ghosty sites rm <slug|id> [--yes]",
|
|
15086
15126
|
"ghosty sites pins [--cancel | --resume]",
|
|
15087
15127
|
"ghosty sites search <slug|id> [--days 28]",
|
|
15088
15128
|
"ghosty sites publish <file.html|folder> [--title T] [--slug S] [--site <slug|id>]",
|
|
@@ -15093,6 +15133,7 @@ HELPS.sites = {
|
|
|
15093
15133
|
["--interval I", "pin: year (default, 2 months free) or month \u2014 the billing period if you need to pay"],
|
|
15094
15134
|
["--currency C", "pin: usd (default) or mxn \u2014 the currency charged if you need to pay"],
|
|
15095
15135
|
["--add-pack", "pin: you already use your slots \u2014 add 3 more (same period and currency as your subscription) and pin this one"],
|
|
15136
|
+
["--yes", "rm: skip the confirmation (required without a terminal)"],
|
|
15096
15137
|
["--cancel / --resume", "pins: cancel at period end (sites go back to Free with notice), or undo it"],
|
|
15097
15138
|
["--days N", "search: Search Console window in days (default 28; Google reports 2\u20133 days late)"],
|
|
15098
15139
|
["--since S / --kind K / --req-id ID", "errors: window (30m, 6h, 7d; default 24h), one event kind, or everything from one request (its x-request-id)"],
|
|
@@ -15101,7 +15142,7 @@ HELPS.sites = {
|
|
|
15101
15142
|
["--slug S", "publish: the slug for a NEW site (a-z, 0-9 and hyphens, 3\u201360, not reserved)"],
|
|
15102
15143
|
["--site X", "publish: update that house site (slug, id or URL) instead of creating one"]
|
|
15103
15144
|
],
|
|
15104
|
-
examples: ["ghosty sites show agenda-perdix", "ghosty sites env set agenda-perdix STRIPE_SECRET_KEY=sk_live_\u2026", "ghosty sites cron pause agenda-perdix cm123", "ghosty sites agent agenda-perdix create", "ghosty sites agent agenda-perdix --model claude-sonnet-5-5", "ghosty sites pin tacos-don-pepe", "ghosty sites pin tacos-don-pepe --interval month --currency mxn", "ghosty sites unpin landing-vieja", "ghosty sites pins --cancel", "ghosty sites publish ./landing/ --site gelatina-de-sandia"],
|
|
15145
|
+
examples: ["ghosty sites show agenda-perdix", "ghosty sites env set agenda-perdix STRIPE_SECRET_KEY=sk_live_\u2026", "ghosty sites cron pause agenda-perdix cm123", "ghosty sites agent agenda-perdix create", "ghosty sites agent agenda-perdix --model claude-sonnet-5-5", "ghosty sites pin tacos-don-pepe", "ghosty sites pin tacos-don-pepe --interval month --currency mxn", "ghosty sites unpin landing-vieja", "ghosty sites rm landing-de-prueba --yes", "ghosty sites pins --cancel", "ghosty sites publish ./landing/ --site gelatina-de-sandia"],
|
|
15105
15146
|
notes: [
|
|
15106
15147
|
"pin: with a free slot it pins right away; without a subscription it prints a card-payment link (the site is pinned when you pay); with every slot used it answers needs_pack (repeat with --add-pack).",
|
|
15107
15148
|
"unpin, cancelling, or a failed payment never pause a site at once: it goes back to the Free rule (30 days since its last change, at least 8 from today, notice 7 days before).",
|
|
@@ -15769,10 +15810,10 @@ async function demosCmd(sub, a1, rest, v) {
|
|
|
15769
15810
|
|
|
15770
15811
|
// src/commands/sites.ts
|
|
15771
15812
|
init_api();
|
|
15772
|
-
init_i18n();
|
|
15773
|
-
init_util();
|
|
15774
15813
|
import { readdir as readdir5, readFile as readFile13, stat as stat3 } from "node:fs/promises";
|
|
15775
15814
|
import { basename as basename4, join as join11, relative as relative2, sep } from "node:path";
|
|
15815
|
+
init_i18n();
|
|
15816
|
+
init_util();
|
|
15776
15817
|
var TEXT_EXT = /* @__PURE__ */ new Set(["html", "htm", "css", "js", "mjs", "json", "txt", "xml", "svg", "webmanifest", "md"]);
|
|
15777
15818
|
var SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", ".DS_Store"]);
|
|
15778
15819
|
async function collectSiteFiles(target) {
|
|
@@ -15812,7 +15853,7 @@ var packPrice = (c, i, lang2) => `$${(PACK[i]?.[c] ?? 0).toLocaleString("en-US")
|
|
|
15812
15853
|
var kb = (n) => n ? `${Math.max(1, Math.round(n / 1024))} KB` : "";
|
|
15813
15854
|
var day = (iso) => iso ? iso.slice(0, 10) : "";
|
|
15814
15855
|
async function sitesCmd(sub, a1, a2, v, a3, rest = []) {
|
|
15815
|
-
const ex = "ghosty sites ls [--house] \xB7 show <slug|id> \xB7 env|cron|files \u2026 \xB7 errors <slug> [--since 24h] [--kind K] [--req-id ID] \xB7 agent <slug> [--agent id] [--model m] \xB7 pin|unpin <slug|id> \xB7 pins [--cancel|--resume] \xB7 search <slug|id> [--days 28] \xB7 domain [ls|add|verify|rm] <slug> [domain] \xB7 publish <file.html|folder> [--title T] [--slug S] [--site <slug|id>] \xB7 slug <slug|id> <new-slug>";
|
|
15856
|
+
const ex = "ghosty sites ls [--house] \xB7 show <slug|id> \xB7 env|cron|files \u2026 \xB7 errors <slug> [--since 24h] [--kind K] [--req-id ID] \xB7 agent <slug> [--agent id] [--model m] \xB7 pin|unpin|rm <slug|id> \xB7 pins [--cancel|--resume] \xB7 search <slug|id> [--days 28] \xB7 domain [ls|add|verify|rm] <slug> [domain] \xB7 publish <file.html|folder> [--title T] [--slug S] [--site <slug|id>] \xB7 slug <slug|id> <new-slug>";
|
|
15816
15857
|
switch (sub ?? "ls") {
|
|
15817
15858
|
case "ls":
|
|
15818
15859
|
case "list": {
|
|
@@ -15841,6 +15882,15 @@ ${dim(t("or release one: ghosty sites unpin <slug>", "o suelta uno: ghosty sites
|
|
|
15841
15882
|
return out(r, () => `${lavender("\u2713")} ${t("Released", "Suelto")} ${bold(r.url)}
|
|
15842
15883
|
${dim(r.expiresAt ? t(`Free rule: pauses ${day(r.expiresAt)} unless it changes (notice 7 days before).`, `Regla Gratis: se pausa el ${day(r.expiresAt)} si no cambia (aviso 7 d\xEDas antes).`) : t("Your plan keeps it published.", "Tu plan lo mantiene publicado."))}`);
|
|
15843
15884
|
}
|
|
15885
|
+
case "rm":
|
|
15886
|
+
case "delete": {
|
|
15887
|
+
if (!a1) throw usage(t("Missing the site (slug, id or URL).", "Falta el sitio (slug, id o URL)."), "ghosty sites rm <slug|id> [--yes]");
|
|
15888
|
+
const retry = `ghosty sites rm ${a1}`;
|
|
15889
|
+
requireYesIfHeadless(v.yes, retry);
|
|
15890
|
+
await confirm(t(`Delete ${a1}? It stops being served and its files go away. This can't be undone.`, `\xBFBorrar ${a1}? Deja de servirse y sus archivos se van. No se puede deshacer.`), { yes: v.yes, retry });
|
|
15891
|
+
const r = await api(`/api/v2/sites/${encodeURIComponent(a1)}`, { method: "DELETE" });
|
|
15892
|
+
return out(r, () => `${lavender("\u2713")} ${t("Deleted", "Borrado")} ${bold(a1)}`);
|
|
15893
|
+
}
|
|
15844
15894
|
case "pins": {
|
|
15845
15895
|
if (v.cancel || v.resume) {
|
|
15846
15896
|
const r2 = await api("/api/v2/sites/pins", { method: "POST", body: { cancel: Boolean(v.cancel) } });
|
|
@@ -17579,6 +17629,8 @@ ${bold("Configure an agent")}
|
|
|
17579
17629
|
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)
|
|
17580
17630
|
skills templates <id> pdf-doc templates it sees: its own and Ghosty's, and which folder wins
|
|
17581
17631
|
dbs ls|tables|query|export|import|rehost|grant|revoke|rename|rm <id> [db] Databases it uses [--write] [--external-write t1,t2] [--external-rows t:col] [--from easybits:ID --dry-run] [--table T --column C]
|
|
17632
|
+
dbs create <id> <name> New database in the owner's account, granted to this agent [--description TEXT] [--read] [--no-grant]
|
|
17633
|
+
dbs import <id> <db> --from csv:FILE --table T A CSV (with header) into a table; creates it if missing [--append] [--dry-run]
|
|
17582
17634
|
dbs export <id> <db> Download a database: whole as .sqlite, or one table as CSV [--table T] [--out FILE]
|
|
17583
17635
|
dbs photos put <id> <db> --table T --key-column K --dir DIR Loose photos to a catalog (SKU-123.jpg \u2192 its row), permanent links [--column C] [--dry-run]
|
|
17584
17636
|
mcp get|set <id> MCP servers [--file servers.json] (http headers accept \${turn.token})
|
|
@@ -17597,7 +17649,7 @@ ${bold("Configure an agent")}
|
|
|
17597
17649
|
channels wa import <id> --from easybits:ID | --from-file F | --from-dir DIR --own-number yes|no Move a personal WhatsApp session here, no QR [--dry-run] [--replace] [--no-connect]
|
|
17598
17650
|
channels wa pair <id> --phone N Pair a personal WhatsApp by code (no QR)
|
|
17599
17651
|
channels wa status|pause <id> Personal WhatsApp: how it is / pause it (keeps the session)
|
|
17600
|
-
channels wa groups ls|enable|disable|set|create <id> [group] Personal WhatsApp groups it answers, and as whom [--role equipo|cliente] [--wake mention|all] [--name "New name"] [--dry-run]
|
|
17652
|
+
channels wa groups ls|enable|disable|set|create <id> [group] Personal WhatsApp groups it answers, and as whom [--role equipo|cliente] [--wake mention|name|all] [--alias "tilin"] [--name "New name"] [--dry-run]
|
|
17601
17653
|
boards ls|create|assign|move-cards|access|followups|rm A workspace's boards: create (--columns-from), where an agent sends cards, move cards, who sees each one, quote follow-ups
|
|
17602
17654
|
cards ls <id> Recent cards on its sales board [--q TEXT] [--paused] [--limit 20]
|
|
17603
17655
|
cards show <id> <card> A card's thread: who wrote, text, attachments and whether gs kept a copy (folio, phone or id)
|
|
@@ -17620,6 +17672,7 @@ ${bold("Sites")} ${dim("(sites your agents publish at <slug>.ghosty.page)")}
|
|
|
17620
17672
|
sites ls Sites your agents published (live and paused) [--house: Ghosty's own demos and landings (staff)]
|
|
17621
17673
|
sites pin <slug|id> Pin it: never pauses, no banner ($49 USD/yr or $5/mo, includes up to 3 sites) [--interval year|month] [--currency usd|mxn] [--add-pack: 3 more]
|
|
17622
17674
|
sites unpin <slug|id> Release its slot (back to the Free rule: 30 days + notice)
|
|
17675
|
+
sites rm <slug|id> Delete one of your sites (stops being served; can't be undone) [--yes]
|
|
17623
17676
|
sites search <slug|id> How Google finds it: clicks, impressions, searches, indexed or not [--days 28]
|
|
17624
17677
|
sites domain add|verify|rm <slug> <dom> Custom domain for a site or app (DNS record \u2192 verify \u2192 HTTPS) [ls <slug>: list]
|
|
17625
17678
|
sites show <slug|id> Everything about a site or app: status, domains, variable names, data, files, tasks
|
|
@@ -17810,6 +17863,8 @@ ${bold("Configurar un agente")}
|
|
|
17810
17863
|
skills ls|get|add|rm <id> [slug] Skills (add del cat\xE1logo, --file SKILL.md o --dir CARPETA; get lista, --out DIR guarda; rm deja copia)
|
|
17811
17864
|
skills templates <id> Plantillas de pdf-doc que ve: las suyas y las de Ghosty, y qu\xE9 carpeta gana
|
|
17812
17865
|
dbs ls|tables|query|export|import|rehost|grant|revoke|rename|rm <id> [db] Bases de datos que usa [--write] [--external-write t1,t2] [--external-rows t:col] [--from easybits:ID --dry-run] [--table T --column C]
|
|
17866
|
+
dbs create <id> <nombre> Base nueva en la cuenta del due\xF1o, concedida a este agente [--description TEXTO] [--read] [--no-grant]
|
|
17867
|
+
dbs import <id> <db> --from csv:ARCHIVO --table T Un CSV (con encabezado) a una tabla; la crea si no existe [--append] [--dry-run]
|
|
17813
17868
|
dbs export <id> <db> Descarga una base: entera como .sqlite, o una tabla en CSV [--table T] [--out ARCHIVO]
|
|
17814
17869
|
dbs photos put <id> <db> --table T --key-column K --dir DIR Fotos sueltas a un cat\xE1logo (SKU-123.jpg \u2192 su fila), ligas permanentes [--column C] [--dry-run]
|
|
17815
17870
|
mcp get|set <id> Servidores MCP [--file servers.json] (headers http admiten \${turn.token})
|
|
@@ -17828,7 +17883,7 @@ ${bold("Configurar un agente")}
|
|
|
17828
17883
|
channels wa import <id> --from easybits:ID | --from-file F | --from-dir DIR --own-number yes|no Mueve aqu\xED una sesi\xF3n de WhatsApp personal, sin QR [--dry-run] [--replace] [--no-connect]
|
|
17829
17884
|
channels wa pair <id> --phone N Vincula un WhatsApp personal con c\xF3digo (sin QR)
|
|
17830
17885
|
channels wa status|pause <id> WhatsApp personal: c\xF3mo est\xE1 / pausarlo (conserva la sesi\xF3n)
|
|
17831
|
-
channels wa groups ls|enable|disable|set|create <id> [grupo] Grupos de WhatsApp personal que contesta, y como qui\xE9n [--role equipo|cliente] [--wake mention|all] [--name "Nombre nuevo"] [--dry-run]
|
|
17886
|
+
channels wa groups ls|enable|disable|set|create <id> [grupo] Grupos de WhatsApp personal que contesta, y como qui\xE9n [--role equipo|cliente] [--wake mention|name|all] [--alias "tilin"] [--name "Nombre nuevo"] [--dry-run]
|
|
17832
17887
|
boards ls|create|assign|move-cards|access|followups|rm Los tableros de un espacio: crear (--columns-from), a d\xF3nde manda tarjetas un agente, mover tarjetas, qui\xE9n ve cada uno, seguimiento de cotizaciones
|
|
17833
17888
|
cards ls <id> Tarjetas recientes de su tablero de ventas [--q TEXTO] [--paused] [--limit 20]
|
|
17834
17889
|
cards show <id> <tarjeta> El hilo de una tarjeta: qui\xE9n escribi\xF3, texto, adjuntos y si gs guard\xF3 copia (folio, tel\xE9fono o id)
|
|
@@ -17851,6 +17906,7 @@ ${bold("Sitios")} ${dim("(los sitios que publican tus agentes en <slug>.ghosty.
|
|
|
17851
17906
|
sites ls Sitios que publicaron tus agentes (vivos y en pausa) [--house: demos y landings de Ghosty (staff)]
|
|
17852
17907
|
sites pin <slug|id> F\xEDjalo: no se pausa y va sin franja ($49 USD al a\xF1o o $5 al mes, incluye hasta 3 sitios) [--interval year|month] [--currency usd|mxn] [--add-pack: 3 m\xE1s]
|
|
17853
17908
|
sites unpin <slug|id> Suelta su lugar (vuelve a la regla Gratis: 30 d\xEDas + aviso)
|
|
17909
|
+
sites rm <slug|id> Borra uno de tus sitios (deja de servirse; no se deshace) [--yes]
|
|
17854
17910
|
sites pins Tu suscripci\xF3n de Sitios fijos y sus lugares [--cancel | --resume]
|
|
17855
17911
|
sites domain add|verify|rm <slug> <dom> Dominio propio para un sitio o app (registro DNS \u2192 verificar \u2192 HTTPS) [ls <slug>: lista]
|
|
17856
17912
|
sites show <slug|id> Todo de un sitio o app: estado, dominios, nombres de variables, datos, archivos, tareas
|
|
@@ -18061,6 +18117,8 @@ async function main() {
|
|
|
18061
18117
|
dir: { type: "string" },
|
|
18062
18118
|
arg: { type: "string", multiple: true },
|
|
18063
18119
|
write: { type: "boolean" },
|
|
18120
|
+
read: { type: "boolean" },
|
|
18121
|
+
"no-grant": { type: "boolean" },
|
|
18064
18122
|
"external-write": { type: "string" },
|
|
18065
18123
|
"external-rows": { type: "string" },
|
|
18066
18124
|
"no-deliver": { type: "boolean" },
|
|
@@ -18166,6 +18224,7 @@ async function main() {
|
|
|
18166
18224
|
handle: { type: "string" },
|
|
18167
18225
|
factory: { type: "string" },
|
|
18168
18226
|
wake: { type: "string" },
|
|
18227
|
+
alias: { type: "string" },
|
|
18169
18228
|
text: { type: "string" },
|
|
18170
18229
|
sender: { type: "string" },
|
|
18171
18230
|
"from-file": { type: "string" },
|
|
@@ -18266,7 +18325,7 @@ async function main() {
|
|
|
18266
18325
|
const tokens = splitTokens(pos, v);
|
|
18267
18326
|
globals.token = tokens.session;
|
|
18268
18327
|
globals.profile = v.profile;
|
|
18269
|
-
if (v.version) return out({ version: "0.
|
|
18328
|
+
if (v.version) return out({ version: "0.103.0" }, () => "0.103.0");
|
|
18270
18329
|
for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
|
|
18271
18330
|
const context = (await readConfig()).workspace;
|
|
18272
18331
|
if (!explicitToken()?.startsWith("gat_")) {
|
|
@@ -18476,7 +18535,7 @@ async function main() {
|
|
|
18476
18535
|
throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
|
|
18477
18536
|
}
|
|
18478
18537
|
}
|
|
18479
|
-
var notice = updateNotice("0.
|
|
18538
|
+
var notice = updateNotice("0.103.0").catch(() => null);
|
|
18480
18539
|
main().then(
|
|
18481
18540
|
async () => {
|
|
18482
18541
|
const n = process.stderr.isTTY ? await notice : null;
|
package/package.json
CHANGED