@samva/cli 0.16.0 → 0.17.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/AGENTS.md +16 -7
- package/dist/bin.mjs +158 -79
- package/package.json +5 -5
package/AGENTS.md
CHANGED
|
@@ -21,9 +21,15 @@ response writes its body to stderr and exits `4` for 401 and 403, otherwise `1`.
|
|
|
21
21
|
is no built-in filter.
|
|
22
22
|
|
|
23
23
|
`samva api-keys` manages the organization's keys: `list`, `get`, `create`, `update`, `rotate`, and
|
|
24
|
-
`revoke`. `create` takes `--name` and
|
|
25
|
-
<resource>=read|write`
|
|
26
|
-
|
|
24
|
+
`revoke`. `create` takes `--name` and either `--full-access` or restricted access built from repeatable
|
|
25
|
+
`--grant <resource>=read|write` and mailbox access: repeatable `--mailbox-permission
|
|
26
|
+
read|update|send|quarantine.read`, optionally narrowed to repeatable `--mailbox <id>` (default:
|
|
27
|
+
every mailbox the owner reaches) with `--send-mode approval` (each send waits for a person other
|
|
28
|
+
than the key). `--namespace <id>` confines a restricted key to one namespace. Passing no access, or both
|
|
29
|
+
`--full-access` and restricted access, exits `2`, as does `--mailbox` or `--send-mode` without a
|
|
30
|
+
`--mailbox-permission`. `--description` and `--expires-at` are optional. `update` renames a key,
|
|
31
|
+
sets its description, or changes a mailbox key's `--send-mode` (a person signed in with `samva
|
|
32
|
+
login`); every other part of a key's access is fixed at creation. The API refuses a key with more access than the
|
|
27
33
|
caller holds. `create` and `rotate` return the secret once: `--json` carries `{apiKey, key,
|
|
28
34
|
displayOnce, warning}`, so `samva api-keys create ... --json | jq -r .data.key` yields the key, and
|
|
29
35
|
human mode prints it to stdout with the warning on stderr. `rotate` and `revoke` require
|
|
@@ -136,7 +142,10 @@ calls to you, rather than to an installation. Read what exists with `list`, `ver
|
|
|
136
142
|
`run <id> <run-id>` (adds the handler's log lines); the list commands page with `--limit`,
|
|
137
143
|
`--cursor`, and `--all --jsonl`.
|
|
138
144
|
|
|
139
|
-
`samva mailboxes` reads and sends as a mailbox
|
|
145
|
+
`samva mailboxes` reads and sends as a mailbox. Every command except `list` and `create`
|
|
146
|
+
takes the mailbox ID as its first argument and the message, action, or endpoint ID second,
|
|
147
|
+
as in `read <mailbox-id> <message-id>` and `endpoints update <mailbox-id> <endpoint-id>`; `events`
|
|
148
|
+
takes any number of mailbox IDs, or none for every mailbox the credential reads. `list` pages with `--limit`, `--cursor`, `--after`,
|
|
140
149
|
and `--before`. `create --address <address> --name <name>` makes a mailbox with one email endpoint; the
|
|
141
150
|
slug defaults to the address's local part, and a collision asks for `--slug` rather than suffixing.
|
|
142
151
|
`get <id>` inspects a mailbox; `update <id> --data <JSON-or-@file>` changes
|
|
@@ -156,9 +165,9 @@ public SDK describes email only.
|
|
|
156
165
|
Quarantine `list` pages the same way, bounded by `--after` and `--before` on when a message was
|
|
157
166
|
held; `release` and `discard` take the held message's `id` and require a person signed in with
|
|
158
167
|
`samva login`. Discard requires confirmation (`--yes` outside a terminal) and supports `--dry-run`.
|
|
159
|
-
`actions list
|
|
160
|
-
`--all --jsonl`. `actions approve <
|
|
161
|
-
|
|
168
|
+
`actions list <mailbox-id>` filters by `--state` and pages with `--limit`, `--cursor`, and
|
|
169
|
+
`--all --jsonl`. `actions approve <mailbox-id> <action-id>` and `actions deny <mailbox-id>
|
|
170
|
+
<action-id> [--reason <text>]` require a person different from the proposer, confirmation
|
|
162
171
|
(`--yes` outside a terminal), and offer `--dry-run`.
|
|
163
172
|
Human mailbox and extension results retain the same facts as JSON: mailbox endpoints (channel, address,
|
|
164
173
|
sender name, default), thread state and activity, message bodies, attachments, authentication and actor,
|
package/dist/bin.mjs
CHANGED
|
@@ -14106,7 +14106,7 @@ var layer12 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE
|
|
|
14106
14106
|
// package.json
|
|
14107
14107
|
var package_default = {
|
|
14108
14108
|
name: "@samva/cli",
|
|
14109
|
-
version: "0.
|
|
14109
|
+
version: "0.17.0",
|
|
14110
14110
|
description: "Samva CLI \u2014 email and platform operations from your terminal",
|
|
14111
14111
|
keywords: [
|
|
14112
14112
|
"cli",
|
|
@@ -14168,10 +14168,10 @@ var package_default = {
|
|
|
14168
14168
|
vitest: "catalog:"
|
|
14169
14169
|
},
|
|
14170
14170
|
optionalDependencies: {
|
|
14171
|
-
"@samva/cli-darwin-arm64": "workspace:0.
|
|
14172
|
-
"@samva/cli-darwin-x64": "workspace:0.
|
|
14173
|
-
"@samva/cli-linux-arm64": "workspace:0.
|
|
14174
|
-
"@samva/cli-linux-x64": "workspace:0.
|
|
14171
|
+
"@samva/cli-darwin-arm64": "workspace:0.17.0",
|
|
14172
|
+
"@samva/cli-darwin-x64": "workspace:0.17.0",
|
|
14173
|
+
"@samva/cli-linux-arm64": "workspace:0.17.0",
|
|
14174
|
+
"@samva/cli-linux-x64": "workspace:0.17.0"
|
|
14175
14175
|
},
|
|
14176
14176
|
engines: {
|
|
14177
14177
|
node: ">=18"
|
|
@@ -19353,6 +19353,7 @@ var Literals4 = (name, choices) => Literals2(argumentKind, name, choices);
|
|
|
19353
19353
|
var optional5 = (arg) => optional3(arg);
|
|
19354
19354
|
var withDescription4 = /* @__PURE__ */ dual(2, (self, description) => withDescription(self, description));
|
|
19355
19355
|
var withDefault6 = withDefault4;
|
|
19356
|
+
var atLeast3 = /* @__PURE__ */ dual(2, (self, min) => atLeast(self, min));
|
|
19356
19357
|
var withSchema3 = /* @__PURE__ */ dual(2, (self, schema) => withSchema(self, schema));
|
|
19357
19358
|
var filterMap3 = /* @__PURE__ */ dual(3, (self, f, onNone) => filterMap2(self, f, onNone));
|
|
19358
19359
|
|
|
@@ -26569,6 +26570,7 @@ var API_KEY_STATEMENT = {
|
|
|
26569
26570
|
};
|
|
26570
26571
|
var API_KEY_RESOURCES = Object.keys(API_KEY_STATEMENT);
|
|
26571
26572
|
var API_KEY_LEVEL_RESOURCES = API_KEY_RESOURCES.filter((resource) => resource !== "mailboxes");
|
|
26573
|
+
var API_KEY_MAILBOX_ACTIONS = mailboxKeyActions;
|
|
26572
26574
|
function apiKeyAccessLevels(resource) {
|
|
26573
26575
|
return API_KEY_STATEMENT[resource].some((action) => action !== "read") ? ["read", "write"] : ["read"];
|
|
26574
26576
|
}
|
|
@@ -29066,7 +29068,7 @@ var parseGrant = (raw) => {
|
|
|
29066
29068
|
if (resource === "mailboxes") {
|
|
29067
29069
|
return new CliUsageError({
|
|
29068
29070
|
code: "invalid_grant",
|
|
29069
|
-
message: "--grant does not cover mailboxes; mailbox
|
|
29071
|
+
message: "--grant does not cover mailboxes; use --mailbox-permission <action> (with optional --mailbox and --send-mode) instead."
|
|
29070
29072
|
});
|
|
29071
29073
|
}
|
|
29072
29074
|
if (!isLevelResource(resource) || !isGrantLevel(level)) {
|
|
@@ -29083,19 +29085,52 @@ var parseGrant = (raw) => {
|
|
|
29083
29085
|
}
|
|
29084
29086
|
return { resource, level };
|
|
29085
29087
|
};
|
|
29086
|
-
var
|
|
29087
|
-
|
|
29088
|
+
var repeated = (values) => values.find((value, index) => values.indexOf(value) !== index);
|
|
29089
|
+
var mailboxAccessFromFlags = (flags) => gen2(function* () {
|
|
29090
|
+
if (flags.permissions.length === 0) {
|
|
29091
|
+
if (flags.mailboxIds.length > 0 || isSome2(flags.sendMode)) {
|
|
29092
|
+
return yield* new CliUsageError({
|
|
29093
|
+
code: "mailbox_permission_required",
|
|
29094
|
+
message: `--mailbox and --send-mode narrow mailbox access; also pass --mailbox-permission ${API_KEY_MAILBOX_ACTIONS.join("|")}.`
|
|
29095
|
+
});
|
|
29096
|
+
}
|
|
29097
|
+
return;
|
|
29098
|
+
}
|
|
29099
|
+
const duplicatePermission = repeated(flags.permissions);
|
|
29100
|
+
if (duplicatePermission !== undefined) {
|
|
29101
|
+
return yield* new CliUsageError({
|
|
29102
|
+
code: "invalid_mailbox_access",
|
|
29103
|
+
message: `--mailbox-permission names ${duplicatePermission} more than once.`
|
|
29104
|
+
});
|
|
29105
|
+
}
|
|
29106
|
+
const duplicateMailbox = repeated(flags.mailboxIds);
|
|
29107
|
+
if (duplicateMailbox !== undefined) {
|
|
29108
|
+
return yield* new CliUsageError({
|
|
29109
|
+
code: "invalid_mailbox_access",
|
|
29110
|
+
message: `--mailbox names ${duplicateMailbox} more than once.`
|
|
29111
|
+
});
|
|
29112
|
+
}
|
|
29113
|
+
return {
|
|
29114
|
+
permissions: flags.permissions,
|
|
29115
|
+
...flags.mailboxIds.length > 0 ? { mailboxIds: flags.mailboxIds } : {},
|
|
29116
|
+
...isSome2(flags.sendMode) ? { sendMode: flags.sendMode.value } : {}
|
|
29117
|
+
};
|
|
29118
|
+
});
|
|
29119
|
+
var accessFromFlags = (grants, fullAccess, mailbox, namespace) => gen2(function* () {
|
|
29120
|
+
const restrictedFlags = grants.length > 0 || mailbox.permissions.length > 0 || mailbox.mailboxIds.length > 0 || isSome2(mailbox.sendMode) || isSome2(namespace);
|
|
29121
|
+
if (fullAccess && restrictedFlags) {
|
|
29088
29122
|
return yield* new CliUsageError({
|
|
29089
29123
|
code: "access_conflict",
|
|
29090
|
-
message: "Pass either --full-access or --grant
|
|
29124
|
+
message: "Pass either --full-access or restricted access (--grant, --mailbox-permission, --namespace), not both."
|
|
29091
29125
|
});
|
|
29092
29126
|
}
|
|
29093
29127
|
if (fullAccess)
|
|
29094
29128
|
return { mode: "full" };
|
|
29095
|
-
|
|
29129
|
+
const mailboxes = yield* mailboxAccessFromFlags(mailbox);
|
|
29130
|
+
if (grants.length === 0 && mailboxes === undefined) {
|
|
29096
29131
|
return yield* new CliUsageError({
|
|
29097
29132
|
code: "access_required",
|
|
29098
|
-
message: "Choose the key's access: --full-access, or one or more --grant <resource>=read|write
|
|
29133
|
+
message: "Choose the key's access: --full-access, or one or more --grant <resource>=read|write and/or --mailbox-permission <action>."
|
|
29099
29134
|
});
|
|
29100
29135
|
}
|
|
29101
29136
|
const resources = {};
|
|
@@ -29111,7 +29146,12 @@ var accessFromFlags = (grants, fullAccess) => gen2(function* () {
|
|
|
29111
29146
|
}
|
|
29112
29147
|
resources[grant.resource] = grant.level;
|
|
29113
29148
|
}
|
|
29114
|
-
return {
|
|
29149
|
+
return {
|
|
29150
|
+
mode: "restricted",
|
|
29151
|
+
resources,
|
|
29152
|
+
...mailboxes === undefined ? {} : { mailboxes },
|
|
29153
|
+
...isSome2(namespace) ? { namespaceId: namespace.value } : {}
|
|
29154
|
+
};
|
|
29115
29155
|
});
|
|
29116
29156
|
var parseExpiresAt = (raw) => Number.isNaN(Date.parse(raw)) ? fail6(new CliUsageError({
|
|
29117
29157
|
code: "invalid_expires_at",
|
|
@@ -29125,7 +29165,12 @@ var describeAccess = (access) => {
|
|
|
29125
29165
|
return "full";
|
|
29126
29166
|
const grants = Object.entries(access.resources).filter(([, level]) => level !== undefined).map(([resource, level]) => `${resource}:${level}`);
|
|
29127
29167
|
if (access.mailboxes !== undefined && access.mailboxes !== null) {
|
|
29128
|
-
|
|
29168
|
+
const { permissions, mailboxIds, sendMode } = access.mailboxes;
|
|
29169
|
+
const scope = [
|
|
29170
|
+
...mailboxIds === undefined || mailboxIds === null ? [] : [mailboxIds.join("+")],
|
|
29171
|
+
...sendMode === undefined || sendMode === "send" ? [] : [`${sendMode} sends`]
|
|
29172
|
+
];
|
|
29173
|
+
grants.push(`mailboxes:${permissions.join("+")}${scope.length === 0 ? "" : ` [${scope.join("; ")}]`}`);
|
|
29129
29174
|
}
|
|
29130
29175
|
if (access.namespaceId !== undefined && access.namespaceId !== null)
|
|
29131
29176
|
grants.push(`namespace:${access.namespaceId}`);
|
|
@@ -29204,11 +29249,19 @@ var create2 = make29("create", {
|
|
|
29204
29249
|
description: String9("description").pipe(withDescription2("What the key is for"), optional4),
|
|
29205
29250
|
expiresAt: String9("expires-at").pipe(withDescription2("When the key stops working, an ISO 8601 instant"), optional4),
|
|
29206
29251
|
grant: String9("grant").pipe(withDescription2(`Give a restricted key a resource at a level, <resource>=read|write (repeatable). Resources: ${GRANTABLE_RESOURCES.join(", ")}`), atLeast2(0)),
|
|
29207
|
-
|
|
29252
|
+
mailboxPermission: Literals3("mailbox-permission", API_KEY_MAILBOX_ACTIONS).pipe(withDescription2(`Let a restricted key work in mailboxes with this action (repeatable): ${API_KEY_MAILBOX_ACTIONS.join(", ")}`), atLeast2(0)),
|
|
29253
|
+
mailbox: String9("mailbox").pipe(withSchema2(MailboxId), withDescription2("Confine the mailbox access to this mailbox (repeatable); omit for every mailbox the owner reaches"), atLeast2(0)),
|
|
29254
|
+
sendMode: Literals3("send-mode", mailboxSendModes).pipe(withDescription2("With approval, each send waits until a person other than the key approves it (default send)"), optional4),
|
|
29255
|
+
namespace: String9("namespace").pipe(withSchema2(NamespaceId), withDescription2("Confine a restricted key to one namespace (ns_...)"), optional4),
|
|
29256
|
+
fullAccess: Boolean6("full-access").pipe(withDescription2("Give the key its owner's full access instead of restricted access"), withDefault5(false)),
|
|
29208
29257
|
dryRun: dryRunFlag,
|
|
29209
29258
|
json: jsonFlag
|
|
29210
29259
|
}).pipe(withDescription3("Create an API key. The secret is shown once; the API refuses access you do not hold."), withExamples([
|
|
29211
29260
|
{ command: "samva api-keys create --name ci --grant email=write --dry-run" },
|
|
29261
|
+
{
|
|
29262
|
+
command: "samva api-keys create --name agent --mailbox-permission read --mailbox-permission send --mailbox mbx_1234567890123456 --send-mode approval",
|
|
29263
|
+
description: "A key that works in one mailbox and needs a person to approve each send"
|
|
29264
|
+
},
|
|
29212
29265
|
{
|
|
29213
29266
|
command: "samva api-keys create --name ci --grant email=write --json | jq -r .data.key",
|
|
29214
29267
|
description: "Pipe the secret into another tool"
|
|
@@ -29216,8 +29269,20 @@ var create2 = make29("create", {
|
|
|
29216
29269
|
{
|
|
29217
29270
|
command: "samva api-keys create --name deploy --full-access --expires-at 2027-01-01T00:00:00Z"
|
|
29218
29271
|
}
|
|
29219
|
-
]), withHandler(({
|
|
29220
|
-
|
|
29272
|
+
]), withHandler(({
|
|
29273
|
+
name,
|
|
29274
|
+
description,
|
|
29275
|
+
expiresAt,
|
|
29276
|
+
grant,
|
|
29277
|
+
mailboxPermission,
|
|
29278
|
+
mailbox,
|
|
29279
|
+
sendMode,
|
|
29280
|
+
namespace,
|
|
29281
|
+
fullAccess,
|
|
29282
|
+
dryRun,
|
|
29283
|
+
json
|
|
29284
|
+
}) => withJsonQuiet(json, gen2(function* () {
|
|
29285
|
+
const access = yield* accessFromFlags(grant, fullAccess, { permissions: mailboxPermission, mailboxIds: mailbox, sendMode }, namespace);
|
|
29221
29286
|
const expires = yield* match(expiresAt, {
|
|
29222
29287
|
onNone: () => void_3,
|
|
29223
29288
|
onSome: parseExpiresAt
|
|
@@ -29233,7 +29298,11 @@ var create2 = make29("create", {
|
|
|
29233
29298
|
});
|
|
29234
29299
|
if (dryRun) {
|
|
29235
29300
|
if (json) {
|
|
29236
|
-
return yield* printJson({
|
|
29301
|
+
return yield* printJson({
|
|
29302
|
+
dryRun: true,
|
|
29303
|
+
action: "api-keys.create",
|
|
29304
|
+
request: payload
|
|
29305
|
+
});
|
|
29237
29306
|
}
|
|
29238
29307
|
return yield* printFields([
|
|
29239
29308
|
["Action", "api-keys.create"],
|
|
@@ -29256,13 +29325,17 @@ var update3 = make29("update", {
|
|
|
29256
29325
|
id: idArgument,
|
|
29257
29326
|
name: String9("name").pipe(withDescription2("New key name"), optional4),
|
|
29258
29327
|
description: String9("description").pipe(withDescription2("New description"), optional4),
|
|
29328
|
+
sendMode: Literals3("send-mode", mailboxSendModes).pipe(withDescription2("Change a mailbox key's send mode: approval holds each send for a person other than the key, send releases them. Takes a person signed in with samva login"), optional4),
|
|
29259
29329
|
dryRun: dryRunFlag,
|
|
29260
29330
|
json: jsonFlag
|
|
29261
|
-
}).pipe(withDescription3("Rename an API key or change
|
|
29262
|
-
|
|
29331
|
+
}).pipe(withDescription3("Rename an API key, change its description, or change a mailbox key's send mode. Its other access is fixed at creation; create a new key to change it."), withExamples([
|
|
29332
|
+
{ command: "samva api-keys update key_abc123 --name ci-prod --dry-run" },
|
|
29333
|
+
{ command: "samva api-keys update key_abc123 --send-mode approval" }
|
|
29334
|
+
]), withHandler(({ id, name, description, sendMode, dryRun, json }) => withJsonQuiet(json, gen2(function* () {
|
|
29335
|
+
if (isNone2(name) && isNone2(description) && isNone2(sendMode)) {
|
|
29263
29336
|
return yield* new CliUsageError({
|
|
29264
29337
|
code: "update_required",
|
|
29265
|
-
message: "Pass --name, --description, or
|
|
29338
|
+
message: "Pass --name, --description, --send-mode, or a combination."
|
|
29266
29339
|
});
|
|
29267
29340
|
}
|
|
29268
29341
|
const payload = yield* decodeRequest(ApiKeysUpdateRequestJson, {
|
|
@@ -29270,6 +29343,10 @@ var update3 = make29("update", {
|
|
|
29270
29343
|
...match(description, {
|
|
29271
29344
|
onNone: () => ({}),
|
|
29272
29345
|
onSome: (value) => ({ description: value })
|
|
29346
|
+
}),
|
|
29347
|
+
...match(sendMode, {
|
|
29348
|
+
onNone: () => ({}),
|
|
29349
|
+
onSome: (value) => ({ mailboxes: { sendMode: value } })
|
|
29273
29350
|
})
|
|
29274
29351
|
});
|
|
29275
29352
|
if (dryRun) {
|
|
@@ -29285,7 +29362,8 @@ var update3 = make29("update", {
|
|
|
29285
29362
|
["Action", "api-keys.update"],
|
|
29286
29363
|
["API key", id],
|
|
29287
29364
|
["Name", payload.name],
|
|
29288
|
-
["Description", payload.description]
|
|
29365
|
+
["Description", payload.description],
|
|
29366
|
+
["Send mode", payload.mailboxes?.sendMode]
|
|
29289
29367
|
]);
|
|
29290
29368
|
}
|
|
29291
29369
|
const client = yield* getClientProvider;
|
|
@@ -66402,7 +66480,7 @@ var refusalNext = (failure) => {
|
|
|
66402
66480
|
case "ForbiddenError":
|
|
66403
66481
|
return "Use a credential that may read mailboxes and follow the API message.";
|
|
66404
66482
|
case "ResourceNotFoundError":
|
|
66405
|
-
return "Run samva mailboxes list to find the mailboxes this credential can read, then retry with those
|
|
66483
|
+
return "Run samva mailboxes list to find the mailboxes this credential can read, then retry with those mailbox ids.";
|
|
66406
66484
|
case "CursorExpiredError":
|
|
66407
66485
|
return "Events after your cursor expired. Read current state from the API and reconnect without --cursor.";
|
|
66408
66486
|
case "ValidationError":
|
|
@@ -66529,12 +66607,16 @@ var tailEvents = (options) => gen2(function* () {
|
|
|
66529
66607
|
})), mapError4(streamError), options.limit === undefined ? (stream) => stream : take3(options.limit), interruptWhen2(interrupted), runForEach2(options.onEvent), raceFirst2(interrupted.pipe(andThen2(sleep2(HANDLER_DRAIN)))))));
|
|
66530
66608
|
});
|
|
66531
66609
|
var mailboxesEventsCommand = make29("events", {
|
|
66610
|
+
mailbox: String10("mailbox-id").pipe(withDescription4("Mailboxes to follow; omit to follow every mailbox the credential reads"), withSchema3(MailboxId), atLeast3(0)),
|
|
66532
66611
|
cursor: String9("cursor").pipe(withDescription2("Replay events after a cursor from an earlier event frame, then go live"), optional4),
|
|
66533
|
-
mailbox: String9("mailbox").pipe(withSchema2(MailboxId), atLeast2(0)),
|
|
66534
66612
|
limit: Int5("limit").pipe(optional4),
|
|
66535
66613
|
noReconnect: Boolean6("no-reconnect").pipe(withDefault5(false), withDescription2("Exit non-zero with the last cursor when the connection drops, instead of reconnecting from it"))
|
|
66536
66614
|
}).pipe(withDescription3("Tail mailbox events, one record per line; --jsonl wraps each in a result envelope; a dropped connection reconnects from the last cursor; Ctrl+C exits cleanly"), withExamples([
|
|
66537
|
-
{ command: "samva mailboxes events
|
|
66615
|
+
{ command: "samva mailboxes events mbx_1234567890123456 --limit 10" },
|
|
66616
|
+
{
|
|
66617
|
+
command: "samva mailboxes events mbx_1234567890123456 mbx_6543210987654321 --jsonl",
|
|
66618
|
+
description: "Follow several mailboxes"
|
|
66619
|
+
},
|
|
66538
66620
|
{ command: "samva mailboxes events --jsonl", description: "Stream envelopes for automation" },
|
|
66539
66621
|
{ command: "samva mailboxes events --cursor <cursor-from-an-event-frame>" },
|
|
66540
66622
|
{
|
|
@@ -71573,7 +71655,7 @@ var decodeThreadPage = decoder3(WireThreadPage, "thread page");
|
|
|
71573
71655
|
var decodeMessage = decoder3(WireMessage, "message");
|
|
71574
71656
|
|
|
71575
71657
|
// src/commands/mailboxes.ts
|
|
71576
|
-
var
|
|
71658
|
+
var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId));
|
|
71577
71659
|
var messageIdArgument = String10("message-id").pipe(withSchema3(MessageId));
|
|
71578
71660
|
var optional6 = (name) => String9(name).pipe(optional4);
|
|
71579
71661
|
var pageFlags2 = {
|
|
@@ -71616,7 +71698,7 @@ var chatContent = (channel, flags) => gen2(function* () {
|
|
|
71616
71698
|
}
|
|
71617
71699
|
if (channel !== "whatsapp")
|
|
71618
71700
|
return yield* usage2("mailbox_chat_template", "A template sends on WhatsApp only.");
|
|
71619
|
-
const templateId = yield*
|
|
71701
|
+
const templateId = yield* decodeEffect2(TemplateId)(flags.template.value).pipe(mapError2(() => usage2("mailbox_chat_template", "--template must be an approved template id (tmpl_\u2026).")));
|
|
71620
71702
|
const dataText = getOrUndefined(flags.data);
|
|
71621
71703
|
if (dataText === undefined)
|
|
71622
71704
|
return { templateId };
|
|
@@ -71734,7 +71816,6 @@ var create9 = make29("create", {
|
|
|
71734
71816
|
return yield* printJson(data);
|
|
71735
71817
|
yield* printMailbox(data);
|
|
71736
71818
|
})));
|
|
71737
|
-
var mailboxIdArgument = String10("mailbox-id").pipe(withSchema3(MailboxId));
|
|
71738
71819
|
var get22 = make29("get", { id: mailboxIdArgument, json: jsonFlag }).pipe(withDescription3("Inspect a mailbox's endpoints and settings"), withHandler(({ id, json }) => gen2(function* () {
|
|
71739
71820
|
const raw = yield* getMailboxJson("Could not read mailbox", `/v1/mailboxes/${id}`);
|
|
71740
71821
|
const result = yield* decodeMailbox(raw);
|
|
@@ -71793,7 +71874,7 @@ var update9 = make29("update", {
|
|
|
71793
71874
|
yield* json ? printJson(result) : printMailbox(result);
|
|
71794
71875
|
})));
|
|
71795
71876
|
var endpointAdd = make29("add", {
|
|
71796
|
-
mailbox:
|
|
71877
|
+
mailbox: mailboxIdArgument,
|
|
71797
71878
|
channel: channelFlag2,
|
|
71798
71879
|
address: String9("address").pipe(withDescription2("The address to add: an email address such as billing@acme.samva.email, or on whatsapp and sms a number you connected, in E.164 form such as +14155550123")),
|
|
71799
71880
|
displayName: String9("display-name").pipe(withDescription2("The sender name messages from this endpoint carry"), optional4),
|
|
@@ -71801,10 +71882,10 @@ var endpointAdd = make29("add", {
|
|
|
71801
71882
|
json: jsonFlag
|
|
71802
71883
|
}).pipe(withDescription3("Add an endpoint on a channel (email by default) to a mailbox"), withExamples([
|
|
71803
71884
|
{
|
|
71804
|
-
command: "samva mailboxes endpoints add
|
|
71885
|
+
command: "samva mailboxes endpoints add mbx_1234567890123456 --address billing@acme.samva.email"
|
|
71805
71886
|
},
|
|
71806
71887
|
{
|
|
71807
|
-
command: "samva mailboxes endpoints add
|
|
71888
|
+
command: "samva mailboxes endpoints add mbx_1234567890123456 --channel whatsapp --address +14155550123",
|
|
71808
71889
|
description: "Add a connected WhatsApp number"
|
|
71809
71890
|
}
|
|
71810
71891
|
]), withHandler(({ mailbox, channel, address, displayName, dryRun, json }) => gen2(function* () {
|
|
@@ -71836,8 +71917,8 @@ var endpointAdd = make29("add", {
|
|
|
71836
71917
|
})));
|
|
71837
71918
|
var endpointIdArgument = String10("endpoint-id").pipe(withSchema3(MailboxEndpointId));
|
|
71838
71919
|
var endpointUpdate = make29("update", {
|
|
71920
|
+
mailbox: mailboxIdArgument,
|
|
71839
71921
|
endpointId: endpointIdArgument,
|
|
71840
|
-
mailbox: mailboxFlag,
|
|
71841
71922
|
displayName: String9("display-name").pipe(withDescription2("The sender name messages from this endpoint carry"), optional4),
|
|
71842
71923
|
clearDisplayName: Boolean6("clear-display-name").pipe(withDescription2("Send under the mailbox's name again"), withDefault5(false)),
|
|
71843
71924
|
makeDefault: Boolean6("default").pipe(withDescription2("Start new conversations from this endpoint on its channel"), withDefault5(false)),
|
|
@@ -71845,7 +71926,7 @@ var endpointUpdate = make29("update", {
|
|
|
71845
71926
|
json: jsonFlag
|
|
71846
71927
|
}).pipe(withDescription3("Rename an endpoint's sender or make it the mailbox's default"), withExamples([
|
|
71847
71928
|
{
|
|
71848
|
-
command: 'samva mailboxes endpoints update mbxep_1234567890123456 --
|
|
71929
|
+
command: 'samva mailboxes endpoints update mbx_1234567890123456 mbxep_1234567890123456 --display-name "Acme Billing" --default'
|
|
71849
71930
|
}
|
|
71850
71931
|
]), withHandler(({ endpointId, mailbox, displayName, clearDisplayName, makeDefault, dryRun, json }) => gen2(function* () {
|
|
71851
71932
|
if (isSome2(displayName) && clearDisplayName)
|
|
@@ -71879,14 +71960,14 @@ var endpointUpdate = make29("update", {
|
|
|
71879
71960
|
yield* json ? printJson(result) : printMailbox(result);
|
|
71880
71961
|
})));
|
|
71881
71962
|
var endpointRemove = make29("remove", {
|
|
71963
|
+
mailbox: mailboxIdArgument,
|
|
71882
71964
|
endpointId: endpointIdArgument,
|
|
71883
|
-
mailbox: mailboxFlag,
|
|
71884
71965
|
dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
|
|
71885
71966
|
yes: Boolean6("yes").pipe(withDefault5(false)),
|
|
71886
71967
|
json: jsonFlag
|
|
71887
71968
|
}).pipe(withDescription3("Remove an endpoint from a mailbox; mail sent to it stops reaching the mailbox"), withExamples([
|
|
71888
71969
|
{
|
|
71889
|
-
command: "samva mailboxes endpoints remove mbxep_1234567890123456 --
|
|
71970
|
+
command: "samva mailboxes endpoints remove mbx_1234567890123456 mbxep_1234567890123456 --yes"
|
|
71890
71971
|
}
|
|
71891
71972
|
]), withHandler(({ endpointId, mailbox, dryRun, yes, json }) => gen2(function* () {
|
|
71892
71973
|
if (dryRun)
|
|
@@ -71918,7 +71999,7 @@ var lifecycle = (verb) => make29(verb, {
|
|
|
71918
71999
|
yield* json ? printJson(result) : printMailbox(result);
|
|
71919
72000
|
})));
|
|
71920
72001
|
var actionsList = make29("list", {
|
|
71921
|
-
mailbox:
|
|
72002
|
+
mailbox: mailboxIdArgument,
|
|
71922
72003
|
...pageFlags2,
|
|
71923
72004
|
state: Literals3("state", MailboxActionState.literals).pipe(optional4),
|
|
71924
72005
|
after: instantFlag("after", "Only actions created after this ISO 8601 instant"),
|
|
@@ -71943,8 +72024,8 @@ var actionsList = make29("list", {
|
|
|
71943
72024
|
});
|
|
71944
72025
|
})));
|
|
71945
72026
|
var actionDecision = (verb) => make29(verb, {
|
|
72027
|
+
mailbox: mailboxIdArgument,
|
|
71946
72028
|
actionId: String10("action-id").pipe(withSchema3(MailboxActionId)),
|
|
71947
|
-
mailbox: mailboxFlag,
|
|
71948
72029
|
...verb === "deny" ? {
|
|
71949
72030
|
reason: optional6("reason").pipe(withDescription2("Denial reason; defaults to Denied by reviewer."))
|
|
71950
72031
|
} : {},
|
|
@@ -71999,7 +72080,7 @@ var remove9 = make29("remove", {
|
|
|
71999
72080
|
yield* log(`Removed mailbox ${id}. The messages it received stay with the organization.`);
|
|
72000
72081
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
72001
72082
|
var threads = make29("threads", {
|
|
72002
|
-
mailbox:
|
|
72083
|
+
mailbox: mailboxIdArgument,
|
|
72003
72084
|
...pageFlags2,
|
|
72004
72085
|
query: optional6("query"),
|
|
72005
72086
|
folder: Literals3("folder", MailboxThreadFolder2.literals).pipe(optional4),
|
|
@@ -72010,37 +72091,35 @@ var threads = make29("threads", {
|
|
|
72010
72091
|
before: instantFlag("before", "Only threads whose last activity is before this ISO 8601 instant"),
|
|
72011
72092
|
json: jsonFlag
|
|
72012
72093
|
}).pipe(withDescription3("Search and list mailbox threads"), withExamples([
|
|
72013
|
-
{ command: "samva mailboxes threads
|
|
72094
|
+
{ command: "samva mailboxes threads mbx_1234567890123456 --query invoice --json" },
|
|
72014
72095
|
{
|
|
72015
|
-
command: "samva mailboxes threads
|
|
72096
|
+
command: "samva mailboxes threads mbx_1234567890123456 --starred --after 2026-10-01T00:00:00Z"
|
|
72016
72097
|
},
|
|
72017
|
-
{ command: "samva mailboxes threads
|
|
72018
|
-
]), withHandler(({ mailbox, limit, cursor, all, query, folder, label, unread, starred, after, before, json }) =>
|
|
72019
|
-
|
|
72020
|
-
|
|
72021
|
-
|
|
72022
|
-
|
|
72023
|
-
|
|
72024
|
-
|
|
72025
|
-
|
|
72026
|
-
|
|
72027
|
-
|
|
72028
|
-
|
|
72029
|
-
|
|
72030
|
-
|
|
72031
|
-
|
|
72032
|
-
|
|
72033
|
-
|
|
72034
|
-
|
|
72035
|
-
human: printThread
|
|
72036
|
-
});
|
|
72098
|
+
{ command: "samva mailboxes threads mbx_1234567890123456 --all --jsonl" }
|
|
72099
|
+
]), withHandler(({ mailbox, limit, cursor, all, query, folder, label, unread, starred, after, before, json }) => followPages({
|
|
72100
|
+
all,
|
|
72101
|
+
json,
|
|
72102
|
+
cursor,
|
|
72103
|
+
page: (pageCursor) => getMailboxJson("Could not list threads", `/v1/mailboxes/${mailbox}/threads${searchParams({
|
|
72104
|
+
cursor: pageCursor,
|
|
72105
|
+
limit: pageLimit(limit),
|
|
72106
|
+
q: getOrUndefined(query),
|
|
72107
|
+
folder: getOrUndefined(folder),
|
|
72108
|
+
label: getOrUndefined(label),
|
|
72109
|
+
unread: unread ? "true" : undefined,
|
|
72110
|
+
starred: starred ? "true" : undefined,
|
|
72111
|
+
after: getOrUndefined(after),
|
|
72112
|
+
before: getOrUndefined(before)
|
|
72113
|
+
})}`).pipe(flatMap3(decodeThreadPage)),
|
|
72114
|
+
empty: "No threads found.",
|
|
72115
|
+
human: printThread
|
|
72037
72116
|
})));
|
|
72038
72117
|
var read2 = make29("read", {
|
|
72118
|
+
mailbox: mailboxIdArgument,
|
|
72039
72119
|
messageId: messageIdArgument,
|
|
72040
|
-
mailbox: mailboxFlag,
|
|
72041
72120
|
json: jsonFlag
|
|
72042
72121
|
}).pipe(withDescription3("Read a mailbox message"), withExamples([
|
|
72043
|
-
{ command: "samva mailboxes read msg_1234567890123456 --
|
|
72122
|
+
{ command: "samva mailboxes read mbx_1234567890123456 msg_1234567890123456 --json" }
|
|
72044
72123
|
]), withHandler(({ messageId, mailbox, json }) => gen2(function* () {
|
|
72045
72124
|
const raw = yield* getMailboxJson("Could not read message", `/v1/mailboxes/${mailbox}/messages/${messageId}`);
|
|
72046
72125
|
const data = yield* decodeMessage(raw);
|
|
@@ -72049,7 +72128,7 @@ var read2 = make29("read", {
|
|
|
72049
72128
|
yield* printMessage2(data);
|
|
72050
72129
|
})));
|
|
72051
72130
|
var send7 = make29("send", {
|
|
72052
|
-
mailbox:
|
|
72131
|
+
mailbox: mailboxIdArgument,
|
|
72053
72132
|
channel: channelFlag2,
|
|
72054
72133
|
to: String9("to").pipe(withDescription2("Recipient email address (repeatable), or one phone number in E.164 form"), atLeast2(1)),
|
|
72055
72134
|
subject: String9("subject").pipe(withDescription2("Email only"), optional4),
|
|
@@ -72060,14 +72139,14 @@ var send7 = make29("send", {
|
|
|
72060
72139
|
json: jsonFlag
|
|
72061
72140
|
}).pipe(withDescription3("Send a message from a mailbox: email by default, or to one phone number with --channel whatsapp or sms"), withExamples([
|
|
72062
72141
|
{
|
|
72063
|
-
command: 'samva mailboxes send
|
|
72142
|
+
command: 'samva mailboxes send mbx_1234567890123456 --to recipient@example.com --subject Hello --text "Hello"'
|
|
72064
72143
|
},
|
|
72065
72144
|
{
|
|
72066
|
-
command: `samva mailboxes send
|
|
72145
|
+
command: `samva mailboxes send mbx_1234567890123456 --channel whatsapp --to +14155550123 --template tmpl_1234567890123456 --data '{"name":"Ada"}'`,
|
|
72067
72146
|
description: "Open a WhatsApp conversation with an approved template"
|
|
72068
72147
|
},
|
|
72069
72148
|
{
|
|
72070
|
-
command: 'samva mailboxes send
|
|
72149
|
+
command: 'samva mailboxes send mbx_1234567890123456 --channel sms --to +14155550123 --text "Your order shipped."'
|
|
72071
72150
|
}
|
|
72072
72151
|
]), withHandler(({
|
|
72073
72152
|
mailbox,
|
|
@@ -72119,18 +72198,18 @@ var send7 = make29("send", {
|
|
|
72119
72198
|
})));
|
|
72120
72199
|
var messageChannel = (mailbox, messageId) => getMailboxJson("Could not read message", `/v1/mailboxes/${mailbox}/messages/${messageId}`).pipe(flatMap3((raw) => decodeUnknownEffect2(Struct({ channel: Literals(["email", "whatsapp", "sms"]) }))(raw).pipe(map7(({ channel }) => channel), mapError2(() => new SamvaCliError({ message: "The API answered with an unreadable message." })))));
|
|
72121
72200
|
var reply2 = make29("reply", {
|
|
72201
|
+
mailbox: mailboxIdArgument,
|
|
72122
72202
|
messageId: messageIdArgument,
|
|
72123
|
-
mailbox: mailboxFlag,
|
|
72124
72203
|
...bodyFlags,
|
|
72125
72204
|
...chatOnlyFlags,
|
|
72126
72205
|
all: Boolean6("all").pipe(withDefault5(false)),
|
|
72127
72206
|
json: jsonFlag
|
|
72128
72207
|
}).pipe(withDescription3("Reply to a message; --all includes the other recipients. A WhatsApp or SMS message is answered on its thread, with --text or a WhatsApp --template"), withExamples([
|
|
72129
72208
|
{
|
|
72130
|
-
command: 'samva mailboxes reply msg_1234567890123456 --
|
|
72209
|
+
command: 'samva mailboxes reply mbx_1234567890123456 msg_1234567890123456 --text "Thanks" --all'
|
|
72131
72210
|
},
|
|
72132
72211
|
{
|
|
72133
|
-
command: "samva mailboxes reply msg_1234567890123456 --
|
|
72212
|
+
command: "samva mailboxes reply mbx_1234567890123456 msg_1234567890123456 --template tmpl_1234567890123456",
|
|
72134
72213
|
description: "Answer a WhatsApp thread whose 24-hour service window has closed"
|
|
72135
72214
|
}
|
|
72136
72215
|
]), withHandler(({ messageId, mailbox, text, html, template, data, idempotencyKey, all, json }) => gen2(function* () {
|
|
@@ -72158,8 +72237,8 @@ var reply2 = make29("reply", {
|
|
|
72158
72237
|
})));
|
|
72159
72238
|
var actionIdArgument = String10("action-id").pipe(withSchema3(MailboxActionId));
|
|
72160
72239
|
var actionGet = make29("get", {
|
|
72240
|
+
mailbox: mailboxIdArgument,
|
|
72161
72241
|
actionId: actionIdArgument,
|
|
72162
|
-
mailbox: mailboxFlag,
|
|
72163
72242
|
json: jsonFlag
|
|
72164
72243
|
}).pipe(withDescription3("Read a mailbox action and its current send progress"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
|
|
72165
72244
|
const client = yield* getClientProvider;
|
|
@@ -72169,8 +72248,8 @@ var actionGet = make29("get", {
|
|
|
72169
72248
|
yield* printAction(data);
|
|
72170
72249
|
})));
|
|
72171
72250
|
var actionCancel = make29("cancel", {
|
|
72251
|
+
mailbox: mailboxIdArgument,
|
|
72172
72252
|
actionId: actionIdArgument,
|
|
72173
|
-
mailbox: mailboxFlag,
|
|
72174
72253
|
json: jsonFlag
|
|
72175
72254
|
}).pipe(withDescription3("Cancel an unaccepted send as a permitted person signed in with samva login"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
|
|
72176
72255
|
const client = yield* getClientProvider;
|
|
@@ -72184,8 +72263,8 @@ var actionCancel = make29("cancel", {
|
|
|
72184
72263
|
]);
|
|
72185
72264
|
})));
|
|
72186
72265
|
var actionRetry = make29("retry", {
|
|
72266
|
+
mailbox: mailboxIdArgument,
|
|
72187
72267
|
actionId: actionIdArgument,
|
|
72188
|
-
mailbox: mailboxFlag,
|
|
72189
72268
|
json: jsonFlag
|
|
72190
72269
|
}).pipe(withDescription3("Resume an eligible ended execution as a permitted person; preserves content and deadline"), withHandler(({ actionId, mailbox, json }) => gen2(function* () {
|
|
72191
72270
|
const client = yield* getClientProvider;
|
|
@@ -72199,14 +72278,14 @@ var actionRetry = make29("retry", {
|
|
|
72199
72278
|
]);
|
|
72200
72279
|
})));
|
|
72201
72280
|
var quarantineList = make29("list", {
|
|
72202
|
-
mailbox:
|
|
72281
|
+
mailbox: mailboxIdArgument,
|
|
72203
72282
|
...pageFlags2,
|
|
72204
72283
|
after: instantFlag("after", "Only messages held after this ISO 8601 instant"),
|
|
72205
72284
|
before: instantFlag("before", "Only messages held before this ISO 8601 instant"),
|
|
72206
72285
|
json: jsonFlag
|
|
72207
72286
|
}).pipe(withDescription3("List held messages without their bodies"), withExamples([
|
|
72208
|
-
{ command: "samva mailboxes quarantine list
|
|
72209
|
-
{ command: "samva mailboxes quarantine list
|
|
72287
|
+
{ command: "samva mailboxes quarantine list mbx_1234567890123456 --json" },
|
|
72288
|
+
{ command: "samva mailboxes quarantine list mbx_1234567890123456 --all --jsonl" }
|
|
72210
72289
|
]), withHandler(({ mailbox, limit, cursor, all, after, before, json }) => gen2(function* () {
|
|
72211
72290
|
const client = yield* getClientProvider;
|
|
72212
72291
|
yield* followPages({
|
|
@@ -72225,12 +72304,12 @@ var quarantineList = make29("list", {
|
|
|
72225
72304
|
});
|
|
72226
72305
|
})));
|
|
72227
72306
|
var release2 = make29("release", {
|
|
72307
|
+
mailbox: mailboxIdArgument,
|
|
72228
72308
|
messageId: messageIdArgument,
|
|
72229
|
-
mailbox: mailboxFlag,
|
|
72230
72309
|
json: jsonFlag
|
|
72231
72310
|
}).pipe(withDescription3("Release a held message as a person signed in with samva login"), withExamples([
|
|
72232
72311
|
{
|
|
72233
|
-
command: "samva mailboxes quarantine release msg_1234567890123456
|
|
72312
|
+
command: "samva mailboxes quarantine release mbx_1234567890123456 msg_1234567890123456"
|
|
72234
72313
|
}
|
|
72235
72314
|
]), withHandler(({ messageId, mailbox, json }) => gen2(function* () {
|
|
72236
72315
|
const client = yield* getClientProvider;
|
|
@@ -72242,12 +72321,12 @@ var release2 = make29("release", {
|
|
|
72242
72321
|
var discard = make29("discard", {
|
|
72243
72322
|
dryRun: Boolean6("dry-run").pipe(withDefault5(false)),
|
|
72244
72323
|
yes: Boolean6("yes").pipe(withDefault5(false)),
|
|
72324
|
+
mailbox: mailboxIdArgument,
|
|
72245
72325
|
messageId: messageIdArgument,
|
|
72246
|
-
mailbox: mailboxFlag,
|
|
72247
72326
|
json: jsonFlag
|
|
72248
72327
|
}).pipe(withDescription3("Discard a held message for good as a person signed in with samva login"), withExamples([
|
|
72249
72328
|
{
|
|
72250
|
-
command: "samva mailboxes quarantine discard msg_1234567890123456
|
|
72329
|
+
command: "samva mailboxes quarantine discard mbx_1234567890123456 msg_1234567890123456"
|
|
72251
72330
|
}
|
|
72252
72331
|
]), withHandler(({ messageId, mailbox, dryRun, yes, json }) => gen2(function* () {
|
|
72253
72332
|
if (dryRun)
|
|
@@ -75659,7 +75738,7 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
|
|
|
75659
75738
|
TemplatesPublish500,
|
|
75660
75739
|
TemplatesPublish504.pipe(status(504))
|
|
75661
75740
|
]
|
|
75662
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable compiled IR and its assets, records the input contract it validates against, and makes that publication current."), get5("templatesGetPublication", "/v1/templates/:id/publications/:publicationId", {
|
|
75741
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.publish").annotate(Summary, "Publish an exact template commit").annotate(Description, "Builds an exact Git commit and entry path, stores the immutable compiled IR and its assets, records the input contract it validates against, and makes that publication current. A commit that compiles to the same build as an existing publication makes that publication current again instead of recording another."), get5("templatesGetPublication", "/v1/templates/:id/publications/:publicationId", {
|
|
75663
75742
|
params: TemplatesGetPublicationPathParams,
|
|
75664
75743
|
success: TemplatesGetPublication200,
|
|
75665
75744
|
error: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@samva/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Samva CLI — email and platform operations from your terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"vitest": "^5.0.3"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@samva/cli-darwin-arm64": "0.
|
|
66
|
-
"@samva/cli-darwin-x64": "0.
|
|
67
|
-
"@samva/cli-linux-arm64": "0.
|
|
68
|
-
"@samva/cli-linux-x64": "0.
|
|
65
|
+
"@samva/cli-darwin-arm64": "0.17.0",
|
|
66
|
+
"@samva/cli-darwin-x64": "0.17.0",
|
|
67
|
+
"@samva/cli-linux-arm64": "0.17.0",
|
|
68
|
+
"@samva/cli-linux-x64": "0.17.0"
|
|
69
69
|
},
|
|
70
70
|
"engines": {
|
|
71
71
|
"node": ">=18"
|