@ghostystudio/cli 0.24.1 → 0.24.2
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 +2 -1
- package/dist/index.js +16 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,8 +90,9 @@ Exit codes: `0` ok · `1` API error · `2` usage error · `3` not signed in.
|
|
|
90
90
|
- `try --replay FILE --out DIR`: replays real conversations from your machine. The report is written after every step, survives Ghosty deploys (it honors `Retry-After`), and `--resume` continues a partial run.
|
|
91
91
|
- `agents doctor` speaks English like the rest of the CLI; `channels whatsapp ls` returns a full URL.
|
|
92
92
|
|
|
93
|
-
### Changes in 0.24.
|
|
93
|
+
### Changes in 0.24.2
|
|
94
94
|
|
|
95
|
+
- `channels whatsapp integrations` also lists numbers the workspace already linked in gs (even if another Formmy account owns them); staff: `--email`.
|
|
95
96
|
- `dbs rename` and `dbs rm` also work for Ghosty staff (migrations), not only the database's owner.
|
|
96
97
|
|
|
97
98
|
### Changes in 0.24.0
|
package/dist/index.js
CHANGED
|
@@ -7600,6 +7600,7 @@ var SERVER_MESSAGES = [
|
|
|
7600
7600
|
["falta name (el nombre nuevo)", "missing name (the new name)"],
|
|
7601
7601
|
["s\xF3lo el due\xF1o, un admin del agente o staff ven los n\xFAmeros de Formmy", "only the owner, an admin of the agent or staff can see the Formmy numbers"],
|
|
7602
7602
|
["no pude leer sus turnos", "couldn't read its turns"],
|
|
7603
|
+
["s\xF3lo staff lista los n\xFAmeros de otro correo", "only staff can list another email's numbers"],
|
|
7603
7604
|
["Tu plan incluye {} base{} de datos.", "Your plan includes {} database{}."],
|
|
7604
7605
|
["El nombre lleva letras min\xFAsculas, n\xFAmeros, guiones o guiones bajos (m\xE1x. 64).", "The name takes lowercase letters, numbers, hyphens or underscores (max 64)."],
|
|
7605
7606
|
["Nombre de tabla inv\xE1lido (letras, n\xFAmeros y _).", "Invalid table name (letters, numbers and _)."],
|
|
@@ -8267,7 +8268,7 @@ async function postLong(path, body, timeoutMs = 9e5) {
|
|
|
8267
8268
|
const req = httpsRequest(`${base}${path}`, {
|
|
8268
8269
|
method: "POST",
|
|
8269
8270
|
timeout: timeoutMs,
|
|
8270
|
-
headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.24.
|
|
8271
|
+
headers: { authorization: `Bearer ${token}`, "user-agent": `ghosty-cli/${"0.24.2"}`, "content-type": "application/json", "content-length": Buffer.byteLength(data) }
|
|
8271
8272
|
}, (res) => {
|
|
8272
8273
|
let buf = "";
|
|
8273
8274
|
res.on("data", (c) => buf += c);
|
|
@@ -8309,7 +8310,7 @@ async function request(path, opts = {}, retried = false) {
|
|
|
8309
8310
|
method: opts.method ?? (opts.body !== void 0 || opts.raw !== void 0 ? "POST" : "GET"),
|
|
8310
8311
|
headers: {
|
|
8311
8312
|
authorization: `Bearer ${token}`,
|
|
8312
|
-
"user-agent": `ghosty-cli/${"0.24.
|
|
8313
|
+
"user-agent": `ghosty-cli/${"0.24.2"}`,
|
|
8313
8314
|
"accept-language": lang(),
|
|
8314
8315
|
...opts.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
8315
8316
|
...opts.headers
|
|
@@ -9304,7 +9305,7 @@ async function call(path, v, init = {}) {
|
|
|
9304
9305
|
"x-ghosty-ts": ts,
|
|
9305
9306
|
"x-ghosty-sig": sig,
|
|
9306
9307
|
"content-type": "application/json",
|
|
9307
|
-
"user-agent": `ghosty-cli/${"0.24.
|
|
9308
|
+
"user-agent": `ghosty-cli/${"0.24.2"}`
|
|
9308
9309
|
},
|
|
9309
9310
|
body: method === "GET" ? void 0 : raw
|
|
9310
9311
|
});
|
|
@@ -10011,7 +10012,7 @@ async function channelsCmd(kind, sub, id, ref, v) {
|
|
|
10011
10012
|
if (!id) throw usage(t("Missing agent id.", "Falta el id del agente."), t("Example", "Ejemplo") + ": ghosty channels whatsapp ls <agent-id>");
|
|
10012
10013
|
if (sub === "link" || sub === "unlink") return linkCmd(sub, id, v);
|
|
10013
10014
|
if (sub === "history") return historyCmd(id, v);
|
|
10014
|
-
if (sub === "integrations") return integrationsCmd(id);
|
|
10015
|
+
if (sub === "integrations") return integrationsCmd(id, v.email);
|
|
10015
10016
|
if (sub === "import" || sub === "status" || sub === "pause" || sub === "pair") return waCmd(sub, id, v);
|
|
10016
10017
|
if (sub === "enable" && !v["dry-run"]) requireYesIfHeadless(v.yes, `ghosty channels whatsapp enable ${id} ${ref ?? "<number>"}`);
|
|
10017
10018
|
const path = `/api/v2/agents/${enc7(id)}/whatsapp`;
|
|
@@ -10150,8 +10151,8 @@ function bareMediaFlag(argv) {
|
|
|
10150
10151
|
if (argv[0] !== "channels" || !argv.includes("history")) return argv;
|
|
10151
10152
|
return argv.map((a, i) => a === "--media" && (argv[i + 1] === void 0 || argv[i + 1].startsWith("-")) ? "--media=" : a);
|
|
10152
10153
|
}
|
|
10153
|
-
async function integrationsCmd(id) {
|
|
10154
|
-
const r = await api(`/api/v2/agents/${enc7(id)}/whatsapp/integrations`);
|
|
10154
|
+
async function integrationsCmd(id, email) {
|
|
10155
|
+
const r = await api(`/api/v2/agents/${enc7(id)}/whatsapp/integrations${email ? `?email=${enc7(email)}` : ""}`);
|
|
10155
10156
|
const who2 = { gs: "gs", easybits: "EasyBits", droplet: "droplet", formmy: "Formmy", other: t("other", "otro") };
|
|
10156
10157
|
const rows = r.integrations.map((i) => ({
|
|
10157
10158
|
number: i.phoneNumber ? `+${i.phoneNumber}` : dim("?"),
|
|
@@ -10164,7 +10165,7 @@ async function integrationsCmd(id) {
|
|
|
10164
10165
|
return out(
|
|
10165
10166
|
r,
|
|
10166
10167
|
() => rows.length ? `${table(rows, ["number", "name", "answered by", "formmy forwards", "formmy agent", "integration"])}
|
|
10167
|
-
${dim(`${t("Next", "Siguiente")}: ghosty channels whatsapp link ${id} --integration <integration> --answer on|off --dry-run`)}` : dim(t(`${r.ownerEmail} has no WhatsApp Business numbers in Formmy.`, `${r.ownerEmail} no tiene n\xFAmeros de WhatsApp Business en Formmy.`))
|
|
10168
|
+
${dim(`${t("Next", "Siguiente")}: ghosty channels whatsapp link ${id} --integration <integration> --answer on|off --dry-run`)}` : dim(t(`${r.ownerEmail} has no WhatsApp Business numbers in Formmy (staff: --email <other Formmy account>).`, `${r.ownerEmail} no tiene n\xFAmeros de WhatsApp Business en Formmy (staff: --email <otra cuenta de Formmy>).`))
|
|
10168
10169
|
);
|
|
10169
10170
|
}
|
|
10170
10171
|
async function historyCmd(id, v) {
|
|
@@ -10485,6 +10486,7 @@ var HELPS_ES = {
|
|
|
10485
10486
|
["--role R", "groups: equipo (el equipo: escribe en bases de datos, tools de admin) o cliente (como cualquier cliente)"],
|
|
10486
10487
|
["--cached", "groups ls: no le pide a WhatsApp la lista en vivo (m\xE1s r\xE1pido; puede faltar alg\xFAn grupo nuevo)"],
|
|
10487
10488
|
["--integration ID", "link/unlink/history: el id de la Integration del n\xFAmero de WhatsApp Business en Formmy"],
|
|
10489
|
+
["--email E", "integrations (staff): lista los n\xFAmeros de otra cuenta de Formmy"],
|
|
10488
10490
|
["--days N", "history: conversaciones activas en los \xFAltimos N d\xEDas (1-30, default 7)"],
|
|
10489
10491
|
["--media", "history: s\xF3lo re-copia los archivos que faltan (fotos, PDF, audios) de las conversaciones ya importadas"],
|
|
10490
10492
|
["--answer on|off", "link (obligatorio, sin default): on = este agente contesta a clientes reales; off = s\xF3lo registra"],
|
|
@@ -10500,7 +10502,7 @@ var HELPS_ES = {
|
|
|
10500
10502
|
"Apagarlo sigue registrando los mensajes; nadie los contesta.",
|
|
10501
10503
|
"Los grupos son del WhatsApp PERSONAL emparejado al agente (no de WhatsApp Business). <group> es su nombre o su jid.",
|
|
10502
10504
|
"link mueve un n\xFAmero que ya vive en Formmy (EasyBits, un droplet) sin rehacer el alta de Meta; unlink lo regresa. S\xF3lo el due\xF1o, un admin del agente o el staff de Ghosty.",
|
|
10503
|
-
"integrations lista los n\xFAmeros de WhatsApp Business del due\xF1o en Formmy (n\xFAmero, nombre, qui\xE9n contesta hoy: gs, EasyBits, un droplet o Formmy) con el id de la Integration que piden link e history.",
|
|
10505
|
+
"integrations lista los n\xFAmeros de WhatsApp Business del due\xF1o en Formmy (n\xFAmero, nombre, qui\xE9n contesta hoy: gs, EasyBits, un droplet o Formmy) con el id de la Integration que piden link e history. Tambi\xE9n salen los n\xFAmeros que el espacio ya enlaz\xF3 en gs, aunque en Formmy sean de otra cuenta.",
|
|
10504
10506
|
"history trae al tablero las tarjetas, mensajes y pedidos recientes del n\xFAmero desde Formmy (enl\xE1zalo antes; --dry-run funciona sin enlazar, para decidir --days). Repetirlo nunca duplica: c\xF3rrelo antes del corte y otra vez justo en el corte. Los archivos (fotos, PDF, audios) tambi\xE9n se copian a gs: Formmy los borra a los 7 d\xEDas, as\xED que trae el n\xFAmero dentro de esa semana; una copia que fall\xF3 se reintenta con --media.",
|
|
10505
10507
|
"import: apaga primero el socket de EasyBits SIN logout (dos sockets se tumban entre s\xED; un logout invalida las llaves). Borra el archivo despu\xE9s."
|
|
10506
10508
|
]
|
|
@@ -10860,7 +10862,7 @@ HELPS.channels = {
|
|
|
10860
10862
|
"ghosty channels whatsapp ls <agent-id>",
|
|
10861
10863
|
"ghosty channels whatsapp enable <agent-id> <number> [--dry-run] [--yes]",
|
|
10862
10864
|
"ghosty channels whatsapp disable <agent-id> <number> [--dry-run]",
|
|
10863
|
-
"ghosty channels whatsapp integrations <agent-id>",
|
|
10865
|
+
"ghosty channels whatsapp integrations <agent-id> [--email OTHER]",
|
|
10864
10866
|
"ghosty channels whatsapp link <agent-id> --integration <formmy-id> --answer on|off [--forward] [--dry-run] [--yes]",
|
|
10865
10867
|
"ghosty channels whatsapp unlink <agent-id> --integration <formmy-id> [--dry-run] [--yes]",
|
|
10866
10868
|
"ghosty channels whatsapp history <agent-id> --integration <formmy-id> [--days 7] [--media] [--dry-run] [--yes]",
|
|
@@ -10878,6 +10880,7 @@ HELPS.channels = {
|
|
|
10878
10880
|
["--role R", "groups: equipo (the team: writes to databases, admin tools) or cliente (like any customer)"],
|
|
10879
10881
|
["--cached", "groups ls: don't ask WhatsApp for the live list (faster; may miss new groups)"],
|
|
10880
10882
|
["--integration ID", "link/unlink/history: the WhatsApp Business number's Integration id in Formmy"],
|
|
10883
|
+
["--email E", "integrations (staff): list the numbers of another Formmy account"],
|
|
10881
10884
|
["--days N", "history: conversations active in the last N days (1-30, default 7)"],
|
|
10882
10885
|
["--media", "history: only re-copy the missing files (photos, PDFs, audio) of conversations already imported"],
|
|
10883
10886
|
["--answer on|off", "link (required, no default): on = this agent answers real customers; off = it only records"],
|
|
@@ -10905,7 +10908,7 @@ HELPS.channels = {
|
|
|
10905
10908
|
"Disabling keeps logging messages; nobody answers them.",
|
|
10906
10909
|
"Groups belong to the PERSONAL WhatsApp paired to the agent (not WhatsApp Business). <group> is its name or its jid.",
|
|
10907
10910
|
"link moves a number that already lives in Formmy (EasyBits, a droplet) without redoing Meta's signup; unlink sends it back. Only the owner, an admin of the agent or Ghosty staff.",
|
|
10908
|
-
"integrations lists the owner's WhatsApp Business numbers in Formmy (number, name, who answers today: gs, EasyBits, a droplet or Formmy) with the Integration id that link and history take.",
|
|
10911
|
+
"integrations lists the owner's WhatsApp Business numbers in Formmy (number, name, who answers today: gs, EasyBits, a droplet or Formmy) with the Integration id that link and history take. Numbers the workspace already linked in gs show up too, even if another Formmy account owns them.",
|
|
10909
10912
|
"history brings the number's recent cards, messages and orders from Formmy to the board (link it first; --dry-run works before linking, to choose --days). Re-running never duplicates: run it before the cutover and again right at it. Files (photos, PDFs, audio) are copied to gs too: Formmy deletes them after 7 days, so bring the number within that week; a copy that failed is retried with --media.",
|
|
10910
10913
|
"import: turn off the EasyBits socket first WITHOUT logout (two sockets knock each other off; a logout invalidates the keys). Delete the file afterwards."
|
|
10911
10914
|
],
|
|
@@ -11694,6 +11697,7 @@ async function main() {
|
|
|
11694
11697
|
"unset-env": { type: "string" },
|
|
11695
11698
|
orphans: { type: "boolean" },
|
|
11696
11699
|
skipped: { type: "boolean" },
|
|
11700
|
+
email: { type: "string" },
|
|
11697
11701
|
keep: { type: "boolean" },
|
|
11698
11702
|
boxes: { type: "boolean" },
|
|
11699
11703
|
like: { type: "string" },
|
|
@@ -11755,7 +11759,7 @@ async function main() {
|
|
|
11755
11759
|
const tokens = splitTokens(pos, v);
|
|
11756
11760
|
globals.token = tokens.session;
|
|
11757
11761
|
globals.profile = v.profile;
|
|
11758
|
-
if (v.version) return out({ version: "0.24.
|
|
11762
|
+
if (v.version) return out({ version: "0.24.2" }, () => "0.24.2");
|
|
11759
11763
|
for (const n of normalizeArgs(pos, v)) if (!globals.json) info(dim(n));
|
|
11760
11764
|
const context = (await readConfig()).workspace;
|
|
11761
11765
|
if (!explicitToken()?.startsWith("gat_")) {
|
|
@@ -11874,7 +11878,7 @@ async function main() {
|
|
|
11874
11878
|
throw unknown(cmd, cmd, COMMANDS, "ghosty --help");
|
|
11875
11879
|
}
|
|
11876
11880
|
}
|
|
11877
|
-
var notice = updateNotice("0.24.
|
|
11881
|
+
var notice = updateNotice("0.24.2").catch(() => null);
|
|
11878
11882
|
main().then(
|
|
11879
11883
|
async () => {
|
|
11880
11884
|
const n = await notice;
|
package/package.json
CHANGED