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