@samva/cli 0.18.0 → 0.19.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 +8 -0
- package/dist/bin.mjs +295 -32
- package/package.json +9 -9
package/AGENTS.md
CHANGED
|
@@ -79,6 +79,14 @@ uploads again. `--dry-run` lists each attachment and uploads nothing.
|
|
|
79
79
|
or the newest publication that still validates input identically. They are mutually exclusive and
|
|
80
80
|
each requires `--template-id`, because a reference is a statement about one template's history.
|
|
81
81
|
|
|
82
|
+
`samva templates list --shared true|false` filters by whether the template's project is shared with
|
|
83
|
+
every namespace, and every listed template reports `shared`. Sharing belongs to an organization-level
|
|
84
|
+
project: `templates create --shared` shares the new project and refuses a namespace (exit `2`), and
|
|
85
|
+
`templates update <id> --data '{}' --shared true|false` shares or unshares the project for every
|
|
86
|
+
entry in it. `--shared` that disagrees with `shared` in `--data` exits `2`. A namespace-scoped key
|
|
87
|
+
lists, reads, and sends shared templates but gets 403 changing them, and the API refuses moving a
|
|
88
|
+
shared project into a namespace.
|
|
89
|
+
|
|
82
90
|
`samva templates workspace <open|diff|patch|add-asset|check|fixture|save|history|publish>` is the
|
|
83
91
|
hosted project workspace over the CLI, for a caller with no clone: an agent in a sandbox, a CI job,
|
|
84
92
|
a script. It reaches the same operations the hosted MCP tools reach, so an agent can start a journey in one
|
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.19.0",
|
|
14110
14110
|
description: "Samva CLI \u2014 email and platform operations from your terminal",
|
|
14111
14111
|
keywords: [
|
|
14112
14112
|
"cli",
|
|
@@ -14157,21 +14157,21 @@ var package_default = {
|
|
|
14157
14157
|
"@samva/contracts": "workspace:*",
|
|
14158
14158
|
"@samva/core": "workspace:*",
|
|
14159
14159
|
"@samva/mailbox": "workspace:*",
|
|
14160
|
-
"@samva/markup": "
|
|
14161
|
-
"@samva/vite": "
|
|
14160
|
+
"@samva/markup": "catalog:",
|
|
14161
|
+
"@samva/vite": "catalog:",
|
|
14162
14162
|
"@types/node": "catalog:",
|
|
14163
14163
|
"better-auth": "catalog:",
|
|
14164
14164
|
effect: "catalog:effect",
|
|
14165
|
-
samva: "workspace:0.
|
|
14165
|
+
samva: "workspace:0.22.0",
|
|
14166
14166
|
typescript: "catalog:",
|
|
14167
14167
|
vite: "~8.3.0",
|
|
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.19.0",
|
|
14172
|
+
"@samva/cli-darwin-x64": "workspace:0.19.0",
|
|
14173
|
+
"@samva/cli-linux-arm64": "workspace:0.19.0",
|
|
14174
|
+
"@samva/cli-linux-x64": "workspace:0.19.0"
|
|
14175
14175
|
},
|
|
14176
14176
|
engines: {
|
|
14177
14177
|
node: ">=18"
|
|
@@ -24189,6 +24189,9 @@ var CreateWebhookPayload = /* @__PURE__ */ Struct({
|
|
|
24189
24189
|
Literal2("webhook.test"),
|
|
24190
24190
|
Literal2("domain.updated"),
|
|
24191
24191
|
Literal2("domain.warming.updated"),
|
|
24192
|
+
Literal2("template.registration.updated"),
|
|
24193
|
+
Literal2("flow.registration.updated"),
|
|
24194
|
+
Literal2("whatsapp.number.connected"),
|
|
24192
24195
|
Literal2("mailbox.message.received"),
|
|
24193
24196
|
Literal2("mailbox.message.sent"),
|
|
24194
24197
|
Literal2("mailbox.action.pending_approval"),
|
|
@@ -24233,6 +24236,9 @@ var UpdateWebhookPayload = /* @__PURE__ */ Struct({
|
|
|
24233
24236
|
Literal2("webhook.test"),
|
|
24234
24237
|
Literal2("domain.updated"),
|
|
24235
24238
|
Literal2("domain.warming.updated"),
|
|
24239
|
+
Literal2("template.registration.updated"),
|
|
24240
|
+
Literal2("flow.registration.updated"),
|
|
24241
|
+
Literal2("whatsapp.number.connected"),
|
|
24236
24242
|
Literal2("mailbox.message.received"),
|
|
24237
24243
|
Literal2("mailbox.message.sent"),
|
|
24238
24244
|
Literal2("mailbox.action.pending_approval"),
|
|
@@ -25093,7 +25099,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
25093
25099
|
};
|
|
25094
25100
|
|
|
25095
25101
|
// ../sdk/dist/package.js
|
|
25096
|
-
var version = "0.
|
|
25102
|
+
var version = "0.22.0";
|
|
25097
25103
|
|
|
25098
25104
|
// ../sdk/dist/client-attribution.js
|
|
25099
25105
|
var SDK_VERSION = version;
|
|
@@ -25432,6 +25438,7 @@ var commandTree = {
|
|
|
25432
25438
|
list: {},
|
|
25433
25439
|
get: {},
|
|
25434
25440
|
create: {},
|
|
25441
|
+
"from-website": {},
|
|
25435
25442
|
update: {},
|
|
25436
25443
|
remove: {}
|
|
25437
25444
|
},
|
|
@@ -27062,6 +27069,7 @@ var SDK_OPERATION_CALLS = {
|
|
|
27062
27069
|
},
|
|
27063
27070
|
templatesList: { kind: "params" },
|
|
27064
27071
|
templatesCreate: { kind: "payload" },
|
|
27072
|
+
templatesCreateFromWebsite: { kind: "payload" },
|
|
27065
27073
|
templatesAddEntry: {
|
|
27066
27074
|
kind: "pathPayload",
|
|
27067
27075
|
paths: ["id"]
|
|
@@ -28553,6 +28561,7 @@ var SamvaOperations = {
|
|
|
28553
28561
|
templatesAttachFamilyMember: operationMetadata85,
|
|
28554
28562
|
templatesDetachFamilyMember: operationMetadata87,
|
|
28555
28563
|
templatesCreateFamilyFromTemplate: operationMetadata85,
|
|
28564
|
+
templatesCreateFromWebsite: operationMetadata85,
|
|
28556
28565
|
templatesAddEntry: operationMetadata85,
|
|
28557
28566
|
unsubscribeList: operationMetadata90,
|
|
28558
28567
|
unsubscribeCreate: operationMetadata91,
|
|
@@ -29451,6 +29460,10 @@ var apiKeysCommand = make29("api-keys").pipe(withDescription3("Create, inspect,
|
|
|
29451
29460
|
|
|
29452
29461
|
// src/commands/brands.ts
|
|
29453
29462
|
import { join as join3, relative, resolve as resolve5 } from "path";
|
|
29463
|
+
// ../../node_modules/.bun/@samva+markup@0.15.0+a19bcd7db259aaf7/node_modules/@samva/markup/dist/dark-scheme-CbCwGDWH.js
|
|
29464
|
+
var DARK_SCHEME_QUERY = /^(?:only\s+)?(?:screen\s+and\s+)?\(\s*prefers-color-scheme\s*:\s*dark\s*\)$/i;
|
|
29465
|
+
var isDarkSchemeQuery = (prelude) => DARK_SCHEME_QUERY.test(prelude.trim());
|
|
29466
|
+
|
|
29454
29467
|
// ../../node_modules/.bun/css-tree@3.2.1/node_modules/css-tree/lib/tokenizer/types.js
|
|
29455
29468
|
var EOF = 0;
|
|
29456
29469
|
var Ident = 1;
|
|
@@ -53223,21 +53236,21 @@ var $ = (e) => {
|
|
|
53223
53236
|
};
|
|
53224
53237
|
var ae = { ok: l, isOk: u, err: d, isError: f, try: T, tryPromise: E, map: D, mapError: O, tryRecover: k, andThen: A, tryRecoverAsync: ee, andThenAsync: te, match: ne, tap: j, tapAsync: M, tapError: N6, tapErrorAsync: P, tapBoth: F4, tapBothAsync: I, unwrap: L, unwrapOr: z, gen: B, await: V, codec: re, all: Q, allAsync: ie, partition: $, partitionAsync: async (e) => $(await Z(e, `Result.partitionAsync input promise rejected`)), flatten: (e) => e.status === `ok` ? e.value : e };
|
|
53225
53238
|
|
|
53226
|
-
// ../../node_modules/.bun/@samva+markup@0.
|
|
53239
|
+
// ../../node_modules/.bun/@samva+markup@0.15.0+a19bcd7db259aaf7/node_modules/@samva/markup/dist/theme-css-s9QwD5Ko.js
|
|
53227
53240
|
var BRAND_NAMESPACES = [
|
|
53228
53241
|
"--color-",
|
|
53229
53242
|
"--font-",
|
|
53230
53243
|
"--text-",
|
|
53231
53244
|
"--leading-",
|
|
53232
53245
|
"--tracking-",
|
|
53233
|
-
"--radius
|
|
53246
|
+
"--radius",
|
|
53234
53247
|
"--spacing",
|
|
53235
53248
|
"--container-",
|
|
53236
53249
|
"--shadow-"
|
|
53237
53250
|
];
|
|
53251
|
+
var inNamespace = (property, namespace) => namespace.endsWith("-") ? property.startsWith(namespace) : property === namespace || property.startsWith(`${namespace}-`);
|
|
53238
53252
|
var BRAND_PROPERTY = /^--[a-z][a-z0-9-]*$/;
|
|
53239
53253
|
var BRAND_UNSAFE_VALUE = /[{};<>\\@]|url\s*\(|expression\s*\(|\/\*/i;
|
|
53240
|
-
var BRAND_DARK_MEDIA = /^\(\s*prefers-color-scheme\s*:\s*dark\s*\)$/i;
|
|
53241
53254
|
var BRAND_FONT_DESCRIPTORS = /* @__PURE__ */ new Set([
|
|
53242
53255
|
"font-family",
|
|
53243
53256
|
"src",
|
|
@@ -53246,7 +53259,6 @@ var BRAND_FONT_DESCRIPTORS = /* @__PURE__ */ new Set([
|
|
|
53246
53259
|
"font-display",
|
|
53247
53260
|
"unicode-range"
|
|
53248
53261
|
]);
|
|
53249
|
-
var darkVariableName = (property) => `${property}-dark`;
|
|
53250
53262
|
var spanOfNode = (node) => ({
|
|
53251
53263
|
start: node.loc?.start.offset ?? 0,
|
|
53252
53264
|
end: node.loc?.end.offset ?? 0
|
|
@@ -53256,6 +53268,7 @@ var unquoteFamily = (value) => {
|
|
|
53256
53268
|
const quoted = /^(['"])(.*)\1$/s.exec(trimmed);
|
|
53257
53269
|
return quoted === null ? trimmed : quoted[2].replace(/\\(.)/g, "$1");
|
|
53258
53270
|
};
|
|
53271
|
+
var quoteFamily = (family) => `"${family.replace(/["\\]/g, "\\$&")}"`;
|
|
53259
53272
|
var parseBrandCss = (css) => {
|
|
53260
53273
|
const diagnostics = [];
|
|
53261
53274
|
const report = (code, message, span) => {
|
|
@@ -53297,7 +53310,7 @@ var parseBrandCss = (css) => {
|
|
|
53297
53310
|
report("brand-css-property", `${property} is not a theme variable; name theme variables --namespace-name.`, span);
|
|
53298
53311
|
continue;
|
|
53299
53312
|
}
|
|
53300
|
-
if (!BRAND_NAMESPACES.some((namespace) => property
|
|
53313
|
+
if (!BRAND_NAMESPACES.some((namespace) => inNamespace(property, namespace))) {
|
|
53301
53314
|
report("brand-css-namespace", `${property} is outside the brand namespaces (${BRAND_NAMESPACES.map((namespace) => namespace.endsWith("-") ? `${namespace}*` : namespace).join(", ")}).`, span);
|
|
53302
53315
|
continue;
|
|
53303
53316
|
}
|
|
@@ -53393,7 +53406,7 @@ var parseBrandCss = (css) => {
|
|
|
53393
53406
|
readFontFace(node);
|
|
53394
53407
|
continue;
|
|
53395
53408
|
}
|
|
53396
|
-
if (name === "media" && node.prelude !== null &&
|
|
53409
|
+
if (name === "media" && node.prelude !== null && isDarkSchemeQuery(generate55(node.prelude))) {
|
|
53397
53410
|
for (const child of node.block.children)
|
|
53398
53411
|
if (child.type === "Atrule" && child.name.toLowerCase() === "theme")
|
|
53399
53412
|
readTheme(child, dark, "dark");
|
|
@@ -53404,19 +53417,103 @@ var parseBrandCss = (css) => {
|
|
|
53404
53417
|
}
|
|
53405
53418
|
report("brand-css-unsupported", "A brand theme contains only @theme, a dark-mode @theme (@media (prefers-color-scheme: dark)), and @font-face.", spanOfNode(node));
|
|
53406
53419
|
}
|
|
53407
|
-
for (const property of Object.keys(dark))
|
|
53408
|
-
if (darkVariableName(property) in variables)
|
|
53409
|
-
report("brand-css-dark-conflict", `${darkVariableName(property)} and the dark-mode ${property} name the same theme variable; keep one.`, {
|
|
53410
|
-
start: 0,
|
|
53411
|
-
end: 0
|
|
53412
|
-
});
|
|
53413
53420
|
return diagnostics.length > 0 ? ae.err(diagnostics) : ae.ok({
|
|
53414
53421
|
variables,
|
|
53415
53422
|
dark,
|
|
53416
53423
|
fontFaces
|
|
53417
53424
|
});
|
|
53418
53425
|
};
|
|
53419
|
-
|
|
53426
|
+
var printDeclarations = (entries, indent) => Object.entries(entries).map(([property, value]) => `${indent}${property}: ${value};`).join(`
|
|
53427
|
+
`);
|
|
53428
|
+
var printFontFace = (face) => [
|
|
53429
|
+
"@font-face {",
|
|
53430
|
+
` font-family: ${quoteFamily(face.family)};`,
|
|
53431
|
+
` src: ${face.src};`,
|
|
53432
|
+
...face.weight === undefined ? [] : [` font-weight: ${face.weight};`],
|
|
53433
|
+
...face.style === undefined ? [] : [` font-style: ${face.style};`],
|
|
53434
|
+
...face.display === undefined ? [] : [` font-display: ${face.display};`],
|
|
53435
|
+
...face.unicodeRange === undefined ? [] : [` unicode-range: ${face.unicodeRange};`],
|
|
53436
|
+
"}"
|
|
53437
|
+
].join(`
|
|
53438
|
+
`);
|
|
53439
|
+
var printBrandCss = (brand) => {
|
|
53440
|
+
const blocks = [
|
|
53441
|
+
...brand.fontFaces.map(printFontFace),
|
|
53442
|
+
...Object.keys(brand.variables).length === 0 ? [] : [`@theme {
|
|
53443
|
+
${printDeclarations(brand.variables, " ")}
|
|
53444
|
+
}`],
|
|
53445
|
+
...Object.keys(brand.dark).length === 0 ? [] : [`@media (prefers-color-scheme: dark) {
|
|
53446
|
+
@theme {
|
|
53447
|
+
${printDeclarations(brand.dark, " ")}
|
|
53448
|
+
}
|
|
53449
|
+
}`]
|
|
53450
|
+
];
|
|
53451
|
+
return blocks.length === 0 ? "" : `${blocks.join(`
|
|
53452
|
+
|
|
53453
|
+
`)}
|
|
53454
|
+
`;
|
|
53455
|
+
};
|
|
53456
|
+
var THEME_COLOR_ROLES = {
|
|
53457
|
+
background: "The page, behind everything.",
|
|
53458
|
+
foreground: "Text on the page.",
|
|
53459
|
+
card: "A surface that groups the message's content.",
|
|
53460
|
+
"card-foreground": "Text on a card.",
|
|
53461
|
+
primary: "The main action's fill (a button), and links.",
|
|
53462
|
+
"primary-foreground": "Text on a primary fill.",
|
|
53463
|
+
secondary: "A quieter action's fill.",
|
|
53464
|
+
"secondary-foreground": "Text on a secondary fill.",
|
|
53465
|
+
muted: "A subdued surface: a code block, a table header.",
|
|
53466
|
+
"muted-foreground": "Secondary text on the page, a card or a muted surface: labels, captions, the footer.",
|
|
53467
|
+
accent: "A highlighted surface: a callout, a selected row.",
|
|
53468
|
+
"accent-foreground": "Text on an accent surface.",
|
|
53469
|
+
border: "Rules, dividers and outlines."
|
|
53470
|
+
};
|
|
53471
|
+
var THEME_COLORS = Object.keys(THEME_COLOR_ROLES);
|
|
53472
|
+
var colorVariables = (colors) => Object.fromEntries(THEME_COLORS.map((name) => [`--color-${name}`, colors[name]]));
|
|
53473
|
+
var DEFAULT_THEME = {
|
|
53474
|
+
variables: {
|
|
53475
|
+
...colorVariables({
|
|
53476
|
+
background: "#ffffff",
|
|
53477
|
+
foreground: "#0a0a0a",
|
|
53478
|
+
card: "#ffffff",
|
|
53479
|
+
"card-foreground": "#0a0a0a",
|
|
53480
|
+
primary: "#171717",
|
|
53481
|
+
"primary-foreground": "#fafafa",
|
|
53482
|
+
secondary: "#f5f5f5",
|
|
53483
|
+
"secondary-foreground": "#171717",
|
|
53484
|
+
muted: "#f5f5f5",
|
|
53485
|
+
"muted-foreground": "#737373",
|
|
53486
|
+
accent: "#f5f5f5",
|
|
53487
|
+
"accent-foreground": "#171717",
|
|
53488
|
+
border: "#e5e5e5"
|
|
53489
|
+
}),
|
|
53490
|
+
"--radius": "8px",
|
|
53491
|
+
"--radius-sm": "calc(var(--radius) - 4px)",
|
|
53492
|
+
"--radius-md": "calc(var(--radius) - 2px)",
|
|
53493
|
+
"--radius-lg": "var(--radius)",
|
|
53494
|
+
"--radius-xl": "calc(var(--radius) + 4px)",
|
|
53495
|
+
"--font-sans": '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
|
|
53496
|
+
"--font-heading": "var(--font-sans)"
|
|
53497
|
+
},
|
|
53498
|
+
dark: colorVariables({
|
|
53499
|
+
background: "#0a0a0a",
|
|
53500
|
+
foreground: "#fafafa",
|
|
53501
|
+
card: "#171717",
|
|
53502
|
+
"card-foreground": "#fafafa",
|
|
53503
|
+
primary: "#fafafa",
|
|
53504
|
+
"primary-foreground": "#171717",
|
|
53505
|
+
secondary: "#262626",
|
|
53506
|
+
"secondary-foreground": "#fafafa",
|
|
53507
|
+
muted: "#262626",
|
|
53508
|
+
"muted-foreground": "#a3a3a3",
|
|
53509
|
+
accent: "#262626",
|
|
53510
|
+
"accent-foreground": "#fafafa",
|
|
53511
|
+
border: "#2e2e2e"
|
|
53512
|
+
}),
|
|
53513
|
+
fontFaces: []
|
|
53514
|
+
};
|
|
53515
|
+
var DEFAULT_THEME_CSS = printBrandCss(DEFAULT_THEME);
|
|
53516
|
+
// ../../node_modules/.bun/@samva+markup@0.15.0+a19bcd7db259aaf7/node_modules/@samva/markup/dist/diagnostic-codes-UXwOO3A-.js
|
|
53420
53517
|
var buildLineMap = (source) => {
|
|
53421
53518
|
const lineStarts = [0];
|
|
53422
53519
|
for (let index = 0;index < source.length; index++) {
|
|
@@ -53641,10 +53738,22 @@ var DIAGNOSTIC_CODES = codes2({
|
|
|
53641
53738
|
summary: "<Columns per> is not a positive integer literal.",
|
|
53642
53739
|
fix: "Write per={2}."
|
|
53643
53740
|
},
|
|
53741
|
+
"invalid-columns-gap": {
|
|
53742
|
+
summary: "<Columns gap> is set on a Columns whose cells are repeated with each or rendered conditionally.",
|
|
53743
|
+
fix: "Write each Column out unconditionally, or pad the cells instead of using gap."
|
|
53744
|
+
},
|
|
53745
|
+
"invalid-columns-stack": {
|
|
53746
|
+
summary: "<Columns stack> is not a true or false literal.",
|
|
53747
|
+
fix: "Write stack={false}, or leave it out to stack on narrow screens."
|
|
53748
|
+
},
|
|
53644
53749
|
"invalid-button-number": {
|
|
53645
53750
|
summary: "A Button size prop is not a finite number.",
|
|
53646
53751
|
fix: "Pass a finite number."
|
|
53647
53752
|
},
|
|
53753
|
+
"invalid-number-prop": {
|
|
53754
|
+
summary: "A primitive's numeric prop, such as <Email gutter>, is not a finite number in range.",
|
|
53755
|
+
fix: "Pass a finite number the message allows, for example gutter={16}."
|
|
53756
|
+
},
|
|
53648
53757
|
"unsupported-element": {
|
|
53649
53758
|
summary: "An element outside the supported email vocabulary.",
|
|
53650
53759
|
fix: "Use an element from the contract's element table."
|
|
@@ -53745,6 +53854,18 @@ var DIAGNOSTIC_CODES = codes2({
|
|
|
53745
53854
|
summary: "A custom property is redefined inside a conditional at-rule.",
|
|
53746
53855
|
fix: "Keep the override on a class rule."
|
|
53747
53856
|
},
|
|
53857
|
+
"email-contrast": {
|
|
53858
|
+
summary: "Text, or a filled button against its surroundings, falls below the contrast ratio in light or dark mode (below 1.5:1 a button is indistinguishable from its surface; WCAG 1.4.11 asks 3:1).",
|
|
53859
|
+
fix: "Pair background and text tokens (bg-primary with text-primary-foreground), give the theme's dark-mode @theme a value for the token, or choose colors that reach the required ratio.",
|
|
53860
|
+
upgrade: [
|
|
53861
|
+
"Move the project's theme onto the theme vocabulary with one dark-mode block. In starter.css and theme.css, rename each color token to the vocabulary name for its role (reference.md, Theme): a page color to --color-background, the main text to --color-foreground, a surface to --color-card with --color-card-foreground, the brand or action color to --color-primary with --color-primary-foreground, subdued text to --color-muted-foreground, a highlight to --color-accent with --color-accent-foreground, rules to --color-border, body and heading fonts to --font-sans and --font-heading, and a corner radius to --radius. Keep every value.",
|
|
53862
|
+
"Move each --color-<name>-dark value into @media (prefers-color-scheme: dark) { @theme { --color-<name>: <value>; } } under the renamed token, and delete the -dark tokens. In every template and partial, rename the utilities to match (bg-surface to bg-card, text-muted to text-muted-foreground, and so on) and delete each dark:\u2026-dark class whose token now has a dark value; keep a dark: class only where it picks a different token in dark mode.",
|
|
53863
|
+
"Then fix what email-contrast still reports at its location: pair each fill with its -foreground token, or give the dark block a value that reaches the ratio. Do not weaken the design to pass: keep the brand's colors and adjust the paired token.",
|
|
53864
|
+
"Compile every entry and render every fixture in light and dark mode; confirm the light render is unchanged apart from fixes. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish."
|
|
53865
|
+
].join(`
|
|
53866
|
+
|
|
53867
|
+
`)
|
|
53868
|
+
},
|
|
53748
53869
|
"email-font-fallback": {
|
|
53749
53870
|
summary: "A font stack names a project font without a generic fallback.",
|
|
53750
53871
|
fix: "End the stack with sans-serif, serif or monospace."
|
|
@@ -54689,10 +54810,10 @@ var listRecipients = /* @__PURE__ */ make42("campaignsListRecipients");
|
|
|
54689
54810
|
|
|
54690
54811
|
// src/lib/run-hold.ts
|
|
54691
54812
|
var WHATSAPP_MESSAGING_LIMIT_HOLD = "whatsapp_messaging_limit";
|
|
54692
|
-
var holdLabel = (reason) => reason === null || reason === undefined ? null : reason === WHATSAPP_MESSAGING_LIMIT_HOLD ? `${reason} (the
|
|
54813
|
+
var holdLabel = (reason) => reason === null || reason === undefined ? null : reason === WHATSAPP_MESSAGING_LIMIT_HOLD ? `${reason} (the messaging limit its business portfolio shares across numbers; the run resumes on its own, sooner if Meta raises the limit)` : reason;
|
|
54693
54814
|
var holdFields = (run) => [
|
|
54694
54815
|
["Held", holdLabel(run.holdReason)],
|
|
54695
|
-
["Resumes
|
|
54816
|
+
["Resumes by", run.holdUntil]
|
|
54696
54817
|
];
|
|
54697
54818
|
var campaignPacingFields = (run, options) => [
|
|
54698
54819
|
...holdFields(run),
|
|
@@ -74045,6 +74166,14 @@ var TemplatePage = /* @__PURE__ */ Struct({
|
|
|
74045
74166
|
items: ArraySchema(TemplateSummary),
|
|
74046
74167
|
nextCursor: Union2([String4, Null2])
|
|
74047
74168
|
}).annotate({ identifier: "TemplatePage" });
|
|
74169
|
+
var TemplateFromWebsite = /* @__PURE__ */ Struct({
|
|
74170
|
+
template: Template,
|
|
74171
|
+
website: Struct({
|
|
74172
|
+
url: String4.annotate({ description: "The address Samva checked, normalized." }),
|
|
74173
|
+
host: String4
|
|
74174
|
+
}),
|
|
74175
|
+
ask: String4.annotate({ description: "The request to send the template assistant in the editor. The assistant reads the site, rebuilds the project's theme and blocks to match it, and proposes a brand that changes nothing until the customer applies it." })
|
|
74176
|
+
}).annotate({ identifier: "TemplateFromWebsite" });
|
|
74048
74177
|
var TemplateFamilyPage = /* @__PURE__ */ Struct({
|
|
74049
74178
|
items: ArraySchema(TemplateFamily),
|
|
74050
74179
|
nextCursor: Union2([String4, Null2])
|
|
@@ -75692,6 +75821,20 @@ var TemplatesCreateFamilyFromTemplate409 = ConflictError2;
|
|
|
75692
75821
|
var TemplatesCreateFamilyFromTemplate422 = ValidationError2;
|
|
75693
75822
|
var TemplatesCreateFamilyFromTemplate500 = InternalError2;
|
|
75694
75823
|
var TemplatesCreateFamilyFromTemplate504 = GatewayTimeoutError2;
|
|
75824
|
+
var TemplatesCreateFromWebsiteRequestJson = /* @__PURE__ */ Struct({
|
|
75825
|
+
url: String4.annotate({ description: "The website whose look the template should match: a public https address, or a bare domain such as `example.com`." }).check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(2048).annotate({ expected: "a string with at most 2048 code points" })).check(isMaxLength(2048).annotate({ expected: "a value with a length of at most 2048" })),
|
|
75826
|
+
name: optionalKey2(Union2([String4.check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(200).annotate({ expected: "a string with at most 200 code points" })).check(isMaxLength(200).annotate({ expected: "a value with a length of at most 200" })), Null2])),
|
|
75827
|
+
namespaceId: optionalKey2(Union2([NamespaceId2, Null2]).annotate({ description: "The namespace the new template project belongs to. Omit for organization level. A namespace-scoped key always creates in its own namespace." })),
|
|
75828
|
+
idempotencyKey: String4.annotate({ description: "Repeating a request with the same key, address, name, and namespace returns the project the first one created, even if the site has since stopped answering. The same key with another address, name, or namespace is refused with a 409." }).check(isMinLength(1).annotate({ expected: "a value with a length of at least 1" })).check(isMaxCodePoints(255).annotate({ expected: "a string with at most 255 code points" })).check(isMaxLength(255).annotate({ expected: "a value with a length of at most 255" }))
|
|
75829
|
+
});
|
|
75830
|
+
var TemplatesCreateFromWebsite201 = TemplateFromWebsite;
|
|
75831
|
+
var TemplatesCreateFromWebsite401 = UnauthorizedError2;
|
|
75832
|
+
var TemplatesCreateFromWebsite403 = ForbiddenError2;
|
|
75833
|
+
var TemplatesCreateFromWebsite404 = ResourceNotFoundError2;
|
|
75834
|
+
var TemplatesCreateFromWebsite409 = ConflictError2;
|
|
75835
|
+
var TemplatesCreateFromWebsite422 = ValidationError2;
|
|
75836
|
+
var TemplatesCreateFromWebsite500 = InternalError2;
|
|
75837
|
+
var TemplatesCreateFromWebsite504 = GatewayTimeoutError2;
|
|
75695
75838
|
var TemplatesAddEntryPathParams = /* @__PURE__ */ Struct({ id: TemplateProjectId2 });
|
|
75696
75839
|
var TemplatesAddEntryRequestJson = /* @__PURE__ */ Struct({
|
|
75697
75840
|
entryPath: String4.check(isMaxCodePoints(1024).annotate({ expected: "a string with at most 1024 code points" })).check(isPattern2(/* @__PURE__ */ new RegExp("^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$", "u")).annotate({ expected: "a string matching the RegExp ^(?!\\/)(?!.*\\\\)(?!.*(?:^|\\/)\\.{1,2}(?:\\/|$))(?!.*(?:^|\\/)\\.git(?:\\/|$))(?:templates|emails)\\/.+\\.tsx$" })).check(isMaxLength(1024).annotate({ expected: "a value with a length of at most 1024" })),
|
|
@@ -76104,7 +76247,19 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
|
|
|
76104
76247
|
TemplatesCreateFamilyFromTemplate500,
|
|
76105
76248
|
TemplatesCreateFamilyFromTemplate504.pipe(status(504))
|
|
76106
76249
|
]
|
|
76107
|
-
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.createFamilyFromTemplate").annotate(Summary, "Create a family from a template").annotate(Description, "Creates a template family containing the specified template and returns the new family with status 201."), post("
|
|
76250
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.createFamilyFromTemplate").annotate(Summary, "Create a family from a template").annotate(Description, "Creates a template family containing the specified template and returns the new family with status 201."), post("templatesCreateFromWebsite", "/v1/templates/from-website", {
|
|
76251
|
+
payload: TemplatesCreateFromWebsiteRequestJson,
|
|
76252
|
+
success: TemplatesCreateFromWebsite201.pipe(status(201)),
|
|
76253
|
+
error: [
|
|
76254
|
+
TemplatesCreateFromWebsite401.pipe(status(401)),
|
|
76255
|
+
TemplatesCreateFromWebsite403.pipe(status(403)),
|
|
76256
|
+
TemplatesCreateFromWebsite404.pipe(status(404)),
|
|
76257
|
+
TemplatesCreateFromWebsite409.pipe(status(409)),
|
|
76258
|
+
TemplatesCreateFromWebsite422.pipe(status(422)),
|
|
76259
|
+
TemplatesCreateFromWebsite500,
|
|
76260
|
+
TemplatesCreateFromWebsite504.pipe(status(504))
|
|
76261
|
+
]
|
|
76262
|
+
}).middleware(ApiKeySecurityMiddleware).annotate(Identifier, "templates.createFromWebsite").annotate(Summary, "Create a template from a website").annotate(Description, "Checks that the website is a public page Samva can read, creates an email template project from Samva's canonical TSX starter, and returns the template with status 201 and the request that makes the template assistant match the site. The assistant runs when the request is sent in the editor; it rebuilds the project's theme and blocks from the site and proposes a brand that applies only after the customer approves it. A 422 names why the site cannot be matched: not a web address, not public, no answer, a missing page, refused automated visits, or not a web page."), post("templatesAddEntry", "/v1/templates/projects/:id/entries", {
|
|
76108
76263
|
params: TemplatesAddEntryPathParams,
|
|
76109
76264
|
payload: TemplatesAddEntryRequestJson,
|
|
76110
76265
|
success: TemplatesAddEntry201.pipe(status(201)),
|
|
@@ -76124,6 +76279,7 @@ var TemplatesGroup = class extends make37("Templates").add(get5("templatesList",
|
|
|
76124
76279
|
var make54 = /* @__PURE__ */ forGroup(TemplatesGroup);
|
|
76125
76280
|
var list26 = /* @__PURE__ */ make54("templatesList");
|
|
76126
76281
|
var create15 = /* @__PURE__ */ make54("templatesCreate");
|
|
76282
|
+
var createFromWebsite = /* @__PURE__ */ make54("templatesCreateFromWebsite");
|
|
76127
76283
|
var addEntry = /* @__PURE__ */ make54("templatesAddEntry");
|
|
76128
76284
|
var getById = /* @__PURE__ */ make54("templatesGetById");
|
|
76129
76285
|
var remove13 = /* @__PURE__ */ make54("templatesRemove");
|
|
@@ -76723,6 +76879,66 @@ var formatReportedDiagnostic = (diagnostic) => {
|
|
|
76723
76879
|
Upgrade: ${diagnostic.upgrade}`;
|
|
76724
76880
|
};
|
|
76725
76881
|
|
|
76882
|
+
// src/commands/templates/from-website-command.ts
|
|
76883
|
+
var webOriginForApi = (apiUrl) => {
|
|
76884
|
+
if (!URL.canParse(apiUrl))
|
|
76885
|
+
return null;
|
|
76886
|
+
const url = new URL(apiUrl);
|
|
76887
|
+
if (!url.hostname.startsWith("api."))
|
|
76888
|
+
return null;
|
|
76889
|
+
url.hostname = url.hostname.slice("api.".length);
|
|
76890
|
+
return url.origin;
|
|
76891
|
+
};
|
|
76892
|
+
var editorPath = (orgSlug, templateId, ask) => `/dashboard/${encodeURIComponent(orgSlug)}/templates/${encodeURIComponent(templateId)}/edit?ask=${encodeURIComponent(ask)}`;
|
|
76893
|
+
var urlArgument = String10("url").pipe(withDescription4("The website to match: a public https address or a bare domain"));
|
|
76894
|
+
var fromWebsiteCommand = make29("from-website", {
|
|
76895
|
+
url: urlArgument,
|
|
76896
|
+
name: String9("name").pipe(withDescription2("Name for the new template; defaults to one derived from the site"), optional4),
|
|
76897
|
+
namespace: namespaceFlag("create"),
|
|
76898
|
+
idempotencyKey: String9("idempotency-key").pipe(withDescription2("Key (1-255 characters) so a retry returns the original template; generated per run when omitted"), optional4),
|
|
76899
|
+
json: jsonFlag
|
|
76900
|
+
}).pipe(withDescription3("Create a template project from a website, then open the editor to have the assistant match its brand"), withExamples([
|
|
76901
|
+
{
|
|
76902
|
+
command: "samva templates from-website example.com",
|
|
76903
|
+
description: "Check the site, create the project, and print the editor link"
|
|
76904
|
+
},
|
|
76905
|
+
{
|
|
76906
|
+
command: 'samva templates from-website https://example.com --name "Example welcome" --json',
|
|
76907
|
+
description: "Machine-readable result with the template, website, ask, and editor link"
|
|
76908
|
+
}
|
|
76909
|
+
]), withHandler(({ url, name, namespace, idempotencyKey, json }) => gen2(function* () {
|
|
76910
|
+
const key = getOrUndefined(idempotencyKey);
|
|
76911
|
+
if (key !== undefined && (key.length < 1 || key.length > 255))
|
|
76912
|
+
return yield* new SamvaCliError({
|
|
76913
|
+
message: "--idempotency-key must contain between 1 and 255 characters."
|
|
76914
|
+
});
|
|
76915
|
+
const client = yield* getClientProvider;
|
|
76916
|
+
const context = yield* resolveExecutionContext;
|
|
76917
|
+
const orgSlug = context.apiKey ? (yield* get25().pipe(client.provide, mapError2((error) => toCliApiError("Could not look up the organization", error)))).organization.slug : context.orgSlug;
|
|
76918
|
+
const result = yield* createFromWebsite({
|
|
76919
|
+
url,
|
|
76920
|
+
...isSome2(name) ? { name: name.value } : {},
|
|
76921
|
+
...namespaceField(namespace),
|
|
76922
|
+
idempotencyKey: key ?? crypto.randomUUID()
|
|
76923
|
+
}).pipe(client.provide, mapError2((error) => toCliApiError("Could not create a template from the website", error)));
|
|
76924
|
+
const path = orgSlug === undefined ? null : editorPath(orgSlug, result.template.id, result.ask);
|
|
76925
|
+
const origin = webOriginForApi(context.apiUrl);
|
|
76926
|
+
const editorUrl = path !== null && origin !== null ? `${origin}${path}` : null;
|
|
76927
|
+
if (json)
|
|
76928
|
+
return yield* printJson({
|
|
76929
|
+
template: { id: result.template.id, name: result.template.name },
|
|
76930
|
+
website: result.website,
|
|
76931
|
+
ask: result.ask,
|
|
76932
|
+
editorUrl
|
|
76933
|
+
});
|
|
76934
|
+
yield* printFields([
|
|
76935
|
+
["Template", result.template.id],
|
|
76936
|
+
["Website", result.website.host],
|
|
76937
|
+
...editorUrl !== null ? [["Editor", editorUrl]] : [["Ask", result.ask]]
|
|
76938
|
+
]);
|
|
76939
|
+
yield* log(editorUrl !== null ? "The brand proposal applies only when you approve it in the editor." : "Open the template in the dashboard editor and send the ask above; the brand proposal applies only when you approve it there.");
|
|
76940
|
+
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
76941
|
+
|
|
76726
76942
|
// src/commands/templates/local-build.ts
|
|
76727
76943
|
import { resolve as resolve9 } from "path";
|
|
76728
76944
|
var buildDir = (dir, assetBase) => runToolchain({
|
|
@@ -78847,13 +79063,18 @@ var build3 = make29("build", {
|
|
|
78847
79063
|
yield* logInfo(`Built ${built.files.length} template file(s) with compiler ${artifact.compilerVersion} to ${target}`);
|
|
78848
79064
|
}
|
|
78849
79065
|
}).pipe(json ? provideService2(MinimumLogLevel2, "None") : identity)));
|
|
79066
|
+
var sharedFilterFlag = Literals3("shared", ["true", "false"]).pipe(withDescription2("Only templates shared with every namespace (true), or only unshared ones (false)"), optional4);
|
|
78850
79067
|
var listRemote = make29("list", {
|
|
78851
79068
|
cursor: String9("cursor").pipe(withDescription2("Resume after this nextCursor from a previous page"), optional4),
|
|
78852
79069
|
limit: Int5("limit").pipe(withDescription2("Items per page"), optional4),
|
|
78853
79070
|
namespace: namespaceFlag("list"),
|
|
79071
|
+
shared: sharedFilterFlag,
|
|
78854
79072
|
all: Boolean6("all").pipe(withDescription2("Traverse every page (requires --jsonl)"), withDefault5(false)),
|
|
78855
79073
|
json: jsonFlag
|
|
78856
|
-
}).pipe(withDescription3("List remote templates"), withExamples([
|
|
79074
|
+
}).pipe(withDescription3("List remote templates"), withExamples([
|
|
79075
|
+
{ command: "samva templates list --json" },
|
|
79076
|
+
{ command: "samva templates list --shared true --json" }
|
|
79077
|
+
]), withHandler(({ cursor, limit, namespace, shared, all, json }) => gen2(function* () {
|
|
78857
79078
|
if (all && !isJsonLinesRequested())
|
|
78858
79079
|
return yield* new CliUsageError({
|
|
78859
79080
|
code: "all_requires_jsonl",
|
|
@@ -78865,7 +79086,8 @@ var listRemote = make29("list", {
|
|
|
78865
79086
|
const query = {
|
|
78866
79087
|
cursor: cursorValue,
|
|
78867
79088
|
limit: limitValue?.toString(),
|
|
78868
|
-
...namespaceField(namespace)
|
|
79089
|
+
...namespaceField(namespace),
|
|
79090
|
+
...match(shared, { onNone: () => ({}), onSome: (value) => ({ shared: value }) })
|
|
78869
79091
|
};
|
|
78870
79092
|
if (all) {
|
|
78871
79093
|
let nextCursor = cursorValue;
|
|
@@ -78892,7 +79114,8 @@ var listRemote = make29("list", {
|
|
|
78892
79114
|
["Name", item.name],
|
|
78893
79115
|
["Slug", item.slug],
|
|
78894
79116
|
["Status", item.status],
|
|
78895
|
-
["Namespace", item.namespaceId ?? "organization"]
|
|
79117
|
+
["Namespace", item.namespaceId ?? "organization"],
|
|
79118
|
+
["Shared", item.shared ? "yes" : "no"]
|
|
78896
79119
|
]);
|
|
78897
79120
|
if (data.nextCursor !== null)
|
|
78898
79121
|
yield* printFields([["Next cursor", data.nextCursor]]);
|
|
@@ -78907,20 +79130,35 @@ var getRemote = make29("get", { id: templateIdArgument2, json: jsonFlag }).pipe(
|
|
|
78907
79130
|
var createRemote = make29("create", {
|
|
78908
79131
|
data: String9("data").pipe(withDescription2("Complete template JSON payload")),
|
|
78909
79132
|
namespace: namespaceFlag("create"),
|
|
79133
|
+
shared: Boolean6("shared").pipe(withDescription2("Share the new organization-level project with every namespace; namespace-scoped keys read and send it but cannot change it"), withDefault5(false)),
|
|
78910
79134
|
dryRun: dryRunFlag6,
|
|
78911
79135
|
json: jsonFlag
|
|
78912
79136
|
}).pipe(withDescription3("Create a remote template from JSON"), withExamples([
|
|
78913
79137
|
{
|
|
78914
79138
|
command: `samva templates create --data '{"name":"Welcome","projectName":"welcome-email","idempotencyKey":"welcome-email-v1"}' --dry-run`
|
|
78915
79139
|
}
|
|
78916
|
-
]), withHandler(({ data, namespace, dryRun, json }) => gen2(function* () {
|
|
79140
|
+
]), withHandler(({ data, namespace, shared, dryRun, json }) => gen2(function* () {
|
|
78917
79141
|
const decoded = yield* decodePayload(data, "--data", CreateTemplatePayload);
|
|
79142
|
+
if (shared && decoded.shared === false)
|
|
79143
|
+
return yield* new CliUsageError({
|
|
79144
|
+
code: "shared_conflict",
|
|
79145
|
+
message: "--shared and shared: false in --data disagree."
|
|
79146
|
+
});
|
|
79147
|
+
if (shared && (isSome2(namespace) || decoded.namespaceId != null))
|
|
79148
|
+
return yield* new CliUsageError({
|
|
79149
|
+
code: "shared_namespace_conflict",
|
|
79150
|
+
message: "--shared shares an organization-level project; it cannot have a namespace."
|
|
79151
|
+
});
|
|
78918
79152
|
if (isSome2(namespace) && decoded.namespaceId != null && decoded.namespaceId !== namespace.value)
|
|
78919
79153
|
return yield* new CliUsageError({
|
|
78920
79154
|
code: "namespace_conflict",
|
|
78921
79155
|
message: "--namespace and the namespaceId in --data name different namespaces."
|
|
78922
79156
|
});
|
|
78923
|
-
const payload = {
|
|
79157
|
+
const payload = {
|
|
79158
|
+
...decoded,
|
|
79159
|
+
...namespaceField(namespace),
|
|
79160
|
+
...shared ? { shared: true } : {}
|
|
79161
|
+
};
|
|
78924
79162
|
if (dryRun)
|
|
78925
79163
|
return yield* json ? printJson({ dryRun: true, action: "templates.create", request: payload }) : printFields([
|
|
78926
79164
|
["Action", "templates.create"],
|
|
@@ -78935,14 +79173,22 @@ var createRemote = make29("create", {
|
|
|
78935
79173
|
var updateRemote = make29("update", {
|
|
78936
79174
|
id: templateIdArgument2,
|
|
78937
79175
|
data: String9("data").pipe(withDescription2("JSON object of template fields to update")),
|
|
79176
|
+
shared: Literals3("shared", ["true", "false"]).pipe(withDescription2("Share the template's organization-level project with every namespace (true) or stop sharing it (false); applies to every entry in the project"), optional4),
|
|
78938
79177
|
dryRun: dryRunFlag6,
|
|
78939
79178
|
json: jsonFlag
|
|
78940
79179
|
}).pipe(withDescription3("Update a remote template from JSON"), withExamples([
|
|
78941
79180
|
{
|
|
78942
79181
|
command: `samva templates update tmpl_abc123 --data '{"name":"Welcome back"}' --dry-run`
|
|
78943
79182
|
}
|
|
78944
|
-
]), withHandler(({ id, data, dryRun, json }) => gen2(function* () {
|
|
78945
|
-
const
|
|
79183
|
+
]), withHandler(({ id, data, shared, dryRun, json }) => gen2(function* () {
|
|
79184
|
+
const parsed = yield* parseObject(data, "--data");
|
|
79185
|
+
const sharedValue = map(shared, (value) => value === "true");
|
|
79186
|
+
if (isSome2(sharedValue) && parsed.shared !== undefined && parsed.shared !== sharedValue.value)
|
|
79187
|
+
return yield* new CliUsageError({
|
|
79188
|
+
code: "shared_conflict",
|
|
79189
|
+
message: "--shared and shared in --data disagree."
|
|
79190
|
+
});
|
|
79191
|
+
const changes = isSome2(sharedValue) ? { ...parsed, shared: sharedValue.value } : parsed;
|
|
78946
79192
|
const payload = yield* decodePayload(JSON.stringify({ data: changes }), "--data", UpdateTemplatePayload);
|
|
78947
79193
|
if (dryRun)
|
|
78948
79194
|
return yield* json ? printJson({ dryRun: true, action: "templates.update", id, request: payload }) : printFields([
|
|
@@ -79054,6 +79300,10 @@ var templatesCommand = make29("templates").pipe(withDescription3("Create, author
|
|
|
79054
79300
|
command: "samva templates clone tmpl_abc123 --dir welcome-email",
|
|
79055
79301
|
description: "Clone an existing project with its repository credential helper"
|
|
79056
79302
|
},
|
|
79303
|
+
{
|
|
79304
|
+
command: "samva templates from-website example.com",
|
|
79305
|
+
description: "Create a project from a website and print the editor link that matches its brand"
|
|
79306
|
+
},
|
|
79057
79307
|
{
|
|
79058
79308
|
command: "samva templates dev",
|
|
79059
79309
|
description: "Start the local visual editor for templates/ and emails/"
|
|
@@ -79094,6 +79344,7 @@ var templatesCommand = make29("templates").pipe(withDescription3("Create, author
|
|
|
79094
79344
|
createRemote,
|
|
79095
79345
|
updateRemote,
|
|
79096
79346
|
removeRemote,
|
|
79347
|
+
fromWebsiteCommand,
|
|
79097
79348
|
devCommand,
|
|
79098
79349
|
check5,
|
|
79099
79350
|
renderCommand,
|
|
@@ -79166,6 +79417,9 @@ var WebhookEndpoint = /* @__PURE__ */ Struct({
|
|
|
79166
79417
|
Literal2("webhook.test"),
|
|
79167
79418
|
Literal2("domain.updated"),
|
|
79168
79419
|
Literal2("domain.warming.updated"),
|
|
79420
|
+
Literal2("template.registration.updated"),
|
|
79421
|
+
Literal2("flow.registration.updated"),
|
|
79422
|
+
Literal2("whatsapp.number.connected"),
|
|
79169
79423
|
Literal2("mailbox.message.received"),
|
|
79170
79424
|
Literal2("mailbox.message.sent"),
|
|
79171
79425
|
Literal2("mailbox.action.pending_approval"),
|
|
@@ -79215,6 +79469,9 @@ var WebhookEndpointListItem = /* @__PURE__ */ Struct({
|
|
|
79215
79469
|
Literal2("webhook.test"),
|
|
79216
79470
|
Literal2("domain.updated"),
|
|
79217
79471
|
Literal2("domain.warming.updated"),
|
|
79472
|
+
Literal2("template.registration.updated"),
|
|
79473
|
+
Literal2("flow.registration.updated"),
|
|
79474
|
+
Literal2("whatsapp.number.connected"),
|
|
79218
79475
|
Literal2("mailbox.message.received"),
|
|
79219
79476
|
Literal2("mailbox.message.sent"),
|
|
79220
79477
|
Literal2("mailbox.action.pending_approval"),
|
|
@@ -79329,6 +79586,9 @@ var WebhooksCreateRequestJson = /* @__PURE__ */ Struct({
|
|
|
79329
79586
|
Literal2("webhook.test"),
|
|
79330
79587
|
Literal2("domain.updated"),
|
|
79331
79588
|
Literal2("domain.warming.updated"),
|
|
79589
|
+
Literal2("template.registration.updated"),
|
|
79590
|
+
Literal2("flow.registration.updated"),
|
|
79591
|
+
Literal2("whatsapp.number.connected"),
|
|
79332
79592
|
Literal2("mailbox.message.received"),
|
|
79333
79593
|
Literal2("mailbox.message.sent"),
|
|
79334
79594
|
Literal2("mailbox.action.pending_approval"),
|
|
@@ -79404,6 +79664,9 @@ var WebhooksUpdateRequestJson = /* @__PURE__ */ Struct({
|
|
|
79404
79664
|
Literal2("webhook.test"),
|
|
79405
79665
|
Literal2("domain.updated"),
|
|
79406
79666
|
Literal2("domain.warming.updated"),
|
|
79667
|
+
Literal2("template.registration.updated"),
|
|
79668
|
+
Literal2("flow.registration.updated"),
|
|
79669
|
+
Literal2("whatsapp.number.connected"),
|
|
79407
79670
|
Literal2("mailbox.message.received"),
|
|
79408
79671
|
Literal2("mailbox.message.sent"),
|
|
79409
79672
|
Literal2("mailbox.action.pending_approval"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@samva/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Samva CLI — email and platform operations from your terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -50,22 +50,22 @@
|
|
|
50
50
|
"@effect/vitest": "4.0.0",
|
|
51
51
|
"@samva/contracts": "0.0.0",
|
|
52
52
|
"@samva/core": "0.0.0",
|
|
53
|
-
"@samva/mailbox": "0.5.
|
|
54
|
-
"@samva/markup": "
|
|
55
|
-
"@samva/vite": "
|
|
53
|
+
"@samva/mailbox": "0.5.2",
|
|
54
|
+
"@samva/markup": "0.15.0",
|
|
55
|
+
"@samva/vite": "0.15.0",
|
|
56
56
|
"@types/node": "^26.6.2",
|
|
57
57
|
"better-auth": "1.7.5",
|
|
58
58
|
"effect": "4.0.0",
|
|
59
|
-
"samva": "0.
|
|
59
|
+
"samva": "0.22.0",
|
|
60
60
|
"typescript": "^7.0.2",
|
|
61
61
|
"vite": "~8.3.0",
|
|
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.19.0",
|
|
66
|
+
"@samva/cli-darwin-x64": "0.19.0",
|
|
67
|
+
"@samva/cli-linux-arm64": "0.19.0",
|
|
68
|
+
"@samva/cli-linux-x64": "0.19.0"
|
|
69
69
|
},
|
|
70
70
|
"engines": {
|
|
71
71
|
"node": ">=18"
|