@mesh-tech/mesh-cli 0.39.0 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/bin/{mesh.auth-preflight-JO5G7SOF.js → mesh.auth-preflight-AUFQ2FGD.js} +1 -1
  2. package/dist/bin/{mesh.chunk-CNLSVKYY.js → mesh.chunk-2ASXJ5DO.js} +233 -581
  3. package/dist/bin/mesh.chunk-2ASXJ5DO.js.map +6 -0
  4. package/dist/bin/{mesh.chunk-WODQO6TP.js → mesh.chunk-6AIG5OJM.js} +3 -3
  5. package/dist/bin/{mesh.chunk-OSV3EZQ3.js → mesh.chunk-6SSOVZOI.js} +1 -1
  6. package/dist/bin/{mesh.chunk-2ZJR5LGN.js → mesh.chunk-7HTKSUWR.js} +1507 -548
  7. package/dist/bin/mesh.chunk-7HTKSUWR.js.map +6 -0
  8. package/dist/bin/{mesh.chunk-UI6EFAMD.js → mesh.chunk-F44A3ACW.js} +2 -2
  9. package/dist/bin/{mesh.chunk-C2TKCYHP.js → mesh.chunk-HJGMOEUG.js} +1 -1
  10. package/dist/bin/{mesh.chunk-O6WRZU4X.js → mesh.chunk-NSQJEX36.js} +1 -1
  11. package/dist/bin/{mesh.chunk-C4ZM7DM2.js → mesh.chunk-PZVI7V3J.js} +1 -1
  12. package/dist/bin/mesh.chunk-TDCH4SFQ.js +419 -0
  13. package/dist/bin/mesh.chunk-TDCH4SFQ.js.map +6 -0
  14. package/dist/bin/mesh.chunk-YE2WIY3Y.js +473 -0
  15. package/dist/bin/mesh.chunk-YE2WIY3Y.js.map +6 -0
  16. package/dist/bin/{mesh.create-app-SOHBL75U.js → mesh.create-app-Z3RKSTBO.js} +3 -3
  17. package/dist/bin/{mesh.dev-token-server-SS7QEQOQ.js → mesh.dev-token-server-XG26C6IQ.js} +2 -2
  18. package/dist/bin/mesh.generate-XSM4C6FQ.js +10 -0
  19. package/dist/bin/mesh.js +9 -8
  20. package/dist/bin/mesh.js.map +1 -1
  21. package/dist/bin/{mesh.login-6VPMWHHU.js → mesh.login-3AWVGPCM.js} +2 -2
  22. package/dist/bin/{mesh.platform-setup-DJJB2PWL.js → mesh.platform-setup-2ZDMHRCI.js} +1 -1
  23. package/dist/bin/{mesh.program-Y4HUNBFP.js → mesh.program-K5JQXEHX.js} +9 -8
  24. package/dist/bin/{mesh.registry-5P4ZLFLJ.js → mesh.registry-JLQYFUNN.js} +4 -4
  25. package/dist/bin/{mesh.registry-identity-ONGUJQAY.js → mesh.registry-identity-3AR27UGO.js} +3 -3
  26. package/dist/bin/mesh.registry-identity-3AR27UGO.js.map +6 -0
  27. package/dist/bin/mesh.review-command-LUVZQN2T.js +238 -0
  28. package/dist/bin/mesh.review-command-LUVZQN2T.js.map +6 -0
  29. package/dist/bin/{mesh.start-5CPWOHDJ.js → mesh.start-KZ5L6SOJ.js} +2 -2
  30. package/dist/bin/{mesh.wizard-FNRTSGVN.js → mesh.wizard-FCTT55KI.js} +7 -7
  31. package/dist/bin/mesh.workspace-membership-DI3YQGEK.js +65 -0
  32. package/dist/bin/mesh.workspace-membership-DI3YQGEK.js.map +6 -0
  33. package/dist/build-info.json +2 -2
  34. package/dist/src/commands/dev-doctor.d.ts +22 -0
  35. package/dist/src/commands/dev-doctor.js +149 -0
  36. package/dist/src/commands/dev-env-leaks.d.ts +24 -0
  37. package/dist/src/commands/dev-env-leaks.js +178 -0
  38. package/dist/src/commands/dev-launch.d.ts +17 -1
  39. package/dist/src/commands/dev-launch.js +130 -5
  40. package/dist/src/commands/dev-readiness.d.ts +49 -0
  41. package/dist/src/commands/dev-readiness.js +78 -0
  42. package/dist/src/commands/dev.d.ts +60 -0
  43. package/dist/src/commands/dev.js +539 -140
  44. package/dist/src/commands/hub/index.js +10 -7
  45. package/dist/src/commands/mcp/generate.d.ts +11 -0
  46. package/dist/src/commands/mcp/generate.js +78 -0
  47. package/dist/src/commands/mcp/index.d.ts +2 -0
  48. package/dist/src/commands/mcp/index.js +70 -0
  49. package/dist/src/commands/mcp/manifest-file.d.ts +5 -0
  50. package/dist/src/commands/mcp/manifest-file.js +24 -0
  51. package/dist/src/commands/mcp/review-command.d.ts +24 -0
  52. package/dist/src/commands/mcp/review-command.js +66 -0
  53. package/dist/src/commands/mcp/review.d.ts +41 -0
  54. package/dist/src/commands/mcp/review.js +140 -0
  55. package/dist/src/commands/mcp/workspace-membership.d.ts +7 -0
  56. package/dist/src/commands/mcp/workspace-membership.js +77 -0
  57. package/dist/src/commands/secrets/reindex.js +2 -7
  58. package/dist/src/commands/secrets/set.d.ts +22 -1
  59. package/dist/src/commands/secrets/set.js +31 -8
  60. package/dist/src/commands/temporal.js +35 -4
  61. package/dist/src/commands/temporal.js.map +2 -2
  62. package/dist/src/program.js +2 -0
  63. package/dist/src/utils/aws-auth.d.ts +4 -0
  64. package/dist/src/utils/aws-auth.js +7 -3
  65. package/dist/src/utils/dev-sessions-root.d.ts +3 -0
  66. package/dist/src/utils/dev-sessions-root.js +45 -0
  67. package/dist/src/utils/kubeconfig.js +2 -2
  68. package/dist/src/utils/tailscale.js +7 -1
  69. package/dist/src/utils/temporal-auth.js +2 -1
  70. package/dist/src/utils/workflow-fingerprint.js +23 -12
  71. package/fragments/agents/AGENTS.md.hbs +3 -1
  72. package/fragments/base/index.ts.hbs +3 -0
  73. package/package.json +7 -5
  74. package/skills/mesh/SKILL.md +10 -6
  75. package/templates/api-auth/index.ts.hbs +1 -0
  76. package/templates/api-role-gating/index.ts.hbs +1 -0
  77. package/templates/external-service/index.ts.hbs +1 -0
  78. package/templates/workflow/index.ts.hbs +2 -0
  79. package/dist/bin/mesh.chunk-2ZJR5LGN.js.map +0 -6
  80. package/dist/bin/mesh.chunk-CNLSVKYY.js.map +0 -6
  81. /package/dist/bin/{mesh.auth-preflight-JO5G7SOF.js.map → mesh.auth-preflight-AUFQ2FGD.js.map} +0 -0
  82. /package/dist/bin/{mesh.chunk-WODQO6TP.js.map → mesh.chunk-6AIG5OJM.js.map} +0 -0
  83. /package/dist/bin/{mesh.chunk-OSV3EZQ3.js.map → mesh.chunk-6SSOVZOI.js.map} +0 -0
  84. /package/dist/bin/{mesh.chunk-UI6EFAMD.js.map → mesh.chunk-F44A3ACW.js.map} +0 -0
  85. /package/dist/bin/{mesh.chunk-C2TKCYHP.js.map → mesh.chunk-HJGMOEUG.js.map} +0 -0
  86. /package/dist/bin/{mesh.chunk-O6WRZU4X.js.map → mesh.chunk-NSQJEX36.js.map} +0 -0
  87. /package/dist/bin/{mesh.chunk-C4ZM7DM2.js.map → mesh.chunk-PZVI7V3J.js.map} +0 -0
  88. /package/dist/bin/{mesh.create-app-SOHBL75U.js.map → mesh.create-app-Z3RKSTBO.js.map} +0 -0
  89. /package/dist/bin/{mesh.dev-token-server-SS7QEQOQ.js.map → mesh.dev-token-server-XG26C6IQ.js.map} +0 -0
  90. /package/dist/bin/{mesh.login-6VPMWHHU.js.map → mesh.generate-XSM4C6FQ.js.map} +0 -0
  91. /package/dist/bin/{mesh.platform-setup-DJJB2PWL.js.map → mesh.login-3AWVGPCM.js.map} +0 -0
  92. /package/dist/bin/{mesh.program-Y4HUNBFP.js.map → mesh.platform-setup-2ZDMHRCI.js.map} +0 -0
  93. /package/dist/bin/{mesh.registry-5P4ZLFLJ.js.map → mesh.program-K5JQXEHX.js.map} +0 -0
  94. /package/dist/bin/{mesh.registry-identity-ONGUJQAY.js.map → mesh.registry-JLQYFUNN.js.map} +0 -0
  95. /package/dist/bin/{mesh.start-5CPWOHDJ.js.map → mesh.start-KZ5L6SOJ.js.map} +0 -0
  96. /package/dist/bin/{mesh.wizard-FNRTSGVN.js.map → mesh.wizard-FCTT55KI.js.map} +0 -0
@@ -1,18 +1,28 @@
1
+ import {
2
+ buildInstanceIndexValue,
3
+ discoverStackExternalServices,
4
+ instanceIndexSecretId,
5
+ instanceKeyFromSecretName,
6
+ isResourceNotFound,
7
+ parseInstanceIndex,
8
+ resolveSecretsContext,
9
+ setCommand
10
+ } from "./mesh.chunk-YE2WIY3Y.js";
1
11
  import {
2
12
  cliReferenceStaleness,
3
13
  resolveCliRuntime,
4
14
  runPortalCommand
5
- } from "./mesh.chunk-C4ZM7DM2.js";
15
+ } from "./mesh.chunk-PZVI7V3J.js";
6
16
  import {
7
17
  registerAppCommands,
8
18
  registerCreateAppCommand
9
- } from "./mesh.chunk-UI6EFAMD.js";
19
+ } from "./mesh.chunk-F44A3ACW.js";
10
20
  import {
11
21
  PLATFORM_SETUP_DEFAULTS
12
- } from "./mesh.chunk-O6WRZU4X.js";
22
+ } from "./mesh.chunk-NSQJEX36.js";
13
23
  import {
14
24
  registerRegistryCommands
15
- } from "./mesh.chunk-WODQO6TP.js";
25
+ } from "./mesh.chunk-6AIG5OJM.js";
16
26
  import {
17
27
  registerSkillsCommands,
18
28
  resolveTargetRoot,
@@ -30,6 +40,7 @@ import {
30
40
  derivePlatformContext,
31
41
  detectContext,
32
42
  detectLocalTenant,
43
+ devSessionsRoot,
33
44
  ensureKubeconfig,
34
45
  findAppRoot,
35
46
  findRepoRoot,
@@ -40,6 +51,7 @@ import {
40
51
  getValidToken,
41
52
  idpEndpoints,
42
53
  mockIdpComposeEnv,
54
+ pickLaunchHostEnv,
43
55
  probeCredentials,
44
56
  pulumiStackOutput,
45
57
  readCredentials,
@@ -55,7 +67,6 @@ import {
55
67
  resolveAwsCredentials,
56
68
  resolveHubPlatformName,
57
69
  resolvePulumiEnv,
58
- resolveStackOption,
59
70
  resolveTemporalAuth,
60
71
  resolveWorktreeIdentity,
61
72
  rewriteDatabaseUrl,
@@ -66,7 +77,7 @@ import {
66
77
  waitForPort,
67
78
  worktreeStackName,
68
79
  writeEnvFile
69
- } from "./mesh.chunk-2ZJR5LGN.js";
80
+ } from "./mesh.chunk-7HTKSUWR.js";
70
81
  import {
71
82
  COMPOSE_PROJECT,
72
83
  DEFAULT_HUB_PORT,
@@ -115,7 +126,7 @@ import {
115
126
  homeNpmrcPath,
116
127
  isNpmAuthError,
117
128
  probeRegistryToken
118
- } from "./mesh.chunk-OSV3EZQ3.js";
129
+ } from "./mesh.chunk-6SSOVZOI.js";
119
130
  import {
120
131
  createVcsFolderReader,
121
132
  deriveVcsBaseUrl,
@@ -914,7 +925,7 @@ async function psqlCommand(options) {
914
925
  const databaseUrl = await getDatabaseUrl(app.tenant, app.stage, { app: appName });
915
926
  const parsed = new URL(databaseUrl);
916
927
  const username = parsed.username;
917
- const password2 = decodeURIComponent(parsed.password);
928
+ const password = decodeURIComponent(parsed.password);
918
929
  const database = parsed.pathname.slice(1);
919
930
  console.log("");
920
931
  logInfo(`Connecting to ${database} as ${username}...`);
@@ -924,7 +935,7 @@ async function psqlCommand(options) {
924
935
  ["-h", "localhost", "-p", "5432", "-U", username, "-d", database],
925
936
  {
926
937
  stdio: "inherit",
927
- env: { ...process.env, PGPASSWORD: password2 }
938
+ env: { ...process.env, PGPASSWORD: password }
928
939
  }
929
940
  );
930
941
  psql.on("exit", (code) => {
@@ -1530,7 +1541,7 @@ var DOCS_PREVIEW_PORT = "4410";
1530
1541
  var CLI_REFERENCE_PATH = "docs/portal/generated/cli-reference.md";
1531
1542
  async function renderCliReference() {
1532
1543
  const [{ createProgram: createProgram2 }, { extractCliReference, renderCliReferenceMarkdown }] = await Promise.all([
1533
- import("./mesh.program-Y4HUNBFP.js"),
1544
+ import("./mesh.program-K5JQXEHX.js"),
1534
1545
  import("./mesh.cli-reference-H3TOPIET.js")
1535
1546
  ]);
1536
1547
  return renderCliReferenceMarkdown(extractCliReference(createProgram2()));
@@ -1602,7 +1613,7 @@ function registerDocsCommand(program) {
1602
1613
  "Serve the Mesh docs locally \u2014 detached in a tmux session by default; the working tree in a mesh-platform checkout, or the published @mesh-tech/docs artifact (role-gated registry) anywhere else"
1603
1614
  ).option("-v, --version <version>", "docs version to serve (== the @mesh-tech/* baseline it describes); default: latest", void 0).option("-p, --port <port>", "port to serve on (0 picks a free one)", "4400").option("--dev", "in a checkout: run the Zudoku dev server (HMR) in the foreground, for authoring", false).option("--foreground", "serve in the foreground (the agent/CI path; automatic when not a TTY)", false).action(
1604
1615
  (opts) => guarded(async () => {
1605
- const { runDocsStart } = await import("./mesh.start-5CPWOHDJ.js");
1616
+ const { runDocsStart } = await import("./mesh.start-KZ5L6SOJ.js");
1606
1617
  await runDocsStart({
1607
1618
  repoRoot: findRepoRoot(process.cwd()),
1608
1619
  version: opts.version,
@@ -1614,13 +1625,13 @@ function registerDocsCommand(program) {
1614
1625
  );
1615
1626
  docs.command("stop").description(`Stop the detached docs server (the tmux session "${"mesh-docs"}")`).action(
1616
1627
  () => guarded(async () => {
1617
- const { runDocsStop } = await import("./mesh.start-5CPWOHDJ.js");
1628
+ const { runDocsStop } = await import("./mesh.start-KZ5L6SOJ.js");
1618
1629
  runDocsStop();
1619
1630
  })()
1620
1631
  );
1621
1632
  docs.command("serve-static", { hidden: true }).option("--root <dir>", "built site root", "").option("--port <port>", "port", "4400").action(
1622
1633
  (opts) => guarded(async () => {
1623
- const { runDocsServeStatic } = await import("./mesh.start-5CPWOHDJ.js");
1634
+ const { runDocsServeStatic } = await import("./mesh.start-KZ5L6SOJ.js");
1624
1635
  await runDocsServeStatic(opts);
1625
1636
  })()
1626
1637
  );
@@ -1663,7 +1674,7 @@ function registerDocsCommand(program) {
1663
1674
  );
1664
1675
  docs.command("list").description("List the published docs versions (each is an @mesh-tech/* baseline)").action(
1665
1676
  () => guarded(async () => {
1666
- const { runDocsList } = await import("./mesh.start-5CPWOHDJ.js");
1677
+ const { runDocsList } = await import("./mesh.start-KZ5L6SOJ.js");
1667
1678
  await runDocsList();
1668
1679
  })()
1669
1680
  );
@@ -1673,7 +1684,6 @@ function registerDocsCommand(program) {
1673
1684
  import { execFileSync as execFileSync2 } from "node:child_process";
1674
1685
  import * as fs4 from "node:fs";
1675
1686
  import * as net3 from "node:net";
1676
- import * as os from "node:os";
1677
1687
  import * as path4 from "node:path";
1678
1688
  import chalk from "chalk";
1679
1689
  var HUB_SESSION_PREFIX = "mesh-hub-dev";
@@ -1706,7 +1716,7 @@ function killInstructions(targets) {
1706
1716
  var DEFAULT_HUB_UI_PORT = Number(DEFAULT_HUB_PORT);
1707
1717
  var DEFAULT_HUB_API_PORT = 3002;
1708
1718
  function devSessionsDir() {
1709
- return path4.join(os.tmpdir(), "mesh-dev-sessions");
1719
+ return devSessionsRoot();
1710
1720
  }
1711
1721
  function listDevSessions(dir = devSessionsDir()) {
1712
1722
  if (!fs4.existsSync(dir)) return [];
@@ -1968,7 +1978,7 @@ function isPortListening(port) {
1968
1978
  });
1969
1979
  }
1970
1980
  function hubEnvDir(sessionName) {
1971
- return path4.join(os.tmpdir(), "mesh-dev-sessions", sessionName);
1981
+ return path4.join(devSessionsRoot(), sessionName);
1972
1982
  }
1973
1983
  function parsePort(raw, fallback, source) {
1974
1984
  if (raw === void 0) return fallback;
@@ -2068,6 +2078,7 @@ ${killInstructions(targets).join("\n")}`,
2068
2078
  const apiDir = path4.join(platformDir, "apps", "hub", "api");
2069
2079
  const uiDir = path4.join(platformDir, "apps", "hub", "ui");
2070
2080
  execFileSync2("tmux", ["new-session", "-d", "-s", hubSession, "-n", "api", "-c", apiDir]);
2081
+ const hostEnv = pickLaunchHostEnv(process.env);
2071
2082
  if (!assembled.apiEnv.DEV_USER_TOKEN_URL && assembled.apiEnv.DEV_USER_ID_TOKEN) {
2072
2083
  const platform = session.state.devOutput.platform;
2073
2084
  const credContext = `mesh.${platform.env}`;
@@ -2077,11 +2088,19 @@ ${killInstructions(targets).join("\n")}`,
2077
2088
  execFileSync2("tmux", ["set-option", "-t", `${hubSession}:token-server`, "remain-on-exit", "on"], {
2078
2089
  stdio: "ignore"
2079
2090
  });
2091
+ const tokenServerEnvFile = path4.join(hubEnvDir(hubSession), "token-server.env.sh");
2092
+ writeEnvFile(tokenServerEnvFile, hostEnv);
2080
2093
  execFileSync2("tmux", [
2081
2094
  "send-keys",
2082
2095
  "-t",
2083
2096
  `${hubSession}:token-server`,
2084
- `npx mesh dev __token-server ${tokenPort} ${credContext}`,
2097
+ buildLaunchCommand(
2098
+ tokenServerEnvFile,
2099
+ platformDir,
2100
+ `npx mesh dev __token-server ${tokenPort} ${credContext}`,
2101
+ void 0,
2102
+ hostEnv
2103
+ ),
2085
2104
  "Enter"
2086
2105
  ]);
2087
2106
  for (let i = 0; i < 15 && !await isPortListening(tokenPort); i++) {
@@ -2093,14 +2112,14 @@ ${killInstructions(targets).join("\n")}`,
2093
2112
  }
2094
2113
  const launch = (window, dir, env, cmd, createWindow) => {
2095
2114
  const envFile = path4.join(hubEnvDir(hubSession), `${window}.env.sh`);
2096
- writeEnvFile(envFile, env);
2115
+ writeEnvFile(envFile, { ...hostEnv, ...env });
2097
2116
  if (createWindow) {
2098
2117
  execFileSync2("tmux", ["new-window", "-t", hubSession, "-n", window, "-c", dir]);
2099
2118
  }
2100
2119
  execFileSync2("tmux", ["set-option", "-t", `${hubSession}:${window}`, "remain-on-exit", "on"], {
2101
2120
  stdio: "ignore"
2102
2121
  });
2103
- execFileSync2("tmux", ["send-keys", "-t", `${hubSession}:${window}`, buildLaunchCommand(envFile, dir, cmd), "Enter"]);
2122
+ execFileSync2("tmux", ["send-keys", "-t", `${hubSession}:${window}`, buildLaunchCommand(envFile, dir, cmd, void 0, hostEnv), "Enter"]);
2104
2123
  };
2105
2124
  launch("api", apiDir, assembled.apiEnv, "pnpm dev", false);
2106
2125
  launch("ui", uiDir, assembled.uiEnv, `pnpm dev --port ${uiPort} --strictPort`, true);
@@ -2141,11 +2160,11 @@ import chalk2 from "chalk";
2141
2160
  import * as fs5 from "fs";
2142
2161
  import * as path5 from "path";
2143
2162
  async function setupPrompts() {
2144
- const [{ default: input2 }, { default: confirm }] = await Promise.all([
2163
+ const [{ default: input }, { default: confirm }] = await Promise.all([
2145
2164
  import("@inquirer/input"),
2146
2165
  import("@inquirer/confirm")
2147
2166
  ]);
2148
- return { input: (args) => input2(args), confirm: (args) => confirm(args) };
2167
+ return { input: (args) => input(args), confirm: (args) => confirm(args) };
2149
2168
  }
2150
2169
  var LOCAL_HUB_API = "http://localhost:4568";
2151
2170
  function isLocalContext(context) {
@@ -2178,7 +2197,7 @@ async function registryChecks(args) {
2178
2197
  const { fix, profile } = args;
2179
2198
  const probe = args.probe ?? probeRegistryToken;
2180
2199
  const login = args.login ?? (async () => {
2181
- const { runRegistryLogin } = await import("./mesh.registry-5P4ZLFLJ.js");
2200
+ const { runRegistryLogin } = await import("./mesh.registry-JLQYFUNN.js");
2182
2201
  await runRegistryLogin(void 0, profile ? { profile } : {});
2183
2202
  });
2184
2203
  const REGISTRY_FIX = registryFixCommand(profile);
@@ -2334,7 +2353,7 @@ function registerInitCommands(program) {
2334
2353
  `nothing deployed yet \u2014 scaffold a tenant platform repo for \`<tenant>.<env>\` (default env: ${PLATFORM_SETUP_DEFAULTS.env}) and print its deploy sequence`
2335
2354
  ).option("--region <region>", `--new-platform: AWS region (default: ${PLATFORM_SETUP_DEFAULTS.region})`).option("--domain <domain>", "--new-platform: base public domain you control; the core stack creates the zone {env}.{domain} and stops at the mesh-gateway Ingress until you delegate its NS records. No default \u2014 a placeholder scaffolds a zone that can never validate").option("--state-bucket <bucket>", "--new-platform: Pulumi state S3 bucket (default: {tenant}-mesh-platform-pulumi-state)").option("--create-state-bucket", "--new-platform: create the state bucket (versioned) if it does not exist").option("--no-create-state-bucket", "--new-platform: never create the state bucket; print the aws command instead").option("--dir <path>", "--new-platform: where to scaffold the platform repo (default: ./{tenant}-mesh-platform)").option("--device", "device-code sign-in for the registry and platform steps (headless / SSH)").option("--profile <aws-profile>", "AWS profile this machine uses: read the registry without the broker (deployers only), and the profile a --new-platform stack config references").option("--skip-repo", "do not bootstrap, check or record anything in the current repo", false).option("--yes", "accept every default and never prompt", false).option("--json", "one JSON document on stdout ({tenant, mode, steps, next}); human output on stderr", false).action(
2336
2355
  async (opts) => {
2337
- const { runInitWizard } = await import("./mesh.wizard-FNRTSGVN.js");
2356
+ const { runInitWizard } = await import("./mesh.wizard-FCTT55KI.js");
2338
2357
  const code = await runInitWizard(opts);
2339
2358
  if (code !== 0) process.exitCode = code;
2340
2359
  }
@@ -2350,7 +2369,7 @@ function registerInitCommands(program) {
2350
2369
  throw new MeshCliError(`Invalid tenant name '${tenant}' (lowercase alphanumeric + dashes).`);
2351
2370
  }
2352
2371
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
2353
- const { resolvePlatformSetup, scaffoldPlatformRepo, ensureStateBucket, renderPlatformNextSteps } = await import("./mesh.platform-setup-DJJB2PWL.js");
2372
+ const { resolvePlatformSetup, scaffoldPlatformRepo, ensureStateBucket, renderPlatformNextSteps } = await import("./mesh.platform-setup-2ZDMHRCI.js");
2354
2373
  const setup = await resolvePlatformSetup(tenant, opts, {
2355
2374
  prompts: interactive && !opts.yes ? await setupPrompts() : void 0,
2356
2375
  interactive
@@ -2416,7 +2435,7 @@ function registerInitCommands(program) {
2416
2435
  // packages/mesh-cli/src/commands/install-shim.ts
2417
2436
  import { execFileSync as execFileSync3 } from "child_process";
2418
2437
  import * as fs6 from "fs";
2419
- import * as os2 from "os";
2438
+ import * as os from "os";
2420
2439
  import * as path6 from "path";
2421
2440
  function shimScript() {
2422
2441
  return `#!/bin/sh
@@ -2490,7 +2509,7 @@ exit 1
2490
2509
  `;
2491
2510
  }
2492
2511
  function defaultShimDir() {
2493
- return path6.join(os2.homedir(), ".local", "bin");
2512
+ return path6.join(os.homedir(), ".local", "bin");
2494
2513
  }
2495
2514
  function dirOnPath(dir, pathEnv) {
2496
2515
  if (!pathEnv) return false;
@@ -2521,7 +2540,7 @@ function registerInstallShimCommand(program) {
2521
2540
  } else {
2522
2541
  logInfo("Bare `mesh <cmd>` now runs the local source of whatever workspace you're in.");
2523
2542
  }
2524
- const diagPath = path6.join(os2.tmpdir(), "mesh-shim-selftest.log");
2543
+ const diagPath = path6.join(os.tmpdir(), "mesh-shim-selftest.log");
2525
2544
  let stdout = "";
2526
2545
  let stderr = "";
2527
2546
  let status = 0;
@@ -2575,7 +2594,7 @@ import chalk3 from "chalk";
2575
2594
  // packages/mesh-cli/src/commands/local/hub-local.ts
2576
2595
  import { execFile, execFileSync as execFileSync4 } from "child_process";
2577
2596
  import * as fs7 from "fs";
2578
- import * as os3 from "os";
2597
+ import * as os2 from "os";
2579
2598
  import * as path7 from "path";
2580
2599
  import { promisify } from "util";
2581
2600
  var execFileAsync = promisify(execFile);
@@ -2586,7 +2605,7 @@ function cacheDir() {
2586
2605
  return meshCacheDir("hub-local");
2587
2606
  }
2588
2607
  function npmrcPath() {
2589
- const p = path7.join(os3.homedir(), ".npmrc");
2608
+ const p = path7.join(os2.homedir(), ".npmrc");
2590
2609
  if (!fs7.existsSync(p) || !fs7.readFileSync(p, "utf-8").includes("codeartifact")) {
2591
2610
  throw new MeshCliError(
2592
2611
  "The local Hub builds from the published @mesh-tech/hub tarball, which needs registry auth.",
@@ -2616,7 +2635,7 @@ function ensureHubAuthImage() {
2616
2635
  logSuccess(`Built ${HUB_AUTH_IMAGE}`);
2617
2636
  }
2618
2637
  function hasRegistryAuth() {
2619
- const p = path7.join(os3.homedir(), ".npmrc");
2638
+ const p = path7.join(os2.homedir(), ".npmrc");
2620
2639
  return fs7.existsSync(p) && fs7.readFileSync(p, "utf-8").includes("codeartifact");
2621
2640
  }
2622
2641
  function localHubVersion() {
@@ -2871,8 +2890,8 @@ function withHubCatalogRefs(pointer, metadataRef) {
2871
2890
  };
2872
2891
  }
2873
2892
  async function publishHubAuthzCatalog(compiled, awsConfig) {
2874
- const { SSMClient: SSMClient4, GetParameterCommand, PutParameterCommand } = await import("@aws-sdk/client-ssm");
2875
- const ssm = new SSMClient4(awsConfig);
2893
+ const { SSMClient: SSMClient3, GetParameterCommand, PutParameterCommand } = await import("@aws-sdk/client-ssm");
2894
+ const ssm = new SSMClient3(awsConfig);
2876
2895
  await ssm.send(
2877
2896
  new PutParameterCommand({
2878
2897
  Name: HUB_OPS_HUB_METADATA_PARAM,
@@ -3344,6 +3363,72 @@ Re-running start from here may recreate shared containers with this checkout's c
3344
3363
  });
3345
3364
  }
3346
3365
 
3366
+ // packages/mesh-cli/src/commands/mcp/index.ts
3367
+ import * as path9 from "node:path";
3368
+ function registerMcpCommands(program) {
3369
+ const mcp = program.command("mcp").description("Manifest-driven MCP Integrations (reviewed tool catalogs)");
3370
+ mcp.command("review <manifest>").description(
3371
+ "Fetch a manifest's MCP server tools/list with the Integration's credential, diff it against the checked-in snapshot, and write the snapshot on confirmation"
3372
+ ).option("--yes", "Write without prompting").option("--dry-run", "Report the diff and write nothing").option("--stack <stack>", "Pulumi stack name (override detection)").option("-t, --tenant <tenant>", "Tenant to address (override detection)").option("--region <region>", "AWS region (default: us-east-2)").option(
3373
+ "--secret <id>",
3374
+ "Secrets Manager secret holding the Integration credential (default: the deployed ExternalService's own secret)"
3375
+ ).action(async (manifest, opts) => {
3376
+ const { runMcpReviewCommand } = await import("./mesh.review-command-LUVZQN2T.js");
3377
+ try {
3378
+ await runMcpReviewCommand(manifest, opts);
3379
+ } catch (error) {
3380
+ logError(error instanceof Error ? error.message : String(error));
3381
+ process.exit(1);
3382
+ }
3383
+ });
3384
+ mcp.command("generate <manifest>").description(
3385
+ "Write the worker package mesh.apps.McpIntegration deploys (package.json, main.ts, openapi.json) from a manifest and its reviewed snapshot; commit it with the lockfile"
3386
+ ).option("--out <dir>", "Package directory (default: <manifest dir>/.mesh-mcp/<name>)").option(
3387
+ "--refresh-versions",
3388
+ "Re-resolve every dependency version instead of keeping the committed ones"
3389
+ ).action(async (manifest, opts) => {
3390
+ const { generateMcpServeDir } = await import("./mesh.generate-XSM4C6FQ.js");
3391
+ const { workspaceMembership } = await import("./mesh.workspace-membership-DI3YQGEK.js");
3392
+ try {
3393
+ const { serveDir, written } = generateMcpServeDir(manifest, {
3394
+ ...opts.out ? { out: opts.out } : {},
3395
+ ...opts.refreshVersions ? { refreshVersions: true } : {}
3396
+ });
3397
+ if (written.length === 0) {
3398
+ logInfo(`${serveDir} is current.`);
3399
+ } else {
3400
+ logInfo(`Wrote ${written.join(", ")} in ${serveDir}.`);
3401
+ if (written.includes("package.json")) {
3402
+ logInfo("Run `pnpm install` so the lockfile records it, then commit both.");
3403
+ }
3404
+ }
3405
+ const membership = workspaceMembership(serveDir);
3406
+ if (!membership.workspaceFile) {
3407
+ logWarn(
3408
+ `No pnpm-workspace.yaml above ${serveDir}: the worker image installs this package from a pnpm workspace, so it must be in one.`
3409
+ );
3410
+ } else if (!membership.member && membership.suggestedGlob) {
3411
+ const { ensureWorkspaceGlobs } = await import("./mesh.create-app-Z3RKSTBO.js");
3412
+ const added = ensureWorkspaceGlobs(path9.dirname(membership.workspaceFile), [
3413
+ membership.suggestedGlob
3414
+ ]);
3415
+ if (added.length > 0) {
3416
+ logInfo(
3417
+ `${membership.workspaceFile}: added ${added.join(", ")} so \`pnpm install\` records the package.`
3418
+ );
3419
+ } else {
3420
+ logWarn(
3421
+ `${serveDir} is not a member of the workspace in ${membership.workspaceFile}, so \`pnpm install\` will not record it. Add "${membership.suggestedGlob}" to its packages.`
3422
+ );
3423
+ }
3424
+ }
3425
+ } catch (error) {
3426
+ logError(error instanceof Error ? error.message : String(error));
3427
+ process.exit(1);
3428
+ }
3429
+ });
3430
+ }
3431
+
3347
3432
  // packages/mesh-cli/src/commands/secrets/index.ts
3348
3433
  import { Option } from "commander";
3349
3434
 
@@ -3463,441 +3548,14 @@ async function execCommand2(args) {
3463
3548
  });
3464
3549
  }
3465
3550
 
3466
- // packages/mesh-cli/src/commands/secrets/set.ts
3467
- import {
3468
- SSMClient,
3469
- GetParametersByPathCommand
3470
- } from "@aws-sdk/client-ssm";
3471
- import {
3472
- SecretsManagerClient as SecretsManagerClient4,
3473
- GetSecretValueCommand as GetSecretValueCommand4,
3474
- PutSecretValueCommand,
3475
- CreateSecretCommand
3476
- } from "@aws-sdk/client-secrets-manager";
3477
- import input from "@inquirer/input";
3478
- import password from "@inquirer/password";
3479
-
3480
- // packages/secrets/src/index.ts
3481
- import {
3482
- SecretsManagerClient as SecretsManagerClient3,
3483
- GetSecretValueCommand as GetSecretValueCommand3
3484
- } from "@aws-sdk/client-secrets-manager";
3485
- var INSTANCE_INDEX_SUFFIX = ".index";
3486
- function instanceIndexSecretId(secretPrefix) {
3487
- return `${secretPrefix}/${INSTANCE_INDEX_SUFFIX}`;
3488
- }
3489
- function isInstanceKey(key) {
3490
- return key.length > 0 && !key.includes("/") && !key.startsWith(".") && !key.endsWith(".config");
3491
- }
3492
- function instanceKeyFromSecretName(secretPrefix, secretName) {
3493
- if (!secretName.startsWith(`${secretPrefix}/`)) return null;
3494
- const key = secretName.slice(secretPrefix.length + 1);
3495
- return isInstanceKey(key) ? key : null;
3496
- }
3497
- function parseInstanceIndex(secretString) {
3498
- let parsed;
3499
- try {
3500
- parsed = JSON.parse(secretString);
3501
- } catch {
3502
- parsed = void 0;
3503
- }
3504
- const instances = parsed?.instances;
3505
- if (!Array.isArray(instances) || !instances.every((k) => typeof k === "string")) {
3506
- throw new Error(
3507
- `Malformed instance index (expected {"instances": string[]}). Rebuild it with: mesh secrets reindex external/<name>`
3508
- );
3509
- }
3510
- return instances.filter(isInstanceKey);
3511
- }
3512
- function buildInstanceIndexValue(keys) {
3513
- const instances = [...new Set([...keys].filter(isInstanceKey))].sort();
3514
- const index = { version: 1, instances };
3515
- return JSON.stringify(index);
3516
- }
3517
-
3518
- // packages/mesh-cli/src/commands/secrets/context.ts
3519
- function resolveSecretsContext(opts, stackOpt = resolveStackOption(opts)) {
3520
- return detectContext(stackOpt, { tenant: opts.tenant, stack: stackOpt });
3521
- }
3522
-
3523
- // packages/mesh-cli/src/commands/secrets/set.ts
3524
- async function ensureAwsCredentialsForStack(stack) {
3525
- if (process.env.AWS_ACCESS_KEY_ID || process.env.AWS_SESSION_TOKEN) return;
3526
- if (!stack) return;
3527
- const appRoot = findAppRoot(process.cwd());
3528
- if (!appRoot) return;
3529
- const roleArn = readStackConfig(appRoot, stack, "mesh:deployerRole");
3530
- if (!roleArn) return;
3531
- const resolved = await resolveAwsCredentials(roleArn, appRoot, stack);
3532
- if (resolved) {
3533
- Object.assign(process.env, resolved.env);
3534
- delete process.env.AWS_PROFILE;
3535
- }
3536
- }
3537
- function normalizeEntry(raw) {
3538
- if (raw.type === "group" && raw.fields) {
3539
- return {
3540
- type: "group",
3541
- name: raw.name ?? "",
3542
- description: raw.description ?? "",
3543
- fields: normalizeFields(raw.fields)
3544
- };
3545
- }
3546
- return {
3547
- type: "field",
3548
- name: raw.name ?? "",
3549
- description: raw.description ?? "",
3550
- secret: raw.secret ?? false,
3551
- optional: raw.optional ?? false
3552
- };
3553
- }
3554
- function normalizeFields(raw) {
3555
- return Object.fromEntries(
3556
- Object.entries(raw).map(([key, value]) => [key, normalizeEntry(value)])
3557
- );
3558
- }
3559
- async function discoverExternalServices(ssmClient, tenant, platformEnv) {
3560
- const services = /* @__PURE__ */ new Map();
3561
- const basePath = `/mesh-platform/${tenant}/${platformEnv}`;
3562
- let nextToken;
3563
- do {
3564
- const response = await ssmClient.send(
3565
- new GetParametersByPathCommand({
3566
- Path: basePath,
3567
- Recursive: true,
3568
- NextToken: nextToken
3569
- })
3570
- );
3571
- for (const param of response.Parameters ?? []) {
3572
- if (!param.Name || !param.Value) continue;
3573
- const metaMatch = param.Name.match(
3574
- /\/external-services\/([^/]+)\/meta$/
3575
- );
3576
- if (metaMatch?.[1]) {
3577
- const serviceName = metaMatch[1];
3578
- const meta = JSON.parse(param.Value);
3579
- const existing = services.get(serviceName);
3580
- services.set(serviceName, { ...existing, meta });
3581
- }
3582
- const credMatch = param.Name.match(
3583
- /\/external-services\/([^/]+)\/credentials$/
3584
- );
3585
- if (credMatch?.[1]) {
3586
- const serviceName = credMatch[1];
3587
- const raw = JSON.parse(param.Value);
3588
- const schema = {
3589
- fields: normalizeFields(raw.fields),
3590
- keyedBy: raw.keyedBy
3591
- };
3592
- const existing = services.get(serviceName);
3593
- if (existing) {
3594
- existing.schema = schema;
3595
- } else {
3596
- services.set(serviceName, { meta: {}, schema });
3597
- }
3598
- }
3599
- }
3600
- nextToken = response.NextToken;
3601
- } while (nextToken);
3602
- return services;
3603
- }
3604
- async function promptFields(fields, existing, result, opts, depth = 0) {
3605
- for (const [fieldKey, entry] of Object.entries(fields)) {
3606
- if (entry.type === "group") {
3607
- const indent = " ".repeat(depth);
3608
- console.error("");
3609
- console.error(`${indent}\u2500\u2500 ${entry.name} \u2500\u2500`);
3610
- const existingGroup = existing[fieldKey] ?? {};
3611
- const resultGroup = {};
3612
- await promptFields(entry.fields, existingGroup, resultGroup, opts, depth + 1);
3613
- result[fieldKey] = resultGroup;
3614
- } else {
3615
- if (entry.optional && !opts.all) {
3616
- const existingVal2 = existing[fieldKey];
3617
- if (existingVal2 !== void 0 && existingVal2 !== "") {
3618
- result[fieldKey] = existingVal2;
3619
- }
3620
- continue;
3621
- }
3622
- const existingVal = existing[fieldKey];
3623
- const hasExisting = !!existingVal && existingVal !== "";
3624
- const message = entry.description ? `${entry.name} (${entry.description})` : entry.name;
3625
- const label = entry.optional ? `${message} [optional]` : message;
3626
- let value;
3627
- if (entry.secret) {
3628
- value = await password({ message: label, mask: "*" });
3629
- if (!value && hasExisting) {
3630
- value = existingVal;
3631
- }
3632
- } else {
3633
- value = await input({
3634
- message: label,
3635
- default: hasExisting ? existingVal : void 0
3636
- });
3637
- }
3638
- result[fieldKey] = value || (hasExisting ? existingVal : "");
3639
- }
3640
- }
3641
- }
3642
- function displaySummary(fields, values, depth = 0) {
3643
- const indent = " ".repeat(depth);
3644
- for (const [key, entry] of Object.entries(fields)) {
3645
- if (entry.type === "group") {
3646
- console.error(`${indent}${entry.name}:`);
3647
- const group = values[key] ?? {};
3648
- displaySummary(entry.fields, group, depth + 1);
3649
- } else {
3650
- const val = values[key];
3651
- if (!val) continue;
3652
- const display = entry.secret ? "********" : String(val);
3653
- console.error(`${indent}${entry.name}: ${display}`);
3654
- }
3655
- }
3656
- }
3657
- async function setCommand(servicePath, opts) {
3658
- const stackOpt = resolveStackOption(opts);
3659
- const context = resolveSecretsContext(opts, stackOpt);
3660
- const region = opts.region ?? process.env.AWS_REGION ?? "us-east-2";
3661
- await ensureAwsCredentialsForStack(stackOpt ?? context.stage);
3662
- const ssmClient = new SSMClient({ region });
3663
- const smClient = new SecretsManagerClient4({ region });
3664
- const services = await discoverExternalServices(
3665
- ssmClient,
3666
- context.tenant,
3667
- context.platformEnv
3668
- );
3669
- if (services.size === 0) {
3670
- logError(
3671
- 'No external services found. Deploy an ExternalService first:\n new mesh.apps.ExternalService("symitar", { env, credentials: { ... } })'
3672
- );
3673
- process.exit(1);
3674
- }
3675
- let serviceName;
3676
- if (servicePath) {
3677
- serviceName = servicePath.replace(/^external\//, "");
3678
- }
3679
- if (!serviceName || !services.has(serviceName)) {
3680
- if (serviceName) {
3681
- logError(`External service "${serviceName}" not found.`);
3682
- }
3683
- console.error("\nAvailable external services:");
3684
- for (const [name, svc2] of services) {
3685
- const desc = svc2.meta?.description ? ` \u2014 ${svc2.meta.description}` : "";
3686
- const type = svc2.meta?.type ? ` (${svc2.meta.type})` : "";
3687
- console.error(` ${name}${type}${desc}`);
3688
- }
3689
- console.error(`
3690
- Usage: mesh secrets set external/<name>`);
3691
- process.exit(serviceName ? 1 : 0);
3692
- }
3693
- const svc = services.get(serviceName);
3694
- const schema = svc.schema;
3695
- if (!schema) {
3696
- logError(`No credential schema found for "${serviceName}".`);
3697
- process.exit(1);
3698
- }
3699
- const secretPrefix = svc.meta.secretPrefix;
3700
- const secretId = opts.key ? `${secretPrefix}/${opts.key}` : secretPrefix;
3701
- if (schema.keyedBy && !opts.key) {
3702
- logError(
3703
- `"${serviceName}" is multi-instance (keyed by ${schema.keyedBy}). Specify an instance:
3704
- mesh secrets set external/${serviceName} --key=<${schema.keyedBy}>`
3705
- );
3706
- process.exit(1);
3707
- }
3708
- if (opts.key && !isInstanceKey(opts.key)) {
3709
- logError(
3710
- `Invalid instance key "${opts.key}": keys must not contain "/", start with ".", or end with ".config" \u2014 those names are reserved for the index and config mirrors.`
3711
- );
3712
- process.exit(1);
3713
- }
3714
- let existing = {};
3715
- try {
3716
- const response = await smClient.send(
3717
- new GetSecretValueCommand4({ SecretId: secretId })
3718
- );
3719
- if (response.SecretString) {
3720
- existing = JSON.parse(response.SecretString);
3721
- }
3722
- } catch (err) {
3723
- if (!isResourceNotFound(err)) {
3724
- throw err;
3725
- }
3726
- }
3727
- if (opts.json) {
3728
- let values2;
3729
- try {
3730
- values2 = JSON.parse(opts.json);
3731
- } catch {
3732
- logError(`Invalid JSON input. Provide valid JSON, e.g.: --json='{"key": "value"}'`);
3733
- return;
3734
- }
3735
- const merged2 = deepMerge(existing, values2);
3736
- await writeSecret(smClient, secretId, merged2, svc.meta);
3737
- await writeConfigMirror(smClient, secretId, schema, merged2, svc.meta);
3738
- if (opts.key) {
3739
- await addKeyToInstanceIndex(smClient, secretPrefix, opts.key, serviceName);
3740
- }
3741
- logSuccess(`Credentials written to ${secretId}`);
3742
- return;
3743
- }
3744
- console.error("");
3745
- logInfo(`Setting credentials for: ${svc.meta.description || serviceName}`);
3746
- if (opts.key) {
3747
- logInfo(`Instance: ${opts.key}`);
3748
- }
3749
- logInfo(`Secret: ${secretId}`);
3750
- const values = {};
3751
- await promptFields(schema.fields, existing, values, { all: !!opts.all });
3752
- console.error("");
3753
- const merged = deepMerge(existing, values);
3754
- await writeSecret(smClient, secretId, merged, svc.meta);
3755
- await writeConfigMirror(smClient, secretId, schema, merged, svc.meta);
3756
- if (opts.key) {
3757
- await addKeyToInstanceIndex(smClient, secretPrefix, opts.key, serviceName);
3758
- }
3759
- logSuccess(`Credentials written to ${secretId}`);
3760
- console.error("\nStored fields:");
3761
- displaySummary(schema.fields, merged);
3762
- console.error("");
3763
- }
3764
- function isResourceNotFound(err) {
3765
- return isAwsErrorCode(err, "ResourceNotFoundException");
3766
- }
3767
- function deepMerge(target, source) {
3768
- const result = { ...target };
3769
- for (const [key, value] of Object.entries(source)) {
3770
- if (value !== null && typeof value === "object" && !Array.isArray(value) && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
3771
- result[key] = deepMerge(
3772
- result[key],
3773
- value
3774
- );
3775
- } else {
3776
- result[key] = value;
3777
- }
3778
- }
3779
- return result;
3780
- }
3781
- async function writeSecret(client, secretId, values, meta) {
3782
- const secretString = JSON.stringify(values);
3783
- try {
3784
- await client.send(
3785
- new PutSecretValueCommand({
3786
- SecretId: secretId,
3787
- SecretString: secretString
3788
- })
3789
- );
3790
- } catch (err) {
3791
- if (isResourceNotFound(err)) {
3792
- await client.send(
3793
- new CreateSecretCommand({
3794
- Name: secretId,
3795
- Description: `External service credentials for ${meta.name} (instance)`,
3796
- SecretString: secretString,
3797
- Tags: [
3798
- { Key: "mesh:type", Value: "external-service" },
3799
- { Key: "mesh:service", Value: meta.name }
3800
- ]
3801
- })
3802
- );
3803
- } else {
3804
- throw err;
3805
- }
3806
- }
3807
- }
3808
- function extractNonSecretFields(fields, values) {
3809
- const result = {};
3810
- for (const [key, entry] of Object.entries(fields)) {
3811
- if (entry.type === "group") {
3812
- const groupValues = values[key] ?? {};
3813
- const filtered = extractNonSecretFields(entry.fields, groupValues);
3814
- if (Object.keys(filtered).length > 0) {
3815
- result[key] = filtered;
3816
- }
3817
- } else if (!entry.secret && values[key] !== void 0) {
3818
- result[key] = values[key];
3819
- }
3820
- }
3821
- return result;
3822
- }
3823
- async function addKeyToInstanceIndex(client, secretPrefix, key, serviceName) {
3824
- const indexId = instanceIndexSecretId(secretPrefix);
3825
- try {
3826
- let keys = [];
3827
- try {
3828
- const res = await client.send(new GetSecretValueCommand4({ SecretId: indexId }));
3829
- keys = parseInstanceIndex(res.SecretString ?? "");
3830
- } catch (err) {
3831
- if (!isResourceNotFound(err)) throw err;
3832
- }
3833
- if (keys.includes(key)) return;
3834
- const secretString = buildInstanceIndexValue([...keys, key]);
3835
- try {
3836
- await client.send(
3837
- new PutSecretValueCommand({ SecretId: indexId, SecretString: secretString })
3838
- );
3839
- } catch (err) {
3840
- if (!isResourceNotFound(err)) throw err;
3841
- await client.send(
3842
- new CreateSecretCommand({
3843
- Name: indexId,
3844
- Description: `Instance-key index for ${serviceName} (read by listInstances(); maintained by mesh secrets set/reindex and the Hub)`,
3845
- SecretString: secretString,
3846
- Tags: [
3847
- { Key: "mesh:type", Value: "external-service-index" },
3848
- { Key: "mesh:service", Value: serviceName }
3849
- ]
3850
- })
3851
- );
3852
- logInfo(
3853
- `Created ${indexId} OUT OF BAND \u2014 the declaring stack does not manage it. Deploy the declaring stack (it creates the index) before writing keys, or import this secret into the stack before its next deploy.`
3854
- );
3855
- }
3856
- } catch (err) {
3857
- logInfo(
3858
- `Warning: failed to record instance "${key}" in ${indexId} \u2014 listInstances() will not see it until you run: mesh secrets reindex external/${serviceName} (${err})`
3859
- );
3860
- }
3861
- }
3862
- async function writeConfigMirror(client, secretId, schema, merged, meta) {
3863
- const configId = `${secretId}/.config`;
3864
- const configValues = extractNonSecretFields(schema.fields, merged);
3865
- const secretString = JSON.stringify(configValues);
3866
- try {
3867
- try {
3868
- await client.send(
3869
- new PutSecretValueCommand({
3870
- SecretId: configId,
3871
- SecretString: secretString
3872
- })
3873
- );
3874
- } catch (err) {
3875
- if (isResourceNotFound(err)) {
3876
- await client.send(
3877
- new CreateSecretCommand({
3878
- Name: configId,
3879
- Description: `Non-secret credential fields for ${meta.name} (Hub display)`,
3880
- SecretString: secretString,
3881
- Tags: [{ Key: "mesh:type", Value: "external-service-config" }]
3882
- })
3883
- );
3884
- } else {
3885
- throw err;
3886
- }
3887
- }
3888
- } catch (err) {
3889
- logInfo(`Warning: failed to write .config mirror to ${configId}: ${err}`);
3890
- }
3891
- }
3892
-
3893
3551
  // packages/mesh-cli/src/commands/secrets/reindex.ts
3894
- import { SSMClient as SSMClient2 } from "@aws-sdk/client-ssm";
3552
+ import { SSMClient } from "@aws-sdk/client-ssm";
3895
3553
  import {
3896
- SecretsManagerClient as SecretsManagerClient5,
3554
+ SecretsManagerClient as SecretsManagerClient3,
3897
3555
  ListSecretsCommand,
3898
- GetSecretValueCommand as GetSecretValueCommand5,
3899
- PutSecretValueCommand as PutSecretValueCommand2,
3900
- CreateSecretCommand as CreateSecretCommand2
3556
+ GetSecretValueCommand as GetSecretValueCommand3,
3557
+ PutSecretValueCommand,
3558
+ CreateSecretCommand
3901
3559
  } from "@aws-sdk/client-secrets-manager";
3902
3560
  async function scanInstanceKeys(client, secretPrefix) {
3903
3561
  const keys = [];
@@ -3921,17 +3579,10 @@ function indexAlreadyMatches(missing, stale, indexExists, malformed) {
3921
3579
  return missing.length === 0 && stale.length === 0 && indexExists && !malformed;
3922
3580
  }
3923
3581
  async function reindexCommand(servicePath, opts) {
3924
- const stackOpt = resolveStackOption(opts);
3925
- const context = resolveSecretsContext(opts, stackOpt);
3926
3582
  const region = opts.region ?? process.env.AWS_REGION ?? "us-east-2";
3927
- await ensureAwsCredentialsForStack(stackOpt ?? context.stage);
3928
- const ssmClient = new SSMClient2({ region });
3929
- const smClient = new SecretsManagerClient5({ region });
3930
- const services = await discoverExternalServices(
3931
- ssmClient,
3932
- context.tenant,
3933
- context.platformEnv
3934
- );
3583
+ const ssmClient = new SSMClient({ region });
3584
+ const { services } = await discoverStackExternalServices(opts, ssmClient);
3585
+ const smClient = new SecretsManagerClient3({ region });
3935
3586
  const serviceName = servicePath?.replace(/^external\//, "");
3936
3587
  if (!serviceName || !services.has(serviceName)) {
3937
3588
  if (serviceName) {
@@ -3961,7 +3612,7 @@ Usage: mesh secrets reindex external/<name>`);
3961
3612
  let indexExists = true;
3962
3613
  let malformed = false;
3963
3614
  try {
3964
- const res = await smClient.send(new GetSecretValueCommand5({ SecretId: indexId }));
3615
+ const res = await smClient.send(new GetSecretValueCommand3({ SecretId: indexId }));
3965
3616
  try {
3966
3617
  listed = parseInstanceIndex(res.SecretString ?? "");
3967
3618
  } catch {
@@ -3994,12 +3645,12 @@ async function writeInstanceIndex(client, secretPrefix, serviceName, keys) {
3994
3645
  const secretString = buildInstanceIndexValue(keys);
3995
3646
  try {
3996
3647
  await client.send(
3997
- new PutSecretValueCommand2({ SecretId: indexId, SecretString: secretString })
3648
+ new PutSecretValueCommand({ SecretId: indexId, SecretString: secretString })
3998
3649
  );
3999
3650
  } catch (err) {
4000
3651
  if (!isResourceNotFound(err)) throw err;
4001
3652
  await client.send(
4002
- new CreateSecretCommand2({
3653
+ new CreateSecretCommand({
4003
3654
  Name: indexId,
4004
3655
  Description: `Instance-key index for ${serviceName} (read by listInstances(); maintained by mesh secrets set/reindex and the Hub)`,
4005
3656
  SecretString: secretString,
@@ -4017,23 +3668,23 @@ async function writeInstanceIndex(client, secretPrefix, serviceName, keys) {
4017
3668
 
4018
3669
  // packages/mesh-cli/src/commands/secrets/migrate-config.ts
4019
3670
  import {
4020
- SSMClient as SSMClient3,
4021
- GetParametersByPathCommand as GetParametersByPathCommand2
3671
+ SSMClient as SSMClient2,
3672
+ GetParametersByPathCommand
4022
3673
  } from "@aws-sdk/client-ssm";
4023
3674
  import {
4024
- SecretsManagerClient as SecretsManagerClient6,
4025
- GetSecretValueCommand as GetSecretValueCommand6,
4026
- PutSecretValueCommand as PutSecretValueCommand3,
4027
- CreateSecretCommand as CreateSecretCommand3,
3675
+ SecretsManagerClient as SecretsManagerClient4,
3676
+ GetSecretValueCommand as GetSecretValueCommand4,
3677
+ PutSecretValueCommand as PutSecretValueCommand2,
3678
+ CreateSecretCommand as CreateSecretCommand2,
4028
3679
  ListSecretsCommand as ListSecretsCommand2
4029
3680
  } from "@aws-sdk/client-secrets-manager";
4030
- function normalizeEntry2(raw) {
3681
+ function normalizeEntry(raw) {
4031
3682
  if (raw.type === "group" && raw.fields) {
4032
3683
  return {
4033
3684
  type: "group",
4034
3685
  name: raw.name ?? "",
4035
3686
  description: raw.description ?? "",
4036
- fields: normalizeFields2(raw.fields)
3687
+ fields: normalizeFields(raw.fields)
4037
3688
  };
4038
3689
  }
4039
3690
  return {
@@ -4044,18 +3695,18 @@ function normalizeEntry2(raw) {
4044
3695
  optional: raw.optional ?? false
4045
3696
  };
4046
3697
  }
4047
- function normalizeFields2(raw) {
3698
+ function normalizeFields(raw) {
4048
3699
  return Object.fromEntries(
4049
- Object.entries(raw).map(([key, value]) => [key, normalizeEntry2(value)])
3700
+ Object.entries(raw).map(([key, value]) => [key, normalizeEntry(value)])
4050
3701
  );
4051
3702
  }
4052
- async function discoverExternalServices2(ssmClient, tenant, platformEnv) {
3703
+ async function discoverExternalServices(ssmClient, tenant, platformEnv) {
4053
3704
  const services = /* @__PURE__ */ new Map();
4054
3705
  const basePath = `/mesh-platform/${tenant}/${platformEnv}`;
4055
3706
  let nextToken;
4056
3707
  do {
4057
3708
  const response = await ssmClient.send(
4058
- new GetParametersByPathCommand2({
3709
+ new GetParametersByPathCommand({
4059
3710
  Path: basePath,
4060
3711
  Recursive: true,
4061
3712
  NextToken: nextToken
@@ -4075,7 +3726,7 @@ async function discoverExternalServices2(ssmClient, tenant, platformEnv) {
4075
3726
  const serviceName = credMatch[1];
4076
3727
  const raw = JSON.parse(param.Value);
4077
3728
  const schema = {
4078
- fields: normalizeFields2(raw.fields),
3729
+ fields: normalizeFields(raw.fields),
4079
3730
  keyedBy: raw.keyedBy
4080
3731
  };
4081
3732
  const existing = services.get(serviceName);
@@ -4090,12 +3741,12 @@ async function discoverExternalServices2(ssmClient, tenant, platformEnv) {
4090
3741
  } while (nextToken);
4091
3742
  return services;
4092
3743
  }
4093
- function extractNonSecretFields2(fields, values) {
3744
+ function extractNonSecretFields(fields, values) {
4094
3745
  const result = {};
4095
3746
  for (const [key, entry] of Object.entries(fields)) {
4096
3747
  if (entry.type === "group") {
4097
3748
  const groupValues = values[key] ?? {};
4098
- const filtered = extractNonSecretFields2(entry.fields, groupValues);
3749
+ const filtered = extractNonSecretFields(entry.fields, groupValues);
4099
3750
  if (Object.keys(filtered).length > 0) {
4100
3751
  result[key] = filtered;
4101
3752
  }
@@ -4107,20 +3758,20 @@ function extractNonSecretFields2(fields, values) {
4107
3758
  }
4108
3759
  async function readSecret(client, secretId) {
4109
3760
  try {
4110
- const res = await client.send(new GetSecretValueCommand6({ SecretId: secretId }));
3761
+ const res = await client.send(new GetSecretValueCommand4({ SecretId: secretId }));
4111
3762
  return res.SecretString ? JSON.parse(res.SecretString) : null;
4112
3763
  } catch (err) {
4113
3764
  if (isAwsErrorCode(err, "ResourceNotFoundException")) return null;
4114
3765
  throw err;
4115
3766
  }
4116
3767
  }
4117
- async function writeSecret2(client, secretId, values, description) {
3768
+ async function writeSecret(client, secretId, values, description) {
4118
3769
  const secretString = JSON.stringify(values);
4119
3770
  try {
4120
- await client.send(new PutSecretValueCommand3({ SecretId: secretId, SecretString: secretString }));
3771
+ await client.send(new PutSecretValueCommand2({ SecretId: secretId, SecretString: secretString }));
4121
3772
  } catch (err) {
4122
3773
  if (isAwsErrorCode(err, "ResourceNotFoundException")) {
4123
- await client.send(new CreateSecretCommand3({
3774
+ await client.send(new CreateSecretCommand2({
4124
3775
  Name: secretId,
4125
3776
  Description: description,
4126
3777
  SecretString: secretString,
@@ -4133,7 +3784,7 @@ async function writeSecret2(client, secretId, values, description) {
4133
3784
  }
4134
3785
  async function secretExists(client, secretId) {
4135
3786
  try {
4136
- await client.send(new GetSecretValueCommand6({ SecretId: secretId }));
3787
+ await client.send(new GetSecretValueCommand4({ SecretId: secretId }));
4137
3788
  return true;
4138
3789
  } catch (err) {
4139
3790
  if (isAwsErrorCode(err, "ResourceNotFoundException")) return false;
@@ -4184,7 +3835,7 @@ async function migrateService(smClient, meta, schema, opts) {
4184
3835
  skipped++;
4185
3836
  return;
4186
3837
  }
4187
- const configValues = extractNonSecretFields2(schema.fields, values);
3838
+ const configValues = extractNonSecretFields(schema.fields, values);
4188
3839
  if (opts.dryRun) {
4189
3840
  const fieldCount = Object.keys(configValues).length;
4190
3841
  logInfo(` DRY-RUN ${label} \u2192 ${configId} (${fieldCount} non-secret fields)`);
@@ -4192,7 +3843,7 @@ async function migrateService(smClient, meta, schema, opts) {
4192
3843
  return;
4193
3844
  }
4194
3845
  const desc = `Non-secret credential fields for ${meta.name} (Hub display)`;
4195
- await writeSecret2(smClient, configId, configValues, desc);
3846
+ await writeSecret(smClient, configId, configValues, desc);
4196
3847
  logSuccess(` OK ${label} \u2192 ${configId}`);
4197
3848
  migrated++;
4198
3849
  } catch (err) {
@@ -4212,12 +3863,12 @@ async function migrateService(smClient, meta, schema, opts) {
4212
3863
  async function migrateConfigCommand(opts) {
4213
3864
  const context = resolveSecretsContext(opts);
4214
3865
  const region = opts.region ?? process.env.AWS_REGION ?? "us-east-2";
4215
- const ssmClient = new SSMClient3({ region });
4216
- const smClient = new SecretsManagerClient6({ region });
3866
+ const ssmClient = new SSMClient2({ region });
3867
+ const smClient = new SecretsManagerClient4({ region });
4217
3868
  logInfo(`Migrating .config mirrors for ${context.tenant}/${context.platformEnv}`);
4218
3869
  if (opts.dryRun) logInfo("DRY-RUN mode \u2014 no writes");
4219
3870
  if (opts.force) logInfo("FORCE mode \u2014 overwrite existing .config");
4220
- const services = await discoverExternalServices2(ssmClient, context.tenant, context.platformEnv);
3871
+ const services = await discoverExternalServices(ssmClient, context.tenant, context.platformEnv);
4221
3872
  if (services.size === 0) {
4222
3873
  logInfo("No external services found.");
4223
3874
  return;
@@ -4481,13 +4132,13 @@ function registerSiteCommands(program) {
4481
4132
 
4482
4133
  // packages/mesh-cli/src/commands/stack.ts
4483
4134
  import { execFileSync as execFileSync6 } from "child_process";
4484
- import * as path10 from "path";
4135
+ import * as path11 from "path";
4485
4136
  import * as fs10 from "fs";
4486
4137
  import { parse as parseYaml2 } from "yaml";
4487
4138
 
4488
4139
  // packages/mesh-cli/src/commands/stack-status.ts
4489
4140
  import * as fs9 from "fs";
4490
- import * as path9 from "path";
4141
+ import * as path10 from "path";
4491
4142
  import { execFileSync as execFileSync5 } from "child_process";
4492
4143
  var INFRA_PACKAGE = "@mesh-tech/infra-components";
4493
4144
  var HUB_PACKAGE2 = "@mesh-tech/hub";
@@ -4505,10 +4156,10 @@ function targetForStack(projectDir, stack) {
4505
4156
  return { stack, kind: "app", tenant: tenant2, env: env2, coreTenant: tenant2, coreEnv: env2 };
4506
4157
  }
4507
4158
  const declared = readStackConfig(projectDir, stack, "mesh:tenant");
4508
- const layerDir = ["core", "platform"].includes(path9.basename(projectDir));
4159
+ const layerDir = ["core", "platform"].includes(path10.basename(projectDir));
4509
4160
  if (!declared && !layerDir) return null;
4510
4161
  const { tenant, env } = splitLayerStack(stack, declared);
4511
- const isCore = path9.basename(projectDir) === "core";
4162
+ const isCore = path10.basename(projectDir) === "core";
4512
4163
  return {
4513
4164
  stack,
4514
4165
  kind: "layer",
@@ -4524,13 +4175,13 @@ function findStatusTargets(cwd, stack) {
4524
4175
  let projectDir = project;
4525
4176
  let repoRoot = null;
4526
4177
  if (!projectDir) {
4527
- const platformDir = path9.join(cwd, "platform");
4528
- if (fs9.existsSync(path9.join(platformDir, "Pulumi.yaml"))) {
4178
+ const platformDir = path10.join(cwd, "platform");
4179
+ if (fs9.existsSync(path10.join(platformDir, "Pulumi.yaml"))) {
4529
4180
  projectDir = platformDir;
4530
4181
  repoRoot = cwd;
4531
4182
  }
4532
- } else if (["core", "platform"].includes(path9.basename(projectDir))) {
4533
- repoRoot = path9.dirname(projectDir);
4183
+ } else if (["core", "platform"].includes(path10.basename(projectDir))) {
4184
+ repoRoot = path10.dirname(projectDir);
4534
4185
  }
4535
4186
  if (!projectDir) return [];
4536
4187
  const stacks = stack ? [stack] : findStackConfigs(projectDir);
@@ -4539,10 +4190,10 @@ function findStatusTargets(cwd, stack) {
4539
4190
  const target = targetForStack(projectDir, name);
4540
4191
  if (!target) continue;
4541
4192
  if (repoRoot && target.kind === "layer") {
4542
- const core = path9.join(repoRoot, "core");
4543
- const platform = path9.join(repoRoot, "platform");
4544
- if (fs9.existsSync(path9.join(core, "package.json"))) target.coreDir = core;
4545
- if (fs9.existsSync(path9.join(platform, "package.json"))) target.platformDir = platform;
4193
+ const core = path10.join(repoRoot, "core");
4194
+ const platform = path10.join(repoRoot, "platform");
4195
+ if (fs9.existsSync(path10.join(core, "package.json"))) target.coreDir = core;
4196
+ if (fs9.existsSync(path10.join(platform, "package.json"))) target.platformDir = platform;
4546
4197
  }
4547
4198
  targets.push(target);
4548
4199
  }
@@ -4551,7 +4202,7 @@ function findStatusTargets(cwd, stack) {
4551
4202
  function pinnedVersion(dir, pkg) {
4552
4203
  if (!dir) return null;
4553
4204
  try {
4554
- const manifest = JSON.parse(fs9.readFileSync(path9.join(dir, "package.json"), "utf-8"));
4205
+ const manifest = JSON.parse(fs9.readFileSync(path10.join(dir, "package.json"), "utf-8"));
4555
4206
  const spec = manifest.dependencies?.[pkg] ?? manifest.devDependencies?.[pkg];
4556
4207
  return typeof spec === "string" ? spec.replace(/^[\^~=v]+/, "") : null;
4557
4208
  } catch {
@@ -4671,8 +4322,8 @@ function latestPublished(pkg, cwd) {
4671
4322
  async function readRegistration(name, region, auth) {
4672
4323
  const { credentials, profile, signInHint } = auth;
4673
4324
  try {
4674
- const { SSMClient: SSMClient4, GetParameterCommand } = await import("@aws-sdk/client-ssm");
4675
- const client = new SSMClient4({
4325
+ const { SSMClient: SSMClient3, GetParameterCommand } = await import("@aws-sdk/client-ssm");
4326
+ const client = new SSMClient3({
4676
4327
  region,
4677
4328
  ...profile && !credentials?.AWS_ACCESS_KEY_ID ? { profile } : {},
4678
4329
  ...credentials?.AWS_ACCESS_KEY_ID ? {
@@ -4743,7 +4394,7 @@ async function runStackStatus(cwd, opts) {
4743
4394
 
4744
4395
  // packages/mesh-cli/src/commands/stack.ts
4745
4396
  function readTopLevelYamlKey(appRoot, stack, key) {
4746
- const configFile = path10.join(appRoot, `Pulumi.${stack}.yaml`);
4397
+ const configFile = path11.join(appRoot, `Pulumi.${stack}.yaml`);
4747
4398
  if (!fs10.existsSync(configFile)) return null;
4748
4399
  const content = fs10.readFileSync(configFile, "utf-8");
4749
4400
  const pattern = new RegExp(`^${key}:\\s*(.+)$`, "m");
@@ -4752,7 +4403,7 @@ function readTopLevelYamlKey(appRoot, stack, key) {
4752
4403
  return match[1].trim().replace(/^["']|["']$/g, "");
4753
4404
  }
4754
4405
  function readConfigBlockKey(appRoot, stack, key) {
4755
- const configFile = path10.join(appRoot, `Pulumi.${stack}.yaml`);
4406
+ const configFile = path11.join(appRoot, `Pulumi.${stack}.yaml`);
4756
4407
  if (!fs10.existsSync(configFile)) return null;
4757
4408
  const content = fs10.readFileSync(configFile, "utf-8");
4758
4409
  const pattern = new RegExp(`^\\s{2}${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*(.+)$`, "m");
@@ -4814,7 +4465,7 @@ ${records}
4814
4465
  }
4815
4466
  }
4816
4467
  function readBaseConfigFromYaml(appRoot, stack) {
4817
- const file = path10.join(appRoot, `Pulumi.${stack}.yaml`);
4468
+ const file = path11.join(appRoot, `Pulumi.${stack}.yaml`);
4818
4469
  if (!fs10.existsSync(file)) return {};
4819
4470
  let doc;
4820
4471
  try {
@@ -4917,7 +4568,7 @@ Specify which to base on: mesh stack init --from <stack>`
4917
4568
  );
4918
4569
  }
4919
4570
  }
4920
- const newConfigPath = path10.join(appRoot, `Pulumi.${newStack}.yaml`);
4571
+ const newConfigPath = path11.join(appRoot, `Pulumi.${newStack}.yaml`);
4921
4572
  const configExists = fs10.existsSync(newConfigPath);
4922
4573
  const secretsProvider = readTopLevelYamlKey(appRoot, baseStack, "secretsprovider");
4923
4574
  const credEnv = await resolvePulumiEnv({ appRoot, stack: baseStack });
@@ -5117,7 +4768,7 @@ Specify which to base on: mesh stack init --from <stack>`
5117
4768
  import { spawnSync as spawnSync2 } from "node:child_process";
5118
4769
  import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "node:fs";
5119
4770
  import { homedir as homedir3 } from "node:os";
5120
- import { dirname as dirname7, join as join13, resolve as resolve6 } from "node:path";
4771
+ import { dirname as dirname8, join as join13, resolve as resolve6 } from "node:path";
5121
4772
 
5122
4773
  // packages/mesh-cli/src/utils/recover-conversation.ts
5123
4774
  async function classifyHistoryEvents(rawEvents, decodePayload) {
@@ -5805,8 +5456,8 @@ function extractEventPayloads(event) {
5805
5456
  if (failure?.message) groups.push({ label: "failure", payloads: [{ __failure: failure }] });
5806
5457
  }
5807
5458
  if (event.nexusOperationScheduledEventAttributes) {
5808
- const input2 = event.nexusOperationScheduledEventAttributes.input;
5809
- if (input2) pushIfAny("input", [input2]);
5459
+ const input = event.nexusOperationScheduledEventAttributes.input;
5460
+ if (input) pushIfAny("input", [input]);
5810
5461
  }
5811
5462
  if (event.nexusOperationCompletedEventAttributes) {
5812
5463
  const result = event.nexusOperationCompletedEventAttributes.result;
@@ -5989,7 +5640,7 @@ async function captureHistory(workflowId, runId, options) {
5989
5640
  const { serializeHistoryToFixture } = await import("./mesh.capture-history-A4IAVVIR.js");
5990
5641
  const { fixture, eventCount, decryptedPayloads } = await serializeHistoryToFixture(events, decrypter);
5991
5642
  const outPath = options.out ?? join13(homedir3(), ".mesh", "replay-histories", `${sanitizeFileId(workflowId)}.json`);
5992
- mkdirSync5(dirname7(outPath), { recursive: true });
5643
+ mkdirSync5(dirname8(outPath), { recursive: true });
5993
5644
  if (options.out) warnIfNotGitIgnored(options.out);
5994
5645
  writeFileSync5(outPath, JSON.stringify(fixture, null, 2) + "\n");
5995
5646
  logSuccess(
@@ -6008,7 +5659,7 @@ function sanitizeFileId(id) {
6008
5659
  function warnIfNotGitIgnored(outPath) {
6009
5660
  const abs = resolve6(outPath);
6010
5661
  try {
6011
- const res = spawnSync2("git", ["-C", dirname7(abs), "check-ignore", "-q", abs], {
5662
+ const res = spawnSync2("git", ["-C", dirname8(abs), "check-ignore", "-q", abs], {
6012
5663
  stdio: "ignore"
6013
5664
  });
6014
5665
  if (res.status !== 1) return;
@@ -6118,7 +5769,7 @@ function registerTemporalCommands(program) {
6118
5769
  // packages/mesh-cli/src/commands/tenant.ts
6119
5770
  import chalk4 from "chalk";
6120
5771
  import * as fs11 from "fs";
6121
- import * as path11 from "path";
5772
+ import * as path12 from "path";
6122
5773
  import { parseDocument, YAMLMap, isMap } from "yaml";
6123
5774
  function validateTenantName(name) {
6124
5775
  return /^[a-z][a-z0-9-]*$/.test(name) && !name.endsWith("-");
@@ -6186,7 +5837,7 @@ function resolveStackConfig(explicitStack) {
6186
5837
  { remediation: { command: "mesh tenant add <name> --stack <stack>" } }
6187
5838
  );
6188
5839
  }
6189
- const file = path11.join(appRoot, `Pulumi.${stack}.yaml`);
5840
+ const file = path12.join(appRoot, `Pulumi.${stack}.yaml`);
6190
5841
  if (!fs11.existsSync(file)) {
6191
5842
  throw new MeshCliError(`Stack config not found: ${file}`, {
6192
5843
  remediation: { command: "mesh tenant add <name> --stack <stack>" }
@@ -6195,7 +5846,7 @@ function resolveStackConfig(explicitStack) {
6195
5846
  return { appRoot, stack, file, content: fs11.readFileSync(file, "utf-8") };
6196
5847
  }
6197
5848
  function readProjectName(appRoot) {
6198
- const projectDoc = parseDocument(fs11.readFileSync(path11.join(appRoot, "Pulumi.yaml"), "utf-8"));
5849
+ const projectDoc = parseDocument(fs11.readFileSync(path12.join(appRoot, "Pulumi.yaml"), "utf-8"));
6199
5850
  return String(projectDoc.get("name") ?? "");
6200
5851
  }
6201
5852
  function looksLikePlatformLayer(projectName) {
@@ -6238,7 +5889,7 @@ function registerTenantCommands(program) {
6238
5889
  if (!result.ok) {
6239
5890
  if (result.reason === "exists") {
6240
5891
  throw new MeshCliError(
6241
- `${result.detail} (${path11.basename(resolved.file)}). Edit the existing entry instead of re-adding it.`
5892
+ `${result.detail} (${path12.basename(resolved.file)}). Edit the existing entry instead of re-adding it.`
6242
5893
  );
6243
5894
  }
6244
5895
  throw new MeshCliError(`${resolved.file}: ${result.detail}`);
@@ -6256,7 +5907,7 @@ function registerTenantCommands(program) {
6256
5907
  return;
6257
5908
  }
6258
5909
  logInfo(
6259
- `Tenant '${name}' registered in ${path11.basename(resolved.file)} (mesh:tenants, subdomain '${subdomain}')${result.createdTenantsBlock ? " \u2014 created the mesh:tenants block" : ""}`
5910
+ `Tenant '${name}' registered in ${path12.basename(resolved.file)} (mesh:tenants, subdomain '${subdomain}')${result.createdTenantsBlock ? " \u2014 created the mesh:tenants block" : ""}`
6260
5911
  );
6261
5912
  console.log("");
6262
5913
  console.log("Next steps:");
@@ -6282,7 +5933,7 @@ function registerTenantCommands(program) {
6282
5933
  `Project '${projectName}' does not look like a platform layer \u2014 tenants are declared on the tenant platform repo's PLATFORM stack (e.g. mesh-sandbox/platform).`
6283
5934
  );
6284
5935
  }
6285
- logInfo(`No tenants declared in ${path11.basename(resolved.file)}.`);
5936
+ logInfo(`No tenants declared in ${path12.basename(resolved.file)}.`);
6286
5937
  return;
6287
5938
  }
6288
5939
  logInfo(`Tenants on stack '${resolved.stack}':`);
@@ -6296,11 +5947,11 @@ function registerTenantCommands(program) {
6296
5947
  // packages/mesh-cli/src/commands/tunnel/index.ts
6297
5948
  import { spawn as spawn5 } from "child_process";
6298
5949
  import * as fs12 from "fs";
6299
- import * as os4 from "os";
6300
- import * as path12 from "path";
5950
+ import * as os3 from "os";
5951
+ import * as path13 from "path";
6301
5952
  import {
6302
- SecretsManagerClient as SecretsManagerClient7,
6303
- GetSecretValueCommand as GetSecretValueCommand7
5953
+ SecretsManagerClient as SecretsManagerClient5,
5954
+ GetSecretValueCommand as GetSecretValueCommand5
6304
5955
  } from "@aws-sdk/client-secrets-manager";
6305
5956
  function resolveTenantEnv(options) {
6306
5957
  if (options.tenant && options.env) {
@@ -6328,8 +5979,8 @@ function readPulumiAwsRegion(stage) {
6328
5979
  }
6329
5980
  function awsProfileSections(name) {
6330
5981
  return [
6331
- [path12.join(os4.homedir(), ".aws", "config"), `[profile ${name}]`],
6332
- [path12.join(os4.homedir(), ".aws", "credentials"), `[${name}]`]
5982
+ [path13.join(os3.homedir(), ".aws", "config"), `[profile ${name}]`],
5983
+ [path13.join(os3.homedir(), ".aws", "credentials"), `[${name}]`]
6333
5984
  ];
6334
5985
  }
6335
5986
  function awsProfileExists(name) {
@@ -6370,8 +6021,8 @@ function awsProfileRegion(profile) {
6370
6021
  }
6371
6022
  function awsDefaultProfileSections() {
6372
6023
  return [
6373
- [path12.join(os4.homedir(), ".aws", "config"), "[default]"],
6374
- [path12.join(os4.homedir(), ".aws", "credentials"), "[default]"]
6024
+ [path13.join(os3.homedir(), ".aws", "config"), "[default]"],
6025
+ [path13.join(os3.homedir(), ".aws", "credentials"), "[default]"]
6375
6026
  ];
6376
6027
  }
6377
6028
  function awsDefaultProfileRegion() {
@@ -6433,11 +6084,11 @@ function getEffectivePort(serviceName, options) {
6433
6084
  return config.localPort;
6434
6085
  }
6435
6086
  }
6436
- function parseServices(input2) {
6437
- if (SERVICE_GROUPS[input2]) {
6438
- return SERVICE_GROUPS[input2];
6087
+ function parseServices(input) {
6088
+ if (SERVICE_GROUPS[input]) {
6089
+ return SERVICE_GROUPS[input];
6439
6090
  }
6440
- return input2.split(",").map((s) => s.trim());
6091
+ return input.split(",").map((s) => s.trim());
6441
6092
  }
6442
6093
  function spawnSsmTunnel(instanceId, service, localPort) {
6443
6094
  return spawn5(
@@ -6584,10 +6235,10 @@ async function tunnelExternal(name, options) {
6584
6235
  const { appTenant, appStage } = resolveCredentialAxis(options);
6585
6236
  const secretId = externalSecretId(appTenant, appStage, name, key);
6586
6237
  const setHint = `mesh secrets set external/${name}${key ? ` --key=${key}` : ""}`;
6587
- const sm = new SecretsManagerClient7({});
6238
+ const sm = new SecretsManagerClient5({});
6588
6239
  let creds;
6589
6240
  try {
6590
- const out = await sm.send(new GetSecretValueCommand7({ SecretId: secretId }));
6241
+ const out = await sm.send(new GetSecretValueCommand5({ SecretId: secretId }));
6591
6242
  creds = JSON.parse(out.SecretString ?? "{}");
6592
6243
  } catch (err) {
6593
6244
  logError(
@@ -6750,7 +6401,7 @@ async function resolveToken(opts) {
6750
6401
  if (opts.token) return opts.token;
6751
6402
  if (process.env.VCS_TOKEN) return process.env.VCS_TOKEN;
6752
6403
  if (opts.context) {
6753
- const { getValidToken: getValidToken2 } = await import("./mesh.login-6VPMWHHU.js");
6404
+ const { getValidToken: getValidToken2 } = await import("./mesh.login-3AWVGPCM.js");
6754
6405
  const token = await getValidToken2(opts.context);
6755
6406
  if (token) return token;
6756
6407
  }
@@ -6758,8 +6409,8 @@ async function resolveToken(opts) {
6758
6409
  "no token: pass --token, set VCS_TOKEN, or pass --context <platform-context> (after mesh login)"
6759
6410
  );
6760
6411
  }
6761
- async function vcsApi(baseUrl, token, path14, method = "GET", body) {
6762
- const res = await fetch(`${baseUrl}${path14}`, {
6412
+ async function vcsApi(baseUrl, token, path15, method = "GET", body) {
6413
+ const res = await fetch(`${baseUrl}${path15}`, {
6763
6414
  method,
6764
6415
  headers: {
6765
6416
  authorization: `Bearer ${token}`,
@@ -6770,7 +6421,7 @@ async function vcsApi(baseUrl, token, path14, method = "GET", body) {
6770
6421
  const data = await res.json().catch(() => ({}));
6771
6422
  if (!res.ok) {
6772
6423
  throw new Error(
6773
- `${method} ${path14} failed (${res.status}): ${String(data.error ?? "unknown error")}`
6424
+ `${method} ${path15} failed (${res.status}): ${String(data.error ?? "unknown error")}`
6774
6425
  );
6775
6426
  }
6776
6427
  return data;
@@ -6803,8 +6454,8 @@ async function cloneCommand(repo, dest, opts) {
6803
6454
 
6804
6455
  // packages/mesh-cli/src/commands/vcs/get.ts
6805
6456
  import { writeFile, mkdir } from "node:fs/promises";
6806
- import { join as join16, dirname as dirname8 } from "node:path";
6807
- async function getCommand(repo, path14, opts) {
6457
+ import { join as join16, dirname as dirname9 } from "node:path";
6458
+ async function getCommand(repo, path15, opts) {
6808
6459
  let vcsBaseUrl;
6809
6460
  let token;
6810
6461
  if (opts.target) {
@@ -6819,18 +6470,18 @@ async function getCommand(repo, path14, opts) {
6819
6470
  if (!token) throw new Error("no token: pass --target (after mesh login), or --token / --context");
6820
6471
  const reader = createVcsFolderReader({ vcsBaseUrl, token });
6821
6472
  try {
6822
- const { ref, files } = await reader.readPath(repo, path14);
6473
+ const { ref, files } = await reader.readPath(repo, path15);
6823
6474
  if (files.length === 0) {
6824
- logInfo(`no files at ${repo}:${path14}`);
6475
+ logInfo(`no files at ${repo}:${path15}`);
6825
6476
  return;
6826
6477
  }
6827
6478
  if (opts.output) {
6828
6479
  for (const f of files) {
6829
6480
  const abs = join16(opts.output, f.path);
6830
- await mkdir(dirname8(abs), { recursive: true });
6481
+ await mkdir(dirname9(abs), { recursive: true });
6831
6482
  await writeFile(abs, f.contents);
6832
6483
  }
6833
- logInfo(`wrote ${files.length} file(s) from ${repo}:${path14} (${ref}) \u2192 ${opts.output}`);
6484
+ logInfo(`wrote ${files.length} file(s) from ${repo}:${path15} (${ref}) \u2192 ${opts.output}`);
6834
6485
  } else {
6835
6486
  for (const f of files) {
6836
6487
  if (files.length > 1) process.stdout.write(`
@@ -6845,10 +6496,10 @@ async function getCommand(repo, path14, opts) {
6845
6496
  }
6846
6497
 
6847
6498
  // packages/mesh-cli/src/commands/vcs/drafts.ts
6848
- async function call(opts, repo, path14, method = "GET", body) {
6499
+ async function call(opts, repo, path15, method = "GET", body) {
6849
6500
  const target = await resolveTarget2({ ...opts, repo });
6850
6501
  const token = await resolveToken(opts);
6851
- return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path14}`, method, body);
6502
+ return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path15}`, method, body);
6852
6503
  }
6853
6504
  async function draftsListCommand(repo, opts) {
6854
6505
  const data = await call(opts, repo, `/drafts${opts.all ? "?all=true" : ""}`);
@@ -6930,13 +6581,13 @@ function parseStatus(out) {
6930
6581
  }
6931
6582
  return changes;
6932
6583
  }
6933
- async function writeOp(cwd, path14) {
6934
- const buf = await readFile2(join17(cwd, path14));
6584
+ async function writeOp(cwd, path15) {
6585
+ const buf = await readFile2(join17(cwd, path15));
6935
6586
  const asUtf8 = buf.toString("utf8");
6936
6587
  if (Buffer.from(asUtf8, "utf8").equals(buf)) {
6937
- return { op: "write", path: path14, content: asUtf8 };
6588
+ return { op: "write", path: path15, content: asUtf8 };
6938
6589
  }
6939
- return { op: "write", path: path14, content: buf.toString("base64"), encoding: "base64" };
6590
+ return { op: "write", path: path15, content: buf.toString("base64"), encoding: "base64" };
6940
6591
  }
6941
6592
  async function proposeCommand(opts) {
6942
6593
  const cwd = process.cwd();
@@ -6980,8 +6631,8 @@ async function proposeCommand(opts) {
6980
6631
  operations,
6981
6632
  ...opts.mergeParent ? { mergeParent: opts.mergeParent } : {}
6982
6633
  };
6983
- const path14 = opts.revise ? `/v1/repos/${target.repo}/proposals/${opts.revise}/revisions` : `/v1/repos/${target.repo}/proposals`;
6984
- const data = await vcsApi(target.baseUrl, token, path14, "POST", body);
6634
+ const path15 = opts.revise ? `/v1/repos/${target.repo}/proposals/${opts.revise}/revisions` : `/v1/repos/${target.repo}/proposals`;
6635
+ const data = await vcsApi(target.baseUrl, token, path15, "POST", body);
6985
6636
  console.log(
6986
6637
  `proposal ${data.proposalId} @ ${data.sha.slice(0, 8)} \u2014 review: mesh vcs show ${target.repo} ${data.proposalId} --url ${target.baseUrl}`
6987
6638
  );
@@ -6989,7 +6640,7 @@ async function proposeCommand(opts) {
6989
6640
 
6990
6641
  // packages/mesh-cli/src/commands/vcs/rm.ts
6991
6642
  import { mkdtemp, rm as rmrf } from "node:fs/promises";
6992
- import { tmpdir as tmpdir3 } from "node:os";
6643
+ import { tmpdir as tmpdir2 } from "node:os";
6993
6644
  import { join as join18 } from "node:path";
6994
6645
  function normalize(p) {
6995
6646
  return p.trim().replace(/^\.\//, "").replace(/\/+$/, "");
@@ -6997,21 +6648,21 @@ function normalize(p) {
6997
6648
  function expandPathsToDeletions(repoFiles, requested) {
6998
6649
  const out = /* @__PURE__ */ new Set();
6999
6650
  for (const raw of requested) {
7000
- const path14 = normalize(raw);
7001
- if (path14.startsWith("/") || path14.split("/").includes("..")) {
6651
+ const path15 = normalize(raw);
6652
+ if (path15.startsWith("/") || path15.split("/").includes("..")) {
7002
6653
  throw new Error(
7003
6654
  `"${raw}" is not a repo-relative path \u2014 vcs paths never start with "/" or traverse with "..".`
7004
6655
  );
7005
6656
  }
7006
- const exact = repoFiles.filter((f) => f === path14);
6657
+ const exact = repoFiles.filter((f) => f === path15);
7007
6658
  if (exact.length > 0) {
7008
6659
  for (const f of exact) out.add(f);
7009
6660
  continue;
7010
6661
  }
7011
- const under = repoFiles.filter((f) => f.startsWith(`${path14}/`));
6662
+ const under = repoFiles.filter((f) => f.startsWith(`${path15}/`));
7012
6663
  if (under.length === 0) {
7013
6664
  throw new Error(
7014
- `"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${path14}`
6665
+ `"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${path15}`
7015
6666
  );
7016
6667
  }
7017
6668
  for (const f of under) out.add(f);
@@ -7022,7 +6673,7 @@ async function rmCommand(repo, paths, opts) {
7022
6673
  const baseUrl = (opts.url ?? process.env.VCS_URL)?.replace(/\/$/, "");
7023
6674
  if (!baseUrl) throw new Error("rm requires --url or VCS_URL");
7024
6675
  const token = await resolveToken(opts);
7025
- const dir = await mkdtemp(join18(tmpdir3(), "mesh-vcs-rm-"));
6676
+ const dir = await mkdtemp(join18(tmpdir2(), "mesh-vcs-rm-"));
7026
6677
  try {
7027
6678
  const git = (args, cwd) => gitWithAuth(args, token, cwd);
7028
6679
  await git([
@@ -7047,7 +6698,7 @@ async function rmCommand(repo, paths, opts) {
7047
6698
  const body = {
7048
6699
  baseCommit: head.trim(),
7049
6700
  message: opts.message ?? `Delete ${doomed.length} file(s)`,
7050
- operations: doomed.map((path14) => ({ op: "delete", path: path14 }))
6701
+ operations: doomed.map((path15) => ({ op: "delete", path: path15 }))
7051
6702
  };
7052
6703
  const data = await vcsApi(
7053
6704
  baseUrl,
@@ -7067,10 +6718,10 @@ async function rmCommand(repo, paths, opts) {
7067
6718
  }
7068
6719
 
7069
6720
  // packages/mesh-cli/src/commands/vcs/review.ts
7070
- async function call2(opts, repo, path14, method = "GET", body) {
6721
+ async function call2(opts, repo, path15, method = "GET", body) {
7071
6722
  const target = await resolveTarget2({ ...opts, repo });
7072
6723
  const token = await resolveToken(opts);
7073
- return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path14}`, method, body);
6724
+ return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path15}`, method, body);
7074
6725
  }
7075
6726
  async function proposalsCommand(repo, opts) {
7076
6727
  console.log(JSON.stringify(await call2(opts, repo, "/proposals"), null, 2));
@@ -7159,7 +6810,7 @@ function registerVcsCommands(program) {
7159
6810
 
7160
6811
  // packages/mesh-cli/src/commands/workflow.ts
7161
6812
  import * as fs13 from "fs";
7162
- import * as path13 from "path";
6813
+ import * as path14 from "path";
7163
6814
  import { createRequire as createRequire2 } from "module";
7164
6815
  import { execFileSync as execFileSync8 } from "child_process";
7165
6816
  var DISCOVERY_HELPERS_SRC = `
@@ -7473,7 +7124,7 @@ function registerWorkflowCommands(program) {
7473
7124
  ).action(
7474
7125
  async (targetPath, opts) => {
7475
7126
  try {
7476
- const resolvedPath = path13.resolve(targetPath);
7127
+ const resolvedPath = path14.resolve(targetPath);
7477
7128
  if (!fs13.existsSync(resolvedPath)) {
7478
7129
  logError(`Path does not exist: ${resolvedPath}`);
7479
7130
  process.exitCode = 1;
@@ -7481,7 +7132,7 @@ function registerWorkflowCommands(program) {
7481
7132
  }
7482
7133
  let resolvedProcessPath;
7483
7134
  if (opts.process) {
7484
- resolvedProcessPath = path13.resolve(opts.process);
7135
+ resolvedProcessPath = path14.resolve(opts.process);
7485
7136
  if (!fs13.existsSync(resolvedProcessPath)) {
7486
7137
  logError(`--process path does not exist: ${resolvedProcessPath}`);
7487
7138
  process.exitCode = 1;
@@ -7531,7 +7182,7 @@ function registerWorkflowCommands(program) {
7531
7182
  "Extract the as-built command/query/activity inventory from Temporal workflow source\n\nThe inventory ({ workflowType, commands, queries, activities }) is the process-\nconformance lint's code-side input \u2014 it is never hand-edited. Supports single\nfiles or directories."
7532
7183
  ).action(async (targetPath) => {
7533
7184
  try {
7534
- const resolvedPath = path13.resolve(targetPath);
7185
+ const resolvedPath = path14.resolve(targetPath);
7535
7186
  if (!fs13.existsSync(resolvedPath)) {
7536
7187
  logError(`Path does not exist: ${resolvedPath}`);
7537
7188
  process.exitCode = 1;
@@ -7578,7 +7229,7 @@ function registerWorkflowCommands(program) {
7578
7229
  "Comma-separated named-selector registry (enables UNKNOWN_SELECTOR checks)"
7579
7230
  ).action(async (targetPath, opts) => {
7580
7231
  try {
7581
- const resolvedPath = path13.resolve(targetPath);
7232
+ const resolvedPath = path14.resolve(targetPath);
7582
7233
  if (!fs13.existsSync(resolvedPath)) {
7583
7234
  logError(`Path does not exist: ${resolvedPath}`);
7584
7235
  process.exitCode = 1;
@@ -7586,7 +7237,7 @@ function registerWorkflowCommands(program) {
7586
7237
  }
7587
7238
  let resolvedProcessPath;
7588
7239
  if (opts.process) {
7589
- resolvedProcessPath = path13.resolve(opts.process);
7240
+ resolvedProcessPath = path14.resolve(opts.process);
7590
7241
  if (!fs13.existsSync(resolvedProcessPath)) {
7591
7242
  logError(`--process path does not exist: ${resolvedProcessPath}`);
7592
7243
  process.exitCode = 1;
@@ -7693,6 +7344,7 @@ function createProgram(options = {}) {
7693
7344
  registerStackCommand(program);
7694
7345
  registerTunnelCommands(program);
7695
7346
  registerSecretsCommands(program);
7347
+ registerMcpCommands(program);
7696
7348
  registerArtifactsCommands(program);
7697
7349
  registerConversationsCommands(program);
7698
7350
  registerVpnCommands(program);