@wraps.dev/cli 3.3.0 → 3.5.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/dist/cli.js CHANGED
@@ -778,13 +778,13 @@ function handleCLIError(error, command6) {
778
778
  docsUrl = wrapsErr.docsUrl;
779
779
  } else {
780
780
  trackError("UNHANDLED_ERROR", cmdContext, {
781
- errorType: error instanceof Error ? error.constructor.name : typeof error,
782
- message: sanitizeErrorMessage(error)
781
+ errorType: error instanceof Error ? error.constructor.name : typeof error
783
782
  });
784
783
  message = error instanceof Error ? error.message : String(error || message);
785
784
  }
786
785
  jsonError(cmdContext, { code, message, suggestion, docsUrl });
787
- process.exit(1);
786
+ process.exitCode = 1;
787
+ return;
788
788
  }
789
789
  console.error("");
790
790
  if (error instanceof WrapsError) {
@@ -804,7 +804,8 @@ ${pc.yellow("Suggestion:")}`);
804
804
  console.log(` ${pc.blue(error.docsUrl)}
805
805
  `);
806
806
  }
807
- process.exit(1);
807
+ process.exitCode = 1;
808
+ return;
808
809
  }
809
810
  if (isAWSError(error)) {
810
811
  const { code, action } = parseAWSError(error);
@@ -830,7 +831,8 @@ ${pc.yellow("Suggestion:")}`);
830
831
  console.log(` ${pc.blue(wrapsError.docsUrl)}
831
832
  `);
832
833
  }
833
- process.exit(1);
834
+ process.exitCode = 1;
835
+ return;
834
836
  }
835
837
  if (isPulumiError(error)) {
836
838
  const { code, iamAction, service, resourceName, resourceType } = parsePulumiError(error);
@@ -862,11 +864,11 @@ ${pc.yellow("Suggestion:")}`);
862
864
  console.log(` ${pc.blue(wrapsError.docsUrl)}
863
865
  `);
864
866
  }
865
- process.exit(1);
867
+ process.exitCode = 1;
868
+ return;
866
869
  }
867
870
  trackError("UNHANDLED_ERROR", cmdContext, {
868
- errorType: error instanceof Error ? error.constructor.name : typeof error,
869
- message: sanitizeErrorMessage(error)
871
+ errorType: error instanceof Error ? error.constructor.name : typeof error
870
872
  });
871
873
  clack.log.error("An unexpected error occurred");
872
874
  if (error instanceof Error) {
@@ -878,7 +880,7 @@ ${pc.yellow("Suggestion:")}`);
878
880
  ${pc.dim("If this persists, please report at:")}`);
879
881
  console.log(` ${pc.blue("https://github.com/wraps-team/wraps/issues")}
880
882
  `);
881
- process.exit(1);
883
+ process.exitCode = 1;
882
884
  }
883
885
  function awsErrorToWrapsError(code, action, originalError, isAgentContext = false) {
884
886
  const originalName = originalError instanceof Error ? originalError.name : "";
@@ -1035,6 +1037,37 @@ Saved regions: ${savedRegions.join(", ")}` : "Pass --region or set AWS_REGION.\n
1035
1037
  `Pass ${flagHint} (or run in an interactive terminal).`,
1036
1038
  "https://wraps.dev/docs/reference/json-output"
1037
1039
  ),
1040
+ // ── User-input rejections ──────────────────────────────────────────────────
1041
+ // "The user gave us bad input and this message says exactly what was wrong."
1042
+ // These are WrapsErrors on purpose: handleCLIError's WrapsError branch
1043
+ // (errors.ts:424 human, :369 JSON) already renders the exact target shape —
1044
+ // a specific telemetry code, the message, the suggestion, exit non-zero —
1045
+ // whereas a bare `throw new Error(...)` falls through to the generic tail,
1046
+ // which prints "An unexpected error occurred" plus a GitHub-issue link and
1047
+ // reports the user's typo as UNHANDLED_ERROR.
1048
+ //
1049
+ // Callers throw these INSTEAD of printing their own clack.log.error and
1050
+ // usage line. That is not tidiness: an unguarded clack.log.error writes to
1051
+ // stdout ahead of the JSON envelope, so `--json` consumers were parsing the
1052
+ // human text and the envelope out of one stream.
1053
+ unknownCommand: (what, typed, suggestion) => new WrapsError(
1054
+ `Unknown ${what}: ${typed || "(none)"}`,
1055
+ "UNKNOWN_COMMAND",
1056
+ suggestion,
1057
+ "https://wraps.dev/docs/cli-reference"
1058
+ ),
1059
+ // Code deliberately reuses MISSING_REQUIRED_FLAG rather than minting a new one:
1060
+ // four commands already emit it inline (commands/sms/verify-number.ts:193,
1061
+ // commands/sms/test.ts:71, commands/email/config-domain.ts:208,
1062
+ // commands/email/test.ts:108), it is already on the errors reference page (:583),
1063
+ // and domains.test.ts:1251 already asserts it. A second code for one condition is
1064
+ // exactly the machine-readable inconsistency this feature exists to remove.
1065
+ missingInput: (what, usage) => new WrapsError(
1066
+ `${what} is required`,
1067
+ "MISSING_REQUIRED_FLAG",
1068
+ `Usage: ${usage}`,
1069
+ "https://wraps.dev/docs/cli-reference"
1070
+ ),
1038
1071
  pulumiError: (message) => new WrapsError(
1039
1072
  `Infrastructure deployment failed: ${message}`,
1040
1073
  "PULUMI_ERROR",
@@ -1913,7 +1946,7 @@ async function needsMigration(localPulumiDir, accountId, region) {
1913
1946
  }
1914
1947
  }
1915
1948
  async function migrateLocalPulumiState(localPulumiDir, bucketName, accountId, region) {
1916
- const pulumi35 = await import("@pulumi/pulumi/automation/index.js");
1949
+ const pulumi36 = await import("@pulumi/pulumi/automation/index.js");
1917
1950
  const stacksDir = join2(localPulumiDir, ".pulumi", "stacks");
1918
1951
  const entries = await readdir(stacksDir);
1919
1952
  for (const entry of entries) {
@@ -1929,12 +1962,12 @@ async function migrateLocalPulumiState(localPulumiDir, bucketName, accountId, re
1929
1962
  for (const stackFile of stackFiles) {
1930
1963
  const stackName = stackFile.replace(".json", "");
1931
1964
  try {
1932
- const localStack = await pulumi35.LocalWorkspace.selectStack({
1965
+ const localStack = await pulumi36.LocalWorkspace.selectStack({
1933
1966
  stackName,
1934
1967
  workDir: localPulumiDir
1935
1968
  });
1936
1969
  const state2 = await localStack.exportStack();
1937
- const s3Stack = await pulumi35.LocalWorkspace.createOrSelectStack(
1970
+ const s3Stack = await pulumi36.LocalWorkspace.createOrSelectStack(
1938
1971
  {
1939
1972
  stackName,
1940
1973
  projectName,
@@ -28346,14 +28379,14 @@ async function withLockRetry(fn, options) {
28346
28379
  throw error;
28347
28380
  }
28348
28381
  const clack67 = await import("@clack/prompts");
28349
- const pc72 = (await import("picocolors")).default;
28382
+ const pc73 = (await import("picocolors")).default;
28350
28383
  if (options.autoConfirm) {
28351
28384
  clack67.log.warn(
28352
28385
  "Stack is locked from a previous interrupted run. Auto-clearing..."
28353
28386
  );
28354
28387
  } else {
28355
28388
  const shouldClear = await clack67.confirm({
28356
- message: `Stack is locked from a previous interrupted run. ${pc72.yellow("Clear the stale lock and retry?")}`,
28389
+ message: `Stack is locked from a previous interrupted run. ${pc73.yellow("Clear the stale lock and retry?")}`,
28357
28390
  initialValue: true
28358
28391
  });
28359
28392
  if (clack67.isCancel(shouldClear) || !shouldClear) {
@@ -28380,8 +28413,8 @@ var init_pulumi = __esm({
28380
28413
  // src/infrastructure/shared/resource-checks.ts
28381
28414
  async function roleExists(roleName) {
28382
28415
  try {
28383
- const { IAMClient: IAMClient6, GetRoleCommand: GetRoleCommand4 } = await import("@aws-sdk/client-iam");
28384
- const iam13 = new IAMClient6({ region: "us-east-1" });
28416
+ const { IAMClient: IAMClient7, GetRoleCommand: GetRoleCommand4 } = await import("@aws-sdk/client-iam");
28417
+ const iam13 = new IAMClient7({ region: "us-east-1" });
28385
28418
  await iam13.send(new GetRoleCommand4({ RoleName: roleName }));
28386
28419
  return true;
28387
28420
  } catch (error) {
@@ -30138,8 +30171,8 @@ __export(iam_agent_user_exports, {
30138
30171
  import * as aws22 from "@pulumi/aws";
30139
30172
  async function userExists2(userName) {
30140
30173
  try {
30141
- const { IAMClient: IAMClient6, GetUserCommand } = await import("@aws-sdk/client-iam");
30142
- const iam13 = new IAMClient6({
30174
+ const { IAMClient: IAMClient7, GetUserCommand } = await import("@aws-sdk/client-iam");
30175
+ const iam13 = new IAMClient7({
30143
30176
  region: getDefaultRegion()
30144
30177
  });
30145
30178
  await iam13.send(new GetUserCommand({ UserName: userName }));
@@ -31692,8 +31725,8 @@ import { homedir as homedir6, tmpdir as tmpdir2 } from "os";
31692
31725
  import { join as join24 } from "path";
31693
31726
  import { Readable as Readable5 } from "stream";
31694
31727
  import { pipeline } from "stream/promises";
31695
- import { cancel as cancel35, confirm as confirm29, intro as intro61, isCancel as isCancel40, log as log60 } from "@clack/prompts";
31696
- import pc70 from "picocolors";
31728
+ import { cancel as cancel35, confirm as confirm30, intro as intro62, isCancel as isCancel41, log as log61 } from "@clack/prompts";
31729
+ import pc71 from "picocolors";
31697
31730
  function isStandaloneInstall() {
31698
31731
  return process.execPath.includes(".wraps/runtime");
31699
31732
  }
@@ -31722,7 +31755,7 @@ function detectPlatformArch() {
31722
31755
  return { platform: platform3, arch };
31723
31756
  }
31724
31757
  async function update(currentVersion) {
31725
- intro61(pc70.bold("Wraps CLI Update"));
31758
+ intro62(pc71.bold("Wraps CLI Update"));
31726
31759
  const progress = new DeploymentProgress();
31727
31760
  const result = await progress.execute(
31728
31761
  "Checking for updates...",
@@ -31734,27 +31767,27 @@ async function update(currentVersion) {
31734
31767
  }
31735
31768
  const { version: latestVersion, release: release2 } = result;
31736
31769
  if (currentVersion === latestVersion) {
31737
- progress.succeed(`Already up to date ${pc70.dim(`(v${currentVersion})`)}`);
31770
+ progress.succeed(`Already up to date ${pc71.dim(`(v${currentVersion})`)}`);
31738
31771
  return;
31739
31772
  }
31740
31773
  console.log();
31741
- log60.info(
31742
- `Current version: ${pc70.dim(`v${currentVersion}`)}
31743
- Latest version: ${pc70.cyan(`v${latestVersion}`)}`
31774
+ log61.info(
31775
+ `Current version: ${pc71.dim(`v${currentVersion}`)}
31776
+ Latest version: ${pc71.cyan(`v${latestVersion}`)}`
31744
31777
  );
31745
31778
  console.log();
31746
31779
  if (!isStandaloneInstall()) {
31747
- log60.info(
31780
+ log61.info(
31748
31781
  `You installed Wraps via npm. Update with:
31749
31782
 
31750
- ${pc70.cyan("npm update -g @wraps.dev/cli")}`
31783
+ ${pc71.cyan("npm update -g @wraps.dev/cli")}`
31751
31784
  );
31752
31785
  return;
31753
31786
  }
31754
- const shouldUpdate = await confirm29({
31787
+ const shouldUpdate = await confirm30({
31755
31788
  message: `Update to v${latestVersion}?`
31756
31789
  });
31757
- if (isCancel40(shouldUpdate) || !shouldUpdate) {
31790
+ if (isCancel41(shouldUpdate) || !shouldUpdate) {
31758
31791
  cancel35("Update cancelled.");
31759
31792
  return;
31760
31793
  }
@@ -31822,7 +31855,7 @@ async function update(currentVersion) {
31822
31855
  });
31823
31856
  console.log();
31824
31857
  progress.succeed(
31825
- `Updated to ${pc70.cyan(`v${latestVersion}`)} successfully!`
31858
+ `Updated to ${pc71.cyan(`v${latestVersion}`)} successfully!`
31826
31859
  );
31827
31860
  } finally {
31828
31861
  rmSync(tmp, { recursive: true, force: true });
@@ -31846,7 +31879,7 @@ import { readFileSync as readFileSync4 } from "fs";
31846
31879
  import { dirname as dirname6, join as join25 } from "path";
31847
31880
  import { fileURLToPath as fileURLToPath6 } from "url";
31848
31881
  import * as clack66 from "@clack/prompts";
31849
- import pc71 from "picocolors";
31882
+ import pc72 from "picocolors";
31850
31883
 
31851
31884
  // src/commands/auth/login.ts
31852
31885
  init_esm_shims();
@@ -32427,7 +32460,7 @@ function collectRemediations(findings) {
32427
32460
  // src/commands/aws/doctor.ts
32428
32461
  init_json_output();
32429
32462
  var CATEGORY = "AWS Setup";
32430
- async function runDiagnostics(state2) {
32463
+ async function runDiagnostics(state2, regionOverride) {
32431
32464
  const results = [];
32432
32465
  if (state2.cliInstalled) {
32433
32466
  results.push({
@@ -32613,6 +32646,8 @@ async function runDiagnostics(state2) {
32613
32646
  }
32614
32647
  return results;
32615
32648
  }
32649
+ const configuredRegion = state2.region || "us-east-1";
32650
+ const effectiveRegion = regionOverride || state2.region;
32616
32651
  if (state2.region) {
32617
32652
  results.push({
32618
32653
  status: "pass",
@@ -32628,6 +32663,14 @@ async function runDiagnostics(state2) {
32628
32663
  remediation: remediations.setAwsRegion()
32629
32664
  });
32630
32665
  }
32666
+ if (regionOverride && regionOverride !== configuredRegion) {
32667
+ results.push({
32668
+ status: "info",
32669
+ category: CATEGORY,
32670
+ name: `Checked region: ${regionOverride}`,
32671
+ details: state2.region ? `Overrides the configured region ${state2.region}. The SES check below is about ${regionOverride}.` : `The SES check below is about ${regionOverride}, not the us-east-1 default.`
32672
+ });
32673
+ }
32631
32674
  if (!state2.sso.configured) {
32632
32675
  const profiles = getConfiguredProfiles();
32633
32676
  if (profiles.length > 1) {
@@ -32640,11 +32683,19 @@ async function runDiagnostics(state2) {
32640
32683
  }
32641
32684
  }
32642
32685
  if (state2.credentialsConfigured) {
32643
- const regionUsed = state2.region || "us-east-1";
32644
- const regionNote = state2.region ? `Region: ${regionUsed}` : `No AWS_REGION set \u2014 defaulted to ${regionUsed}. Set AWS_REGION if your deployment lives elsewhere.`;
32686
+ const regionUsed = effectiveRegion || "us-east-1";
32687
+ const regionNote = effectiveRegion ? `Region: ${regionUsed}` : `No AWS_REGION set \u2014 defaulted to ${regionUsed}. Set AWS_REGION if your deployment lives elsewhere.`;
32645
32688
  try {
32646
- const sandbox = await isSESSandbox(regionUsed);
32647
- if (sandbox) {
32689
+ const ses = await getSESAccountStatus(regionUsed);
32690
+ if (ses.sandboxUncertain) {
32691
+ results.push({
32692
+ status: "info",
32693
+ category: CATEGORY,
32694
+ name: "Could not confirm SES account status",
32695
+ details: `SES may not be enabled in this region, or the account may lack ses:GetAccount.
32696
+ ${regionNote}`
32697
+ });
32698
+ } else if (ses.isSandbox) {
32648
32699
  results.push({
32649
32700
  status: "warn",
32650
32701
  category: CATEGORY,
@@ -32665,7 +32716,7 @@ ${regionNote}`,
32665
32716
  results.push({
32666
32717
  status: "info",
32667
32718
  category: CATEGORY,
32668
- name: "Could not check SES status",
32719
+ name: "Could not confirm SES account status",
32669
32720
  details: `SES may not be enabled in this region.
32670
32721
  ${regionNote}`
32671
32722
  });
@@ -32731,22 +32782,32 @@ function suggestionsFor(results) {
32731
32782
  results.filter((r6) => r6.status === "fail" || r6.status === "warn")
32732
32783
  ).map(formatRemediation);
32733
32784
  }
32734
- async function collectAwsFindings() {
32735
- const state2 = await detectAWSState();
32736
- return { findings: await runDiagnostics(state2), state: state2 };
32785
+ async function collectAwsFindings(options = {}) {
32786
+ const state2 = options.state ?? await detectAWSState();
32787
+ return { findings: await runDiagnostics(state2, options.region), state: state2 };
32737
32788
  }
32738
- async function doctor() {
32789
+ async function doctor(options = {}) {
32739
32790
  const startTime = Date.now();
32740
32791
  if (!isJsonMode()) {
32741
32792
  clack5.intro(pc6.bold("AWS Setup Diagnostics"));
32742
32793
  }
32743
32794
  const spinner11 = isJsonMode() ? null : clack5.spinner();
32744
32795
  spinner11?.start("Running diagnostics...");
32745
- const { findings: results } = await collectAwsFindings();
32796
+ const { findings: results, state: state2 } = await collectAwsFindings({
32797
+ region: options.region
32798
+ });
32746
32799
  spinner11?.stop("Diagnostics complete");
32747
32800
  const failCount = results.filter((r6) => r6.status === "fail").length;
32748
32801
  const warnCount = results.filter((r6) => r6.status === "warn").length;
32749
32802
  const passCount = results.filter((r6) => r6.status === "pass").length;
32803
+ trackCommand("aws:doctor", {
32804
+ success: true,
32805
+ duration_ms: Date.now() - startTime,
32806
+ region: options.region || state2.region || "us-east-1",
32807
+ pass_count: passCount,
32808
+ fail_count: failCount,
32809
+ warn_count: warnCount
32810
+ });
32750
32811
  if (isJsonMode()) {
32751
32812
  jsonSuccess("aws.doctor", {
32752
32813
  checks: results.map((r6) => ({
@@ -32778,13 +32839,6 @@ async function doctor() {
32778
32839
  console.log(` ${pc6.dim("-")} ${suggestion}`);
32779
32840
  }
32780
32841
  }
32781
- trackCommand("aws:doctor", {
32782
- success: true,
32783
- duration_ms: Date.now() - startTime,
32784
- pass_count: passCount,
32785
- fail_count: failCount,
32786
- warn_count: warnCount
32787
- });
32788
32842
  console.log();
32789
32843
  clack5.outro(
32790
32844
  pc6.dim(failCount > 0 ? "See suggested fixes above" : "Ready to deploy")
@@ -34188,8 +34242,8 @@ init_constants();
34188
34242
  import * as aws3 from "@pulumi/aws";
34189
34243
  async function getExistingOIDCProviderArn(url) {
34190
34244
  try {
34191
- const { IAMClient: IAMClient6, ListOpenIDConnectProvidersCommand } = await import("@aws-sdk/client-iam");
34192
- const iam13 = new IAMClient6({
34245
+ const { IAMClient: IAMClient7, ListOpenIDConnectProvidersCommand } = await import("@aws-sdk/client-iam");
34246
+ const iam13 = new IAMClient7({
34193
34247
  region: getDefaultRegion()
34194
34248
  });
34195
34249
  const response = await iam13.send(new ListOpenIDConnectProvidersCommand({}));
@@ -36269,6 +36323,7 @@ ${pc16.dim("Tip:")} Run ${pc16.cyan("wraps cdn sync")} to update infrastructure
36269
36323
  init_esm_shims();
36270
36324
  init_events();
36271
36325
  init_aws();
36326
+ init_aws_detection();
36272
36327
  import * as clack16 from "@clack/prompts";
36273
36328
  import pc18 from "picocolors";
36274
36329
  init_json_output();
@@ -37256,19 +37311,23 @@ async function wrapsDoctor(options) {
37256
37311
  clack16.intro(pc18.bold("Wraps Doctor"));
37257
37312
  }
37258
37313
  const progress = new DeploymentProgress();
37259
- const { findings: awsFindings, state: state2 } = await progress.execute(
37260
- "Checking AWS setup",
37261
- async () => collectAwsFindings()
37314
+ const state2 = await progress.execute(
37315
+ "Detecting AWS setup",
37316
+ async () => detectAWSState()
37262
37317
  );
37263
- const findings = [...awsFindings];
37264
37318
  const emailConnections = state2.credentialsConfigured && state2.accountId ? await findConnectionsWithService(state2.accountId, "email") : [];
37265
37319
  const regionExplicit = Boolean(
37266
37320
  options.region || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION
37267
37321
  );
37268
- let region = options.region || await getAWSRegion();
37322
+ let region = options.region || state2.region || await getAWSRegion();
37269
37323
  if (!regionExplicit && emailConnections.length > 0) {
37270
37324
  region = emailConnections[0].region;
37271
37325
  }
37326
+ const { findings: awsFindings } = await progress.execute(
37327
+ "Checking AWS setup",
37328
+ async () => collectAwsFindings({ region, state: state2 })
37329
+ );
37330
+ const findings = [...awsFindings];
37272
37331
  if (state2.credentialsConfigured && state2.accountId) {
37273
37332
  if (!regionExplicit && emailConnections.length > 1) {
37274
37333
  findings.push({
@@ -38273,8 +38332,8 @@ function convertToSMTPPassword2(secretAccessKey, region) {
38273
38332
  }
38274
38333
  async function userExists(userName) {
38275
38334
  try {
38276
- const { IAMClient: IAMClient6, GetUserCommand } = await import("@aws-sdk/client-iam");
38277
- const iam13 = new IAMClient6({
38335
+ const { IAMClient: IAMClient7, GetUserCommand } = await import("@aws-sdk/client-iam");
38336
+ const iam13 = new IAMClient7({
38278
38337
  region: getDefaultRegion()
38279
38338
  });
38280
38339
  await iam13.send(new GetUserCommand({ UserName: userName }));
@@ -47187,8 +47246,8 @@ function getRequiredActions(config2) {
47187
47246
  }
47188
47247
  async function checkIAMPermissions(userArn, actions, region) {
47189
47248
  try {
47190
- const { IAMClient: IAMClient6, SimulatePrincipalPolicyCommand } = await import("@aws-sdk/client-iam");
47191
- const client2 = new IAMClient6({ region });
47249
+ const { IAMClient: IAMClient7, SimulatePrincipalPolicyCommand } = await import("@aws-sdk/client-iam");
47250
+ const client2 = new IAMClient7({ region });
47192
47251
  const batchSize = 100;
47193
47252
  const batches = [];
47194
47253
  for (let i6 = 0; i6 < actions.length; i6 += batchSize) {
@@ -48041,12 +48100,12 @@ async function emailLogsList(options) {
48041
48100
  }
48042
48101
  const COL = { time: 8, status: 11, to: 28, subject: 40, msgId: 18 };
48043
48102
  const header = pc32.bold("Time".padEnd(COL.time)) + " " + pc32.bold("Status".padEnd(COL.status)) + " " + pc32.bold("To".padEnd(COL.to)) + " " + pc32.bold("Subject".padEnd(COL.subject)) + " " + pc32.bold("Message ID");
48044
- const rows = data.logs.map((log62) => {
48045
- const time2 = relativeTime(log62.createdAt).padEnd(COL.time);
48046
- const status2 = padVisible(colorStatus(log62.status), COL.status);
48047
- const to = padVisible(truncate(log62.recipient, COL.to), COL.to);
48048
- const subject = padVisible(truncate(log62.subject, COL.subject), COL.subject);
48049
- const msgId = truncate(log62.messageId, COL.msgId);
48103
+ const rows = data.logs.map((log63) => {
48104
+ const time2 = relativeTime(log63.createdAt).padEnd(COL.time);
48105
+ const status2 = padVisible(colorStatus(log63.status), COL.status);
48106
+ const to = padVisible(truncate(log63.recipient, COL.to), COL.to);
48107
+ const subject = padVisible(truncate(log63.subject, COL.subject), COL.subject);
48108
+ const msgId = truncate(log63.messageId, COL.msgId);
48050
48109
  return `${time2} ${status2} ${to} ${subject} ${msgId}`;
48051
48110
  });
48052
48111
  clack30.note(
@@ -48104,32 +48163,32 @@ async function emailLogsGet(options) {
48104
48163
  }
48105
48164
  return;
48106
48165
  }
48107
- const log62 = await resp.json();
48166
+ const log63 = await resp.json();
48108
48167
  if (isJsonMode()) {
48109
- jsonSuccess("email.logs.get", log62);
48168
+ jsonSuccess("email.logs.get", log63);
48110
48169
  return;
48111
48170
  }
48112
48171
  const kv = (label, value) => `${pc32.dim(label.padEnd(16))} ${value ?? pc32.dim("\u2014")}`;
48113
- const sentAt = log62.sentAt ? new Date(log62.sentAt).toLocaleString() : null;
48114
- const deliveredAt = log62.deliveredAt ? new Date(log62.deliveredAt).toLocaleString() : null;
48115
- const bouncedAt = log62.bouncedAt ? new Date(log62.bouncedAt).toLocaleString() : null;
48116
- const createdAt = new Date(log62.createdAt).toLocaleString();
48172
+ const sentAt = log63.sentAt ? new Date(log63.sentAt).toLocaleString() : null;
48173
+ const deliveredAt = log63.deliveredAt ? new Date(log63.deliveredAt).toLocaleString() : null;
48174
+ const bouncedAt = log63.bouncedAt ? new Date(log63.bouncedAt).toLocaleString() : null;
48175
+ const createdAt = new Date(log63.createdAt).toLocaleString();
48117
48176
  const lines = [
48118
- kv("Message ID:", log62.messageId),
48119
- kv("Status:", log62.status ? colorStatus(log62.status) : null),
48120
- kv("To:", log62.recipient),
48121
- kv("From:", log62.from),
48122
- kv("Subject:", log62.subject),
48123
- kv("Source:", log62.sourceType),
48177
+ kv("Message ID:", log63.messageId),
48178
+ kv("Status:", log63.status ? colorStatus(log63.status) : null),
48179
+ kv("To:", log63.recipient),
48180
+ kv("From:", log63.from),
48181
+ kv("Subject:", log63.subject),
48182
+ kv("Source:", log63.sourceType),
48124
48183
  kv("Sent:", sentAt),
48125
48184
  kv("Delivered:", deliveredAt),
48126
48185
  kv("Bounced:", bouncedAt),
48127
- ...log62.bouncedSubType ? [kv("Bounce type:", log62.bouncedSubType)] : [],
48186
+ ...log63.bouncedSubType ? [kv("Bounce type:", log63.bouncedSubType)] : [],
48128
48187
  kv("Created:", createdAt)
48129
48188
  ];
48130
48189
  clack30.note(
48131
48190
  lines.join("\n"),
48132
- `Log Detail \u2014 ${log62.messageId ?? "(no message id)"}`
48191
+ `Log Detail \u2014 ${log63.messageId ?? "(no message id)"}`
48133
48192
  );
48134
48193
  }
48135
48194
 
@@ -53345,10 +53404,7 @@ ${pc40.bold("Cost Impact:")}`);
53345
53404
  trackError("STACK_LOCKED", "email:upgrade", { step: "deploy" });
53346
53405
  throw errors.stackLocked();
53347
53406
  }
53348
- trackError("UPGRADE_FAILED", "email:upgrade", {
53349
- step: "deploy",
53350
- error_detail: redactSensitiveValues(msg).slice(0, 3e3)
53351
- });
53407
+ trackError("UPGRADE_FAILED", "email:upgrade", { step: "deploy" });
53352
53408
  throw new Error(`Pulumi upgrade failed: ${extractPulumiErrorSummary(msg)}`);
53353
53409
  }
53354
53410
  let dnsAutoCreated = false;
@@ -55663,7 +55719,7 @@ import pc44 from "picocolors";
55663
55719
  // src/utils/license.ts
55664
55720
  init_esm_shims();
55665
55721
  import { sign as sign2 } from "crypto";
55666
- var VALID_TIERS = ["starter", "growth", "scale"];
55722
+ var VALID_TIERS = ["pro", "business", "starter", "growth", "scale"];
55667
55723
  function generateLicenseKey(tier, expires) {
55668
55724
  if (!VALID_TIERS.includes(tier)) {
55669
55725
  throw new Error(
@@ -55687,7 +55743,7 @@ function generateLicenseKey(tier, expires) {
55687
55743
 
55688
55744
  // src/commands/license/generate.ts
55689
55745
  init_json_output();
55690
- var VALID_TIERS2 = ["starter", "growth", "scale"];
55746
+ var VALID_TIERS2 = ["pro", "business", "starter", "growth", "scale"];
55691
55747
  async function licenseGenerate(options) {
55692
55748
  if (!isJsonMode()) {
55693
55749
  clack43.intro(pc44.bold("Wraps License Key Generator"));
@@ -56296,7 +56352,6 @@ import pc47 from "picocolors";
56296
56352
  init_events();
56297
56353
  init_aws();
56298
56354
  init_config();
56299
- init_errors();
56300
56355
  init_fs();
56301
56356
  init_json_output();
56302
56357
  init_metadata();
@@ -56960,9 +57015,7 @@ You can try the manual flow: ${pc47.cyan("wraps auth logout")} then ${pc47.cyan(
56960
57015
  progress.stop();
56961
57016
  const duration = Date.now() - startTime;
56962
57017
  const errorCode = error instanceof Error ? error.name : "UNKNOWN_ERROR";
56963
- trackError(errorCode, "platform:connect", {
56964
- message: sanitizeErrorMessage(error)
56965
- });
57018
+ trackError(errorCode, "platform:connect", { step: "authenticated" });
56966
57019
  trackCommand("platform:connect", {
56967
57020
  success: false,
56968
57021
  duration_ms: duration,
@@ -57243,9 +57296,7 @@ ${pc47.bold("Next Steps:")}`);
57243
57296
  progress.stop();
57244
57297
  const duration = Date.now() - startTime;
57245
57298
  const errorCode = error instanceof Error ? error.name : "UNKNOWN_ERROR";
57246
- trackError(errorCode, "platform:connect", {
57247
- message: sanitizeErrorMessage(error)
57248
- });
57299
+ trackError(errorCode, "platform:connect", { step: "unauthenticated" });
57249
57300
  trackCommand("platform:connect", {
57250
57301
  success: false,
57251
57302
  duration_ms: duration
@@ -57254,54 +57305,285 @@ ${pc47.bold("Next Steps:")}`);
57254
57305
  }
57255
57306
  }
57256
57307
 
57308
+ // src/commands/platform/disconnect.ts
57309
+ init_esm_shims();
57310
+ init_dist();
57311
+ import {
57312
+ DeleteRoleCommand as DeleteRoleCommand2,
57313
+ DeleteRolePolicyCommand as DeleteRolePolicyCommand2,
57314
+ IAMClient as IAMClient4
57315
+ } from "@aws-sdk/client-iam";
57316
+ import { confirm as confirm22, intro as intro40, isCancel as isCancel30, log as log42, outro as outro27 } from "@clack/prompts";
57317
+ import * as pulumi27 from "@pulumi/pulumi";
57318
+ import pc48 from "picocolors";
57319
+ init_aws();
57320
+ init_errors();
57321
+ init_fs();
57322
+ init_json_output();
57323
+ init_metadata();
57324
+ init_output();
57325
+ init_prompts();
57326
+ init_pulumi();
57327
+ init_region_resolver();
57328
+ async function removeConsoleAccessRole(region) {
57329
+ const iam13 = new IAMClient4({ region });
57330
+ try {
57331
+ await iam13.send(
57332
+ new DeleteRolePolicyCommand2({
57333
+ RoleName: CONSOLE_ACCESS_ROLE_NAME,
57334
+ PolicyName: "wraps-console-access-policy"
57335
+ })
57336
+ );
57337
+ } catch (error) {
57338
+ if (!isAWSNotFoundError(error)) {
57339
+ throw error;
57340
+ }
57341
+ }
57342
+ try {
57343
+ await iam13.send(
57344
+ new DeleteRoleCommand2({ RoleName: CONSOLE_ACCESS_ROLE_NAME })
57345
+ );
57346
+ return true;
57347
+ } catch (error) {
57348
+ if (isAWSNotFoundError(error)) {
57349
+ return false;
57350
+ }
57351
+ throw error;
57352
+ }
57353
+ }
57354
+ async function disconnect(options) {
57355
+ const json = isJsonMode();
57356
+ if (!json) {
57357
+ intro40(pc48.bold("Disconnect from Wraps Platform"));
57358
+ }
57359
+ const progress = new DeploymentProgress();
57360
+ try {
57361
+ await progress.execute(
57362
+ "Checking Pulumi CLI installation",
57363
+ async () => await ensurePulumiInstalled()
57364
+ );
57365
+ const identity = await progress.execute(
57366
+ "Validating AWS credentials",
57367
+ async () => validateAWSCredentials()
57368
+ );
57369
+ const region = await resolveRegionForCommand({
57370
+ accountId: identity.accountId,
57371
+ optionRegion: options.region,
57372
+ label: "connection"
57373
+ });
57374
+ const metadata = await loadConnectionMetadata(identity.accountId, region);
57375
+ if (!metadata) {
57376
+ progress.stop();
57377
+ if (json) {
57378
+ jsonError("platform.disconnect", {
57379
+ code: "NO_DEPLOYMENT",
57380
+ message: `No Wraps deployment found for account ${identity.accountId} in ${region}.`,
57381
+ suggestion: "Run `wraps email init` to deploy infrastructure first."
57382
+ });
57383
+ return;
57384
+ }
57385
+ log42.error(
57386
+ `No Wraps deployment found for account ${pc48.cyan(identity.accountId)} in region ${pc48.cyan(region)}`
57387
+ );
57388
+ process.exit(1);
57389
+ }
57390
+ const emailService = metadata.services.email;
57391
+ if (!emailService?.config) {
57392
+ progress.stop();
57393
+ if (json) {
57394
+ jsonError("platform.disconnect", {
57395
+ code: "NO_EMAIL_SERVICE",
57396
+ message: "No email service deployed in this region.",
57397
+ suggestion: "Run `wraps email init` first."
57398
+ });
57399
+ return;
57400
+ }
57401
+ log42.error("No email service deployed in this region.");
57402
+ process.exit(1);
57403
+ }
57404
+ if (!emailService.webhookSecret) {
57405
+ progress.stop();
57406
+ if (json) {
57407
+ jsonSuccess("platform.disconnect", {
57408
+ accountId: identity.accountId,
57409
+ region,
57410
+ disconnected: false,
57411
+ reason: "not connected"
57412
+ });
57413
+ return;
57414
+ }
57415
+ log42.info("This account is not connected to the Wraps Platform.");
57416
+ outro27("Nothing to do");
57417
+ return;
57418
+ }
57419
+ const stillSelfhosted = !!emailService.selfhostWebhook;
57420
+ if (!(options.force || options.yes || json)) {
57421
+ progress.stop();
57422
+ log42.warn(
57423
+ `SES events from AWS account ${pc48.cyan(identity.accountId)} will stop reaching ${pc48.cyan("app.wraps.dev")}.`
57424
+ );
57425
+ log42.info(
57426
+ [
57427
+ "This does NOT affect sending \u2014 your mail flows through your own SES.",
57428
+ `Wraps' cross-account IAM role (${pc48.cyan(CONSOLE_ACCESS_ROLE_NAME)}) will be deleted, revoking dashboard access to this account.`,
57429
+ stillSelfhosted ? `Your self-hosted control plane (${pc48.cyan(emailService.selfhostWebhook?.url ?? "self-hosted")}) keeps receiving events.` : "Dashboard email logs and analytics will stop updating for this account."
57430
+ ].join("\n ")
57431
+ );
57432
+ const confirmed = await confirm22({
57433
+ message: "Disconnect from the Wraps Platform?",
57434
+ initialValue: false
57435
+ });
57436
+ if (isCancel30(confirmed) || !confirmed) {
57437
+ outro27("Disconnect cancelled");
57438
+ return;
57439
+ }
57440
+ }
57441
+ emailService.webhookSecret = void 0;
57442
+ emailService.webhookUrl = void 0;
57443
+ await saveConnectionMetadata(metadata);
57444
+ if (metadata.provider === "vercel" && !metadata.vercel) {
57445
+ progress.stop();
57446
+ metadata.vercel = await promptVercelConfig();
57447
+ }
57448
+ const stackConfig = buildEmailStackConfig(metadata, region, {
57449
+ webhook: void 0
57450
+ });
57451
+ await progress.execute("Removing platform event target", async () => {
57452
+ await ensurePulumiWorkDir({ accountId: identity.accountId, region });
57453
+ const stack = await pulumi27.automation.LocalWorkspace.createOrSelectStack(
57454
+ {
57455
+ stackName: emailService.pulumiStackName || `wraps-${identity.accountId}-${region}`,
57456
+ projectName: "wraps-email",
57457
+ program: async () => {
57458
+ const result = await deployEmailStack(stackConfig);
57459
+ return {
57460
+ roleArn: result.roleArn,
57461
+ configSetName: result.configSetName,
57462
+ tableName: result.tableName,
57463
+ region: result.region
57464
+ };
57465
+ }
57466
+ },
57467
+ {
57468
+ workDir: getPulumiWorkDir(),
57469
+ envVars: {
57470
+ PULUMI_CONFIG_PASSPHRASE: "",
57471
+ AWS_REGION: region
57472
+ },
57473
+ secretsProvider: "passphrase"
57474
+ }
57475
+ );
57476
+ await stack.setConfig("aws:region", { value: region });
57477
+ await stack.refresh({ onOutput: () => {
57478
+ } });
57479
+ const stackState = await stack.exportStack();
57480
+ const resourceCount = stackState.deployment?.resources?.length ?? 0;
57481
+ if (resourceCount > 1) {
57482
+ stackConfig.skipResourceImports = true;
57483
+ }
57484
+ await stack.up({ onOutput: () => {
57485
+ } });
57486
+ });
57487
+ progress.succeed("Platform event target removed");
57488
+ const roleRemoved = await progress.execute(
57489
+ "Revoking dashboard access",
57490
+ async () => removeConsoleAccessRole(region)
57491
+ );
57492
+ metadata.platform = void 0;
57493
+ await saveConnectionMetadata(metadata);
57494
+ if (json) {
57495
+ jsonSuccess("platform.disconnect", {
57496
+ accountId: identity.accountId,
57497
+ region,
57498
+ disconnected: true,
57499
+ selfhostWebhookRetained: stillSelfhosted,
57500
+ consoleAccessRoleRemoved: roleRemoved
57501
+ });
57502
+ return;
57503
+ }
57504
+ console.log();
57505
+ log42.success("Disconnected from the Wraps Platform.");
57506
+ console.log();
57507
+ console.log(
57508
+ ` SES events from ${pc48.cyan(identity.accountId)} no longer reach app.wraps.dev.`
57509
+ );
57510
+ console.log(
57511
+ roleRemoved ? ` Wraps' cross-account access role was deleted \u2014 the dashboard can no longer read this account.` : " No cross-account access role was present to remove."
57512
+ );
57513
+ if (stillSelfhosted) {
57514
+ console.log(
57515
+ ` Your self-hosted plane at ${pc48.cyan(emailService.selfhostWebhook?.url ?? "")} is unchanged.`
57516
+ );
57517
+ }
57518
+ console.log(
57519
+ pc48.dim(` Reconnect any time with ${pc48.cyan("wraps platform connect")}.`)
57520
+ );
57521
+ console.log();
57522
+ outro27("Done");
57523
+ } catch (error) {
57524
+ progress.stop();
57525
+ if (json) {
57526
+ jsonError("platform.disconnect", {
57527
+ code: "DISCONNECT_FAILED",
57528
+ message: error instanceof Error ? error.message : String(error)
57529
+ });
57530
+ return;
57531
+ }
57532
+ throw error;
57533
+ }
57534
+ }
57535
+
57257
57536
  // src/commands/platform/index.ts
57258
57537
  init_esm_shims();
57259
57538
  import * as clack46 from "@clack/prompts";
57260
- import pc48 from "picocolors";
57539
+ import pc49 from "picocolors";
57261
57540
  async function platform2() {
57262
- clack46.intro(pc48.bold("Wraps Platform"));
57541
+ clack46.intro(pc49.bold("Wraps Platform"));
57263
57542
  console.log();
57264
57543
  console.log(
57265
57544
  " The Wraps Platform extends the free CLI with hosted features:"
57266
57545
  );
57267
57546
  console.log();
57268
- console.log(` ${pc48.bold("Features:")}`);
57269
- console.log(` ${pc48.green("\u2713")} Visual email template editor`);
57270
- console.log(` ${pc48.green("\u2713")} Broadcast campaigns & scheduling`);
57271
- console.log(` ${pc48.green("\u2713")} Contact management & segments`);
57272
- console.log(` ${pc48.green("\u2713")} Workflow automations`);
57273
- console.log(` ${pc48.green("\u2713")} Analytics dashboard`);
57274
- console.log(` ${pc48.green("\u2713")} Team collaboration`);
57547
+ console.log(` ${pc49.bold("Features:")}`);
57548
+ console.log(` ${pc49.green("\u2713")} Visual email template editor`);
57549
+ console.log(` ${pc49.green("\u2713")} Broadcast campaigns & scheduling`);
57550
+ console.log(` ${pc49.green("\u2713")} Contact management & segments`);
57551
+ console.log(` ${pc49.green("\u2713")} Workflow automations`);
57552
+ console.log(` ${pc49.green("\u2713")} Analytics dashboard`);
57553
+ console.log(` ${pc49.green("\u2713")} Team collaboration`);
57275
57554
  console.log();
57276
- console.log(` ${pc48.bold("Pricing:")}`);
57277
- console.log(` ${pc48.cyan("Starter")} $10/mo 5,000 contacts`);
57278
- console.log(` ${pc48.cyan("Growth")} $25/mo 25,000 contacts`);
57279
- console.log(` ${pc48.cyan("Scale")} $50/mo 100,000 contacts`);
57280
- console.log(` ${pc48.cyan("Enterprise")} Custom Unlimited contacts`);
57555
+ console.log(` ${pc49.bold("Pricing:")}`);
57556
+ console.log(` ${pc49.cyan("Starter")} $10/mo 5,000 contacts`);
57557
+ console.log(` ${pc49.cyan("Growth")} $25/mo 25,000 contacts`);
57558
+ console.log(` ${pc49.cyan("Scale")} $50/mo 100,000 contacts`);
57559
+ console.log(` ${pc49.cyan("Enterprise")} Custom Unlimited contacts`);
57281
57560
  console.log();
57282
57561
  console.log(
57283
- pc48.dim(" + AWS costs at $0.10 per 1,000 emails (paid directly to AWS)")
57562
+ pc49.dim(" + AWS costs at $0.10 per 1,000 emails (paid directly to AWS)")
57284
57563
  );
57285
57564
  console.log();
57286
57565
  console.log(
57287
- ` ${pc48.bold("Learn more:")} ${pc48.cyan("https://wraps.dev/platform")}`
57566
+ ` ${pc49.bold("Learn more:")} ${pc49.cyan("https://wraps.dev/platform")}`
57288
57567
  );
57289
57568
  console.log();
57290
- console.log(pc48.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
57569
+ console.log(pc49.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
57291
57570
  console.log();
57292
- console.log(` ${pc48.bold("Platform Commands:")}`);
57571
+ console.log(` ${pc49.bold("Platform Commands:")}`);
57293
57572
  console.log();
57294
57573
  console.log(
57295
- ` ${pc48.cyan("wraps platform connect")} Connect infrastructure to Wraps Platform`
57574
+ ` ${pc49.cyan("wraps platform connect")} Connect infrastructure to Wraps Platform`
57575
+ );
57576
+ console.log(
57577
+ ` ${pc49.cyan("wraps platform disconnect")} Stop streaming events to Wraps Platform`
57296
57578
  );
57297
57579
  console.log(
57298
- ` ${pc48.cyan("wraps platform update-role")} Update IAM permissions for dashboard`
57580
+ ` ${pc49.cyan("wraps platform update-role")} Update IAM permissions for dashboard`
57299
57581
  );
57300
57582
  console.log();
57301
57583
  console.log(
57302
- pc48.dim(" The connect command sets up event streaming and IAM permissions")
57584
+ pc49.dim(" The connect command sets up event streaming and IAM permissions")
57303
57585
  );
57304
- console.log(pc48.dim(" in one step. Run it after deploying infrastructure."));
57586
+ console.log(pc49.dim(" in one step. Run it after deploying infrastructure."));
57305
57587
  console.log();
57306
57588
  }
57307
57589
 
@@ -57317,15 +57599,15 @@ init_region_resolver();
57317
57599
  import {
57318
57600
  CreateRoleCommand as CreateRoleCommand2,
57319
57601
  GetRoleCommand as GetRoleCommand2,
57320
- IAMClient as IAMClient4,
57602
+ IAMClient as IAMClient5,
57321
57603
  UpdateAssumeRolePolicyCommand as UpdateAssumeRolePolicyCommand2
57322
57604
  } from "@aws-sdk/client-iam";
57323
- import { confirm as confirm22, intro as intro41, isCancel as isCancel30, log as log42, outro as outro27 } from "@clack/prompts";
57324
- import pc49 from "picocolors";
57605
+ import { confirm as confirm23, intro as intro42, isCancel as isCancel31, log as log43, outro as outro28 } from "@clack/prompts";
57606
+ import pc50 from "picocolors";
57325
57607
  async function updateRole(options) {
57326
57608
  const startTime = Date.now();
57327
57609
  if (!isJsonMode()) {
57328
- intro41(pc49.bold("Update Platform Access Role"));
57610
+ intro42(pc50.bold("Update Platform Access Role"));
57329
57611
  }
57330
57612
  const progress = new DeploymentProgress();
57331
57613
  const identity = await progress.execute(
@@ -57340,19 +57622,19 @@ async function updateRole(options) {
57340
57622
  const metadata = await loadConnectionMetadata(identity.accountId, region);
57341
57623
  if (!metadata) {
57342
57624
  progress.stop();
57343
- log42.error(
57344
- `No Wraps deployment found for account ${pc49.cyan(identity.accountId)} in region ${pc49.cyan(region)}`
57625
+ log43.error(
57626
+ `No Wraps deployment found for account ${pc50.cyan(identity.accountId)} in region ${pc50.cyan(region)}`
57345
57627
  );
57346
57628
  console.log(
57347
57629
  `
57348
- Run ${pc49.cyan("wraps email init")} to deploy infrastructure first.
57630
+ Run ${pc50.cyan("wraps email init")} to deploy infrastructure first.
57349
57631
  `
57350
57632
  );
57351
57633
  process.exit(1);
57352
57634
  }
57353
57635
  const selfhosted = options.selfhosted === true;
57354
57636
  const roleName = selfhosted ? SELFHOST_CONSOLE_ACCESS_ROLE_NAME : CONSOLE_ACCESS_ROLE_NAME;
57355
- const iam13 = new IAMClient4({ region: "us-east-1" });
57637
+ const iam13 = new IAMClient5({ region: "us-east-1" });
57356
57638
  const WRAPS_PLATFORM_ACCOUNT_ID2 = "905130073023";
57357
57639
  const trustedAccountId = selfhosted ? metadata.accountId : WRAPS_PLATFORM_ACCOUNT_ID2;
57358
57640
  let roleExists2 = false;
@@ -57368,13 +57650,13 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure first.
57368
57650
  const externalId = selfhosted ? metadata.selfhostPlatform?.externalId : metadata.platform?.externalId;
57369
57651
  if (!(roleExists2 || externalId)) {
57370
57652
  progress.stop();
57371
- log42.warn(`IAM role ${pc49.cyan(roleName)} does not exist`);
57653
+ log43.warn(`IAM role ${pc50.cyan(roleName)} does not exist`);
57372
57654
  if (selfhosted) {
57373
57655
  console.log(
57374
57656
  "\nThis role is created when your self-hosted control plane connects this AWS account."
57375
57657
  );
57376
57658
  console.log(
57377
- `Run ${pc49.cyan("wraps selfhost connect")} to create the role automatically.
57659
+ `Run ${pc50.cyan("wraps selfhost connect")} to create the role automatically.
57378
57660
  `
57379
57661
  );
57380
57662
  } else {
@@ -57382,28 +57664,28 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure first.
57382
57664
  "\nThis role is created when you connect AWS accounts through the Wraps Platform."
57383
57665
  );
57384
57666
  console.log(
57385
- `Run ${pc49.cyan("wraps platform connect")} while logged in to create the role automatically.
57667
+ `Run ${pc50.cyan("wraps platform connect")} while logged in to create the role automatically.
57386
57668
  `
57387
57669
  );
57388
57670
  }
57389
57671
  process.exit(0);
57390
57672
  }
57391
57673
  if (roleExists2) {
57392
- progress.info(`Found IAM role: ${pc49.cyan(roleName)}`);
57674
+ progress.info(`Found IAM role: ${pc50.cyan(roleName)}`);
57393
57675
  } else {
57394
57676
  progress.info(
57395
- `IAM role ${pc49.cyan(roleName)} not found \u2014 will create it using stored externalId`
57677
+ `IAM role ${pc50.cyan(roleName)} not found \u2014 will create it using stored externalId`
57396
57678
  );
57397
57679
  }
57398
57680
  if (!options.force) {
57399
57681
  progress.stop();
57400
57682
  const actionLabel = roleExists2 ? "Update" : "Create";
57401
- const shouldContinue = await confirm22({
57402
- message: `${actionLabel} IAM role ${pc49.cyan(roleName)} with latest permissions?`,
57683
+ const shouldContinue = await confirm23({
57684
+ message: `${actionLabel} IAM role ${pc50.cyan(roleName)} with latest permissions?`,
57403
57685
  initialValue: true
57404
57686
  });
57405
- if (isCancel30(shouldContinue) || !shouldContinue) {
57406
- outro27(`${actionLabel} cancelled`);
57687
+ if (isCancel31(shouldContinue) || !shouldContinue) {
57688
+ outro28(`${actionLabel} cancelled`);
57407
57689
  process.exit(0);
57408
57690
  }
57409
57691
  }
@@ -57509,51 +57791,51 @@ Run ${pc49.cyan("wraps email init")} to deploy infrastructure first.
57509
57791
  });
57510
57792
  return;
57511
57793
  }
57512
- outro27(pc49.green(`\u2713 Platform access role ${actionVerb} successfully`));
57794
+ outro28(pc50.green(`\u2713 Platform access role ${actionVerb} successfully`));
57513
57795
  console.log(`
57514
- ${pc49.bold("Permissions:")}`);
57796
+ ${pc50.bold("Permissions:")}`);
57515
57797
  console.log(`
57516
- ${pc49.bold(pc49.cyan("Email:"))}`);
57798
+ ${pc50.bold(pc50.cyan("Email:"))}`);
57517
57799
  console.log(
57518
- ` ${pc49.green("\u2713")} SES metrics and identity verification (always enabled)`
57800
+ ` ${pc50.green("\u2713")} SES metrics and identity verification (always enabled)`
57519
57801
  );
57520
- console.log(` ${pc49.green("\u2713")} SES template management (always enabled)`);
57521
- console.log(` ${pc49.green("\u2713")} Inbound bucket detection (always enabled)`);
57802
+ console.log(` ${pc50.green("\u2713")} SES template management (always enabled)`);
57803
+ console.log(` ${pc50.green("\u2713")} Inbound bucket detection (always enabled)`);
57522
57804
  if (sendingEnabled) {
57523
- console.log(` ${pc49.green("\u2713")} Email sending via SES`);
57805
+ console.log(` ${pc50.green("\u2713")} Email sending via SES`);
57524
57806
  }
57525
57807
  console.log(
57526
- ` ${pc49.green("\u2713")} DynamoDB read access (including DescribeTable)`
57808
+ ` ${pc50.green("\u2713")} DynamoDB read access (including DescribeTable)`
57527
57809
  );
57528
57810
  if (eventTracking?.enabled) {
57529
- console.log(` ${pc49.green("\u2713")} EventBridge and SQS access`);
57811
+ console.log(` ${pc50.green("\u2713")} EventBridge and SQS access`);
57530
57812
  }
57531
57813
  if (emailArchiving?.enabled) {
57532
- console.log(` ${pc49.green("\u2713")} Mail Manager Archive access`);
57814
+ console.log(` ${pc50.green("\u2713")} Mail Manager Archive access`);
57533
57815
  }
57534
57816
  const inbound = emailConfig?.inbound;
57535
57817
  if (inbound?.enabled) {
57536
- console.log(` ${pc49.green("\u2713")} S3 access for inbound email`);
57818
+ console.log(` ${pc50.green("\u2713")} S3 access for inbound email`);
57537
57819
  }
57538
57820
  if (smsEnabled) {
57539
57821
  console.log(`
57540
- ${pc49.bold(pc49.cyan("SMS:"))}`);
57822
+ ${pc50.bold(pc50.cyan("SMS:"))}`);
57541
57823
  console.log(
57542
- ` ${pc49.green("\u2713")} SMS Voice V2 read access (phone numbers, config, registrations)`
57824
+ ` ${pc50.green("\u2713")} SMS Voice V2 read access (phone numbers, config, registrations)`
57543
57825
  );
57544
57826
  if (smsSendingEnabled) {
57545
- console.log(` ${pc49.green("\u2713")} SMS sending via SMS Voice V2`);
57827
+ console.log(` ${pc50.green("\u2713")} SMS sending via SMS Voice V2`);
57546
57828
  }
57547
57829
  if (smsEventTracking?.dynamoDBHistory) {
57548
- console.log(` ${pc49.green("\u2713")} DynamoDB read access for SMS history`);
57830
+ console.log(` ${pc50.green("\u2713")} DynamoDB read access for SMS history`);
57549
57831
  }
57550
57832
  if (smsEventTracking?.enabled) {
57551
- console.log(` ${pc49.green("\u2713")} SNS topic access for SMS events`);
57833
+ console.log(` ${pc50.green("\u2713")} SNS topic access for SMS events`);
57552
57834
  }
57553
57835
  }
57554
57836
  console.log(
57555
57837
  `
57556
- ${pc49.dim(`The Wraps Platform will now have ${actionVerb} permissions for feature detection.`)}
57838
+ ${pc50.dim(`The Wraps Platform will now have ${actionVerb} permissions for feature detection.`)}
57557
57839
  `
57558
57840
  );
57559
57841
  }
@@ -57751,12 +58033,12 @@ function buildConsolePolicyDocument2(emailConfig, smsConfig) {
57751
58033
  init_esm_shims();
57752
58034
  init_events();
57753
58035
  import * as clack47 from "@clack/prompts";
57754
- import pc50 from "picocolors";
58036
+ import pc51 from "picocolors";
57755
58037
 
57756
58038
  // src/utils/selfhost/email-stack.ts
57757
58039
  init_esm_shims();
57758
58040
  init_dist();
57759
- import { GetRoleCommand as GetRoleCommand3, IAMClient as IAMClient5 } from "@aws-sdk/client-iam";
58041
+ import { GetRoleCommand as GetRoleCommand3, IAMClient as IAMClient6 } from "@aws-sdk/client-iam";
57760
58042
  import {
57761
58043
  ListConfigurationSetsCommand as ListConfigurationSetsCommand2,
57762
58044
  ListEmailIdentitiesCommand,
@@ -57764,7 +58046,7 @@ import {
57764
58046
  } from "@aws-sdk/client-sesv2";
57765
58047
  async function detectEmailStack(region) {
57766
58048
  try {
57767
- const iam13 = new IAMClient5({ region });
58049
+ const iam13 = new IAMClient6({ region });
57768
58050
  const ses = new SESv2Client9({ region });
57769
58051
  const [roleResult, setsResult, identitiesResult] = await Promise.allSettled(
57770
58052
  [
@@ -57815,7 +58097,7 @@ init_region_resolver();
57815
58097
  async function selfhostEnv(options) {
57816
58098
  const startTime = Date.now();
57817
58099
  if (!isJsonMode()) {
57818
- clack47.intro(pc50.bold("Wraps Self-Hosted \u2014 Vercel Environment Variables"));
58100
+ clack47.intro(pc51.bold("Wraps Self-Hosted \u2014 Vercel Environment Variables"));
57819
58101
  }
57820
58102
  const identity = await validateAWSCredentials();
57821
58103
  const region = await resolveRegionForCommand({
@@ -57829,7 +58111,7 @@ async function selfhostEnv(options) {
57829
58111
  clack47.log.error("No self-hosted deployment found");
57830
58112
  console.log(
57831
58113
  `
57832
- Run ${pc50.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane.
58114
+ Run ${pc51.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane.
57833
58115
  `
57834
58116
  );
57835
58117
  process.exit(1);
@@ -57843,7 +58125,7 @@ Run ${pc50.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
57843
58125
  );
57844
58126
  console.log(
57845
58127
  `
57846
- The deployment may have failed partway through. Run ${pc50.cyan("pnpm selfhost:upgrade")} from your fork to complete it.
58128
+ The deployment may have failed partway through. Run ${pc51.cyan("pnpm selfhost:upgrade")} from your fork to complete it.
57847
58129
  `
57848
58130
  );
57849
58131
  process.exit(1);
@@ -57949,7 +58231,7 @@ The deployment may have failed partway through. Run ${pc50.cyan("pnpm selfhost:u
57949
58231
  `# AWS_ROLE_ARN=arn:aws:iam::${identity.accountId}:role/<your-vercel-backend-role>`
57950
58232
  );
57951
58233
  clack47.outro(
57952
- pc50.dim(
58234
+ pc51.dim(
57953
58235
  "Paste into Vercel \u2192 Settings \u2192 Environment Variables \u2192 Add from .env"
57954
58236
  )
57955
58237
  );
@@ -57964,7 +58246,7 @@ init_esm_shims();
57964
58246
  init_events();
57965
58247
  import * as clack48 from "@clack/prompts";
57966
58248
  import open2 from "open";
57967
- import pc51 from "picocolors";
58249
+ import pc52 from "picocolors";
57968
58250
  init_aws();
57969
58251
  init_config();
57970
58252
  init_json_output();
@@ -57973,7 +58255,7 @@ init_region_resolver();
57973
58255
  async function selfhostLogin(options) {
57974
58256
  const startTime = Date.now();
57975
58257
  if (!isJsonMode()) {
57976
- clack48.intro(pc51.bold("Wraps Self-Hosted \u203A Sign In"));
58258
+ clack48.intro(pc52.bold("Wraps Self-Hosted \u203A Sign In"));
57977
58259
  }
57978
58260
  const identity = await validateAWSCredentials();
57979
58261
  const region = await resolveRegionForCommand({
@@ -57987,7 +58269,7 @@ async function selfhostLogin(options) {
57987
58269
  clack48.log.error("No self-hosted deployment found.");
57988
58270
  console.log(
57989
58271
  `
57990
- Run ${pc51.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane first.
58272
+ Run ${pc52.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane first.
57991
58273
  `
57992
58274
  );
57993
58275
  process.exit(1);
@@ -57995,7 +58277,7 @@ Run ${pc51.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
57995
58277
  }
57996
58278
  const { appUrl: baseURL } = metadata.services.selfhost.config;
57997
58279
  const apiUrl = await reconcileSelfhostApiUrl(metadata, region);
57998
- clack48.log.info(`Connecting to: ${pc51.cyan(baseURL)}`);
58280
+ clack48.log.info(`Connecting to: ${pc52.cyan(baseURL)}`);
57999
58281
  const authClient = createCliAuthClient(baseURL);
58000
58282
  const spinner11 = clack48.spinner();
58001
58283
  const { data: codeData, error: codeError } = await authClient.device.code({
@@ -58011,14 +58293,14 @@ Run ${pc51.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
58011
58293
  step: "request_code"
58012
58294
  });
58013
58295
  clack48.log.error(
58014
- `Failed to reach ${pc51.cyan(baseURL)}. Make sure the dashboard is deployed and reachable.`
58296
+ `Failed to reach ${pc52.cyan(baseURL)}. Make sure the dashboard is deployed and reachable.`
58015
58297
  );
58016
58298
  throw new Error("Failed to start device authorization.");
58017
58299
  }
58018
58300
  const { device_code, user_code, interval, expires_in } = codeData;
58019
58301
  const formatted = `${user_code.slice(0, 4)}-${user_code.slice(4)}`;
58020
- clack48.log.info(`Your code: ${pc51.bold(pc51.cyan(formatted))}`);
58021
- clack48.log.info(`Visit: ${pc51.underline(`${baseURL}/device`)}`);
58302
+ clack48.log.info(`Your code: ${pc52.bold(pc52.cyan(formatted))}`);
58303
+ clack48.log.info(`Visit: ${pc52.underline(`${baseURL}/device`)}`);
58022
58304
  try {
58023
58305
  await open2(`${baseURL}/device?user_code=${user_code}`);
58024
58306
  clack48.log.info("Opening browser...");
@@ -58055,18 +58337,18 @@ Run ${pc51.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
58055
58337
  });
58056
58338
  clack48.log.success("Signed in to your self-hosted Wraps instance.");
58057
58339
  if (organizations.length === 1) {
58058
- clack48.log.info(`Organization: ${pc51.cyan(organizations[0].name)}`);
58340
+ clack48.log.info(`Organization: ${pc52.cyan(organizations[0].name)}`);
58059
58341
  } else if (organizations.length > 1) {
58060
58342
  clack48.log.info(`${organizations.length} organizations available`);
58061
58343
  } else {
58062
58344
  clack48.log.info(
58063
- `No organizations found. Create one at ${pc51.underline(`${baseURL}/onboarding`)} and run ${pc51.cyan("wraps selfhost login")} again.`
58345
+ `No organizations found. Create one at ${pc52.underline(`${baseURL}/onboarding`)} and run ${pc52.cyan("wraps selfhost login")} again.`
58064
58346
  );
58065
58347
  }
58066
58348
  if (isJsonMode()) {
58067
58349
  jsonSuccess("selfhost.login", { tokenType: "session", organizations });
58068
58350
  } else {
58069
- clack48.outro(pc51.green("Done!"));
58351
+ clack48.outro(pc52.green("Done!"));
58070
58352
  }
58071
58353
  return;
58072
58354
  }
@@ -58114,10 +58396,10 @@ init_json_output();
58114
58396
  init_metadata();
58115
58397
  init_region_resolver();
58116
58398
  import * as clack49 from "@clack/prompts";
58117
- import pc52 from "picocolors";
58399
+ import pc53 from "picocolors";
58118
58400
  async function selfhostLogout(options) {
58119
58401
  if (!isJsonMode()) {
58120
- clack49.intro(pc52.bold("Wraps Self-Hosted \u203A Sign Out"));
58402
+ clack49.intro(pc53.bold("Wraps Self-Hosted \u203A Sign Out"));
58121
58403
  }
58122
58404
  const identity = await validateAWSCredentials();
58123
58405
  const region = await resolveRegionForCommand({
@@ -58131,7 +58413,7 @@ async function selfhostLogout(options) {
58131
58413
  clack49.log.error("No self-hosted deployment found.");
58132
58414
  console.log(
58133
58415
  `
58134
- Run ${pc52.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane first.
58416
+ Run ${pc53.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted control plane first.
58135
58417
  `
58136
58418
  );
58137
58419
  process.exit(1);
@@ -58150,7 +58432,7 @@ Run ${pc52.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
58150
58432
  });
58151
58433
  return;
58152
58434
  }
58153
- clack49.log.info(`Not signed in to ${pc52.cyan(baseURL)}.`);
58435
+ clack49.log.info(`Not signed in to ${pc53.cyan(baseURL)}.`);
58154
58436
  return;
58155
58437
  }
58156
58438
  await clearSelfhostAuth(baseURL);
@@ -58159,13 +58441,13 @@ Run ${pc52.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
58159
58441
  jsonSuccess("selfhost.logout", { loggedOut: true });
58160
58442
  return;
58161
58443
  }
58162
- clack49.log.success(`Signed out of ${pc52.cyan(baseURL)}.`);
58444
+ clack49.log.success(`Signed out of ${pc53.cyan(baseURL)}.`);
58163
58445
  }
58164
58446
 
58165
58447
  // src/commands/selfhost/logs.ts
58166
58448
  init_esm_shims();
58167
58449
  import * as clack50 from "@clack/prompts";
58168
- import pc53 from "picocolors";
58450
+ import pc54 from "picocolors";
58169
58451
 
58170
58452
  // src/utils/selfhost/logs.ts
58171
58453
  init_esm_shims();
@@ -58504,10 +58786,10 @@ var MAX_INTERVAL_SECONDS = 60;
58504
58786
  var FOLLOW_BACKFILL_MS = 5 * 60 * 1e3;
58505
58787
  var MAX_ENTRIES = 1e3;
58506
58788
  var SOURCE_COLORS = {
58507
- api: pc53.cyan,
58508
- web: pc53.magenta,
58509
- workers: pc53.blue,
58510
- other: pc53.gray
58789
+ api: pc54.cyan,
58790
+ web: pc54.magenta,
58791
+ workers: pc54.blue,
58792
+ other: pc54.gray
58511
58793
  };
58512
58794
  function formatTime(timestamp) {
58513
58795
  const date2 = new Date(timestamp);
@@ -58516,25 +58798,25 @@ function formatTime(timestamp) {
58516
58798
  }
58517
58799
  function colorLevel(level) {
58518
58800
  if (!level) {
58519
- return pc53.dim(" ");
58801
+ return pc54.dim(" ");
58520
58802
  }
58521
58803
  const padded = level.padEnd(5).slice(0, 5);
58522
58804
  if (level === "ERROR" || level === "FATAL" || level === "CRITICAL") {
58523
- return pc53.red(padded);
58805
+ return pc54.red(padded);
58524
58806
  }
58525
58807
  if (level === "WARN") {
58526
- return pc53.yellow(padded);
58808
+ return pc54.yellow(padded);
58527
58809
  }
58528
58810
  if (level === "INFO") {
58529
- return pc53.green(padded);
58811
+ return pc54.green(padded);
58530
58812
  }
58531
- return pc53.dim(padded);
58813
+ return pc54.dim(padded);
58532
58814
  }
58533
58815
  function renderEntry(entry, options) {
58534
58816
  const level = detectLevel(entry.message);
58535
58817
  const label = logSourceLabel(entry.source).padEnd(options.sourceWidth);
58536
58818
  const body = options.verbose ? entry.message : formatMessageBody(entry.message);
58537
- return `${pc53.dim(formatTime(entry.timestamp))} ${SOURCE_COLORS[entry.source](label)} ${colorLevel(level)} ${body}`;
58819
+ return `${pc54.dim(formatTime(entry.timestamp))} ${SOURCE_COLORS[entry.source](label)} ${colorLevel(level)} ${body}`;
58538
58820
  }
58539
58821
  function toJsonEntry(entry) {
58540
58822
  return {
@@ -58605,17 +58887,17 @@ function printGroupSummary(groups) {
58605
58887
  bySource.set(group4.source, existing);
58606
58888
  }
58607
58889
  const parts = [...bySource.entries()].map(
58608
- ([source, names]) => `${SOURCE_COLORS[source](logSourceLabel(source))} ${pc53.dim(`(${names.length})`)}`
58890
+ ([source, names]) => `${SOURCE_COLORS[source](logSourceLabel(source))} ${pc54.dim(`(${names.length})`)}`
58609
58891
  );
58610
58892
  console.log(
58611
- `${pc53.dim("Sources:")} ${parts.join(pc53.dim(" \xB7 "))} ${pc53.dim(`${groups.length} log group${groups.length === 1 ? "" : "s"}`)}`
58893
+ `${pc54.dim("Sources:")} ${parts.join(pc54.dim(" \xB7 "))} ${pc54.dim(`${groups.length} log group${groups.length === 1 ? "" : "s"}`)}`
58612
58894
  );
58613
58895
  }
58614
58896
  async function selfhostLogs(options) {
58615
58897
  const progress = new DeploymentProgress();
58616
58898
  const json = isJsonMode();
58617
58899
  if (!json) {
58618
- clack50.intro(pc53.bold("Wraps Self-Hosted Logs"));
58900
+ clack50.intro(pc54.bold("Wraps Self-Hosted Logs"));
58619
58901
  }
58620
58902
  const sinceMs = parseSince(options.since ?? DEFAULT_SINCE);
58621
58903
  const intervalSeconds = parseInterval(options.interval);
@@ -58717,18 +58999,18 @@ async function printWindow(context, window) {
58717
58999
  clack50.log.info(
58718
59000
  window.errorsOnly ? `No errors in the last ${window.sinceLabel}.` : `No log events in the last ${window.sinceLabel}.`
58719
59001
  );
58720
- clack50.outro(pc53.dim("Nothing to report"));
59002
+ clack50.outro(pc54.dim("Nothing to report"));
58721
59003
  return;
58722
59004
  }
58723
59005
  context.emit(entries);
58724
59006
  console.log("");
58725
59007
  if (entries.length >= MAX_ENTRIES) {
58726
59008
  clack50.log.warn(
58727
- `Showing the most recent ${MAX_ENTRIES} events \u2014 narrow the window with ${pc53.cyan("--since")} to see more.`
59009
+ `Showing the most recent ${MAX_ENTRIES} events \u2014 narrow the window with ${pc54.cyan("--since")} to see more.`
58728
59010
  );
58729
59011
  }
58730
59012
  clack50.outro(
58731
- pc53.dim(
59013
+ pc54.dim(
58732
59014
  `${entries.length} event${entries.length === 1 ? "" : "s"} from the last ${window.sinceLabel}`
58733
59015
  )
58734
59016
  );
@@ -58737,17 +59019,17 @@ function printFollowHeader(context) {
58737
59019
  printGroupSummary(context.groups);
58738
59020
  if (context.live) {
58739
59021
  console.log(
58740
- pc53.yellow(
59022
+ pc54.yellow(
58741
59023
  "\u26A0 CloudWatch Live Tail bills ~$0.01/min for as long as this session is open."
58742
59024
  )
58743
59025
  );
58744
59026
  console.log(
58745
- pc53.dim(`Live tailing \xB7 ${pc53.reset(pc53.bold("Ctrl+C"))} to stop`)
59027
+ pc54.dim(`Live tailing \xB7 ${pc54.reset(pc54.bold("Ctrl+C"))} to stop`)
58746
59028
  );
58747
59029
  } else {
58748
59030
  console.log(
58749
- pc53.dim(
58750
- `Polling every ${context.intervalSeconds}s \xB7 ${pc53.reset(pc53.bold("Ctrl+C"))} to stop`
59031
+ pc54.dim(
59032
+ `Polling every ${context.intervalSeconds}s \xB7 ${pc54.reset(pc54.bold("Ctrl+C"))} to stop`
58751
59033
  )
58752
59034
  );
58753
59035
  }
@@ -58797,13 +59079,13 @@ async function follow(context) {
58797
59079
  }
58798
59080
  if (!context.json) {
58799
59081
  console.log("");
58800
- clack50.outro(pc53.dim("Stopped"));
59082
+ clack50.outro(pc54.dim("Stopped"));
58801
59083
  }
58802
59084
  }
58803
59085
  async function runLiveTail(context, control) {
58804
59086
  if (context.groups.length > liveTailGroupLimit() && !context.json) {
58805
59087
  clack50.log.warn(
58806
- `Live Tail supports ${liveTailGroupLimit()} log groups per session \u2014 tailing the first ${liveTailGroupLimit()}. Use ${pc53.cyan("--source")} to choose which.`
59088
+ `Live Tail supports ${liveTailGroupLimit()} log groups per session \u2014 tailing the first ${liveTailGroupLimit()}. Use ${pc54.cyan("--source")} to choose which.`
58807
59089
  );
58808
59090
  }
58809
59091
  const session = startSelfhostLiveTail({
@@ -58824,7 +59106,7 @@ async function runLiveTail(context, control) {
58824
59106
  }
58825
59107
  if (!(control.isStopped() || context.json)) {
58826
59108
  clack50.log.warn(
58827
- `Live Tail session ended (AWS caps sessions at ~3 hours). Run ${pc53.cyan("wraps selfhost logs --follow --live")} again to resume.`
59109
+ `Live Tail session ended (AWS caps sessions at ~3 hours). Run ${pc54.cyan("wraps selfhost logs --follow --live")} again to resume.`
58828
59110
  );
58829
59111
  }
58830
59112
  }
@@ -58851,7 +59133,7 @@ function isAbortError(error) {
58851
59133
  init_esm_shims();
58852
59134
  init_events();
58853
59135
  import * as clack51 from "@clack/prompts";
58854
- import pc54 from "picocolors";
59136
+ import pc55 from "picocolors";
58855
59137
  init_aws();
58856
59138
  init_json_output();
58857
59139
  init_metadata();
@@ -58861,26 +59143,26 @@ function displaySelfhostStatus(options) {
58861
59143
  const lines = [];
58862
59144
  const incomplete = !(options.apiUrl && options.appUrl);
58863
59145
  lines.push(
58864
- incomplete ? pc54.bold(pc54.yellow("Self-Hosted Control Plane Incomplete")) : pc54.bold(pc54.green("Self-Hosted Control Plane Active"))
59146
+ incomplete ? pc55.bold(pc55.yellow("Self-Hosted Control Plane Incomplete")) : pc55.bold(pc55.green("Self-Hosted Control Plane Active"))
58865
59147
  );
58866
59148
  if (incomplete) {
58867
59149
  lines.push(
58868
- pc54.yellow(
58869
- `A previous deploy did not finish. Run ${pc54.cyan("pnpm selfhost:upgrade")} from your fork to complete it.`
59150
+ pc55.yellow(
59151
+ `A previous deploy did not finish. Run ${pc55.cyan("pnpm selfhost:upgrade")} from your fork to complete it.`
58870
59152
  )
58871
59153
  );
58872
59154
  }
58873
59155
  lines.push("");
58874
- lines.push(pc54.bold("API"));
58875
- lines.push(` URL: ${pc54.cyan(options.apiUrl || "(not deployed)")}`);
58876
- lines.push(` Region: ${pc54.cyan(options.region)}`);
58877
- lines.push(` Deployed: ${pc54.dim(options.deployedAt)}`);
59156
+ lines.push(pc55.bold("API"));
59157
+ lines.push(` URL: ${pc55.cyan(options.apiUrl || "(not deployed)")}`);
59158
+ lines.push(` Region: ${pc55.cyan(options.region)}`);
59159
+ lines.push(` Deployed: ${pc55.dim(options.deployedAt)}`);
58878
59160
  lines.push("");
58879
- lines.push(pc54.bold("Configuration"));
58880
- lines.push(` App URL: ${pc54.cyan(options.appUrl || "(not deployed)")}`);
58881
- lines.push(` License Key: ${pc54.dim(`${options.licenseKeyPrefix}...`)}`);
59161
+ lines.push(pc55.bold("Configuration"));
59162
+ lines.push(` App URL: ${pc55.cyan(options.appUrl || "(not deployed)")}`);
59163
+ lines.push(` License Key: ${pc55.dim(`${options.licenseKeyPrefix}...`)}`);
58882
59164
  if (options.neonProjectId) {
58883
- lines.push(` Neon Project: ${pc54.dim(options.neonProjectId)}`);
59165
+ lines.push(` Neon Project: ${pc55.dim(options.neonProjectId)}`);
58884
59166
  }
58885
59167
  clack51.note(lines.join("\n"), "Self-Hosted Status");
58886
59168
  }
@@ -58888,7 +59170,7 @@ async function selfhostStatus(options) {
58888
59170
  const startTime = Date.now();
58889
59171
  const progress = new DeploymentProgress();
58890
59172
  if (!isJsonMode()) {
58891
- clack51.intro(pc54.bold("Wraps Self-Hosted Status"));
59173
+ clack51.intro(pc55.bold("Wraps Self-Hosted Status"));
58892
59174
  }
58893
59175
  const identity = await progress.execute(
58894
59176
  "Loading self-hosted status",
@@ -58906,7 +59188,7 @@ async function selfhostStatus(options) {
58906
59188
  clack51.log.error("No self-hosted deployment found");
58907
59189
  console.log(
58908
59190
  `
58909
- Run ${pc54.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted platform.
59191
+ Run ${pc55.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hosted platform.
58910
59192
  `
58911
59193
  );
58912
59194
  process.exit(1);
@@ -58929,24 +59211,24 @@ Run ${pc54.cyan("pnpm selfhost:deploy")} from your fork to deploy the self-hoste
58929
59211
  }
58930
59212
  displaySelfhostStatus(statusData);
58931
59213
  console.log("");
58932
- clack51.log.info(pc54.bold("Commands:"));
59214
+ clack51.log.info(pc55.bold("Commands:"));
58933
59215
  console.log(
58934
- ` ${pc54.cyan("pnpm selfhost:upgrade")} (from your fork) - Redeploy the platform and run migrations`
59216
+ ` ${pc55.cyan("pnpm selfhost:upgrade")} (from your fork) - Redeploy the platform and run migrations`
58935
59217
  );
58936
59218
  trackCommand("selfhost:status", {
58937
59219
  success: true,
58938
59220
  duration_ms: Date.now() - startTime
58939
59221
  });
58940
- clack51.outro(pc54.dim("Self-hosted deployment is active"));
59222
+ clack51.outro(pc55.dim("Self-hosted deployment is active"));
58941
59223
  }
58942
59224
 
58943
59225
  // src/commands/shared/dashboard.ts
58944
59226
  init_esm_shims();
58945
59227
  import * as clack52 from "@clack/prompts";
58946
- import * as pulumi27 from "@pulumi/pulumi";
59228
+ import * as pulumi28 from "@pulumi/pulumi";
58947
59229
  import getPort from "get-port";
58948
59230
  import open3 from "open";
58949
- import pc55 from "picocolors";
59231
+ import pc56 from "picocolors";
58950
59232
 
58951
59233
  // src/console/server.ts
58952
59234
  init_esm_shims();
@@ -60146,13 +60428,13 @@ function createMetricsRouter(config2) {
60146
60428
  const router = createRouter5();
60147
60429
  router.get("/stream", async (req, res) => {
60148
60430
  const connectionId = randomUUID().slice(0, 8);
60149
- const log62 = (msg, data) => {
60431
+ const log63 = (msg, data) => {
60150
60432
  console.log(JSON.stringify({ connectionId, msg, ...data }));
60151
60433
  };
60152
60434
  res.setHeader("Content-Type", "text/event-stream");
60153
60435
  res.setHeader("Cache-Control", "no-cache");
60154
60436
  res.setHeader("Connection", "keep-alive");
60155
- log62("SSE connected");
60437
+ log63("SSE connected");
60156
60438
  res.write('data: {"type":"connected"}\n\n');
60157
60439
  const { startTime, endTime } = req.query;
60158
60440
  const getTimeRange = () => ({
@@ -60162,7 +60444,7 @@ function createMetricsRouter(config2) {
60162
60444
  const sendMetrics = async () => {
60163
60445
  try {
60164
60446
  const timeRange = getTimeRange();
60165
- log62("Fetching metrics", {
60447
+ log63("Fetching metrics", {
60166
60448
  start: timeRange.start.toISOString(),
60167
60449
  end: timeRange.end.toISOString()
60168
60450
  });
@@ -60175,7 +60457,7 @@ function createMetricsRouter(config2) {
60175
60457
  ),
60176
60458
  fetchSendQuota(config2.roleArn, config2.region)
60177
60459
  ]);
60178
- log62("Metrics fetched successfully");
60460
+ log63("Metrics fetched successfully");
60179
60461
  const data = {
60180
60462
  type: "metrics",
60181
60463
  timestamp: Date.now(),
@@ -60205,7 +60487,7 @@ function createMetricsRouter(config2) {
60205
60487
  const interval = setInterval(sendMetrics, 6e4);
60206
60488
  req.on("close", () => {
60207
60489
  clearInterval(interval);
60208
- log62("SSE disconnected");
60490
+ log63("SSE disconnected");
60209
60491
  });
60210
60492
  });
60211
60493
  router.get("/snapshot", async (_req, res) => {
@@ -61461,9 +61743,9 @@ function createUserRouter(config2) {
61461
61743
  if (config2.roleArn) {
61462
61744
  console.log("[User API] Attempting to fetch account alias via IAM");
61463
61745
  const { assumeRole: assumeRole2 } = await Promise.resolve().then(() => (init_assume_role(), assume_role_exports));
61464
- const { IAMClient: IAMClient6, ListAccountAliasesCommand } = await import("@aws-sdk/client-iam");
61746
+ const { IAMClient: IAMClient7, ListAccountAliasesCommand } = await import("@aws-sdk/client-iam");
61465
61747
  const credentials = await assumeRole2(config2.roleArn, region);
61466
- const iamClient = new IAMClient6({ region, credentials });
61748
+ const iamClient = new IAMClient7({ region, credentials });
61467
61749
  const response = await iamClient.send(
61468
61750
  new ListAccountAliasesCommand({})
61469
61751
  );
@@ -61600,7 +61882,7 @@ init_output();
61600
61882
  init_pulumi();
61601
61883
  async function dashboard(options) {
61602
61884
  await ensurePulumiInstalled();
61603
- clack52.intro(pc55.bold("Wraps Dashboard"));
61885
+ clack52.intro(pc56.bold("Wraps Dashboard"));
61604
61886
  const progress = new DeploymentProgress();
61605
61887
  const identity = await progress.execute(
61606
61888
  "Validating AWS credentials",
@@ -61613,7 +61895,7 @@ async function dashboard(options) {
61613
61895
  try {
61614
61896
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
61615
61897
  try {
61616
- const emailStack = await pulumi27.automation.LocalWorkspace.selectStack({
61898
+ const emailStack = await pulumi28.automation.LocalWorkspace.selectStack({
61617
61899
  stackName: `wraps-${identity.accountId}-${region}`,
61618
61900
  workDir: getPulumiWorkDir()
61619
61901
  });
@@ -61621,7 +61903,7 @@ async function dashboard(options) {
61621
61903
  } catch (_emailError) {
61622
61904
  }
61623
61905
  try {
61624
- const smsStack = await pulumi27.automation.LocalWorkspace.selectStack({
61906
+ const smsStack = await pulumi28.automation.LocalWorkspace.selectStack({
61625
61907
  stackName: `wraps-sms-${identity.accountId}-${region}`,
61626
61908
  workDir: getPulumiWorkDir()
61627
61909
  });
@@ -61629,7 +61911,7 @@ async function dashboard(options) {
61629
61911
  } catch (_smsError) {
61630
61912
  }
61631
61913
  try {
61632
- const cdnStack = await pulumi27.automation.LocalWorkspace.selectStack({
61914
+ const cdnStack = await pulumi28.automation.LocalWorkspace.selectStack({
61633
61915
  stackName: `wraps-cdn-${identity.accountId}-${region}`,
61634
61916
  workDir: getPulumiWorkDir()
61635
61917
  });
@@ -61643,7 +61925,7 @@ async function dashboard(options) {
61643
61925
  progress.stop();
61644
61926
  clack52.log.error("No Wraps infrastructure found");
61645
61927
  console.log(
61646
- `\\nRun ${pc55.cyan("wraps email init")}, ${pc55.cyan("wraps sms init")}, or ${pc55.cyan("wraps storage init")} to deploy infrastructure first.\\n`
61928
+ `\\nRun ${pc56.cyan("wraps email init")}, ${pc56.cyan("wraps sms init")}, or ${pc56.cyan("wraps storage init")} to deploy infrastructure first.\\n`
61647
61929
  );
61648
61930
  process.exit(1);
61649
61931
  }
@@ -61687,7 +61969,7 @@ async function dashboard(options) {
61687
61969
  progress.stop();
61688
61970
  clack52.log.success("Starting dashboard server...");
61689
61971
  console.log(
61690
- `${pc55.dim("Using current AWS credentials (no role assumption)")}\\n`
61972
+ `${pc56.dim("Using current AWS credentials (no role assumption)")}\\n`
61691
61973
  );
61692
61974
  const { url } = await startConsoleServer({
61693
61975
  port,
@@ -61720,8 +62002,8 @@ async function dashboard(options) {
61720
62002
  cdnCustomDomain,
61721
62003
  cdnCertificateArn
61722
62004
  });
61723
- console.log(`\\n${pc55.bold("Dashboard:")} ${pc55.cyan(url)}`);
61724
- console.log(`${pc55.dim("Press Ctrl+C to stop")}\\n`);
62005
+ console.log(`\\n${pc56.bold("Dashboard:")} ${pc56.cyan(url)}`);
62006
+ console.log(`${pc56.dim("Press Ctrl+C to stop")}\\n`);
61725
62007
  getTelemetryClient().showFooterOnce();
61726
62008
  if (!options.noOpen) {
61727
62009
  await open3(url);
@@ -61743,7 +62025,7 @@ init_errors();
61743
62025
  init_json_output();
61744
62026
  init_metadata();
61745
62027
  import * as clack53 from "@clack/prompts";
61746
- import pc56 from "picocolors";
62028
+ import pc57 from "picocolors";
61747
62029
  async function destroy(options) {
61748
62030
  trackCommand("destroy", { success: true });
61749
62031
  if (isJsonMode() && !options.force) {
@@ -61754,7 +62036,7 @@ async function destroy(options) {
61754
62036
  );
61755
62037
  }
61756
62038
  if (!isJsonMode()) {
61757
- clack53.intro(pc56.bold("Wraps Infrastructure Teardown"));
62039
+ clack53.intro(pc57.bold("Wraps Infrastructure Teardown"));
61758
62040
  }
61759
62041
  const spinner11 = clack53.spinner();
61760
62042
  spinner11.start("Validating AWS credentials");
@@ -61776,14 +62058,14 @@ async function destroy(options) {
61776
62058
  clack53.log.warn("No Wraps services found in this region");
61777
62059
  console.log(
61778
62060
  `
61779
- Run ${pc56.cyan("wraps email init")} to deploy infrastructure.
62061
+ Run ${pc57.cyan("wraps email init")} to deploy infrastructure.
61780
62062
  `
61781
62063
  );
61782
62064
  process.exit(0);
61783
62065
  }
61784
62066
  if (deployedServices.length === 1) {
61785
62067
  const service = deployedServices[0];
61786
- clack53.log.info(`Found ${pc56.cyan(service)} service deployed`);
62068
+ clack53.log.info(`Found ${pc57.cyan(service)} service deployed`);
61787
62069
  if (service === "email") {
61788
62070
  await emailDestroy(options);
61789
62071
  return;
@@ -61821,7 +62103,7 @@ Run ${pc56.cyan("wraps email init")} to deploy infrastructure.
61821
62103
  await emailDestroy(options);
61822
62104
  }
61823
62105
  if (serviceToDestroy === "all") {
61824
- clack53.outro(pc56.green("All Wraps infrastructure has been removed"));
62106
+ clack53.outro(pc57.green("All Wraps infrastructure has been removed"));
61825
62107
  }
61826
62108
  }
61827
62109
 
@@ -61829,8 +62111,8 @@ Run ${pc56.cyan("wraps email init")} to deploy infrastructure.
61829
62111
  init_esm_shims();
61830
62112
  init_events();
61831
62113
  import * as clack54 from "@clack/prompts";
61832
- import * as pulumi28 from "@pulumi/pulumi";
61833
- import pc57 from "picocolors";
62114
+ import * as pulumi29 from "@pulumi/pulumi";
62115
+ import pc58 from "picocolors";
61834
62116
  init_aws();
61835
62117
  init_fs();
61836
62118
  init_json_output();
@@ -61841,23 +62123,23 @@ async function status(options) {
61841
62123
  const startTime = Date.now();
61842
62124
  const progress = new DeploymentProgress();
61843
62125
  if (!isJsonMode()) {
61844
- clack54.intro(pc57.bold("Wraps Infrastructure Status"));
62126
+ clack54.intro(pc58.bold("Wraps Infrastructure Status"));
61845
62127
  }
61846
62128
  const identity = await progress.execute(
61847
62129
  "Loading infrastructure status",
61848
62130
  async () => validateAWSCredentials()
61849
62131
  );
61850
62132
  if (!isJsonMode()) {
61851
- progress.info(`AWS Account: ${pc57.cyan(identity.accountId)}`);
62133
+ progress.info(`AWS Account: ${pc58.cyan(identity.accountId)}`);
61852
62134
  }
61853
62135
  const region = options.region || await getAWSRegion();
61854
62136
  if (!isJsonMode()) {
61855
- progress.info(`Region: ${pc57.cyan(region)}`);
62137
+ progress.info(`Region: ${pc58.cyan(region)}`);
61856
62138
  }
61857
62139
  const services = [];
61858
62140
  try {
61859
62141
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
61860
- const emailStack = await pulumi28.automation.LocalWorkspace.selectStack({
62142
+ const emailStack = await pulumi29.automation.LocalWorkspace.selectStack({
61861
62143
  stackName: `wraps-${identity.accountId}-${region}`,
61862
62144
  workDir: getPulumiWorkDir()
61863
62145
  });
@@ -61876,7 +62158,7 @@ async function status(options) {
61876
62158
  services.push({ name: "Email", status: "not_deployed" });
61877
62159
  }
61878
62160
  try {
61879
- const smsStack = await pulumi28.automation.LocalWorkspace.selectStack({
62161
+ const smsStack = await pulumi29.automation.LocalWorkspace.selectStack({
61880
62162
  stackName: `wraps-sms-${identity.accountId}-${region}`,
61881
62163
  workDir: getPulumiWorkDir()
61882
62164
  });
@@ -61907,33 +62189,33 @@ async function status(options) {
61907
62189
  clack54.note(
61908
62190
  services.map((s2) => {
61909
62191
  if (s2.status === "deployed") {
61910
- const details = s2.details ? pc57.dim(` (${s2.details})`) : "";
61911
- return ` ${pc57.green("\u2713")} ${s2.name}${details}`;
62192
+ const details = s2.details ? pc58.dim(` (${s2.details})`) : "";
62193
+ return ` ${pc58.green("\u2713")} ${s2.name}${details}`;
61912
62194
  }
61913
- return ` ${pc57.dim("\u25CB")} ${s2.name} ${pc57.dim("(not deployed)")}`;
62195
+ return ` ${pc58.dim("\u25CB")} ${s2.name} ${pc58.dim("(not deployed)")}`;
61914
62196
  }).join("\n"),
61915
62197
  "Services"
61916
62198
  );
61917
62199
  const hasDeployedServices = services.some((s2) => s2.status === "deployed");
61918
62200
  if (hasDeployedServices) {
61919
62201
  console.log(`
61920
- ${pc57.bold("Details:")}`);
62202
+ ${pc58.bold("Details:")}`);
61921
62203
  if (services.find((s2) => s2.name === "Email")?.status === "deployed") {
61922
- console.log(` ${pc57.dim("Email:")} ${pc57.cyan("wraps email status")}`);
62204
+ console.log(` ${pc58.dim("Email:")} ${pc58.cyan("wraps email status")}`);
61923
62205
  }
61924
62206
  if (services.find((s2) => s2.name === "SMS")?.status === "deployed") {
61925
- console.log(` ${pc57.dim("SMS:")} ${pc57.cyan("wraps sms status")}`);
62207
+ console.log(` ${pc58.dim("SMS:")} ${pc58.cyan("wraps sms status")}`);
61926
62208
  }
61927
62209
  } else {
61928
62210
  console.log(`
61929
- ${pc57.bold("Get started:")}`);
61930
- console.log(` ${pc57.dim("Deploy email:")} ${pc57.cyan("wraps email init")}`);
61931
- console.log(` ${pc57.dim("Deploy SMS:")} ${pc57.cyan("wraps sms init")}`);
62211
+ ${pc58.bold("Get started:")}`);
62212
+ console.log(` ${pc58.dim("Deploy email:")} ${pc58.cyan("wraps email init")}`);
62213
+ console.log(` ${pc58.dim("Deploy SMS:")} ${pc58.cyan("wraps sms init")}`);
61932
62214
  }
61933
62215
  const dashboardUrl = await resolveDashboardUrl(identity.accountId, region);
61934
62216
  console.log(`
61935
- ${pc57.bold("Dashboard:")} ${pc57.blue(dashboardUrl)}`);
61936
- console.log(`${pc57.bold("Docs:")} ${pc57.blue("https://wraps.dev/docs")}
62217
+ ${pc58.bold("Dashboard:")} ${pc58.blue(dashboardUrl)}`);
62218
+ console.log(`${pc58.bold("Docs:")} ${pc58.blue("https://wraps.dev/docs")}
61937
62219
  `);
61938
62220
  trackCommand("status", {
61939
62221
  success: true,
@@ -61945,13 +62227,13 @@ ${pc57.bold("Dashboard:")} ${pc57.blue(dashboardUrl)}`);
61945
62227
  // src/commands/sms/destroy.ts
61946
62228
  init_esm_shims();
61947
62229
  import * as clack55 from "@clack/prompts";
61948
- import * as pulumi30 from "@pulumi/pulumi";
61949
- import pc58 from "picocolors";
62230
+ import * as pulumi31 from "@pulumi/pulumi";
62231
+ import pc59 from "picocolors";
61950
62232
 
61951
62233
  // src/infrastructure/sms-stack.ts
61952
62234
  init_esm_shims();
61953
62235
  import * as aws24 from "@pulumi/aws";
61954
- import * as pulumi29 from "@pulumi/pulumi";
62236
+ import * as pulumi30 from "@pulumi/pulumi";
61955
62237
  init_resource_checks();
61956
62238
  async function createSMSIAMRole(config2) {
61957
62239
  const statements = [];
@@ -62231,7 +62513,7 @@ async function createSMSSNSResources(config2) {
62231
62513
  });
62232
62514
  new aws24.sqs.QueuePolicy("wraps-sms-events-queue-policy", {
62233
62515
  queueUrl: config2.queueUrl,
62234
- policy: pulumi29.all([config2.queueArn, topic.arn]).apply(
62516
+ policy: pulumi30.all([config2.queueArn, topic.arn]).apply(
62235
62517
  ([queueArn, topicArn2]) => JSON.stringify({
62236
62518
  Version: "2012-10-17",
62237
62519
  Statement: [
@@ -62330,7 +62612,7 @@ async function deploySMSLambdaFunction(config2) {
62330
62612
  });
62331
62613
  new aws24.iam.RolePolicy("wraps-sms-lambda-policy", {
62332
62614
  role: lambdaRole.name,
62333
- policy: pulumi29.all([config2.tableName, config2.queueArn]).apply(
62615
+ policy: pulumi30.all([config2.tableName, config2.queueArn]).apply(
62334
62616
  ([tableName, queueArn]) => JSON.stringify({
62335
62617
  Version: "2012-10-17",
62336
62618
  Statement: [
@@ -62367,7 +62649,7 @@ async function deploySMSLambdaFunction(config2) {
62367
62649
  runtime: "nodejs24.x",
62368
62650
  handler: "index.handler",
62369
62651
  role: lambdaRole.arn,
62370
- code: new pulumi29.asset.FileArchive(codeDir),
62652
+ code: new pulumi30.asset.FileArchive(codeDir),
62371
62653
  timeout: 300,
62372
62654
  // 5 minutes
62373
62655
  memorySize: 512,
@@ -62637,18 +62919,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
62637
62919
  const existing = await client2.send(
62638
62920
  new DescribeProtectConfigurationsCommand({})
62639
62921
  );
62640
- for (const pc72 of existing.ProtectConfigurations || []) {
62641
- if (!(pc72.ProtectConfigurationArn && pc72.ProtectConfigurationId)) {
62922
+ for (const pc73 of existing.ProtectConfigurations || []) {
62923
+ if (!(pc73.ProtectConfigurationArn && pc73.ProtectConfigurationId)) {
62642
62924
  continue;
62643
62925
  }
62644
62926
  const tagsResponse = await client2.send(
62645
62927
  new ListTagsForResourceCommand({
62646
- ResourceArn: pc72.ProtectConfigurationArn
62928
+ ResourceArn: pc73.ProtectConfigurationArn
62647
62929
  })
62648
62930
  );
62649
62931
  const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
62650
62932
  if (nameTag?.Value === protectConfigName) {
62651
- existingProtectConfigId = pc72.ProtectConfigurationId;
62933
+ existingProtectConfigId = pc73.ProtectConfigurationId;
62652
62934
  break;
62653
62935
  }
62654
62936
  }
@@ -62744,13 +63026,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
62744
63026
  new DescribeProtectConfigurationsCommand({})
62745
63027
  );
62746
63028
  if (existing.ProtectConfigurations) {
62747
- for (const pc72 of existing.ProtectConfigurations) {
62748
- if (!(pc72.ProtectConfigurationArn && pc72.ProtectConfigurationId)) {
63029
+ for (const pc73 of existing.ProtectConfigurations) {
63030
+ if (!(pc73.ProtectConfigurationArn && pc73.ProtectConfigurationId)) {
62749
63031
  continue;
62750
63032
  }
62751
63033
  const tagsResponse = await client2.send(
62752
63034
  new ListTagsForResourceCommand({
62753
- ResourceArn: pc72.ProtectConfigurationArn
63035
+ ResourceArn: pc73.ProtectConfigurationArn
62754
63036
  })
62755
63037
  );
62756
63038
  const isWrapsManaged = tagsResponse.Tags?.some(
@@ -62759,7 +63041,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
62759
63041
  if (isWrapsManaged) {
62760
63042
  await client2.send(
62761
63043
  new DeleteProtectConfigurationCommand({
62762
- ProtectConfigurationId: pc72.ProtectConfigurationId
63044
+ ProtectConfigurationId: pc73.ProtectConfigurationId
62763
63045
  })
62764
63046
  );
62765
63047
  }
@@ -62795,7 +63077,7 @@ async function smsDestroy(options) {
62795
63077
  }
62796
63078
  if (!isJsonMode()) {
62797
63079
  clack55.intro(
62798
- pc58.bold(
63080
+ pc59.bold(
62799
63081
  options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
62800
63082
  )
62801
63083
  );
@@ -62845,7 +63127,7 @@ async function smsDestroy(options) {
62845
63127
  }
62846
63128
  if (!(options.force || options.preview)) {
62847
63129
  const confirmed = await clack55.confirm({
62848
- message: pc58.red(
63130
+ message: pc59.red(
62849
63131
  "Are you sure you want to destroy all SMS infrastructure?"
62850
63132
  ),
62851
63133
  initialValue: false
@@ -62864,7 +63146,7 @@ async function smsDestroy(options) {
62864
63146
  const stackName = storedStackName || `wraps-sms-${identity.accountId}-${region}`;
62865
63147
  let stack;
62866
63148
  try {
62867
- stack = await pulumi30.automation.LocalWorkspace.selectStack({
63149
+ stack = await pulumi31.automation.LocalWorkspace.selectStack({
62868
63150
  stackName,
62869
63151
  workDir: getPulumiWorkDir()
62870
63152
  });
@@ -62884,7 +63166,7 @@ async function smsDestroy(options) {
62884
63166
  commandName: "wraps sms destroy"
62885
63167
  });
62886
63168
  clack55.outro(
62887
- pc58.green("Preview complete. Run without --preview to destroy.")
63169
+ pc59.green("Preview complete. Run without --preview to destroy.")
62888
63170
  );
62889
63171
  trackServiceRemoved("sms", {
62890
63172
  preview: true,
@@ -62922,7 +63204,7 @@ async function smsDestroy(options) {
62922
63204
  const stackName = storedStackName || `wraps-sms-${identity.accountId}-${region}`;
62923
63205
  let stack;
62924
63206
  try {
62925
- stack = await pulumi30.automation.LocalWorkspace.selectStack({
63207
+ stack = await pulumi31.automation.LocalWorkspace.selectStack({
62926
63208
  stackName,
62927
63209
  workDir: getPulumiWorkDir()
62928
63210
  });
@@ -62981,20 +63263,20 @@ async function smsDestroy(options) {
62981
63263
  }
62982
63264
  if (destroyFailed) {
62983
63265
  clack55.outro(
62984
- pc58.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
63266
+ pc59.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
62985
63267
  );
62986
63268
  } else {
62987
- clack55.outro(pc58.green("SMS infrastructure has been removed"));
63269
+ clack55.outro(pc59.green("SMS infrastructure has been removed"));
62988
63270
  console.log(`
62989
- ${pc58.bold("Cleaned up:")}`);
62990
- console.log(` ${pc58.green("\u2713")} Phone number released`);
62991
- console.log(` ${pc58.green("\u2713")} Configuration set deleted`);
62992
- console.log(` ${pc58.green("\u2713")} Event processing infrastructure removed`);
62993
- console.log(` ${pc58.green("\u2713")} IAM role deleted`);
63271
+ ${pc59.bold("Cleaned up:")}`);
63272
+ console.log(` ${pc59.green("\u2713")} Phone number released`);
63273
+ console.log(` ${pc59.green("\u2713")} Configuration set deleted`);
63274
+ console.log(` ${pc59.green("\u2713")} Event processing infrastructure removed`);
63275
+ console.log(` ${pc59.green("\u2713")} IAM role deleted`);
62994
63276
  }
62995
63277
  console.log(
62996
63278
  `
62997
- Run ${pc58.cyan("wraps sms init")} to deploy infrastructure again.
63279
+ Run ${pc59.cyan("wraps sms init")} to deploy infrastructure again.
62998
63280
  `
62999
63281
  );
63000
63282
  trackServiceRemoved("sms", {
@@ -63007,8 +63289,8 @@ Run ${pc58.cyan("wraps sms init")} to deploy infrastructure again.
63007
63289
  // src/commands/sms/init.ts
63008
63290
  init_esm_shims();
63009
63291
  import * as clack56 from "@clack/prompts";
63010
- import * as pulumi31 from "@pulumi/pulumi";
63011
- import pc60 from "picocolors";
63292
+ import * as pulumi32 from "@pulumi/pulumi";
63293
+ import pc61 from "picocolors";
63012
63294
  init_events();
63013
63295
  init_aws();
63014
63296
  init_errors();
@@ -63246,16 +63528,16 @@ function getSMSCostSummary(config2, messagesPerMonth = 1e3) {
63246
63528
 
63247
63529
  // src/utils/sms/output.ts
63248
63530
  init_esm_shims();
63249
- import pc59 from "picocolors";
63531
+ import pc60 from "picocolors";
63250
63532
  function displaySMSSDKUsage(region) {
63251
- console.log(pc59.dim(" npm install @wraps.dev/sms"));
63533
+ console.log(pc60.dim(" npm install @wraps.dev/sms"));
63252
63534
  console.log("");
63253
- console.log(pc59.dim(" import { WrapsSMS } from '@wraps.dev/sms';"));
63254
- console.log(pc59.dim(` const sms = new WrapsSMS({ region: '${region}' });`));
63255
- console.log(pc59.dim(" await sms.send({"));
63256
- console.log(pc59.dim(" to: '+14155551234',"));
63257
- console.log(pc59.dim(" message: 'Your code is 123456',"));
63258
- console.log(pc59.dim(" });"));
63535
+ console.log(pc60.dim(" import { WrapsSMS } from '@wraps.dev/sms';"));
63536
+ console.log(pc60.dim(` const sms = new WrapsSMS({ region: '${region}' });`));
63537
+ console.log(pc60.dim(" await sms.send({"));
63538
+ console.log(pc60.dim(" to: '+14155551234',"));
63539
+ console.log(pc60.dim(" message: 'Your code is 123456',"));
63540
+ console.log(pc60.dim(" });"));
63259
63541
  }
63260
63542
 
63261
63543
  // src/utils/sms/presets.ts
@@ -63577,14 +63859,14 @@ function parseVolume(raw) {
63577
63859
  async function init3(options) {
63578
63860
  const startTime = Date.now();
63579
63861
  if (!isJsonMode()) {
63580
- clack56.intro(pc60.bold("Wraps SMS Infrastructure Setup"));
63862
+ clack56.intro(pc61.bold("Wraps SMS Infrastructure Setup"));
63581
63863
  }
63582
63864
  const progress = new DeploymentProgress();
63583
63865
  const identity = await progress.execute(
63584
63866
  "Validating AWS credentials",
63585
63867
  async () => validateAWSCredentials()
63586
63868
  );
63587
- progress.info(`Connected to AWS account: ${pc60.cyan(identity.accountId)}`);
63869
+ progress.info(`Connected to AWS account: ${pc61.cyan(identity.accountId)}`);
63588
63870
  const wasAutoInstalled = await progress.execute(
63589
63871
  "Checking Pulumi CLI installation",
63590
63872
  async () => await ensurePulumiInstalled()
@@ -63604,9 +63886,9 @@ async function init3(options) {
63604
63886
  );
63605
63887
  if (existingConnection?.services?.sms) {
63606
63888
  clack56.log.warn(
63607
- `SMS already configured for account ${pc60.cyan(identity.accountId)} in region ${pc60.cyan(region)}`
63889
+ `SMS already configured for account ${pc61.cyan(identity.accountId)} in region ${pc61.cyan(region)}`
63608
63890
  );
63609
- clack56.log.info(`Use ${pc60.cyan("wraps sms status")} to view current setup`);
63891
+ clack56.log.info(`Use ${pc61.cyan("wraps sms status")} to view current setup`);
63610
63892
  process.exit(0);
63611
63893
  }
63612
63894
  let preset = options.preset;
@@ -63652,7 +63934,7 @@ async function init3(options) {
63652
63934
  }
63653
63935
  progress.info(
63654
63936
  `
63655
- ${pc60.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
63937
+ ${pc61.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
63656
63938
  );
63657
63939
  let allowedCountries;
63658
63940
  if (options.countries) {
@@ -63690,13 +63972,13 @@ ${pc60.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
63690
63972
  estimatedVolume = await promptEstimatedSMSVolume();
63691
63973
  }
63692
63974
  progress.info(`
63693
- ${pc60.bold("Cost Estimate:")}`);
63975
+ ${pc61.bold("Cost Estimate:")}`);
63694
63976
  const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
63695
63977
  clack56.log.info(costSummary);
63696
63978
  const warnings = validateSMSConfig(smsConfig);
63697
63979
  if (warnings.length > 0) {
63698
63980
  progress.info(`
63699
- ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63981
+ ${pc61.yellow(pc61.bold("Important Notes:"))}`);
63700
63982
  for (const warning2 of warnings) {
63701
63983
  clack56.log.warn(warning2);
63702
63984
  }
@@ -63716,7 +63998,7 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63716
63998
  };
63717
63999
  const createStack = async () => {
63718
64000
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
63719
- const stack = await pulumi31.automation.LocalWorkspace.createOrSelectStack(
64001
+ const stack = await pulumi32.automation.LocalWorkspace.createOrSelectStack(
63720
64002
  {
63721
64003
  stackName: `wraps-sms-${identity.accountId}-${region}`,
63722
64004
  projectName: "wraps-sms",
@@ -63765,7 +64047,7 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63765
64047
  commandName: "wraps sms init"
63766
64048
  });
63767
64049
  clack56.outro(
63768
- pc60.green("Preview complete. Run without --preview to deploy.")
64050
+ pc61.green("Preview complete. Run without --preview to deploy.")
63769
64051
  );
63770
64052
  trackServiceInit("sms", true, {
63771
64053
  provider,
@@ -63816,7 +64098,7 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63816
64098
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
63817
64099
  clack56.log.warn(`Phone pool creation failed: ${msg}`);
63818
64100
  clack56.log.info(
63819
- `Run ${pc60.cyan("wraps sms sync")} to retry SDK resource creation.`
64101
+ `Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
63820
64102
  );
63821
64103
  }
63822
64104
  }
@@ -63834,7 +64116,7 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63834
64116
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
63835
64117
  clack56.log.warn(`Event destination creation failed: ${msg}`);
63836
64118
  clack56.log.info(
63837
- `Run ${pc60.cyan("wraps sms sync")} to retry SDK resource creation.`
64119
+ `Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
63838
64120
  );
63839
64121
  }
63840
64122
  }
@@ -63855,7 +64137,7 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63855
64137
  const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
63856
64138
  clack56.log.warn(`Protect configuration creation failed: ${msg}`);
63857
64139
  clack56.log.info(
63858
- `Run ${pc60.cyan("wraps sms sync")} to retry SDK resource creation.`
64140
+ `Run ${pc61.cyan("wraps sms sync")} to retry SDK resource creation.`
63859
64141
  );
63860
64142
  }
63861
64143
  }
@@ -63905,40 +64187,40 @@ ${pc60.yellow(pc60.bold("Important Notes:"))}`);
63905
64187
  return;
63906
64188
  }
63907
64189
  console.log("\n");
63908
- clack56.log.success(pc60.green(pc60.bold("SMS infrastructure deployed!")));
64190
+ clack56.log.success(pc61.green(pc61.bold("SMS infrastructure deployed!")));
63909
64191
  console.log("\n");
63910
64192
  clack56.note(
63911
64193
  [
63912
- `${pc60.bold("Phone Number:")} ${pc60.cyan(outputs.phoneNumber || "Provisioning...")}`,
63913
- `${pc60.bold("Phone Type:")} ${pc60.cyan(smsConfig.phoneNumberType || "simulator")}`,
63914
- `${pc60.bold("Config Set:")} ${pc60.cyan(outputs.configSetName || "wraps-sms-config")}`,
63915
- `${pc60.bold("Region:")} ${pc60.cyan(outputs.region)}`,
63916
- outputs.tableName ? `${pc60.bold("History Table:")} ${pc60.cyan(outputs.tableName)}` : "",
64194
+ `${pc61.bold("Phone Number:")} ${pc61.cyan(outputs.phoneNumber || "Provisioning...")}`,
64195
+ `${pc61.bold("Phone Type:")} ${pc61.cyan(smsConfig.phoneNumberType || "simulator")}`,
64196
+ `${pc61.bold("Config Set:")} ${pc61.cyan(outputs.configSetName || "wraps-sms-config")}`,
64197
+ `${pc61.bold("Region:")} ${pc61.cyan(outputs.region)}`,
64198
+ outputs.tableName ? `${pc61.bold("History Table:")} ${pc61.cyan(outputs.tableName)}` : "",
63917
64199
  "",
63918
- pc60.dim("IAM Role:"),
63919
- pc60.dim(` ${outputs.roleArn}`)
64200
+ pc61.dim("IAM Role:"),
64201
+ pc61.dim(` ${outputs.roleArn}`)
63920
64202
  ].filter(Boolean).join("\n"),
63921
64203
  "SMS Infrastructure"
63922
64204
  );
63923
64205
  const nextSteps = [];
63924
64206
  if (smsConfig.phoneNumberType === "toll-free") {
63925
64207
  nextSteps.push(
63926
- `${pc60.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
64208
+ `${pc61.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
63927
64209
  );
63928
64210
  }
63929
64211
  nextSteps.push(
63930
- `${pc60.cyan("wraps sms test --to +1234567890")} - Send a test message`
64212
+ `${pc61.cyan("wraps sms test --to +1234567890")} - Send a test message`
63931
64213
  );
63932
- nextSteps.push(`${pc60.cyan("wraps sms status")} - View SMS configuration`);
64214
+ nextSteps.push(`${pc61.cyan("wraps sms status")} - View SMS configuration`);
63933
64215
  console.log("\n");
63934
- clack56.log.info(pc60.bold("Next steps:"));
64216
+ clack56.log.info(pc61.bold("Next steps:"));
63935
64217
  for (const step of nextSteps) {
63936
64218
  console.log(` ${step}`);
63937
64219
  }
63938
64220
  console.log("\n");
63939
- clack56.log.info(pc60.bold("SDK Usage:"));
64221
+ clack56.log.info(pc61.bold("SDK Usage:"));
63940
64222
  displaySMSSDKUsage(region);
63941
- clack56.outro(pc60.green("Setup complete!"));
64223
+ clack56.outro(pc61.green("Setup complete!"));
63942
64224
  const duration = Date.now() - startTime;
63943
64225
  const enabledFeatures = [];
63944
64226
  if (smsConfig.tracking?.enabled) {
@@ -63975,7 +64257,7 @@ init_json_output();
63975
64257
  init_metadata();
63976
64258
  init_output();
63977
64259
  import * as clack57 from "@clack/prompts";
63978
- import pc61 from "picocolors";
64260
+ import pc62 from "picocolors";
63979
64261
  async function getPhoneNumberDetails(region) {
63980
64262
  const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
63981
64263
  const client2 = new PinpointSMSVoiceV2Client5({ region });
@@ -64016,7 +64298,7 @@ async function getRegistrationStatus(region, registrationId) {
64016
64298
  async function smsRegister(options) {
64017
64299
  const startTime = Date.now();
64018
64300
  if (!isJsonMode()) {
64019
- clack57.intro(pc61.bold("Wraps SMS - Toll-Free Registration"));
64301
+ clack57.intro(pc62.bold("Wraps SMS - Toll-Free Registration"));
64020
64302
  }
64021
64303
  const progress = new DeploymentProgress();
64022
64304
  const identity = await progress.execute(
@@ -64030,7 +64312,7 @@ async function smsRegister(options) {
64030
64312
  const metadata = await loadConnectionMetadata(identity.accountId, region);
64031
64313
  if (!metadata?.services?.sms) {
64032
64314
  clack57.log.error("No SMS infrastructure found.");
64033
- clack57.log.info(`Run ${pc61.cyan("wraps sms init")} first.`);
64315
+ clack57.log.info(`Run ${pc62.cyan("wraps sms init")} first.`);
64034
64316
  process.exit(1);
64035
64317
  }
64036
64318
  const phoneDetails = await progress.execute(
@@ -64064,14 +64346,14 @@ async function smsRegister(options) {
64064
64346
  }
64065
64347
  console.log("");
64066
64348
  console.log(
64067
- `${pc61.bold("Phone Number:")} ${pc61.cyan(phoneDetails.phoneNumber)}`
64349
+ `${pc62.bold("Phone Number:")} ${pc62.cyan(phoneDetails.phoneNumber)}`
64068
64350
  );
64069
- console.log(`${pc61.bold("Type:")} ${pc61.cyan(phoneDetails.type)}`);
64351
+ console.log(`${pc62.bold("Type:")} ${pc62.cyan(phoneDetails.type)}`);
64070
64352
  console.log(
64071
- `${pc61.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc61.green(phoneDetails.status) : pc61.yellow(phoneDetails.status)}`
64353
+ `${pc62.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc62.green(phoneDetails.status) : pc62.yellow(phoneDetails.status)}`
64072
64354
  );
64073
64355
  if (registrationStatus) {
64074
- console.log(`${pc61.bold("Registration:")} ${pc61.cyan(registrationStatus)}`);
64356
+ console.log(`${pc62.bold("Registration:")} ${pc62.cyan(registrationStatus)}`);
64075
64357
  }
64076
64358
  console.log("");
64077
64359
  if (phoneDetails.status === "ACTIVE") {
@@ -64089,21 +64371,21 @@ async function smsRegister(options) {
64089
64371
  clack57.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
64090
64372
  process.exit(0);
64091
64373
  }
64092
- console.log(pc61.bold("Toll-Free Registration Required"));
64374
+ console.log(pc62.bold("Toll-Free Registration Required"));
64093
64375
  console.log("");
64094
64376
  console.log(
64095
- pc61.dim("To send SMS at scale, you must register your toll-free number.")
64377
+ pc62.dim("To send SMS at scale, you must register your toll-free number.")
64096
64378
  );
64097
- console.log(pc61.dim("This process typically takes 1-15 business days."));
64379
+ console.log(pc62.dim("This process typically takes 1-15 business days."));
64098
64380
  console.log("");
64099
- console.log(pc61.bold("You'll need to provide:"));
64100
- console.log(` ${pc61.dim("\u2022")} Business name and address`);
64381
+ console.log(pc62.bold("You'll need to provide:"));
64382
+ console.log(` ${pc62.dim("\u2022")} Business name and address`);
64101
64383
  console.log(
64102
- ` ${pc61.dim("\u2022")} Use case description (what messages you're sending)`
64384
+ ` ${pc62.dim("\u2022")} Use case description (what messages you're sending)`
64103
64385
  );
64104
- console.log(` ${pc61.dim("\u2022")} Sample messages (2-3 examples)`);
64105
- console.log(` ${pc61.dim("\u2022")} How users opt-in to receive messages`);
64106
- console.log(` ${pc61.dim("\u2022")} Expected monthly message volume`);
64386
+ console.log(` ${pc62.dim("\u2022")} Sample messages (2-3 examples)`);
64387
+ console.log(` ${pc62.dim("\u2022")} How users opt-in to receive messages`);
64388
+ console.log(` ${pc62.dim("\u2022")} Expected monthly message volume`);
64107
64389
  console.log("");
64108
64390
  const openConsole = await clack57.confirm({
64109
64391
  message: "Open AWS Console to start registration?",
@@ -64128,33 +64410,33 @@ async function smsRegister(options) {
64128
64410
  } catch {
64129
64411
  clack57.log.info("Open this URL in your browser:");
64130
64412
  console.log(`
64131
- ${pc61.cyan(consoleUrl)}
64413
+ ${pc62.cyan(consoleUrl)}
64132
64414
  `);
64133
64415
  }
64134
64416
  }
64135
64417
  console.log("");
64136
- console.log(pc61.bold("Next Steps:"));
64418
+ console.log(pc62.bold("Next Steps:"));
64137
64419
  console.log(
64138
- ` 1. Click ${pc61.cyan("Create registration")} in the AWS Console`
64420
+ ` 1. Click ${pc62.cyan("Create registration")} in the AWS Console`
64139
64421
  );
64140
- console.log(` 2. Select ${pc61.cyan("Toll-free number registration")}`);
64422
+ console.log(` 2. Select ${pc62.cyan("Toll-free number registration")}`);
64141
64423
  console.log(" 3. Fill out the business information form");
64142
64424
  console.log(" 4. Submit and wait for approval (1-15 business days)");
64143
64425
  console.log("");
64144
64426
  console.log(
64145
- pc61.dim("Once approved, run `wraps sms sync` to complete setup.")
64427
+ pc62.dim("Once approved, run `wraps sms sync` to complete setup.")
64146
64428
  );
64147
64429
  } else {
64148
64430
  const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
64149
64431
  console.log("");
64150
64432
  console.log("When you're ready, go to:");
64151
- console.log(` ${pc61.cyan(consoleUrl)}`);
64433
+ console.log(` ${pc62.cyan(consoleUrl)}`);
64152
64434
  }
64153
64435
  trackCommand("sms:register", {
64154
64436
  success: true,
64155
64437
  duration_ms: Date.now() - startTime
64156
64438
  });
64157
- clack57.outro(pc61.dim("Good luck with your registration!"));
64439
+ clack57.outro(pc62.dim("Good luck with your registration!"));
64158
64440
  }
64159
64441
 
64160
64442
  // src/commands/sms/status.ts
@@ -64168,44 +64450,44 @@ init_output();
64168
64450
  init_pulumi();
64169
64451
  init_region_resolver();
64170
64452
  import * as clack58 from "@clack/prompts";
64171
- import * as pulumi32 from "@pulumi/pulumi";
64172
- import pc62 from "picocolors";
64453
+ import * as pulumi33 from "@pulumi/pulumi";
64454
+ import pc63 from "picocolors";
64173
64455
  function displaySMSStatus(options) {
64174
64456
  const lines = [];
64175
- lines.push(pc62.bold(pc62.green("SMS Infrastructure Active")));
64457
+ lines.push(pc63.bold(pc63.green("SMS Infrastructure Active")));
64176
64458
  lines.push("");
64177
- lines.push(pc62.bold("Phone Number"));
64459
+ lines.push(pc63.bold("Phone Number"));
64178
64460
  if (options.phoneNumber) {
64179
- lines.push(` Number: ${pc62.cyan(options.phoneNumber)}`);
64461
+ lines.push(` Number: ${pc63.cyan(options.phoneNumber)}`);
64180
64462
  } else {
64181
- lines.push(` Number: ${pc62.yellow("Provisioning...")}`);
64463
+ lines.push(` Number: ${pc63.yellow("Provisioning...")}`);
64182
64464
  }
64183
- lines.push(` Type: ${pc62.cyan(options.phoneNumberType || "simulator")}`);
64465
+ lines.push(` Type: ${pc63.cyan(options.phoneNumberType || "simulator")}`);
64184
64466
  lines.push("");
64185
- lines.push(pc62.bold("Configuration"));
64186
- lines.push(` Region: ${pc62.cyan(options.region)}`);
64467
+ lines.push(pc63.bold("Configuration"));
64468
+ lines.push(` Region: ${pc63.cyan(options.region)}`);
64187
64469
  if (options.preset) {
64188
- lines.push(` Preset: ${pc62.cyan(options.preset)}`);
64470
+ lines.push(` Preset: ${pc63.cyan(options.preset)}`);
64189
64471
  }
64190
64472
  if (options.configSetName) {
64191
- lines.push(` Config Set: ${pc62.cyan(options.configSetName)}`);
64473
+ lines.push(` Config Set: ${pc63.cyan(options.configSetName)}`);
64192
64474
  }
64193
64475
  lines.push("");
64194
- lines.push(pc62.bold("Features"));
64476
+ lines.push(pc63.bold("Features"));
64195
64477
  lines.push(
64196
- ` Event Tracking: ${options.eventTracking ? pc62.green("Enabled") : pc62.dim("Disabled")}`
64478
+ ` Event Tracking: ${options.eventTracking ? pc63.green("Enabled") : pc63.dim("Disabled")}`
64197
64479
  );
64198
64480
  if (options.tableName) {
64199
- lines.push(` Message History: ${pc62.green("Enabled")}`);
64200
- lines.push(` Table: ${pc62.dim(options.tableName)}`);
64481
+ lines.push(` Message History: ${pc63.green("Enabled")}`);
64482
+ lines.push(` Table: ${pc63.dim(options.tableName)}`);
64201
64483
  }
64202
64484
  if (options.queueUrl) {
64203
- lines.push(` Event Queue: ${pc62.green("Enabled")}`);
64485
+ lines.push(` Event Queue: ${pc63.green("Enabled")}`);
64204
64486
  }
64205
64487
  lines.push("");
64206
64488
  if (options.roleArn) {
64207
- lines.push(pc62.bold("IAM Role"));
64208
- lines.push(` ${pc62.dim(options.roleArn)}`);
64489
+ lines.push(pc63.bold("IAM Role"));
64490
+ lines.push(` ${pc63.dim(options.roleArn)}`);
64209
64491
  }
64210
64492
  clack58.note(lines.join("\n"), "SMS Status");
64211
64493
  }
@@ -64214,7 +64496,7 @@ async function smsStatus(options) {
64214
64496
  const startTime = Date.now();
64215
64497
  const progress = new DeploymentProgress();
64216
64498
  if (!isJsonMode()) {
64217
- clack58.intro(pc62.bold("Wraps SMS Status"));
64499
+ clack58.intro(pc63.bold("Wraps SMS Status"));
64218
64500
  }
64219
64501
  const identity = await progress.execute(
64220
64502
  "Loading SMS infrastructure status",
@@ -64232,7 +64514,7 @@ async function smsStatus(options) {
64232
64514
  clack58.log.error("No SMS infrastructure found");
64233
64515
  console.log(
64234
64516
  `
64235
- Run ${pc62.cyan("wraps sms init")} to deploy SMS infrastructure.
64517
+ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure.
64236
64518
  `
64237
64519
  );
64238
64520
  process.exit(1);
@@ -64241,7 +64523,7 @@ Run ${pc62.cyan("wraps sms init")} to deploy SMS infrastructure.
64241
64523
  try {
64242
64524
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
64243
64525
  const stackName = metadata.services.sms.pulumiStackName || `wraps-sms-${identity.accountId}-${region}`;
64244
- const stack = await pulumi32.automation.LocalWorkspace.selectStack({
64526
+ const stack = await pulumi33.automation.LocalWorkspace.selectStack({
64245
64527
  stackName,
64246
64528
  workDir: getPulumiWorkDir()
64247
64529
  });
@@ -64268,25 +64550,25 @@ Run ${pc62.cyan("wraps sms init")} to deploy SMS infrastructure.
64268
64550
  }
64269
64551
  displaySMSStatus(smsStatusData);
64270
64552
  console.log("");
64271
- clack58.log.info(pc62.bold("Commands:"));
64553
+ clack58.log.info(pc63.bold("Commands:"));
64272
64554
  console.log(
64273
- ` ${pc62.cyan("wraps sms test --to +1234567890")} - Send a test message`
64555
+ ` ${pc63.cyan("wraps sms test --to +1234567890")} - Send a test message`
64274
64556
  );
64275
- console.log(` ${pc62.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
64557
+ console.log(` ${pc63.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
64276
64558
  trackCommand("sms:status", {
64277
64559
  success: true,
64278
64560
  phone_type: smsConfig?.phoneNumberType,
64279
64561
  event_tracking: smsConfig?.eventTracking?.enabled,
64280
64562
  duration_ms: Date.now() - startTime
64281
64563
  });
64282
- clack58.outro(pc62.dim("SMS infrastructure is ready"));
64564
+ clack58.outro(pc63.dim("SMS infrastructure is ready"));
64283
64565
  }
64284
64566
 
64285
64567
  // src/commands/sms/sync.ts
64286
64568
  init_esm_shims();
64287
64569
  import * as clack59 from "@clack/prompts";
64288
- import * as pulumi33 from "@pulumi/pulumi";
64289
- import pc63 from "picocolors";
64570
+ import * as pulumi34 from "@pulumi/pulumi";
64571
+ import pc64 from "picocolors";
64290
64572
  init_events();
64291
64573
  init_aws();
64292
64574
  init_errors();
@@ -64299,7 +64581,7 @@ async function smsSync(options) {
64299
64581
  await ensurePulumiInstalled();
64300
64582
  const startTime = Date.now();
64301
64583
  if (!isJsonMode()) {
64302
- clack59.intro(pc63.bold("Wraps SMS Infrastructure Sync"));
64584
+ clack59.intro(pc64.bold("Wraps SMS Infrastructure Sync"));
64303
64585
  }
64304
64586
  const progress = new DeploymentProgress();
64305
64587
  const identity = await progress.execute(
@@ -64314,7 +64596,7 @@ async function smsSync(options) {
64314
64596
  clack59.log.error("No SMS infrastructure found to sync");
64315
64597
  console.log(
64316
64598
  `
64317
- Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
64599
+ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure first.
64318
64600
  `
64319
64601
  );
64320
64602
  process.exit(1);
@@ -64323,10 +64605,10 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
64323
64605
  const storedStackName = smsService.pulumiStackName;
64324
64606
  progress.info("Found existing SMS configuration");
64325
64607
  progress.info(
64326
- `Phone type: ${pc63.cyan(smsConfig.phoneNumberType || "simulator")}`
64608
+ `Phone type: ${pc64.cyan(smsConfig.phoneNumberType || "simulator")}`
64327
64609
  );
64328
64610
  progress.info(
64329
- `Event tracking: ${pc63.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
64611
+ `Event tracking: ${pc64.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
64330
64612
  );
64331
64613
  if (!options.yes) {
64332
64614
  const confirmed = await clack59.confirm({
@@ -64349,7 +64631,7 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
64349
64631
  outputs = await progress.execute("Syncing SMS infrastructure", async () => {
64350
64632
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
64351
64633
  const stackName = storedStackName || `wraps-sms-${identity.accountId}-${region}`;
64352
- const stack = await pulumi33.automation.LocalWorkspace.createOrSelectStack(
64634
+ const stack = await pulumi34.automation.LocalWorkspace.createOrSelectStack(
64353
64635
  {
64354
64636
  stackName,
64355
64637
  projectName: "wraps-sms",
@@ -64459,7 +64741,7 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
64459
64741
  return;
64460
64742
  }
64461
64743
  console.log("\n");
64462
- clack59.log.success(pc63.green("SMS infrastructure synced successfully!"));
64744
+ clack59.log.success(pc64.green("SMS infrastructure synced successfully!"));
64463
64745
  const changes = [];
64464
64746
  if (outputs.lambdaFunctions?.length) {
64465
64747
  changes.push("Lambda functions updated");
@@ -64467,13 +64749,13 @@ Run ${pc63.cyan("wraps sms init")} to deploy SMS infrastructure first.
64467
64749
  changes.push("SDK resources verified");
64468
64750
  console.log("");
64469
64751
  for (const change of changes) {
64470
- console.log(` ${pc63.green("\u2713")} ${change}`);
64752
+ console.log(` ${pc64.green("\u2713")} ${change}`);
64471
64753
  }
64472
64754
  trackCommand("sms:sync", {
64473
64755
  success: true,
64474
64756
  duration_ms: Date.now() - startTime
64475
64757
  });
64476
- clack59.outro(pc63.green("Sync complete!"));
64758
+ clack59.outro(pc64.green("Sync complete!"));
64477
64759
  }
64478
64760
 
64479
64761
  // src/commands/sms/test.ts
@@ -64489,7 +64771,7 @@ import {
64489
64771
  SendTextMessageCommand
64490
64772
  } from "@aws-sdk/client-pinpoint-sms-voice-v2";
64491
64773
  import * as clack60 from "@clack/prompts";
64492
- import pc64 from "picocolors";
64774
+ import pc65 from "picocolors";
64493
64775
 
64494
64776
  // src/utils/sms/validation.ts
64495
64777
  init_esm_shims();
@@ -64512,7 +64794,7 @@ async function smsTest(options) {
64512
64794
  const startTime = Date.now();
64513
64795
  const progress = new DeploymentProgress();
64514
64796
  if (!isJsonMode()) {
64515
- clack60.intro(pc64.bold("Wraps SMS Test"));
64797
+ clack60.intro(pc65.bold("Wraps SMS Test"));
64516
64798
  }
64517
64799
  const identity = await progress.execute(
64518
64800
  "Validating AWS credentials",
@@ -64525,7 +64807,7 @@ async function smsTest(options) {
64525
64807
  clack60.log.error("No SMS infrastructure found");
64526
64808
  console.log(
64527
64809
  `
64528
- Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
64810
+ Run ${pc65.cyan("wraps sms init")} to deploy SMS infrastructure.
64529
64811
  `
64530
64812
  );
64531
64813
  process.exit(1);
@@ -64654,16 +64936,16 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
64654
64936
  return;
64655
64937
  }
64656
64938
  console.log("\n");
64657
- clack60.log.success(pc64.green("Test SMS sent successfully!"));
64939
+ clack60.log.success(pc65.green("Test SMS sent successfully!"));
64658
64940
  console.log("");
64659
64941
  clack60.note(
64660
64942
  [
64661
- `${pc64.bold("Message ID:")} ${pc64.cyan(messageId || "unknown")}`,
64662
- `${pc64.bold("To:")} ${pc64.cyan(toNumber)}`,
64663
- `${pc64.bold("Message:")} ${message}`,
64664
- `${pc64.bold("Type:")} ${pc64.cyan(smsConfig?.phoneNumberType || "simulator")}`,
64943
+ `${pc65.bold("Message ID:")} ${pc65.cyan(messageId || "unknown")}`,
64944
+ `${pc65.bold("To:")} ${pc65.cyan(toNumber)}`,
64945
+ `${pc65.bold("Message:")} ${message}`,
64946
+ `${pc65.bold("Type:")} ${pc65.cyan(smsConfig?.phoneNumberType || "simulator")}`,
64665
64947
  "",
64666
- pc64.dim(
64948
+ pc65.dim(
64667
64949
  smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
64668
64950
  )
64669
64951
  ].join("\n"),
@@ -64672,10 +64954,10 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
64672
64954
  if (smsConfig?.eventTracking?.enabled) {
64673
64955
  console.log("");
64674
64956
  clack60.log.info(
64675
- pc64.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
64957
+ pc65.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
64676
64958
  );
64677
64959
  }
64678
- clack60.outro(pc64.green("Test complete!"));
64960
+ clack60.outro(pc65.green("Test complete!"));
64679
64961
  } catch (error) {
64680
64962
  progress.stop();
64681
64963
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -64700,7 +64982,7 @@ Run ${pc64.cyan("wraps sms init")} to deploy SMS infrastructure.
64700
64982
  clack60.log.error("Toll-free number registration is not complete");
64701
64983
  console.log(
64702
64984
  `
64703
- Run ${pc64.cyan("wraps sms register")} to check registration status.
64985
+ Run ${pc65.cyan("wraps sms register")} to check registration status.
64704
64986
  `
64705
64987
  );
64706
64988
  } else if (errorName === "AccessDeniedException") {
@@ -64709,7 +64991,7 @@ Run ${pc64.cyan("wraps sms register")} to check registration status.
64709
64991
  );
64710
64992
  console.log(
64711
64993
  `
64712
- Run ${pc64.cyan("wraps sms upgrade")} to update IAM policies.
64994
+ Run ${pc65.cyan("wraps sms upgrade")} to update IAM policies.
64713
64995
  `
64714
64996
  );
64715
64997
  } else {
@@ -64722,8 +65004,8 @@ Run ${pc64.cyan("wraps sms upgrade")} to update IAM policies.
64722
65004
  // src/commands/sms/upgrade.ts
64723
65005
  init_esm_shims();
64724
65006
  import * as clack61 from "@clack/prompts";
64725
- import * as pulumi34 from "@pulumi/pulumi";
64726
- import pc65 from "picocolors";
65007
+ import * as pulumi35 from "@pulumi/pulumi";
65008
+ import pc66 from "picocolors";
64727
65009
  init_events();
64728
65010
  init_aws();
64729
65011
  init_errors();
@@ -64738,7 +65020,7 @@ async function smsUpgrade(options) {
64738
65020
  const startTime = Date.now();
64739
65021
  let upgradeAction = "";
64740
65022
  if (!isJsonMode()) {
64741
- clack61.intro(pc65.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
65023
+ clack61.intro(pc66.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
64742
65024
  }
64743
65025
  const progress = new DeploymentProgress();
64744
65026
  const wasAutoInstalled = await progress.execute(
@@ -64752,7 +65034,7 @@ async function smsUpgrade(options) {
64752
65034
  "Validating AWS credentials",
64753
65035
  async () => validateAWSCredentials()
64754
65036
  );
64755
- progress.info(`Connected to AWS account: ${pc65.cyan(identity.accountId)}`);
65037
+ progress.info(`Connected to AWS account: ${pc66.cyan(identity.accountId)}`);
64756
65038
  const region = await resolveRegionForCommand({
64757
65039
  accountId: identity.accountId,
64758
65040
  optionRegion: options.region,
@@ -64762,34 +65044,34 @@ async function smsUpgrade(options) {
64762
65044
  const metadata = await loadConnectionMetadata(identity.accountId, region);
64763
65045
  if (!metadata) {
64764
65046
  clack61.log.error(
64765
- `No Wraps connection found for account ${pc65.cyan(identity.accountId)} in region ${pc65.cyan(region)}`
65047
+ `No Wraps connection found for account ${pc66.cyan(identity.accountId)} in region ${pc66.cyan(region)}`
64766
65048
  );
64767
65049
  clack61.log.info(
64768
- `Use ${pc65.cyan("wraps sms init")} to create new infrastructure.`
65050
+ `Use ${pc66.cyan("wraps sms init")} to create new infrastructure.`
64769
65051
  );
64770
65052
  process.exit(1);
64771
65053
  }
64772
65054
  if (!metadata.services.sms) {
64773
65055
  clack61.log.error("No SMS infrastructure found");
64774
65056
  clack61.log.info(
64775
- `Use ${pc65.cyan("wraps sms init")} to deploy SMS infrastructure.`
65057
+ `Use ${pc66.cyan("wraps sms init")} to deploy SMS infrastructure.`
64776
65058
  );
64777
65059
  process.exit(1);
64778
65060
  }
64779
65061
  progress.info(`Found existing connection created: ${metadata.timestamp}`);
64780
65062
  console.log(`
64781
- ${pc65.bold("Current Configuration:")}
65063
+ ${pc66.bold("Current Configuration:")}
64782
65064
  `);
64783
65065
  if (metadata.services.sms.preset) {
64784
- console.log(` Preset: ${pc65.cyan(metadata.services.sms.preset)}`);
65066
+ console.log(` Preset: ${pc66.cyan(metadata.services.sms.preset)}`);
64785
65067
  } else {
64786
- console.log(` Preset: ${pc65.cyan("custom")}`);
65068
+ console.log(` Preset: ${pc66.cyan("custom")}`);
64787
65069
  }
64788
65070
  const config2 = metadata.services.sms.config;
64789
65071
  if (!config2) {
64790
65072
  clack61.log.error("No SMS configuration found in metadata");
64791
65073
  clack61.log.info(
64792
- `Use ${pc65.cyan("wraps sms init")} to create new infrastructure.`
65074
+ `Use ${pc66.cyan("wraps sms init")} to create new infrastructure.`
64793
65075
  );
64794
65076
  process.exit(1);
64795
65077
  }
@@ -64801,45 +65083,45 @@ ${pc65.bold("Current Configuration:")}
64801
65083
  "short-code": "Short code ($995+/mo, 100+ MPS)"
64802
65084
  };
64803
65085
  console.log(
64804
- ` Phone Type: ${pc65.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
65086
+ ` Phone Type: ${pc66.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
64805
65087
  );
64806
65088
  }
64807
65089
  if (config2.tracking?.enabled) {
64808
- console.log(` ${pc65.green("\u2713")} Delivery Tracking`);
65090
+ console.log(` ${pc66.green("\u2713")} Delivery Tracking`);
64809
65091
  if (config2.tracking.linkTracking) {
64810
- console.log(` ${pc65.dim("\u2514\u2500")} Link click tracking enabled`);
65092
+ console.log(` ${pc66.dim("\u2514\u2500")} Link click tracking enabled`);
64811
65093
  }
64812
65094
  }
64813
65095
  if (config2.eventTracking?.enabled) {
64814
- console.log(` ${pc65.green("\u2713")} Event Tracking (SNS)`);
65096
+ console.log(` ${pc66.green("\u2713")} Event Tracking (SNS)`);
64815
65097
  if (config2.eventTracking.dynamoDBHistory) {
64816
65098
  console.log(
64817
- ` ${pc65.dim("\u2514\u2500")} Message History: ${pc65.cyan(config2.eventTracking.archiveRetention || "90days")}`
65099
+ ` ${pc66.dim("\u2514\u2500")} Message History: ${pc66.cyan(config2.eventTracking.archiveRetention || "90days")}`
64818
65100
  );
64819
65101
  }
64820
65102
  }
64821
65103
  if (config2.messageArchiving?.enabled) {
64822
65104
  console.log(
64823
- ` ${pc65.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
65105
+ ` ${pc66.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
64824
65106
  );
64825
65107
  }
64826
65108
  if (config2.optOutManagement) {
64827
- console.log(` ${pc65.green("\u2713")} Opt-out Management`);
65109
+ console.log(` ${pc66.green("\u2713")} Opt-out Management`);
64828
65110
  }
64829
65111
  if (config2.protectConfiguration?.enabled) {
64830
65112
  const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
64831
- console.log(` ${pc65.green("\u2713")} Fraud Protection`);
64832
- console.log(` ${pc65.dim("\u2514\u2500")} Allowed countries: ${pc65.cyan(countries)}`);
65113
+ console.log(` ${pc66.green("\u2713")} Fraud Protection`);
65114
+ console.log(` ${pc66.dim("\u2514\u2500")} Allowed countries: ${pc66.cyan(countries)}`);
64833
65115
  if (config2.protectConfiguration.aitFiltering) {
64834
- console.log(` ${pc65.dim("\u2514\u2500")} AIT filtering: ${pc65.cyan("enabled")}`);
65116
+ console.log(` ${pc66.dim("\u2514\u2500")} AIT filtering: ${pc66.cyan("enabled")}`);
64835
65117
  }
64836
65118
  } else {
64837
- console.log(` ${pc65.dim("\u25CB")} Fraud Protection (not configured)`);
65119
+ console.log(` ${pc66.dim("\u25CB")} Fraud Protection (not configured)`);
64838
65120
  }
64839
65121
  const currentCostData = calculateSMSCosts(config2, 1e4);
64840
65122
  console.log(
64841
65123
  `
64842
- Estimated Cost: ${pc65.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
65124
+ Estimated Cost: ${pc66.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
64843
65125
  );
64844
65126
  console.log("");
64845
65127
  const phoneTypeLabels = {
@@ -64946,22 +65228,22 @@ ${pc65.bold("Current Configuration:")}
64946
65228
  if (selectedType === "toll-free") {
64947
65229
  console.log(
64948
65230
  `
64949
- ${pc65.yellow("\u26A0")} ${pc65.bold("Toll-free Registration Required")}
65231
+ ${pc66.yellow("\u26A0")} ${pc66.bold("Toll-free Registration Required")}
64950
65232
  `
64951
65233
  );
64952
65234
  console.log(
64953
- pc65.dim("Toll-free numbers require carrier registration before")
65235
+ pc66.dim("Toll-free numbers require carrier registration before")
64954
65236
  );
64955
65237
  console.log(
64956
- pc65.dim("they can send messages at scale. After deployment:\n")
65238
+ pc66.dim("they can send messages at scale. After deployment:\n")
64957
65239
  );
64958
65240
  console.log(
64959
- ` 1. Run ${pc65.cyan("wraps sms register")} to start registration`
65241
+ ` 1. Run ${pc66.cyan("wraps sms register")} to start registration`
64960
65242
  );
64961
65243
  console.log(" 2. Submit your business use case information");
64962
65244
  console.log(" 3. Wait for carrier verification (1-5 business days)");
64963
65245
  console.log(
64964
- pc65.dim("\nUntil verified, sending is limited to low volume.\n")
65246
+ pc66.dim("\nUntil verified, sending is limited to low volume.\n")
64965
65247
  );
64966
65248
  const confirmTollFree = await clack61.confirm({
64967
65249
  message: "Continue with toll-free number request?",
@@ -64975,10 +65257,10 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("Toll-free Registration Required")}
64975
65257
  if (selectedType === "10dlc") {
64976
65258
  console.log(
64977
65259
  `
64978
- ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
65260
+ ${pc66.yellow("\u26A0")} ${pc66.bold("10DLC Campaign Registration Required")}
64979
65261
  `
64980
65262
  );
64981
- console.log(pc65.dim("10DLC requires brand and campaign registration:"));
65263
+ console.log(pc66.dim("10DLC requires brand and campaign registration:"));
64982
65264
  console.log(" \u2022 Brand registration: one-time $4 fee");
64983
65265
  console.log(" \u2022 Campaign registration: $15/mo per campaign");
64984
65266
  console.log(" \u2022 Verification takes 1-7 business days");
@@ -65211,12 +65493,12 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
65211
65493
  const enableLinkTracking = !config2.tracking?.linkTracking;
65212
65494
  if (enableLinkTracking) {
65213
65495
  clack61.log.info(
65214
- pc65.dim(
65496
+ pc66.dim(
65215
65497
  "Link tracking will track clicks on URLs in your SMS messages."
65216
65498
  )
65217
65499
  );
65218
65500
  clack61.log.info(
65219
- pc65.dim("URLs will be rewritten to go through a tracking endpoint.")
65501
+ pc66.dim("URLs will be rewritten to go through a tracking endpoint.")
65220
65502
  );
65221
65503
  }
65222
65504
  const confirmed = await clack61.confirm({
@@ -65429,18 +65711,18 @@ ${pc65.yellow("\u26A0")} ${pc65.bold("10DLC Campaign Registration Required")}
65429
65711
  const newCostData = calculateSMSCosts(updatedConfig, 1e4);
65430
65712
  const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
65431
65713
  console.log(`
65432
- ${pc65.bold("Cost Impact:")}`);
65714
+ ${pc66.bold("Cost Impact:")}`);
65433
65715
  console.log(
65434
- ` Current: ${pc65.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
65716
+ ` Current: ${pc66.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
65435
65717
  );
65436
65718
  console.log(
65437
- ` New: ${pc65.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
65719
+ ` New: ${pc66.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
65438
65720
  );
65439
65721
  if (costDiff > 0) {
65440
- console.log(` Change: ${pc65.yellow(`+${formatCost3(costDiff)}/mo`)}`);
65722
+ console.log(` Change: ${pc66.yellow(`+${formatCost3(costDiff)}/mo`)}`);
65441
65723
  } else if (costDiff < 0) {
65442
65724
  console.log(
65443
- ` Change: ${pc65.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
65725
+ ` Change: ${pc66.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
65444
65726
  );
65445
65727
  }
65446
65728
  console.log("");
@@ -65469,7 +65751,7 @@ ${pc65.bold("Cost Impact:")}`);
65469
65751
  const stackName = metadata.services.sms?.pulumiStackName || `wraps-sms-${identity.accountId}-${region}`;
65470
65752
  const createStack = async () => {
65471
65753
  await ensurePulumiWorkDir({ accountId: identity.accountId, region });
65472
- const stack = await pulumi34.automation.LocalWorkspace.createOrSelectStack(
65754
+ const stack = await pulumi35.automation.LocalWorkspace.createOrSelectStack(
65473
65755
  {
65474
65756
  stackName,
65475
65757
  projectName: "wraps-sms",
@@ -65520,7 +65802,7 @@ ${pc65.bold("Cost Impact:")}`);
65520
65802
  commandName: "wraps sms upgrade"
65521
65803
  });
65522
65804
  clack61.outro(
65523
- pc65.green("Preview complete. Run without --preview to upgrade.")
65805
+ pc66.green("Preview complete. Run without --preview to upgrade.")
65524
65806
  );
65525
65807
  trackServiceUpgrade("sms", {
65526
65808
  region,
@@ -65625,43 +65907,43 @@ ${pc65.bold("Cost Impact:")}`);
65625
65907
  }
65626
65908
  progress.info("Connection metadata updated");
65627
65909
  console.log("\n");
65628
- clack61.log.success(pc65.green(pc65.bold("SMS infrastructure upgraded!")));
65910
+ clack61.log.success(pc66.green(pc66.bold("SMS infrastructure upgraded!")));
65629
65911
  console.log("\n");
65630
65912
  clack61.note(
65631
65913
  [
65632
- `${pc65.bold("Phone Number:")} ${pc65.cyan(outputs.phoneNumber || "Provisioning...")}`,
65633
- `${pc65.bold("Phone Type:")} ${pc65.cyan(updatedConfig.phoneNumberType || "simulator")}`,
65634
- `${pc65.bold("Config Set:")} ${pc65.cyan(outputs.configSetName || "wraps-sms-config")}`,
65635
- `${pc65.bold("Region:")} ${pc65.cyan(outputs.region)}`,
65636
- outputs.tableName ? `${pc65.bold("History Table:")} ${pc65.cyan(outputs.tableName)}` : "",
65914
+ `${pc66.bold("Phone Number:")} ${pc66.cyan(outputs.phoneNumber || "Provisioning...")}`,
65915
+ `${pc66.bold("Phone Type:")} ${pc66.cyan(updatedConfig.phoneNumberType || "simulator")}`,
65916
+ `${pc66.bold("Config Set:")} ${pc66.cyan(outputs.configSetName || "wraps-sms-config")}`,
65917
+ `${pc66.bold("Region:")} ${pc66.cyan(outputs.region)}`,
65918
+ outputs.tableName ? `${pc66.bold("History Table:")} ${pc66.cyan(outputs.tableName)}` : "",
65637
65919
  "",
65638
- pc65.dim("IAM Role:"),
65639
- pc65.dim(` ${outputs.roleArn}`)
65920
+ pc66.dim("IAM Role:"),
65921
+ pc66.dim(` ${outputs.roleArn}`)
65640
65922
  ].filter(Boolean).join("\n"),
65641
65923
  "SMS Infrastructure"
65642
65924
  );
65643
65925
  console.log(`
65644
- ${pc65.green("\u2713")} ${pc65.bold("Upgrade complete!")}
65926
+ ${pc66.green("\u2713")} ${pc66.bold("Upgrade complete!")}
65645
65927
  `);
65646
65928
  if (upgradeAction === "phone-number") {
65647
65929
  console.log(
65648
- `Upgraded to ${pc65.cyan(updatedConfig.phoneNumberType)} number (${pc65.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65930
+ `Upgraded to ${pc66.cyan(updatedConfig.phoneNumberType)} number (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65649
65931
  `
65650
65932
  );
65651
65933
  if (updatedConfig.phoneNumberType === "toll-free") {
65652
- console.log(`${pc65.bold("Next Steps:")}`);
65934
+ console.log(`${pc66.bold("Next Steps:")}`);
65653
65935
  console.log(
65654
- ` 1. Run ${pc65.cyan("wraps sms register")} to start toll-free registration`
65936
+ ` 1. Run ${pc66.cyan("wraps sms register")} to start toll-free registration`
65655
65937
  );
65656
65938
  console.log(" 2. Submit your business information and use case");
65657
65939
  console.log(" 3. Wait for carrier verification (1-5 business days)");
65658
65940
  console.log("");
65659
65941
  console.log(
65660
- pc65.dim("Until verified, your number can only send limited messages.")
65942
+ pc66.dim("Until verified, your number can only send limited messages.")
65661
65943
  );
65662
65944
  console.log("");
65663
65945
  } else if (updatedConfig.phoneNumberType === "10dlc") {
65664
- console.log(`${pc65.bold("Next Steps:")}`);
65946
+ console.log(`${pc66.bold("Next Steps:")}`);
65665
65947
  console.log(" 1. Register your brand in the AWS Console");
65666
65948
  console.log(" 2. Create a 10DLC campaign for your use case");
65667
65949
  console.log(" 3. Wait for campaign approval (1-7 business days)");
@@ -65669,16 +65951,16 @@ ${pc65.green("\u2713")} ${pc65.bold("Upgrade complete!")}
65669
65951
  }
65670
65952
  } else if (upgradeAction === "preset" && newPreset) {
65671
65953
  console.log(
65672
- `Upgraded to ${pc65.cyan(newPreset)} preset (${pc65.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65954
+ `Upgraded to ${pc66.cyan(newPreset)} preset (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65673
65955
  `
65674
65956
  );
65675
65957
  } else {
65676
65958
  console.log(
65677
- `Updated configuration (${pc65.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65959
+ `Updated configuration (${pc66.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
65678
65960
  `
65679
65961
  );
65680
65962
  }
65681
- console.log(pc65.dim(getSMSCostSummary(updatedConfig, 1e4)));
65963
+ console.log(pc66.dim(getSMSCostSummary(updatedConfig, 1e4)));
65682
65964
  const enabledFeatures = [];
65683
65965
  if (updatedConfig.tracking?.enabled) {
65684
65966
  enabledFeatures.push("tracking");
@@ -65702,7 +65984,7 @@ ${pc65.green("\u2713")} ${pc65.bold("Upgrade complete!")}
65702
65984
  action: typeof upgradeAction === "string" ? upgradeAction : void 0,
65703
65985
  duration_ms: Date.now() - startTime
65704
65986
  });
65705
- clack61.outro(pc65.green("Upgrade complete!"));
65987
+ clack61.outro(pc66.green("Upgrade complete!"));
65706
65988
  }
65707
65989
 
65708
65990
  // src/commands/sms/verify-number.ts
@@ -65722,12 +66004,12 @@ import {
65722
66004
  VerifyDestinationNumberCommand
65723
66005
  } from "@aws-sdk/client-pinpoint-sms-voice-v2";
65724
66006
  import * as clack62 from "@clack/prompts";
65725
- import pc66 from "picocolors";
66007
+ import pc67 from "picocolors";
65726
66008
  async function smsVerifyNumber(options) {
65727
66009
  const startTime = Date.now();
65728
66010
  const progress = new DeploymentProgress();
65729
66011
  if (!isJsonMode()) {
65730
- clack62.intro(pc66.bold("Wraps SMS - Verify Destination Number"));
66012
+ clack62.intro(pc67.bold("Wraps SMS - Verify Destination Number"));
65731
66013
  }
65732
66014
  const identity = await progress.execute(
65733
66015
  "Validating AWS credentials",
@@ -65740,7 +66022,7 @@ async function smsVerifyNumber(options) {
65740
66022
  clack62.log.error("No SMS infrastructure found");
65741
66023
  console.log(
65742
66024
  `
65743
- Run ${pc66.cyan("wraps sms init")} to deploy SMS infrastructure.
66025
+ Run ${pc67.cyan("wraps sms init")} to deploy SMS infrastructure.
65744
66026
  `
65745
66027
  );
65746
66028
  process.exit(1);
@@ -65757,16 +66039,16 @@ Run ${pc66.cyan("wraps sms init")} to deploy SMS infrastructure.
65757
66039
  clack62.log.info("No verified destination numbers found");
65758
66040
  console.log(
65759
66041
  `
65760
- Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
66042
+ Run ${pc67.cyan("wraps sms verify-number")} to verify a number.
65761
66043
  `
65762
66044
  );
65763
66045
  } else {
65764
66046
  console.log("\n");
65765
- clack62.log.info(pc66.bold("Verified Destination Numbers:"));
66047
+ clack62.log.info(pc67.bold("Verified Destination Numbers:"));
65766
66048
  console.log("");
65767
66049
  for (const num of response.VerifiedDestinationNumbers) {
65768
- const status2 = num.Status === "VERIFIED" ? pc66.green("\u2713 Verified") : pc66.yellow("\u29D6 Pending");
65769
- console.log(` ${pc66.cyan(num.DestinationPhoneNumber)} - ${status2}`);
66050
+ const status2 = num.Status === "VERIFIED" ? pc67.green("\u2713 Verified") : pc67.yellow("\u29D6 Pending");
66051
+ console.log(` ${pc67.cyan(num.DestinationPhoneNumber)} - ${status2}`);
65770
66052
  }
65771
66053
  console.log("");
65772
66054
  }
@@ -65784,7 +66066,7 @@ Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
65784
66066
  });
65785
66067
  return;
65786
66068
  }
65787
- clack62.outro(pc66.green("Done!"));
66069
+ clack62.outro(pc67.green("Done!"));
65788
66070
  return;
65789
66071
  } catch (error) {
65790
66072
  progress.stop();
@@ -65803,7 +66085,7 @@ Run ${pc66.cyan("wraps sms verify-number")} to verify a number.
65803
66085
  clack62.log.error("Phone number is required for deletion");
65804
66086
  console.log(
65805
66087
  `
65806
- Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
66088
+ Usage: ${pc67.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
65807
66089
  `
65808
66090
  );
65809
66091
  process.exit(1);
@@ -65828,7 +66110,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
65828
66110
  );
65829
66111
  });
65830
66112
  progress.stop();
65831
- clack62.log.success(`Removed ${pc66.cyan(phoneNumber2)} from verified list`);
66113
+ clack62.log.success(`Removed ${pc67.cyan(phoneNumber2)} from verified list`);
65832
66114
  trackCommand("sms:verify-number:delete", {
65833
66115
  success: true,
65834
66116
  duration_ms: Date.now() - startTime
@@ -65840,7 +66122,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
65840
66122
  });
65841
66123
  return;
65842
66124
  }
65843
- clack62.outro(pc66.green("Done!"));
66125
+ clack62.outro(pc67.green("Done!"));
65844
66126
  return;
65845
66127
  } catch (error) {
65846
66128
  progress.stop();
@@ -65912,11 +66194,11 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
65912
66194
  progress.stop();
65913
66195
  console.log("\n");
65914
66196
  clack62.log.success(
65915
- pc66.green(`Phone number ${pc66.cyan(phoneNumber)} verified!`)
66197
+ pc67.green(`Phone number ${pc67.cyan(phoneNumber)} verified!`)
65916
66198
  );
65917
66199
  console.log("");
65918
66200
  console.log(
65919
- `You can now send test messages to this number with ${pc66.cyan("wraps sms test")}`
66201
+ `You can now send test messages to this number with ${pc67.cyan("wraps sms test")}`
65920
66202
  );
65921
66203
  trackCommand("sms:verify-number:confirm", {
65922
66204
  success: true,
@@ -65929,7 +66211,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
65929
66211
  });
65930
66212
  return;
65931
66213
  }
65932
- clack62.outro(pc66.green("Verification complete!"));
66214
+ clack62.outro(pc67.green("Verification complete!"));
65933
66215
  return;
65934
66216
  } catch (error) {
65935
66217
  progress.stop();
@@ -65938,7 +66220,7 @@ Usage: ${pc66.cyan("wraps sms verify-number --delete --phone-number +14155551234
65938
66220
  clack62.log.error("Invalid verification code. Please try again.");
65939
66221
  console.log(
65940
66222
  `
65941
- Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
66223
+ Run ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
65942
66224
  `
65943
66225
  );
65944
66226
  } else {
@@ -65974,11 +66256,11 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
65974
66256
  );
65975
66257
  });
65976
66258
  progress.stop();
65977
- clack62.log.success(`Verification code resent to ${pc66.cyan(phoneNumber)}`);
66259
+ clack62.log.success(`Verification code resent to ${pc67.cyan(phoneNumber)}`);
65978
66260
  console.log("");
65979
66261
  console.log(
65980
66262
  `Once you receive the code, run:
65981
- ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
66263
+ ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
65982
66264
  );
65983
66265
  trackCommand("sms:verify-number:resend", {
65984
66266
  success: true,
@@ -65991,7 +66273,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
65991
66273
  });
65992
66274
  return;
65993
66275
  }
65994
- clack62.outro(pc66.green("Code sent!"));
66276
+ clack62.outro(pc67.green("Code sent!"));
65995
66277
  return;
65996
66278
  } catch (error) {
65997
66279
  progress.stop();
@@ -66020,9 +66302,9 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66020
66302
  return;
66021
66303
  }
66022
66304
  clack62.log.info(
66023
- `Number ${pc66.cyan(phoneNumber)} is already verified and ready to use!`
66305
+ `Number ${pc67.cyan(phoneNumber)} is already verified and ready to use!`
66024
66306
  );
66025
- clack62.outro(pc66.green("Done!"));
66307
+ clack62.outro(pc67.green("Done!"));
66026
66308
  return;
66027
66309
  }
66028
66310
  if (existingNumber?.Status === "PENDING") {
@@ -66047,14 +66329,14 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66047
66329
  return;
66048
66330
  }
66049
66331
  clack62.log.info(
66050
- `Verification already in progress. New code sent to ${pc66.cyan(phoneNumber)}`
66332
+ `Verification already in progress. New code sent to ${pc67.cyan(phoneNumber)}`
66051
66333
  );
66052
66334
  console.log("");
66053
66335
  console.log(
66054
66336
  `Once you receive the code, run:
66055
- ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
66337
+ ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
66056
66338
  );
66057
- clack62.outro(pc66.green("Code sent!"));
66339
+ clack62.outro(pc67.green("Code sent!"));
66058
66340
  return;
66059
66341
  }
66060
66342
  const createResponse = await progress.execute(
@@ -66076,7 +66358,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66076
66358
  progress.stop();
66077
66359
  console.log("\n");
66078
66360
  clack62.log.success(
66079
- `Verification code sent to ${pc66.cyan(phoneNumber)} via SMS`
66361
+ `Verification code sent to ${pc67.cyan(phoneNumber)} via SMS`
66080
66362
  );
66081
66363
  console.log("");
66082
66364
  clack62.note(
@@ -66084,9 +66366,9 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66084
66366
  "1. Check your phone for the verification code",
66085
66367
  "",
66086
66368
  "2. Complete verification with:",
66087
- ` ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
66369
+ ` ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
66088
66370
  "",
66089
- pc66.dim("The code expires in 24 hours")
66371
+ pc67.dim("The code expires in 24 hours")
66090
66372
  ].join("\n"),
66091
66373
  "Next Steps"
66092
66374
  );
@@ -66102,7 +66384,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66102
66384
  });
66103
66385
  return;
66104
66386
  }
66105
- clack62.outro(pc66.green("Verification started!"));
66387
+ clack62.outro(pc67.green("Verification started!"));
66106
66388
  } catch (error) {
66107
66389
  progress.stop();
66108
66390
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -66110,7 +66392,7 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66110
66392
  clack62.log.error("This number is already being verified");
66111
66393
  console.log(
66112
66394
  `
66113
- Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
66395
+ Run ${pc67.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
66114
66396
  `
66115
66397
  );
66116
66398
  } else {
@@ -66127,21 +66409,21 @@ Run ${pc66.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
66127
66409
  init_esm_shims();
66128
66410
  init_events();
66129
66411
  import * as clack63 from "@clack/prompts";
66130
- import pc67 from "picocolors";
66412
+ import pc68 from "picocolors";
66131
66413
  async function support() {
66132
66414
  trackCommand("support", { success: true });
66133
- clack63.intro(pc67.bold("Get Help with Wraps"));
66415
+ clack63.intro(pc68.bold("Get Help with Wraps"));
66134
66416
  console.log();
66135
- console.log(` ${pc67.bold("Email:")} ${pc67.cyan("hey@wraps.dev")}`);
66417
+ console.log(` ${pc68.bold("Email:")} ${pc68.cyan("hey@wraps.dev")}`);
66136
66418
  console.log(
66137
- ` ${pc67.bold("GitHub:")} ${pc67.cyan("https://github.com/wraps-dev/wraps/issues")}`
66419
+ ` ${pc68.bold("GitHub:")} ${pc68.cyan("https://github.com/wraps-dev/wraps/issues")}`
66138
66420
  );
66139
- console.log(` ${pc67.bold("Docs:")} ${pc67.cyan("https://wraps.dev/docs")}`);
66421
+ console.log(` ${pc68.bold("Docs:")} ${pc68.cyan("https://wraps.dev/docs")}`);
66140
66422
  console.log(
66141
- ` ${pc67.bold("AI docs:")} ${pc67.cyan("https://wraps.dev/llms-full.txt")} ${pc67.dim("(complete docs, one file)")}`
66423
+ ` ${pc68.bold("AI docs:")} ${pc68.cyan("https://wraps.dev/llms-full.txt")} ${pc68.dim("(complete docs, one file)")}`
66142
66424
  );
66143
66425
  console.log();
66144
- console.log(pc67.dim(" Response time: Usually within 24 hours"));
66426
+ console.log(pc68.dim(" Response time: Usually within 24 hours"));
66145
66427
  console.log();
66146
66428
  }
66147
66429
 
@@ -66149,7 +66431,7 @@ async function support() {
66149
66431
  init_esm_shims();
66150
66432
  init_client();
66151
66433
  import * as clack64 from "@clack/prompts";
66152
- import pc68 from "picocolors";
66434
+ import pc69 from "picocolors";
66153
66435
  async function telemetryEnable() {
66154
66436
  const client2 = getTelemetryClient();
66155
66437
  const override = client2.enable();
@@ -66157,60 +66439,60 @@ async function telemetryEnable() {
66157
66439
  clack64.log.warn(
66158
66440
  "Telemetry enabled in config, but overridden by environment"
66159
66441
  );
66160
- console.log(` Reason: ${pc68.yellow(override)}`);
66161
- console.log(` Config: ${pc68.dim(client2.getConfigPath())}`);
66442
+ console.log(` Reason: ${pc69.yellow(override)}`);
66443
+ console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
66162
66444
  console.log();
66163
66445
  } else {
66164
- clack64.log.success(pc68.green("Telemetry enabled"));
66165
- console.log(` Config: ${pc68.dim(client2.getConfigPath())}`);
66446
+ clack64.log.success(pc69.green("Telemetry enabled"));
66447
+ console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
66166
66448
  console.log(`
66167
- ${pc68.dim("Thank you for helping improve Wraps!")}
66449
+ ${pc69.dim("Thank you for helping improve Wraps!")}
66168
66450
  `);
66169
66451
  }
66170
66452
  }
66171
66453
  async function telemetryDisable() {
66172
66454
  const client2 = getTelemetryClient();
66173
66455
  client2.disable();
66174
- clack64.log.success(pc68.green("Telemetry disabled"));
66175
- console.log(` Config: ${pc68.dim(client2.getConfigPath())}`);
66456
+ clack64.log.success(pc69.green("Telemetry disabled"));
66457
+ console.log(` Config: ${pc69.dim(client2.getConfigPath())}`);
66176
66458
  console.log(
66177
66459
  `
66178
- ${pc68.dim("You can re-enable with:")} wraps telemetry enable
66460
+ ${pc69.dim("You can re-enable with:")} wraps telemetry enable
66179
66461
  `
66180
66462
  );
66181
66463
  }
66182
66464
  async function telemetryStatus() {
66183
66465
  const client2 = getTelemetryClient();
66184
- clack64.intro(pc68.bold("Telemetry Status"));
66466
+ clack64.intro(pc69.bold("Telemetry Status"));
66185
66467
  const override = client2.getEnvOverride();
66186
- const status2 = client2.isEnabled() ? pc68.green("Enabled") : pc68.red("Disabled");
66468
+ const status2 = client2.isEnabled() ? pc69.green("Enabled") : pc69.red("Disabled");
66187
66469
  console.log();
66188
- console.log(` ${pc68.bold("Status:")} ${status2}`);
66470
+ console.log(` ${pc69.bold("Status:")} ${status2}`);
66189
66471
  if (!client2.isEnabled() && override) {
66190
- console.log(` ${pc68.bold("Reason:")} ${pc68.yellow(override)}`);
66472
+ console.log(` ${pc69.bold("Reason:")} ${pc69.yellow(override)}`);
66191
66473
  }
66192
- console.log(` ${pc68.bold("Config file:")} ${pc68.dim(client2.getConfigPath())}`);
66474
+ console.log(` ${pc69.bold("Config file:")} ${pc69.dim(client2.getConfigPath())}`);
66193
66475
  if (client2.isEnabled()) {
66194
66476
  console.log();
66195
- console.log(pc68.bold(" How to opt-out:"));
66196
- console.log(` ${pc68.cyan("wraps telemetry disable")}`);
66477
+ console.log(pc69.bold(" How to opt-out:"));
66478
+ console.log(` ${pc69.cyan("wraps telemetry disable")}`);
66197
66479
  console.log(
66198
- ` ${pc68.dim("Or set:")} ${pc68.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
66480
+ ` ${pc69.dim("Or set:")} ${pc69.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
66199
66481
  );
66200
- console.log(` ${pc68.dim("Or set:")} ${pc68.cyan("DO_NOT_TRACK=1")}`);
66482
+ console.log(` ${pc69.dim("Or set:")} ${pc69.cyan("DO_NOT_TRACK=1")}`);
66201
66483
  } else {
66202
66484
  console.log();
66203
- console.log(pc68.bold(" How to opt-in:"));
66204
- console.log(` ${pc68.cyan("wraps telemetry enable")}`);
66485
+ console.log(pc69.bold(" How to opt-in:"));
66486
+ console.log(` ${pc69.cyan("wraps telemetry enable")}`);
66205
66487
  }
66206
66488
  console.log();
66207
- console.log(pc68.bold(" Debug mode:"));
66489
+ console.log(pc69.bold(" Debug mode:"));
66208
66490
  console.log(
66209
- ` ${pc68.dim("See what would be sent:")} ${pc68.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
66491
+ ` ${pc69.dim("See what would be sent:")} ${pc69.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
66210
66492
  );
66211
66493
  console.log();
66212
66494
  console.log(
66213
- ` ${pc68.dim("Learn more:")} ${pc68.cyan("https://wraps.dev/docs/telemetry")}`
66495
+ ` ${pc69.dim("Learn more:")} ${pc69.cyan("https://wraps.dev/docs/telemetry")}`
66214
66496
  );
66215
66497
  console.log();
66216
66498
  }
@@ -66220,7 +66502,7 @@ init_esm_shims();
66220
66502
  import { existsSync as existsSync18, mkdirSync as mkdirSync2, writeFileSync } from "fs";
66221
66503
  import { join as join23 } from "path";
66222
66504
  import * as clack65 from "@clack/prompts";
66223
- import pc69 from "picocolors";
66505
+ import pc70 from "picocolors";
66224
66506
  var EXAMPLE_CASCADE_WORKFLOW = `import {
66225
66507
  defineWorkflow,
66226
66508
  sendEmail,
@@ -66315,13 +66597,13 @@ export default defineConfig({
66315
66597
  });
66316
66598
  `;
66317
66599
  async function workflowInit(options = {}) {
66318
- clack65.intro(pc69.bgCyan(pc69.black(" wraps workflow init ")));
66600
+ clack65.intro(pc70.bgCyan(pc70.black(" wraps workflow init ")));
66319
66601
  const wrapsDir = join23(process.cwd(), "wraps");
66320
66602
  const workflowsDir = join23(wrapsDir, "workflows");
66321
66603
  const configPath = join23(wrapsDir, "wraps.config.ts");
66322
66604
  if (existsSync18(workflowsDir)) {
66323
66605
  clack65.log.info(
66324
- `Workflows directory already exists at ${pc69.cyan("wraps/workflows/")}`
66606
+ `Workflows directory already exists at ${pc70.cyan("wraps/workflows/")}`
66325
66607
  );
66326
66608
  const files = existsSync18(join23(workflowsDir, "cart-recovery.ts")) || existsSync18(join23(workflowsDir, "welcome-sequence.ts"));
66327
66609
  if (files && !options.yes) {
@@ -66356,39 +66638,123 @@ async function workflowInit(options = {}) {
66356
66638
  s2.stop("Created 2 example workflows");
66357
66639
  if (!existsSync18(configPath)) {
66358
66640
  writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
66359
- clack65.log.info(`Created ${pc69.cyan("wraps/wraps.config.ts")}`);
66641
+ clack65.log.info(`Created ${pc70.cyan("wraps/wraps.config.ts")}`);
66360
66642
  }
66361
66643
  clack65.log.success(
66362
- `${pc69.bold("Workflows scaffolded!")} Created:
66363
- ${pc69.cyan("wraps/wraps.config.ts")} \u2014 Project config
66364
- ${pc69.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
66365
- ${pc69.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
66644
+ `${pc70.bold("Workflows scaffolded!")} Created:
66645
+ ${pc70.cyan("wraps/wraps.config.ts")} \u2014 Project config
66646
+ ${pc70.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
66647
+ ${pc70.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
66366
66648
  );
66367
66649
  showNextSteps2();
66368
- clack65.outro(pc69.green("Happy orchestrating!"));
66650
+ clack65.outro(pc70.green("Happy orchestrating!"));
66369
66651
  } catch (error) {
66370
66652
  clack65.log.error(
66371
66653
  `Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
66372
66654
  );
66373
- clack65.outro(pc69.red("Scaffolding failed."));
66655
+ clack65.outro(pc70.red("Scaffolding failed."));
66374
66656
  process.exitCode = 1;
66375
66657
  }
66376
66658
  }
66377
66659
  function showNextSteps2() {
66378
66660
  clack65.log.info(
66379
- `${pc69.bold("Next steps:")}
66661
+ `${pc70.bold("Next steps:")}
66380
66662
 
66381
- 1. Edit ${pc69.cyan("wraps/wraps.config.ts")} with your org slug and domain
66382
- 2. Edit your workflows in ${pc69.cyan("wraps/workflows/")}
66383
- 3. Validate: ${pc69.cyan("wraps email workflows validate")}
66384
- 4. Push: ${pc69.cyan("wraps email workflows push")}
66663
+ 1. Edit ${pc70.cyan("wraps/wraps.config.ts")} with your org slug and domain
66664
+ 2. Edit your workflows in ${pc70.cyan("wraps/workflows/")}
66665
+ 3. Validate: ${pc70.cyan("wraps email workflows validate")}
66666
+ 4. Push: ${pc70.cyan("wraps email workflows push")}
66385
66667
 
66386
- ${pc69.dim("Docs:")} ${pc69.underline("https://wraps.dev/docs/guides/orchestration")}`
66668
+ ${pc70.dim("Docs:")} ${pc70.underline("https://wraps.dev/docs/guides/orchestration")}`
66387
66669
  );
66388
66670
  }
66389
66671
 
66390
66672
  // src/cli.ts
66391
66673
  init_client();
66674
+
66675
+ // src/telemetry/command-name.ts
66676
+ init_esm_shims();
66677
+
66678
+ // src/utils/shared/did-you-mean.ts
66679
+ init_esm_shims();
66680
+ var TOP_LEVEL_COMMANDS = [
66681
+ "auth",
66682
+ "aws",
66683
+ "cdn",
66684
+ "completion",
66685
+ "console",
66686
+ "destroy",
66687
+ "doctor",
66688
+ "email",
66689
+ "help",
66690
+ "license",
66691
+ "news",
66692
+ "permissions",
66693
+ "platform",
66694
+ "push",
66695
+ "selfhost",
66696
+ "sms",
66697
+ "status",
66698
+ "support",
66699
+ "telemetry",
66700
+ "update",
66701
+ "workflow"
66702
+ ];
66703
+ function distance(a6, b6) {
66704
+ let previous = Array.from({ length: b6.length + 1 }, (_, i6) => i6);
66705
+ for (let i6 = 1; i6 <= a6.length; i6++) {
66706
+ const current = [i6];
66707
+ for (let j6 = 1; j6 <= b6.length; j6++) {
66708
+ const substitution = previous[j6 - 1] + (a6[i6 - 1] === b6[j6 - 1] ? 0 : 1);
66709
+ current[j6] = Math.min(current[j6 - 1] + 1, previous[j6] + 1, substitution);
66710
+ }
66711
+ previous = current;
66712
+ }
66713
+ return previous[b6.length];
66714
+ }
66715
+ var MAX_DISTANCE = 2;
66716
+ function suggestCommand(input, known = TOP_LEVEL_COMMANDS) {
66717
+ const needle = input.toLowerCase();
66718
+ if (needle === "") {
66719
+ return null;
66720
+ }
66721
+ const candidates = known.filter((candidate) => candidate !== needle);
66722
+ let prefixMatch = null;
66723
+ for (const candidate of candidates) {
66724
+ if (candidate.startsWith(needle) && (prefixMatch === null || candidate.length < prefixMatch.length)) {
66725
+ prefixMatch = candidate;
66726
+ }
66727
+ }
66728
+ if (prefixMatch) {
66729
+ return prefixMatch;
66730
+ }
66731
+ let best = null;
66732
+ let bestDistance = Number.POSITIVE_INFINITY;
66733
+ for (const candidate of candidates) {
66734
+ const candidateDistance = distance(needle, candidate);
66735
+ if (candidateDistance < bestDistance) {
66736
+ best = candidate;
66737
+ bestDistance = candidateDistance;
66738
+ }
66739
+ }
66740
+ return bestDistance <= MAX_DISTANCE ? best : null;
66741
+ }
66742
+
66743
+ // src/telemetry/command-name.ts
66744
+ var UNKNOWN = "unknown";
66745
+ var COMMAND_WORD = /^[a-z][a-z0-9-]{0,31}$/;
66746
+ var COMMANDS_WITH_DATA_SECOND_POSITIONAL = ["push"];
66747
+ function telemetryCommandName(primaryCommand2, subCommand2) {
66748
+ if (!(primaryCommand2 && TOP_LEVEL_COMMANDS.includes(primaryCommand2))) {
66749
+ return UNKNOWN;
66750
+ }
66751
+ if (!subCommand2 || COMMANDS_WITH_DATA_SECOND_POSITIONAL.includes(primaryCommand2)) {
66752
+ return primaryCommand2;
66753
+ }
66754
+ return COMMAND_WORD.test(subCommand2) ? `${primaryCommand2}:${subCommand2}` : `${primaryCommand2}:${UNKNOWN}`;
66755
+ }
66756
+
66757
+ // src/cli.ts
66392
66758
  init_events();
66393
66759
 
66394
66760
  // src/utils/shared/arg-parser.ts
@@ -66562,71 +66928,6 @@ function printCompletionScript() {
66562
66928
  console.log("# --preview : Preview changes without deploying\n");
66563
66929
  }
66564
66930
 
66565
- // src/utils/shared/did-you-mean.ts
66566
- init_esm_shims();
66567
- var TOP_LEVEL_COMMANDS = [
66568
- "auth",
66569
- "aws",
66570
- "cdn",
66571
- "completion",
66572
- "console",
66573
- "destroy",
66574
- "doctor",
66575
- "email",
66576
- "help",
66577
- "license",
66578
- "news",
66579
- "permissions",
66580
- "platform",
66581
- "push",
66582
- "selfhost",
66583
- "sms",
66584
- "status",
66585
- "support",
66586
- "telemetry",
66587
- "update",
66588
- "workflow"
66589
- ];
66590
- function distance(a6, b6) {
66591
- let previous = Array.from({ length: b6.length + 1 }, (_, i6) => i6);
66592
- for (let i6 = 1; i6 <= a6.length; i6++) {
66593
- const current = [i6];
66594
- for (let j6 = 1; j6 <= b6.length; j6++) {
66595
- const substitution = previous[j6 - 1] + (a6[i6 - 1] === b6[j6 - 1] ? 0 : 1);
66596
- current[j6] = Math.min(current[j6 - 1] + 1, previous[j6] + 1, substitution);
66597
- }
66598
- previous = current;
66599
- }
66600
- return previous[b6.length];
66601
- }
66602
- var MAX_DISTANCE = 2;
66603
- function suggestCommand(input, known = TOP_LEVEL_COMMANDS) {
66604
- const needle = input.toLowerCase();
66605
- if (needle === "") {
66606
- return null;
66607
- }
66608
- const candidates = known.filter((candidate) => candidate !== needle);
66609
- let prefixMatch = null;
66610
- for (const candidate of candidates) {
66611
- if (candidate.startsWith(needle) && (prefixMatch === null || candidate.length < prefixMatch.length)) {
66612
- prefixMatch = candidate;
66613
- }
66614
- }
66615
- if (prefixMatch) {
66616
- return prefixMatch;
66617
- }
66618
- let best = null;
66619
- let bestDistance = Number.POSITIVE_INFINITY;
66620
- for (const candidate of candidates) {
66621
- const candidateDistance = distance(needle, candidate);
66622
- if (candidateDistance < bestDistance) {
66623
- best = candidate;
66624
- bestDistance = candidateDistance;
66625
- }
66626
- }
66627
- return bestDistance <= MAX_DISTANCE ? best : null;
66628
- }
66629
-
66630
66931
  // src/cli.ts
66631
66932
  init_errors();
66632
66933
  init_json_output();
@@ -66656,238 +66957,241 @@ function showVersion() {
66656
66957
  process.exit(0);
66657
66958
  }
66658
66959
  function showHelp() {
66659
- clack66.intro(pc71.bold(`WRAPS CLI v${VERSION}`));
66960
+ clack66.intro(pc72.bold(`WRAPS CLI v${VERSION}`));
66660
66961
  console.log("Deploy AWS infrastructure to your account\n");
66661
66962
  console.log("Usage: wraps [service] <command> [options]\n");
66662
66963
  console.log("Services:");
66663
- console.log(` ${pc71.cyan("email")} Email infrastructure (AWS SES)`);
66964
+ console.log(` ${pc72.cyan("email")} Email infrastructure (AWS SES)`);
66664
66965
  console.log(
66665
- ` ${pc71.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
66966
+ ` ${pc72.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
66666
66967
  );
66667
66968
  console.log(
66668
- ` ${pc71.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
66969
+ ` ${pc72.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)`
66669
66970
  );
66670
66971
  console.log(
66671
- ` ${pc71.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
66972
+ ` ${pc72.cyan("selfhost")} Self-hosted Wraps control plane (enterprise)`
66672
66973
  );
66673
66974
  console.log(
66674
- ` ${pc71.cyan("license")} License key management (Wraps team only)
66975
+ ` ${pc72.cyan("license")} License key management (Wraps team only)
66675
66976
  `
66676
66977
  );
66677
66978
  console.log("Email Commands:");
66678
66979
  console.log(
66679
- ` ${pc71.cyan("email init")} Deploy new email infrastructure`
66980
+ ` ${pc72.cyan("email init")} Deploy new email infrastructure`
66680
66981
  );
66681
66982
  console.log(
66682
- ` ${pc71.cyan("email check")} Check email deliverability for a domain`
66983
+ ` ${pc72.cyan("email check")} Check email deliverability for a domain`
66683
66984
  );
66684
66985
  console.log(
66685
- ` ${pc71.cyan("email connect")} Connect to existing AWS SES`
66986
+ ` ${pc72.cyan("email connect")} Connect to existing AWS SES`
66686
66987
  );
66687
66988
  console.log(
66688
- ` ${pc71.cyan("email status")} Show email infrastructure details`
66989
+ ` ${pc72.cyan("email status")} Show email infrastructure details`
66689
66990
  );
66690
66991
  console.log(
66691
- ` ${pc71.cyan("email plan")} Show SES pricing plan and cheaper options`
66992
+ ` ${pc72.cyan("email plan")} Show SES pricing plan and cheaper options`
66692
66993
  );
66693
- console.log(` ${pc71.cyan("email test")} Send a test email`);
66694
- console.log(` ${pc71.cyan("email verify")} Verify domain DNS records`);
66994
+ console.log(` ${pc72.cyan("email test")} Send a test email`);
66995
+ console.log(` ${pc72.cyan("email verify")} Verify domain DNS records`);
66695
66996
  console.log(
66696
- ` ${pc71.cyan("email sync")} Apply CLI updates to infrastructure`
66997
+ ` ${pc72.cyan("email sync")} Apply CLI updates to infrastructure`
66697
66998
  );
66698
- console.log(` ${pc71.cyan("email upgrade")} Add features`);
66999
+ console.log(` ${pc72.cyan("email upgrade")} Add features`);
66699
67000
  console.log(
66700
- ` ${pc71.cyan("email restore")} Restore original configuration`
67001
+ ` ${pc72.cyan("email restore")} Restore original configuration`
66701
67002
  );
66702
67003
  console.log(
66703
- ` ${pc71.cyan("email destroy")} Remove email infrastructure`
67004
+ ` ${pc72.cyan("email destroy")} Remove email infrastructure`
66704
67005
  );
66705
67006
  console.log(
66706
- ` ${pc71.cyan("email doctor")} Diagnose and clean up email infrastructure`
67007
+ ` ${pc72.cyan("email doctor")} Diagnose and clean up email infrastructure`
66707
67008
  );
66708
- console.log(` ${pc71.cyan("email domains add")} Add a domain to SES`);
66709
- console.log(` ${pc71.cyan("email domains list")} List all domains`);
66710
- console.log(` ${pc71.cyan("email domains remove")} Remove a domain`);
67009
+ console.log(` ${pc72.cyan("email domains add")} Add a domain to SES`);
67010
+ console.log(` ${pc72.cyan("email domains list")} List all domains`);
67011
+ console.log(` ${pc72.cyan("email domains remove")} Remove a domain`);
66711
67012
  console.log(
66712
- ` ${pc71.cyan("email inbound init")} Enable inbound email receiving`
67013
+ ` ${pc72.cyan("email inbound init")} Enable inbound email receiving`
66713
67014
  );
66714
- console.log(` ${pc71.cyan("email inbound status")} Show inbound email status`);
67015
+ console.log(` ${pc72.cyan("email inbound status")} Show inbound email status`);
66715
67016
  console.log(
66716
- ` ${pc71.cyan("email inbound verify")} Verify inbound DNS records`
67017
+ ` ${pc72.cyan("email inbound verify")} Verify inbound DNS records`
66717
67018
  );
66718
67019
  console.log(
66719
- ` ${pc71.cyan("email inbound test")} Send test email and verify receipt`
67020
+ ` ${pc72.cyan("email inbound test")} Send test email and verify receipt`
66720
67021
  );
66721
67022
  console.log(
66722
- ` ${pc71.cyan("email inbound destroy")} Remove inbound email infrastructure
67023
+ ` ${pc72.cyan("email inbound destroy")} Remove inbound email infrastructure
66723
67024
  `
66724
67025
  );
66725
67026
  console.log("Agent Commands:");
66726
67027
  console.log(
66727
- ` ${pc71.cyan("email agent create")} Create a leashed agent mailbox`
67028
+ ` ${pc72.cyan("email agent create")} Create a leashed agent mailbox`
66728
67029
  );
66729
- console.log(` ${pc71.cyan("email agent list")} List agents`);
67030
+ console.log(` ${pc72.cyan("email agent list")} List agents`);
66730
67031
  console.log(
66731
- ` ${pc71.cyan("email agent kill")} Kill an agent (revoke sending)
67032
+ ` ${pc72.cyan("email agent kill")} Kill an agent (revoke sending)
66732
67033
  `
66733
67034
  );
66734
67035
  console.log("Template Commands:");
66735
67036
  console.log(
66736
- ` ${pc71.cyan("email templates init")} Initialize templates-as-code`
67037
+ ` ${pc72.cyan("email templates init")} Initialize templates-as-code`
66737
67038
  );
66738
67039
  console.log(
66739
- ` ${pc71.cyan("email templates push")} Push templates to SES + dashboard`
67040
+ ` ${pc72.cyan("email templates push")} Push templates to SES + dashboard`
66740
67041
  );
66741
67042
  console.log(
66742
- ` ${pc71.cyan("email templates preview")} Preview templates in browser`
67043
+ ` ${pc72.cyan("email templates preview")} Preview templates in browser`
66743
67044
  );
66744
67045
  console.log(
66745
- ` ${pc71.cyan("push")} ${pc71.dim("(alias for email templates push)")}
67046
+ ` ${pc72.cyan("push")} ${pc72.dim("(alias for email templates push)")}
66746
67047
  `
66747
67048
  );
66748
67049
  console.log("Workflow Commands:");
66749
67050
  console.log(
66750
- ` ${pc71.cyan("email workflows init")} Initialize workflows-as-code`
67051
+ ` ${pc72.cyan("email workflows init")} Initialize workflows-as-code`
66751
67052
  );
66752
67053
  console.log(
66753
- ` ${pc71.cyan("email workflows validate")} Validate workflow files`
67054
+ ` ${pc72.cyan("email workflows validate")} Validate workflow files`
66754
67055
  );
66755
67056
  console.log(
66756
- ` ${pc71.cyan("email workflows push")} Push workflows to dashboard
67057
+ ` ${pc72.cyan("email workflows push")} Push workflows to dashboard
66757
67058
  `
66758
67059
  );
66759
67060
  console.log("SMS Commands:");
66760
- console.log(` ${pc71.cyan("sms init")} Deploy SMS infrastructure`);
67061
+ console.log(` ${pc72.cyan("sms init")} Deploy SMS infrastructure`);
66761
67062
  console.log(
66762
- ` ${pc71.cyan("sms status")} Show SMS infrastructure details`
67063
+ ` ${pc72.cyan("sms status")} Show SMS infrastructure details`
66763
67064
  );
66764
- console.log(` ${pc71.cyan("sms test")} Send a test SMS message`);
67065
+ console.log(` ${pc72.cyan("sms test")} Send a test SMS message`);
66765
67066
  console.log(
66766
- ` ${pc71.cyan("sms verify-number")} Verify a destination phone number`
67067
+ ` ${pc72.cyan("sms verify-number")} Verify a destination phone number`
66767
67068
  );
66768
67069
  console.log(
66769
- ` ${pc71.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
67070
+ ` ${pc72.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
66770
67071
  );
66771
- console.log(` ${pc71.cyan("sms upgrade")} Upgrade SMS features`);
66772
- console.log(` ${pc71.cyan("sms register")} Register toll-free number`);
67072
+ console.log(` ${pc72.cyan("sms upgrade")} Upgrade SMS features`);
67073
+ console.log(` ${pc72.cyan("sms register")} Register toll-free number`);
66773
67074
  console.log(
66774
- ` ${pc71.cyan("sms destroy")} Remove SMS infrastructure
67075
+ ` ${pc72.cyan("sms destroy")} Remove SMS infrastructure
66775
67076
  `
66776
67077
  );
66777
67078
  console.log("CDN Commands:");
66778
67079
  console.log(
66779
- ` ${pc71.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
67080
+ ` ${pc72.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
66780
67081
  );
66781
67082
  console.log(
66782
- ` ${pc71.cyan("cdn status")} Show CDN infrastructure details`
67083
+ ` ${pc72.cyan("cdn status")} Show CDN infrastructure details`
66783
67084
  );
66784
67085
  console.log(
66785
- ` ${pc71.cyan("cdn verify")} Check DNS and certificate status`
67086
+ ` ${pc72.cyan("cdn verify")} Check DNS and certificate status`
66786
67087
  );
66787
67088
  console.log(
66788
- ` ${pc71.cyan("cdn upgrade")} Add custom domain after cert validation`
67089
+ ` ${pc72.cyan("cdn upgrade")} Add custom domain after cert validation`
66789
67090
  );
66790
67091
  console.log(
66791
- ` ${pc71.cyan("cdn sync")} Sync infrastructure with current config`
67092
+ ` ${pc72.cyan("cdn sync")} Sync infrastructure with current config`
66792
67093
  );
66793
67094
  console.log(
66794
- ` ${pc71.cyan("cdn destroy")} Remove CDN infrastructure
67095
+ ` ${pc72.cyan("cdn destroy")} Remove CDN infrastructure
66795
67096
  `
66796
67097
  );
66797
67098
  console.log("Self-Hosted Commands:");
66798
67099
  console.log(
66799
- ` ${pc71.cyan("selfhost login")} Sign in to your self-hosted Wraps instance`
67100
+ ` ${pc72.cyan("selfhost login")} Sign in to your self-hosted Wraps instance`
66800
67101
  );
66801
67102
  console.log(
66802
- ` ${pc71.cyan("selfhost logout")} Sign out of your self-hosted Wraps instance`
67103
+ ` ${pc72.cyan("selfhost logout")} Sign out of your self-hosted Wraps instance`
66803
67104
  );
66804
67105
  console.log(
66805
- ` ${pc71.cyan("selfhost status")} Show self-hosted deployment details`
67106
+ ` ${pc72.cyan("selfhost status")} Show self-hosted deployment details`
66806
67107
  );
66807
67108
  console.log(
66808
- ` ${pc71.cyan("selfhost logs")} Stream logs from your self-hosted API, dashboard, and workers`
67109
+ ` ${pc72.cyan("selfhost logs")} Stream logs from your self-hosted API, dashboard, and workers`
66809
67110
  );
66810
67111
  console.log(
66811
- ` ${pc71.cyan("selfhost env")} Print env vars for hosting the dashboard yourself`
67112
+ ` ${pc72.cyan("selfhost env")} Print env vars for hosting the dashboard yourself`
66812
67113
  );
66813
67114
  console.log(
66814
- ` ${pc71.cyan("selfhost connect")} Connect your AWS account to your self-hosted instance`
67115
+ ` ${pc72.cyan("selfhost connect")} Connect your AWS account to your self-hosted instance`
66815
67116
  );
66816
67117
  console.log(
66817
- ` ${pc71.cyan("selfhost update-role")} Refresh your self-hosted console role's permissions
67118
+ ` ${pc72.cyan("selfhost update-role")} Refresh your self-hosted console role's permissions
66818
67119
  `
66819
67120
  );
66820
67121
  console.log("Local Development:");
66821
67122
  console.log(
66822
- ` ${pc71.cyan("console")} Start local web console
67123
+ ` ${pc72.cyan("console")} Start local web console
66823
67124
  `
66824
67125
  );
66825
67126
  console.log("Platform:");
66826
67127
  console.log(
66827
- ` ${pc71.cyan("platform")} Show platform info and pricing`
67128
+ ` ${pc72.cyan("platform")} Show platform info and pricing`
67129
+ );
67130
+ console.log(
67131
+ ` ${pc72.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
66828
67132
  );
66829
67133
  console.log(
66830
- ` ${pc71.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
67134
+ ` ${pc72.cyan("platform disconnect")} Stop streaming events to Wraps Platform`
66831
67135
  );
66832
67136
  console.log(
66833
- ` ${pc71.cyan("platform update-role")} Update platform IAM permissions
67137
+ ` ${pc72.cyan("platform update-role")} Update platform IAM permissions
66834
67138
  `
66835
67139
  );
66836
67140
  console.log("Auth:");
66837
67141
  console.log(
66838
- ` ${pc71.cyan("auth login")} Sign in to wraps.dev (device flow)`
67142
+ ` ${pc72.cyan("auth login")} Sign in to wraps.dev (device flow)`
66839
67143
  );
66840
- console.log(` ${pc71.cyan("auth status")} Show current auth state`);
67144
+ console.log(` ${pc72.cyan("auth status")} Show current auth state`);
66841
67145
  console.log(
66842
- ` ${pc71.cyan("auth logout")} Sign out and remove stored token
67146
+ ` ${pc72.cyan("auth logout")} Sign out and remove stored token
66843
67147
  `
66844
67148
  );
66845
67149
  console.log("AWS Setup:");
66846
67150
  console.log(
66847
- ` ${pc71.cyan("aws setup")} Interactive AWS setup wizard`
67151
+ ` ${pc72.cyan("aws setup")} Interactive AWS setup wizard`
66848
67152
  );
66849
67153
  console.log(
66850
- ` ${pc71.cyan("aws doctor")} Diagnose AWS configuration issues
67154
+ ` ${pc72.cyan("aws doctor")} Diagnose AWS configuration issues
66851
67155
  `
66852
67156
  );
66853
67157
  console.log("Global Commands:");
66854
- console.log(` ${pc71.cyan("status")} Show overview of all services`);
67158
+ console.log(` ${pc72.cyan("status")} Show overview of all services`);
66855
67159
  console.log(
66856
- ` ${pc71.cyan("doctor")} Diagnose AWS + email infrastructure`
67160
+ ` ${pc72.cyan("doctor")} Diagnose AWS + email infrastructure`
66857
67161
  );
66858
- console.log(` ${pc71.cyan("destroy")} Remove deployed infrastructure`);
66859
- console.log(` ${pc71.cyan("permissions")} Show required AWS IAM permissions`);
66860
- console.log(` ${pc71.cyan("completion")} Generate shell completion script`);
67162
+ console.log(` ${pc72.cyan("destroy")} Remove deployed infrastructure`);
67163
+ console.log(` ${pc72.cyan("permissions")} Show required AWS IAM permissions`);
67164
+ console.log(` ${pc72.cyan("completion")} Generate shell completion script`);
66861
67165
  console.log(
66862
- ` ${pc71.cyan("telemetry")} Manage anonymous telemetry settings`
67166
+ ` ${pc72.cyan("telemetry")} Manage anonymous telemetry settings`
66863
67167
  );
66864
- console.log(` ${pc71.cyan("update")} Update CLI to latest version`);
66865
- console.log(` ${pc71.cyan("news")} Show recent Wraps updates`);
67168
+ console.log(` ${pc72.cyan("update")} Update CLI to latest version`);
67169
+ console.log(` ${pc72.cyan("news")} Show recent Wraps updates`);
66866
67170
  console.log(
66867
- ` ${pc71.cyan("support")} Get help and support contact info
67171
+ ` ${pc72.cyan("support")} Get help and support contact info
66868
67172
  `
66869
67173
  );
66870
67174
  console.log("Options:");
66871
67175
  console.log(
66872
- ` ${pc71.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
67176
+ ` ${pc72.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
66873
67177
  );
66874
- console.log(` ${pc71.dim("-r, --region")} AWS region`);
66875
- console.log(` ${pc71.dim("-d, --domain")} Domain name`);
66876
- console.log(` ${pc71.dim("--account")} AWS account ID or alias`);
66877
- console.log(` ${pc71.dim("--preset")} Configuration preset`);
66878
- console.log(` ${pc71.dim("--token")} API key or token for auth`);
66879
- console.log(` ${pc71.dim("-y, --yes")} Skip confirmation prompts`);
66880
- console.log(` ${pc71.dim("-f, --force")} Force destructive operations`);
67178
+ console.log(` ${pc72.dim("-r, --region")} AWS region`);
67179
+ console.log(` ${pc72.dim("-d, --domain")} Domain name`);
67180
+ console.log(` ${pc72.dim("--account")} AWS account ID or alias`);
67181
+ console.log(` ${pc72.dim("--preset")} Configuration preset`);
67182
+ console.log(` ${pc72.dim("--token")} API key or token for auth`);
67183
+ console.log(` ${pc72.dim("-y, --yes")} Skip confirmation prompts`);
67184
+ console.log(` ${pc72.dim("-f, --force")} Force destructive operations`);
66881
67185
  console.log(
66882
- ` ${pc71.dim("--preview")} Preview changes without deploying`
67186
+ ` ${pc72.dim("--preview")} Preview changes without deploying`
66883
67187
  );
66884
- console.log(` ${pc71.dim("-v, --version")} Show version number
67188
+ console.log(` ${pc72.dim("-v, --version")} Show version number
66885
67189
  `);
66886
67190
  console.log(
66887
- `Run ${pc71.cyan("wraps <service> <command> --help")} for more information.`
67191
+ `Run ${pc72.cyan("wraps <service> <command> --help")} for more information.`
66888
67192
  );
66889
67193
  console.log(
66890
- `AI agents: complete docs at ${pc71.cyan("https://wraps.dev/llms-full.txt")}
67194
+ `AI agents: complete docs at ${pc72.cyan("https://wraps.dev/llms-full.txt")}
66891
67195
  `
66892
67196
  );
66893
67197
  }
@@ -66909,25 +67213,25 @@ if (!primaryCommand) {
66909
67213
  const telemetry = getTelemetryClient();
66910
67214
  if (!isJsonMode() && telemetry.shouldShowNotification()) {
66911
67215
  console.log();
66912
- clack66.log.info(pc71.bold("Anonymous Telemetry"));
67216
+ clack66.log.info(pc72.bold("Anonymous Telemetry"));
66913
67217
  console.log(
66914
- ` Wraps collects ${pc71.cyan("anonymous usage data")} to improve the CLI.`
67218
+ ` Wraps collects ${pc72.cyan("anonymous usage data")} to improve the CLI.`
66915
67219
  );
66916
67220
  console.log(
66917
- ` We ${pc71.bold("never")} collect: domains, AWS credentials, email content, or PII.`
67221
+ ` We ${pc72.bold("never")} collect: domains, AWS credentials, email content, or PII.`
66918
67222
  );
66919
67223
  console.log(
66920
- ` We ${pc71.bold("only")} collect: command names, success/failure, CLI version, OS.`
67224
+ ` We ${pc72.bold("only")} collect: command names, success/failure, CLI version, OS.`
66921
67225
  );
66922
67226
  console.log();
66923
- console.log(` Opt-out anytime: ${pc71.cyan("wraps telemetry disable")}`);
66924
- console.log(` Or set: ${pc71.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
66925
- console.log(` Learn more: ${pc71.cyan("https://wraps.dev/docs")}`);
67227
+ console.log(` Opt-out anytime: ${pc72.cyan("wraps telemetry disable")}`);
67228
+ console.log(` Or set: ${pc72.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
67229
+ console.log(` Learn more: ${pc72.cyan("https://wraps.dev/docs")}`);
66926
67230
  console.log();
66927
67231
  telemetry.markNotificationShown();
66928
67232
  }
66929
67233
  trackCommand("interactive:menu", { success: true, duration_ms: 0 });
66930
- clack66.intro(pc71.bold(`WRAPS CLI v${VERSION}`));
67234
+ clack66.intro(pc72.bold(`WRAPS CLI v${VERSION}`));
66931
67235
  console.log(" Deploy AWS infrastructure to your account.\n");
66932
67236
  const action = await clack66.select({
66933
67237
  message: "What would you like to do?",
@@ -67055,8 +67359,9 @@ if (!primaryCommand) {
67055
67359
  await telemetry.shutdown();
67056
67360
  }
67057
67361
  }
67058
- interactiveMenu().then(() => process.exit(0)).catch((err) => {
67362
+ interactiveMenu().then(() => process.exit(0)).catch(async (err) => {
67059
67363
  handleCLIError(err);
67364
+ await getTelemetryClient().shutdown();
67060
67365
  process.exit(1);
67061
67366
  });
67062
67367
  }
@@ -67065,20 +67370,20 @@ async function run() {
67065
67370
  const telemetry = getTelemetryClient();
67066
67371
  if (!isJsonMode() && telemetry.shouldShowNotification()) {
67067
67372
  console.log();
67068
- clack66.log.info(pc71.bold("Anonymous Telemetry"));
67373
+ clack66.log.info(pc72.bold("Anonymous Telemetry"));
67069
67374
  console.log(
67070
- ` Wraps collects ${pc71.cyan("anonymous usage data")} to improve the CLI.`
67375
+ ` Wraps collects ${pc72.cyan("anonymous usage data")} to improve the CLI.`
67071
67376
  );
67072
67377
  console.log(
67073
- ` We ${pc71.bold("never")} collect: domains, AWS credentials, email content, or PII.`
67378
+ ` We ${pc72.bold("never")} collect: domains, AWS credentials, email content, or PII.`
67074
67379
  );
67075
67380
  console.log(
67076
- ` We ${pc71.bold("only")} collect: command names, success/failure, CLI version, OS.`
67381
+ ` We ${pc72.bold("only")} collect: command names, success/failure, CLI version, OS.`
67077
67382
  );
67078
67383
  console.log();
67079
- console.log(` Opt-out anytime: ${pc71.cyan("wraps telemetry disable")}`);
67080
- console.log(` Or set: ${pc71.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
67081
- console.log(` Learn more: ${pc71.cyan("https://wraps.dev/docs")}`);
67384
+ console.log(` Opt-out anytime: ${pc72.cyan("wraps telemetry disable")}`);
67385
+ console.log(` Or set: ${pc72.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
67386
+ console.log(` Learn more: ${pc72.cyan("https://wraps.dev/docs")}`);
67082
67387
  console.log();
67083
67388
  telemetry.markNotificationShown();
67084
67389
  }
@@ -67173,13 +67478,10 @@ async function run() {
67173
67478
  break;
67174
67479
  case "verify": {
67175
67480
  if (!flags.domain) {
67176
- clack66.log.error("--domain flag is required");
67177
- console.log(
67178
- `
67179
- Usage: ${pc71.cyan("wraps email verify --domain yourapp.com")}
67180
- `
67481
+ throw errors.missingInput(
67482
+ "--domain",
67483
+ "wraps email verify --domain yourapp.com"
67181
67484
  );
67182
- throw new Error("Missing required flag: --domain");
67183
67485
  }
67184
67486
  await verifyDomain({
67185
67487
  domain: flags.domain,
@@ -67248,16 +67550,10 @@ Usage: ${pc71.cyan("wraps email verify --domain yourapp.com")}
67248
67550
  });
67249
67551
  break;
67250
67552
  default:
67251
- clack66.log.error(
67252
- `Unknown inbound command: ${inboundSubCommand || "(none)"}`
67253
- );
67254
- console.log(
67255
- `
67256
- Available commands: ${pc71.cyan("init")}, ${pc71.cyan("destroy")}, ${pc71.cyan("status")}, ${pc71.cyan("verify")}, ${pc71.cyan("test")}, ${pc71.cyan("add")}, ${pc71.cyan("remove")}
67257
- `
67258
- );
67259
- throw new Error(
67260
- `Unknown inbound command: ${inboundSubCommand || "(none)"}`
67553
+ throw errors.unknownCommand(
67554
+ "inbound command",
67555
+ inboundSubCommand,
67556
+ "Available commands: init, destroy, status, verify, test, add, remove"
67261
67557
  );
67262
67558
  }
67263
67559
  break;
@@ -67290,16 +67586,10 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("destroy")}, ${pc71.cyan("
67290
67586
  });
67291
67587
  break;
67292
67588
  default:
67293
- clack66.log.error(
67294
- `Unknown agent command: ${agentSubCommand || "(none)"}`
67295
- );
67296
- console.log(
67297
- `
67298
- Available commands: ${pc71.cyan("create")}, ${pc71.cyan("list")}, ${pc71.cyan("kill")}
67299
- `
67300
- );
67301
- throw new Error(
67302
- `Unknown agent command: ${agentSubCommand || "(none)"}`
67589
+ throw errors.unknownCommand(
67590
+ "agent command",
67591
+ agentSubCommand,
67592
+ "Available commands: create, list, kill"
67303
67593
  );
67304
67594
  }
67305
67595
  break;
@@ -67347,16 +67637,10 @@ Available commands: ${pc71.cyan("create")}, ${pc71.cyan("list")}, ${pc71.cyan("k
67347
67637
  break;
67348
67638
  }
67349
67639
  default:
67350
- clack66.log.error(
67351
- `Unknown reply command: ${replySubCommand || "(none)"}`
67352
- );
67353
- console.log(
67354
- `
67355
- Available commands: ${pc71.cyan("init")}, ${pc71.cyan("rotate")}, ${pc71.cyan("status")}, ${pc71.cyan("destroy")}, ${pc71.cyan("decode")}
67356
- `
67357
- );
67358
- throw new Error(
67359
- `Unknown reply command: ${replySubCommand || "(none)"}`
67640
+ throw errors.unknownCommand(
67641
+ "reply command",
67642
+ replySubCommand,
67643
+ "Available commands: init, rotate, status, destroy, decode"
67360
67644
  );
67361
67645
  }
67362
67646
  break;
@@ -67377,39 +67661,30 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("rotate")}, ${pc71.cyan("s
67377
67661
  break;
67378
67662
  case "verify": {
67379
67663
  if (!flags.domain) {
67380
- clack66.log.error("--domain flag is required");
67381
- console.log(
67382
- `
67383
- Usage: ${pc71.cyan("wraps email domains verify --domain yourapp.com")}
67384
- `
67664
+ throw errors.missingInput(
67665
+ "--domain",
67666
+ "wraps email domains verify --domain yourapp.com"
67385
67667
  );
67386
- throw new Error("Missing required flag: --domain");
67387
67668
  }
67388
67669
  await verifyDomain({ domain: flags.domain });
67389
67670
  break;
67390
67671
  }
67391
67672
  case "get-dkim": {
67392
67673
  if (!flags.domain) {
67393
- clack66.log.error("--domain flag is required");
67394
- console.log(
67395
- `
67396
- Usage: ${pc71.cyan("wraps email domains get-dkim --domain yourapp.com")}
67397
- `
67674
+ throw errors.missingInput(
67675
+ "--domain",
67676
+ "wraps email domains get-dkim --domain yourapp.com"
67398
67677
  );
67399
- throw new Error("Missing required flag: --domain");
67400
67678
  }
67401
67679
  await getDkim({ domain: flags.domain });
67402
67680
  break;
67403
67681
  }
67404
67682
  case "remove": {
67405
67683
  if (!flags.domain) {
67406
- clack66.log.error("--domain flag is required");
67407
- console.log(
67408
- `
67409
- Usage: ${pc71.cyan("wraps email domains remove --domain yourapp.com --force")}
67410
- `
67684
+ throw errors.missingInput(
67685
+ "--domain",
67686
+ "wraps email domains remove --domain yourapp.com --force"
67411
67687
  );
67412
- throw new Error("Missing required flag: --domain");
67413
67688
  }
67414
67689
  await removeDomain({
67415
67690
  domain: flags.domain,
@@ -67436,16 +67711,10 @@ Usage: ${pc71.cyan("wraps email domains remove --domain yourapp.com --force")}
67436
67711
  break;
67437
67712
  }
67438
67713
  default:
67439
- clack66.log.error(
67440
- `Unknown domains command: ${domainsSubCommand || "(none)"}`
67441
- );
67442
- console.log(
67443
- `
67444
- Available commands: ${pc71.cyan("add")}, ${pc71.cyan("list")}, ${pc71.cyan("verify")}, ${pc71.cyan("get-dkim")}, ${pc71.cyan("remove")}, ${pc71.cyan("config")}
67445
- `
67446
- );
67447
- throw new Error(
67448
- `Unknown domains command: ${domainsSubCommand || "(none)"}`
67714
+ throw errors.unknownCommand(
67715
+ "domains command",
67716
+ domainsSubCommand,
67717
+ "Available commands: add, list, verify, get-dkim, remove, config"
67449
67718
  );
67450
67719
  }
67451
67720
  break;
@@ -67483,16 +67752,10 @@ Available commands: ${pc71.cyan("add")}, ${pc71.cyan("list")}, ${pc71.cyan("veri
67483
67752
  });
67484
67753
  break;
67485
67754
  default:
67486
- clack66.log.error(
67487
- `Unknown templates command: ${templatesSubCommand || "(none)"}`
67488
- );
67489
- console.log(
67490
- `
67491
- Available commands: ${pc71.cyan("init")}, ${pc71.cyan("push")}, ${pc71.cyan("preview")}
67492
- `
67493
- );
67494
- throw new Error(
67495
- `Unknown templates command: ${templatesSubCommand || "(none)"}`
67755
+ throw errors.unknownCommand(
67756
+ "templates command",
67757
+ templatesSubCommand,
67758
+ "Available commands: init, push, preview"
67496
67759
  );
67497
67760
  }
67498
67761
  break;
@@ -67527,16 +67790,10 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("push")}, ${pc71.cyan("pre
67527
67790
  });
67528
67791
  break;
67529
67792
  default:
67530
- clack66.log.error(
67531
- `Unknown workflows command: ${workflowsSubCommand || "(none)"}`
67532
- );
67533
- console.log(
67534
- `
67535
- Available commands: ${pc71.cyan("init")}, ${pc71.cyan("validate")}, ${pc71.cyan("push")}
67536
- `
67537
- );
67538
- throw new Error(
67539
- `Unknown workflows command: ${workflowsSubCommand || "(none)"}`
67793
+ throw errors.unknownCommand(
67794
+ "workflows command",
67795
+ workflowsSubCommand,
67796
+ "Available commands: init, validate, push"
67540
67797
  );
67541
67798
  }
67542
67799
  break;
@@ -67557,8 +67814,10 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("validate")}, ${pc71.cyan(
67557
67814
  case "get": {
67558
67815
  const messageId = sub[3];
67559
67816
  if (!messageId) {
67560
- clack66.log.error("Usage: wraps email logs get <message-id>");
67561
- throw new Error("Missing required argument: <message-id>");
67817
+ throw errors.missingInput(
67818
+ "<message-id>",
67819
+ "wraps email logs get <message-id>"
67820
+ );
67562
67821
  }
67563
67822
  await emailLogsGet({
67564
67823
  messageId,
@@ -67569,16 +67828,10 @@ Available commands: ${pc71.cyan("init")}, ${pc71.cyan("validate")}, ${pc71.cyan(
67569
67828
  break;
67570
67829
  }
67571
67830
  default:
67572
- clack66.log.error(
67573
- `Unknown logs command: ${logsSubCommand || "(none)"}`
67574
- );
67575
- console.log(
67576
- `
67577
- Available commands: ${pc71.cyan("list")}, ${pc71.cyan("get <message-id>")}
67578
- `
67579
- );
67580
- throw new Error(
67581
- `Unknown logs command: ${logsSubCommand || "(none)"}`
67831
+ throw errors.unknownCommand(
67832
+ "logs command",
67833
+ logsSubCommand,
67834
+ "Available commands: list, get <message-id>"
67582
67835
  );
67583
67836
  }
67584
67837
  break;
@@ -67599,13 +67852,11 @@ Available commands: ${pc71.cyan("list")}, ${pc71.cyan("get <message-id>")}
67599
67852
  });
67600
67853
  break;
67601
67854
  default:
67602
- clack66.log.error(`Unknown email command: ${subCommand}`);
67603
- console.log(
67604
- `
67605
- Run ${pc71.cyan("wraps --help")} for available commands.
67606
- `
67855
+ throw errors.unknownCommand(
67856
+ "email command",
67857
+ subCommand,
67858
+ "Run wraps --help for available commands."
67607
67859
  );
67608
- throw new Error(`Unknown email command: ${subCommand}`);
67609
67860
  }
67610
67861
  const emailDuration = Date.now() - startTime;
67611
67862
  const emailCommandName = `email:${subCommand}`;
@@ -67627,13 +67878,11 @@ Run ${pc71.cyan("wraps --help")} for available commands.
67627
67878
  });
67628
67879
  break;
67629
67880
  default:
67630
- clack66.log.error(`Unknown license command: ${subCommand}`);
67631
- console.log(
67632
- `
67633
- Run ${pc71.cyan("wraps --help")} for available commands.
67634
- `
67881
+ throw errors.unknownCommand(
67882
+ "license command",
67883
+ subCommand,
67884
+ "Run wraps --help for available commands."
67635
67885
  );
67636
- throw new Error(`Unknown license command: ${subCommand}`);
67637
67886
  }
67638
67887
  trackCommand(`license:${subCommand}`, {
67639
67888
  success: true,
@@ -67701,13 +67950,11 @@ Run ${pc71.cyan("wraps --help")} for available commands.
67701
67950
  });
67702
67951
  break;
67703
67952
  default:
67704
- clack66.log.error(`Unknown selfhost command: ${subCommand}`);
67705
- console.log(
67706
- `
67707
- Run ${pc71.cyan("wraps --help")} for available commands.
67708
- `
67953
+ throw errors.unknownCommand(
67954
+ "selfhost command",
67955
+ subCommand,
67956
+ "Run wraps --help for available commands."
67709
67957
  );
67710
- throw new Error(`Unknown selfhost command: ${subCommand}`);
67711
67958
  }
67712
67959
  const selfhostDuration = Date.now() - startTime;
67713
67960
  const selfhostCommandName = `selfhost:${subCommand}`;
@@ -67787,13 +68034,11 @@ Run ${pc71.cyan("wraps --help")} for available commands.
67787
68034
  });
67788
68035
  break;
67789
68036
  default:
67790
- clack66.log.error(`Unknown sms command: ${subCommand}`);
67791
- console.log(
67792
- `
67793
- Run ${pc71.cyan("wraps --help")} for available commands.
67794
- `
68037
+ throw errors.unknownCommand(
68038
+ "sms command",
68039
+ subCommand,
68040
+ "Run wraps --help for available commands."
67795
68041
  );
67796
- throw new Error(`Unknown sms command: ${subCommand}`);
67797
68042
  }
67798
68043
  const smsDuration = Date.now() - startTime;
67799
68044
  const smsCommandName = `sms:${subCommand}`;
@@ -67851,13 +68096,11 @@ Run ${pc71.cyan("wraps --help")} for available commands.
67851
68096
  });
67852
68097
  break;
67853
68098
  default:
67854
- clack66.log.error(`Unknown cdn command: ${subCommand}`);
67855
- console.log(
67856
- `
67857
- Run ${pc71.cyan("wraps --help")} for available commands.
67858
- `
68099
+ throw errors.unknownCommand(
68100
+ "cdn command",
68101
+ subCommand,
68102
+ "Run wraps --help for available commands."
67859
68103
  );
67860
- throw new Error(`Unknown cdn command: ${subCommand}`);
67861
68104
  }
67862
68105
  const cdnDuration = Date.now() - startTime;
67863
68106
  const cdnCommandName = `cdn:${subCommand}`;
@@ -67876,16 +68119,10 @@ Run ${pc71.cyan("wraps --help")} for available commands.
67876
68119
  });
67877
68120
  break;
67878
68121
  default:
67879
- clack66.log.error(
67880
- `Unknown workflow command: ${subCommand || "(none)"}`
67881
- );
67882
- console.log(`
67883
- Available commands: ${pc71.cyan("init")}
67884
- `);
67885
- console.log(`Run ${pc71.cyan("wraps --help")} for more information.
67886
- `);
67887
- throw new Error(
67888
- `Unknown workflow command: ${subCommand || "(none)"}`
68122
+ throw errors.unknownCommand(
68123
+ "workflow command",
68124
+ subCommand,
68125
+ "Available commands: init\n\nRun wraps --help for more information."
67889
68126
  );
67890
68127
  }
67891
68128
  const workflowDuration = Date.now() - startTime;
@@ -67916,6 +68153,14 @@ Available commands: ${pc71.cyan("init")}
67916
68153
  json: flags.json
67917
68154
  });
67918
68155
  break;
68156
+ case "disconnect":
68157
+ await disconnect({
68158
+ region: flags.region,
68159
+ force: flags.force,
68160
+ yes: flags.yes,
68161
+ json: flags.json
68162
+ });
68163
+ break;
67919
68164
  case "update-role":
67920
68165
  await updateRole({
67921
68166
  region: flags.region,
@@ -67924,17 +68169,11 @@ Available commands: ${pc71.cyan("init")}
67924
68169
  });
67925
68170
  break;
67926
68171
  default:
67927
- clack66.log.error(`Unknown platform command: ${subCommand}`);
67928
- console.log(
67929
- `
67930
- Available commands: ${pc71.cyan("connect")}, ${pc71.cyan("update-role")}
67931
- `
68172
+ throw errors.unknownCommand(
68173
+ "platform command",
68174
+ subCommand,
68175
+ "Available commands: connect, disconnect, update-role\n\nRun wraps platform for more information."
67932
68176
  );
67933
- console.log(
67934
- `Run ${pc71.cyan("wraps platform")} for more information.
67935
- `
67936
- );
67937
- throw new Error(`Unknown platform command: ${subCommand}`);
67938
68177
  }
67939
68178
  const platformDuration = Date.now() - startTime;
67940
68179
  const platformCommandName = `platform:${subCommand}`;
@@ -67956,13 +68195,11 @@ Available commands: ${pc71.cyan("connect")}, ${pc71.cyan("update-role")}
67956
68195
  await logout();
67957
68196
  break;
67958
68197
  default:
67959
- clack66.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
67960
- console.log(
67961
- `
67962
- Available commands: ${pc71.cyan("login")}, ${pc71.cyan("status")}, ${pc71.cyan("logout")}
67963
- `
68198
+ throw errors.unknownCommand(
68199
+ "auth command",
68200
+ subCommand,
68201
+ "Available commands: login, status, logout"
67964
68202
  );
67965
- throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
67966
68203
  }
67967
68204
  return;
67968
68205
  }
@@ -67972,18 +68209,14 @@ Available commands: ${pc71.cyan("login")}, ${pc71.cyan("status")}, ${pc71.cyan("
67972
68209
  await setup({});
67973
68210
  break;
67974
68211
  case "doctor":
67975
- await doctor();
68212
+ await doctor({ region: flags.region, json: flags.json });
67976
68213
  break;
67977
68214
  default:
67978
- clack66.log.error(`Unknown aws command: ${subCommand}`);
67979
- console.log(
67980
- `
67981
- Available commands: ${pc71.cyan("setup")}, ${pc71.cyan("doctor")}
67982
- `
68215
+ throw errors.unknownCommand(
68216
+ "aws command",
68217
+ subCommand,
68218
+ "Available commands: setup, doctor\n\nRun wraps --help for more information."
67983
68219
  );
67984
- console.log(`Run ${pc71.cyan("wraps --help")} for more information.
67985
- `);
67986
- throw new Error(`Unknown aws command: ${subCommand}`);
67987
68220
  }
67988
68221
  const awsDuration = Date.now() - startTime;
67989
68222
  const awsCommandName = `aws:${subCommand}`;
@@ -68068,13 +68301,11 @@ Available commands: ${pc71.cyan("setup")}, ${pc71.cyan("doctor")}
68068
68301
  await telemetryStatus();
68069
68302
  break;
68070
68303
  default:
68071
- clack66.log.error(`Unknown telemetry command: ${subCommand}`);
68072
- console.log(
68073
- `
68074
- Available commands: ${pc71.cyan("enable")}, ${pc71.cyan("disable")}, ${pc71.cyan("status")}
68075
- `
68304
+ throw errors.unknownCommand(
68305
+ "telemetry command",
68306
+ subCommand,
68307
+ "Available commands: enable, disable, status"
68076
68308
  );
68077
- throw new Error(`Unknown telemetry command: ${subCommand}`);
68078
68309
  }
68079
68310
  break;
68080
68311
  }
@@ -68095,29 +68326,22 @@ Please specify a command for ${primaryCommand} service.
68095
68326
  showHelp();
68096
68327
  break;
68097
68328
  default: {
68098
- clack66.log.error(`Unknown command: ${primaryCommand}`);
68099
- const suggestion = suggestCommand(primaryCommand);
68100
- if (suggestion) {
68101
- console.log(`
68102
- Did you mean ${pc71.cyan(`wraps ${suggestion}`)}?`);
68103
- }
68104
- console.log(
68105
- `
68106
- Run ${pc71.cyan("wraps --help")} for available commands.
68107
- `
68108
- );
68109
- throw new Error(`Unknown command: ${primaryCommand}`);
68329
+ const didYouMean = suggestCommand(primaryCommand);
68330
+ const hint = didYouMean ? `Did you mean: wraps ${didYouMean}
68331
+
68332
+ Run wraps --help for available commands.` : "Run wraps --help for available commands.";
68333
+ throw errors.unknownCommand("command", primaryCommand, hint);
68110
68334
  }
68111
68335
  }
68112
68336
  const duration = Date.now() - startTime;
68113
- const commandName = subCommand ? `${primaryCommand}:${subCommand}` : primaryCommand;
68337
+ const commandName = telemetryCommandName(primaryCommand, subCommand);
68114
68338
  trackCommand(commandName, {
68115
68339
  success: true,
68116
68340
  duration_ms: duration
68117
68341
  });
68118
68342
  } catch (error) {
68119
68343
  const duration = Date.now() - startTime;
68120
- const commandName = subCommand ? `${primaryCommand}:${subCommand}` : primaryCommand;
68344
+ const commandName = telemetryCommandName(primaryCommand, subCommand);
68121
68345
  trackCommand(commandName, {
68122
68346
  success: false,
68123
68347
  duration_ms: duration
@@ -68125,6 +68349,9 @@ Run ${pc71.cyan("wraps --help")} for available commands.
68125
68349
  handleCLIError(error, commandName);
68126
68350
  } finally {
68127
68351
  await telemetry.shutdown();
68352
+ if (process.exitCode) {
68353
+ process.exit(process.exitCode);
68354
+ }
68128
68355
  }
68129
68356
  }
68130
68357
  if (primaryCommand) {