@ghostlytools/cli 1.3.3 → 1.3.5

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 (58) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +2 -1
  3. package/dist/assets/{api-Bg7bh_6E.js → api-CgPyYfjH.js} +2 -2
  4. package/dist/assets/{api-B1fADtqd.js → api-Do7NjRg2.js} +44 -9
  5. package/dist/assets/api-Do7NjRg2.js.map +1 -0
  6. package/dist/assets/{apiKit-BsUZPHLn.js → apiKit-eh5qBKIl.js} +2 -2
  7. package/dist/assets/{apiKit-BsUZPHLn.js.map → apiKit-eh5qBKIl.js.map} +1 -1
  8. package/dist/assets/{apps-DepomCiX.js → apps-B83dRFga.js} +1 -1
  9. package/dist/assets/{apps-BaUNt-5c.js → apps-Cl9MtELY.js} +2 -2
  10. package/dist/assets/{apps-BaUNt-5c.js.map → apps-Cl9MtELY.js.map} +1 -1
  11. package/dist/assets/{arkade-CNnMaoEQ.js → arkade-B5Xn40bC.js} +2 -2
  12. package/dist/assets/{arkade-CNnMaoEQ.js.map → arkade-B5Xn40bC.js.map} +1 -1
  13. package/dist/assets/{backup-Bbz3lyC5.js → backup-BjZcDFjL.js} +4 -4
  14. package/dist/assets/{backup-Bbz3lyC5.js.map → backup-BjZcDFjL.js.map} +1 -1
  15. package/dist/assets/{backup-B5Q1W-Ey.js → backup-CDOh2tuw.js} +1 -1
  16. package/dist/assets/buttons-CFabREDv.js +2 -0
  17. package/dist/assets/{buttons-DS1iURp8.js → buttons-CUKHafux.js} +3 -3
  18. package/dist/assets/{buttons-DS1iURp8.js.map → buttons-CUKHafux.js.map} +1 -1
  19. package/dist/assets/{envelope-fNC941z4.js → envelope-wspXCjle.js} +2 -2
  20. package/dist/assets/{envelope-fNC941z4.js.map → envelope-wspXCjle.js.map} +1 -1
  21. package/dist/assets/{groupFiles-6qnLCnOm.js → groupFiles-Cfrjo3YS.js} +31 -4
  22. package/dist/assets/{groupFiles-6qnLCnOm.js.map → groupFiles-Cfrjo3YS.js.map} +1 -1
  23. package/dist/assets/{host-Dj3C1fn3.js → host-BdS-7nRW.js} +8 -8
  24. package/dist/assets/{host-Dj3C1fn3.js.map → host-BdS-7nRW.js.map} +1 -1
  25. package/dist/assets/{hyperdhtRelay-CrgYQN-g.js → hyperdhtRelay-H97Vz73W.js} +2 -2
  26. package/dist/assets/{hyperdhtRelay-CrgYQN-g.js.map → hyperdhtRelay-H97Vz73W.js.map} +1 -1
  27. package/dist/assets/{irohWeb-DSyLp5Re.js → irohWeb-jErC-V0J.js} +2 -2
  28. package/dist/assets/{irohWeb-DSyLp5Re.js.map → irohWeb-jErC-V0J.js.map} +1 -1
  29. package/dist/assets/{main-BDd11Yd1.js → main-C14lA5aK.js} +24 -18
  30. package/dist/assets/main-C14lA5aK.js.map +1 -0
  31. package/dist/assets/{mainline-CLTo0nGa.js → mainline-CYI1tZT7.js} +2 -2
  32. package/dist/assets/{mainline-CLTo0nGa.js.map → mainline-CYI1tZT7.js.map} +1 -1
  33. package/dist/assets/{networkReason-DwcadZz5.js → networkReason-CiHrd-kG.js} +2 -2
  34. package/dist/assets/{networkReason-DwcadZz5.js.map → networkReason-CiHrd-kG.js.map} +1 -1
  35. package/dist/assets/{nwc-BNFyyECH.js → nwc-0JYm8Vys.js} +3 -3
  36. package/dist/assets/{nwc-BNFyyECH.js.map → nwc-0JYm8Vys.js.map} +1 -1
  37. package/dist/assets/{nwcProvider-BbjJOfLD.js → nwcProvider-2coJAsqr.js} +2 -2
  38. package/dist/assets/{nwcProvider-BbjJOfLD.js.map → nwcProvider-2coJAsqr.js.map} +1 -1
  39. package/dist/assets/{registry-CoLHpxkb.js → registry-BptCF3tL.js} +3 -3
  40. package/dist/assets/{registry-CoLHpxkb.js.map → registry-BptCF3tL.js.map} +1 -1
  41. package/dist/assets/{registry-DoTb6uEr.js → registry-sML83UvL.js} +1 -1
  42. package/dist/assets/{resolve-BIDJ-UUl.js → resolve-2hGrvTen.js} +2 -2
  43. package/dist/assets/{resolve-BIDJ-UUl.js.map → resolve-2hGrvTen.js.map} +1 -1
  44. package/dist/assets/{server-Bx3RGkBC.js → server-BbPiCghe.js} +106 -35
  45. package/dist/assets/server-BbPiCghe.js.map +1 -0
  46. package/dist/assets/{src-D7gcJElT.js → src-BLzG4Sfv.js} +14 -2
  47. package/dist/assets/src-BLzG4Sfv.js.map +1 -0
  48. package/dist/assets/{turnRefs-PN644M9o.js → turnRefs-ClWSgjb0.js} +2 -2
  49. package/dist/assets/{turnRefs-PN644M9o.js.map → turnRefs-ClWSgjb0.js.map} +1 -1
  50. package/dist/assets/{usdt-B2TLRlYa.js → usdt-zwyn_AQK.js} +3 -3
  51. package/dist/assets/{usdt-B2TLRlYa.js.map → usdt-zwyn_AQK.js.map} +1 -1
  52. package/dist/ghostly.mjs +1 -1
  53. package/package.json +1 -1
  54. package/dist/assets/api-B1fADtqd.js.map +0 -1
  55. package/dist/assets/buttons-CUd7j0ZA.js +0 -2
  56. package/dist/assets/main-BDd11Yd1.js.map +0 -1
  57. package/dist/assets/server-Bx3RGkBC.js.map +0 -1
  58. package/dist/assets/src-D7gcJElT.js.map +0 -1
package/README.md CHANGED
@@ -115,7 +115,7 @@ The rows are in alphabetical order of their first command, and every command of
115
115
  | `chat wait <chat> [--until live\|text\|paired] [--timeout s]` | Wait for a chat to go live, carry text, or see its contact. Live means a session that exists now, in this run of the daemon: a chat that was live before a restart counts once its contact answers again |
116
116
  | `daemon [--detach] [--timeout s]`, `daemon status`, `daemon stop [--timeout s]`, `daemon restart [--timeout s]` | Keep the profile online; `status` names its version and its socket (`socket`, for the [socket API](#the-socket-api)); `restart` stops it and starts this release's code in the background ([After an upgrade](#after-an-upgrade)). Ctrl-C, SIGTERM and the terminal closing (SIGHUP) stop it cleanly |
117
117
  | `edit <chat> <message> [text… \| --text <text> \| --stdin] [--force] [--wait none\|confirmed] [--timeout s]` | Replace the text of a message you sent (1:1 chats, `group edit` for a group; `<message>` is the `messageId` `send` gave, or its wire id). The contact sees it in place, marked edited; `--wait confirmed` waits for its app to confirm (the default without a daemon). At most 100 edits a message, no time limit; an older contact app gets it once it shows edits |
118
- | `engine <method> [json \| -] [--confirm-real] [--show-secret]`, `engine --list` | Any call of the app's engine |
118
+ | `engine <method> [json \| -] [--confirm-real] [--show-secret] [--force]`, `engine --list` | Any call of the app's engine |
119
119
  | `events [--since seq]` | What the event journal holds, without following |
120
120
  | `file list <chat\|group>`, `file accept\|decline\|pause\|resume\|cancel [<chat>] <file>` | Transfers; a file over 25 MiB waits for `file accept` (files/3), and so does a group's file that did not come by itself (over 8 MiB). A file's id names its chat or its group, so `<chat>` may be left out |
121
121
  | `file resend [<chat>] <file>`, `file request [<chat>] <file>` | A file that stopped moving: sent again from here, or asked for again from the contact (a group's file: from whoever holds it); either goes on from the bytes the receiver holds (files/3) |
package/SKILL.md CHANGED
@@ -358,7 +358,8 @@ proof needs a person who holds the key: leave that to the owner.
358
358
 
359
359
  - Output is JSON. A failure is `{"error":{"code","message"}}` with exit 1 (failed), 2 (usage), 3 (not found),
360
360
  4 (timed out) or 5 (needs `--force`, `--yes` or `--confirm-real`).
361
- - `send` refuses text that looks like a recovery phrase, a private key or a Cashu token unless `--force`.
361
+ - `send` (and `ghostly engine sendMessage` and the other sends through `engine`) refuses text that looks like a recovery
362
+ phrase, a private key or a Cashu token unless `--force`.
362
363
  - Spending real money (Mainnet) needs `--confirm-real`.
363
364
  - Seeds, keys and backups are never printed without `--show-secret`; `group show` and `group list` hide entry links, and
364
365
  `chat list` and `chat show` a pending chat's invite code.
@@ -1,3 +1,3 @@
1
- import { a as findChat, s as findGroup } from "./apiKit-BsUZPHLn.js";
2
- import { a as hideStateSecrets, i as groupSendRefused, n as SETTABLE, o as mentionsFor, r as callApi, s as redactSettings, t as API_METHODS } from "./api-B1fADtqd.js";
1
+ import { a as findChat, s as findGroup } from "./apiKit-eh5qBKIl.js";
2
+ import { a as hideStateSecrets, i as groupSendRefused, n as SETTABLE, o as mentionsFor, r as callApi, s as redactSettings, t as API_METHODS } from "./api-Do7NjRg2.js";
3
3
  export { API_METHODS, SETTABLE, callApi, findChat, findGroup, groupSendRefused, hideStateSecrets, mentionsFor, redactSettings };
@@ -1,14 +1,14 @@
1
- import { $n as GROUP_FILE_LIMITS, Bo as GhostlyHttpError, Cl as randomBytes$1, Fo as AWAITING_PEER_MS, Hr as TYPING_REFRESH_MS, Qa as appCardId, Sc as ownInviteRefusal, Vr as TYPING_KINDS, Wo as LIMITS, Wr as sanitizeTypingStatus, Xi as identityStatement, Za as STATUS_CARD_LIMITS, _a as VOICE_LIMITS, _l as MAX_AVATAR_LENGTH, _o as isAppRef, at as groupName, ba as parseVoiceMeta, bc as inviteLink, ci as APP_DATA_MAX_BYTES, eo as cardLine, ga as PLAYABLE_AUDIO, ha as sanitizeMime, m as APP_PERMISSIONS, ma as sanitizeFileName, no as checkStatusCard, po as appRef, va as baseMime, vl as sanitizeAvatar, wa as readImageMeta, wl as toBase64Url, xa as voicePeaksOf, y as isAppUrl } from "./src-D7gcJElT.js";
1
+ import { $n as GROUP_FILE_LIMITS, Bo as GhostlyHttpError, Cl as randomBytes$1, Fo as AWAITING_PEER_MS, Hr as TYPING_REFRESH_MS, Qa as appCardId, Sc as ownInviteRefusal, Vr as TYPING_KINDS, Wo as LIMITS, Wr as sanitizeTypingStatus, Xi as identityStatement, Za as STATUS_CARD_LIMITS, _a as VOICE_LIMITS, _l as MAX_AVATAR_LENGTH, _o as isAppRef, at as groupName, ba as parseVoiceMeta, bc as inviteLink, ci as APP_DATA_MAX_BYTES, eo as cardLine, ga as PLAYABLE_AUDIO, ha as sanitizeMime, m as APP_PERMISSIONS, ma as sanitizeFileName, no as checkStatusCard, po as appRef, va as baseMime, vl as sanitizeAvatar, wa as readImageMeta, wl as toBase64Url, xa as voicePeaksOf, y as isAppUrl } from "./src-BLzG4Sfv.js";
2
2
  import { c as fileStore } from "./idb-B5L8wuOm.js";
3
- import { O as waitingGroupFile, T as removeStored, U as iceServerProblem, W as iceServerSetting, i as groupOfFile, l as replyRef, n as groupFileId, v as paymentNetwork } from "./groupFiles-6qnLCnOm.js";
3
+ import { O as waitingGroupFile, T as removeStored, U as iceServerProblem, W as iceServerSetting, i as groupOfFile, l as replyRef, n as groupFileId, v as paymentNetwork } from "./groupFiles-Cfrjo3YS.js";
4
4
  import { f as FILE_BYTES_STEP, o as fileBytes, s as fileBytesOf } from "./fileBytes-Di7VZtmU.js";
5
- import { t as IDENTITY_PROVIDERS } from "./registry-CoLHpxkb.js";
6
- import { a as waitForEdit, c as findSecret, i as pressable, n as buttonsCard, o as waitForGroupFrame, s as waitForMessage, t as BUTTON_METHODS } from "./buttons-DS1iURp8.js";
7
- import { i as ENGINE_READS, n as withStoredIds, r as ENGINE_METHODS } from "./turnRefs-PN644M9o.js";
5
+ import { t as IDENTITY_PROVIDERS } from "./registry-BptCF3tL.js";
6
+ import { a as waitForEdit, c as findSecret, i as pressable, n as buttonsCard, o as waitForGroupFrame, s as waitForMessage, t as BUTTON_METHODS } from "./buttons-CUKHafux.js";
7
+ import { i as ENGINE_READS, n as withStoredIds, r as ENGINE_METHODS } from "./turnRefs-ClWSgjb0.js";
8
8
  import { i as localFileError, r as asCliError, t as CliError } from "./errors-B-zMxbcd.js";
9
- import { _ as str, a as findChat, c as groupOf, d as messageOf, f as node, g as state, h as sentAt, i as chatOrGroup, l as inviteTaken, m as oneOf, n as bool, o as findChatOrGroup, p as num, r as chatOf, s as findGroup, u as list, v as waitForState } from "./apiKit-BsUZPHLn.js";
10
- import { t as BACKUP_METHODS } from "./backup-Bbz3lyC5.js";
11
- import { o as checkedBundle } from "./apps-BaUNt-5c.js";
9
+ import { _ as str, a as findChat, c as groupOf, d as messageOf, f as node, g as state, h as sentAt, i as chatOrGroup, l as inviteTaken, m as oneOf, n as bool, o as findChatOrGroup, p as num, r as chatOf, s as findGroup, u as list, v as waitForState } from "./apiKit-eh5qBKIl.js";
10
+ import { t as BACKUP_METHODS } from "./backup-BjZcDFjL.js";
11
+ import { o as checkedBundle } from "./apps-Cl9MtELY.js";
12
12
  import { generateMnemonic } from "@scure/bip39";
13
13
  import { wordlist } from "@scure/bip39/wordlists/english.js";
14
14
  import { openAsBlob, readFileSync, renameSync, writeFileSync } from "node:fs";
@@ -999,6 +999,17 @@ function cardTexts(value, out = []) {
999
999
  return out;
1000
1000
  }
1001
1001
  /**
1002
+ * The first text in `value` (a card's fields, a message's text…) that looks like a seed, a private key or a Cashu token,
1003
+ * read as given and as a card carries it (`cardLine`).
1004
+ */
1005
+ function secretIn(value) {
1006
+ for (const text of cardTexts(value)) {
1007
+ const secret = findSecret(text) ?? findSecret(cardLine(text, Infinity) ?? "");
1008
+ if (secret) return secret;
1009
+ }
1010
+ return null;
1011
+ }
1012
+ /**
1002
1013
  * The secret guard `send` has (docs/CLI.md § Safety): a card whose text looks like a seed, a private key or a Cashu
1003
1014
  * token goes only with `--force`. `fields` are what this command gives (an update's own, not the card it merges over).
1004
1015
  * A card's text is read as given and as the card carries it (`cardLine`): a line loses its invisible characters on the
@@ -4061,6 +4072,7 @@ var METHODS = {
4061
4072
  if (raw !== void 0 && (raw === null || typeof raw !== "object" || Array.isArray(raw))) throw new CliError("bad_request", "params must be an object");
4062
4073
  let args = raw;
4063
4074
  if (args && "confirmedReal" in args && !bool(params, "confirmReal")) throw new CliError("confirm", `${method} spends real money: pass --confirm-real (confirmReal: true over the socket) to confirm it`);
4075
+ if (args && ENGINE_SENDS.has(method) && !bool(params, "force")) await guardEngineSend(ctx, method, args);
4064
4076
  if (method === "getMessages") return node(ctx).getMessages(str(args ?? {}, "linkId", true));
4065
4077
  if (method === "getState") return state(ctx);
4066
4078
  if (method === "setActiveLink") inviteShown.get(ctx)?.();
@@ -4070,6 +4082,29 @@ var METHODS = {
4070
4082
  return await target.call(node(ctx), args) ?? null;
4071
4083
  }
4072
4084
  };
4085
+ /**
4086
+ * The engine's calls that send a text this side writes: `engine.call` runs the secret guard of `send`, `edit` and
4087
+ * `forward` on them too (docs/CLI.md § Safety), so a raw call is no way around it. `force: true` (`--force`) sends it.
4088
+ */
4089
+ var ENGINE_SENDS = /* @__PURE__ */ new Set([
4090
+ "sendMessage",
4091
+ "sendGroupMessage",
4092
+ "editMessage",
4093
+ "forwardMessages"
4094
+ ]);
4095
+ async function guardEngineSend(ctx, method, args) {
4096
+ let texts = [args.text, args.card];
4097
+ if (method === "forwardMessages") {
4098
+ const ids = Array.isArray(args.messageIds) ? args.messageIds.filter((id) => typeof id === "string") : [];
4099
+ const linkId = args.linkId;
4100
+ texts = typeof linkId === "string" && linkId ? await Promise.all(ids.map(async (id) => {
4101
+ const message = await node(ctx).getMessage(linkId, id);
4102
+ return message && !message.file ? message.text : null;
4103
+ })) : [];
4104
+ }
4105
+ const secret = secretIn(texts);
4106
+ if (secret) throw new CliError("confirm", `The text looks like ${secret.kind === "cashu" ? "a Cashu token (money anyone who reads it can take)" : "a secret (a seed or a private key)"}; call ${method} with --force if you mean to`, { kind: secret.kind });
4107
+ }
4073
4108
  /** Reacts to a message of a chat or a group (`group:<id>`): `emoji`, or `remove` for "" (WISP 400 § Reactions). */
4074
4109
  async function react(ctx, linkId, params) {
4075
4110
  const messageId = str(params, "message", true);
@@ -4214,4 +4249,4 @@ async function callApi(ctx, method, params = {}) {
4214
4249
  //#endregion
4215
4250
  export { flushCardUpdates as _, hideStateSecrets as a, paymentJson as c, nodeLocalFetch as d, chatJson as f, resumeHolds as g, groupMessageJson as h, groupSendRefused as i, reportAppFrames as l, groupJson as m, SETTABLE as n, mentionsFor as o, chatMessageJson as p, callApi as r, redactSettings as s, API_METHODS as t, servedApps as u };
4216
4251
 
4217
- //# sourceMappingURL=api-B1fADtqd.js.map
4252
+ //# sourceMappingURL=api-Do7NjRg2.js.map