@mesh-tech/mesh-cli 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/mesh.js CHANGED
@@ -1251,9 +1251,11 @@ var init_cache_home = __esm({
1251
1251
  // libs/mesh-cli/src/commands/local/stack.ts
1252
1252
  var stack_exports = {};
1253
1253
  __export(stack_exports, {
1254
+ BASE_COMPOSE_FILE: () => BASE_COMPOSE_FILE,
1254
1255
  COMPOSE_PROJECT: () => COMPOSE_PROJECT,
1255
1256
  DEFAULT_HUB_PORT: () => DEFAULT_HUB_PORT,
1256
1257
  HUB_OVERLAY_FILE: () => HUB_OVERLAY_FILE,
1258
+ IDPS_OVERLAY_FILE: () => IDPS_OVERLAY_FILE,
1257
1259
  ONE_SHOT_SERVICES: () => ONE_SHOT_SERVICES,
1258
1260
  STACK_ENDPOINTS: () => STACK_ENDPOINTS,
1259
1261
  compose: () => compose,
@@ -1264,11 +1266,12 @@ __export(stack_exports, {
1264
1266
  findPackageRoot: () => findPackageRoot,
1265
1267
  hubApiRunning: () => hubApiRunning,
1266
1268
  hubEndpoints: () => hubEndpoints,
1267
- hubOverlayRunning: () => hubOverlayRunning,
1268
1269
  hubOverlayServices: () => hubOverlayServices,
1269
1270
  hubPort: () => hubPort,
1271
+ idpsOverlayServices: () => idpsOverlayServices,
1270
1272
  localLogsDir: () => localLogsDir,
1271
1273
  localProbesDir: () => localProbesDir,
1274
+ overlayRunning: () => overlayRunning,
1272
1275
  parseComposePs: () => parseComposePs,
1273
1276
  parseComposeServiceNames: () => parseComposeServiceNames,
1274
1277
  probeEndpoint: () => probeEndpoint,
@@ -1368,17 +1371,29 @@ function parseComposeServiceNames(yamlText) {
1368
1371
  const doc = parseYaml(yamlText);
1369
1372
  return Object.keys(doc?.services ?? {});
1370
1373
  }
1371
- function hubOverlayServices() {
1372
- if (!hubOverlayServicesCache) {
1373
- const file = path5.join(stackDir(), HUB_OVERLAY_FILE);
1374
- if (!fs5.existsSync(file)) {
1375
- throw new MeshCliError(`Local stack assets are incomplete: ${file} is missing.`, {
1376
- remediation: { command: "npm install -g @mesh-tech/mesh-cli" }
1377
- });
1378
- }
1379
- hubOverlayServicesCache = new Set(parseComposeServiceNames(fs5.readFileSync(file, "utf-8")));
1374
+ function overlayServicesOf(overlayFile) {
1375
+ const cached = overlayServicesCache.get(overlayFile);
1376
+ if (cached) return cached;
1377
+ const file = path5.join(stackDir(), overlayFile);
1378
+ if (!fs5.existsSync(file)) {
1379
+ throw new MeshCliError(`Local stack assets are incomplete: ${file} is missing.`, {
1380
+ remediation: { command: "npm install -g @mesh-tech/mesh-cli" }
1381
+ });
1380
1382
  }
1381
- return hubOverlayServicesCache;
1383
+ const base = new Set(
1384
+ parseComposeServiceNames(fs5.readFileSync(path5.join(stackDir(), BASE_COMPOSE_FILE), "utf-8"))
1385
+ );
1386
+ const names = new Set(
1387
+ parseComposeServiceNames(fs5.readFileSync(file, "utf-8")).filter((n) => !base.has(n))
1388
+ );
1389
+ overlayServicesCache.set(overlayFile, names);
1390
+ return names;
1391
+ }
1392
+ function hubOverlayServices() {
1393
+ return overlayServicesOf(HUB_OVERLAY_FILE);
1394
+ }
1395
+ function idpsOverlayServices() {
1396
+ return overlayServicesOf(IDPS_OVERLAY_FILE);
1382
1397
  }
1383
1398
  function stackOwnedElsewhere() {
1384
1399
  try {
@@ -1416,6 +1431,7 @@ function compose(args, opts = {}) {
1416
1431
  const dir = stackDir();
1417
1432
  const files = ["-f", path5.join(dir, "docker-compose.yml")];
1418
1433
  if (opts.hub) files.push("-f", path5.join(dir, "docker-compose.hub.yml"));
1434
+ if (opts.idps) files.push("-f", path5.join(dir, IDPS_OVERLAY_FILE));
1419
1435
  const fullArgs = ["compose", "-p", COMPOSE_PROJECT, ...files, ...args];
1420
1436
  return execFileSync4("docker", fullArgs, {
1421
1437
  cwd: dir,
@@ -1451,6 +1467,7 @@ async function composeStreamed(args, opts = {}) {
1451
1467
  const dir = stackDir();
1452
1468
  const files = ["-f", path5.join(dir, "docker-compose.yml")];
1453
1469
  if (opts.hub) files.push("-f", path5.join(dir, "docker-compose.hub.yml"));
1470
+ if (opts.idps) files.push("-f", path5.join(dir, IDPS_OVERLAY_FILE));
1454
1471
  const fullArgs = ["compose", "-p", COMPOSE_PROJECT, ...files, ...args];
1455
1472
  const env = {
1456
1473
  ...process.env,
@@ -1539,11 +1556,14 @@ function stackServices() {
1539
1556
  return parseComposePs(compose(["ps", "-a", "--format", "json"], { hub: true }));
1540
1557
  }
1541
1558
  function crashedServices(services, opts) {
1559
+ const dormant = new Set(
1560
+ opts.overlays.filter((o) => !o.started).flatMap((o) => [...o.services])
1561
+ );
1542
1562
  return services.filter(
1543
- (s) => s.state === "exited" && !ONE_SHOT_SERVICES.has(s.name) && (opts.overlayStarted || !opts.overlayServices.has(s.name))
1563
+ (s) => s.state === "exited" && !ONE_SHOT_SERVICES.has(s.name) && !dormant.has(s.name)
1544
1564
  );
1545
1565
  }
1546
- function hubOverlayRunning(services, overlayServices) {
1566
+ function overlayRunning(services, overlayServices) {
1547
1567
  return services.some((s) => overlayServices.has(s.name) && s.state === "running");
1548
1568
  }
1549
1569
  function hubApiRunning(services) {
@@ -1563,7 +1583,7 @@ async function probeEndpoint(endpoint) {
1563
1583
  }
1564
1584
  return true;
1565
1585
  }
1566
- var COMPOSE_PROJECT, STACK_ENDPOINTS, DEFAULT_HUB_PORT, HUB_OVERLAY_FILE, hubOverlayServicesCache, ONE_SHOT_SERVICES;
1586
+ var COMPOSE_PROJECT, STACK_ENDPOINTS, DEFAULT_HUB_PORT, BASE_COMPOSE_FILE, HUB_OVERLAY_FILE, IDPS_OVERLAY_FILE, overlayServicesCache, ONE_SHOT_SERVICES;
1567
1587
  var init_stack = __esm({
1568
1588
  "libs/mesh-cli/src/commands/local/stack.ts"() {
1569
1589
  "use strict";
@@ -1668,7 +1688,10 @@ var init_stack = __esm({
1668
1688
  }
1669
1689
  ];
1670
1690
  DEFAULT_HUB_PORT = "9000";
1691
+ BASE_COMPOSE_FILE = "docker-compose.yml";
1671
1692
  HUB_OVERLAY_FILE = "docker-compose.hub.yml";
1693
+ IDPS_OVERLAY_FILE = "docker-compose.idps.yml";
1694
+ overlayServicesCache = /* @__PURE__ */ new Map();
1672
1695
  ONE_SHOT_SERVICES = /* @__PURE__ */ new Set(["spicedb-migrate", "zitadel-machinekey-init"]);
1673
1696
  }
1674
1697
  });
@@ -3803,11 +3826,11 @@ function readAllCredentials() {
3803
3826
  function readCredentials(context) {
3804
3827
  return readAllCredentials()[context] ?? null;
3805
3828
  }
3806
- function atomicWriteFileSync(path47, data, mode) {
3807
- const tmpPath = `${path47}.${process.pid}.${atomicWriteCounter++}.tmp`;
3829
+ function atomicWriteFileSync(path48, data, mode) {
3830
+ const tmpPath = `${path48}.${process.pid}.${atomicWriteCounter++}.tmp`;
3808
3831
  try {
3809
3832
  fs10.writeFileSync(tmpPath, data, { mode });
3810
- fs10.renameSync(tmpPath, path47);
3833
+ fs10.renameSync(tmpPath, path48);
3811
3834
  } catch (err) {
3812
3835
  try {
3813
3836
  fs10.unlinkSync(tmpPath);
@@ -6674,10 +6697,143 @@ var init_src = __esm({
6674
6697
  }
6675
6698
  });
6676
6699
 
6677
- // libs/mesh-cli/src/commands/local/seed-zitadel.ts
6700
+ // libs/mesh-cli/src/commands/local/mock-idps.ts
6701
+ import { execFileSync as execFileSync13 } from "child_process";
6678
6702
  import * as fs16 from "fs";
6679
- import * as os5 from "os";
6680
6703
  import * as path16 from "path";
6704
+ function ensureMockSamlSigningKey() {
6705
+ const dir = keyDir();
6706
+ const certPath = path16.join(dir, "cert.pem");
6707
+ const keyPath = path16.join(dir, "key.pem");
6708
+ if (!fs16.existsSync(certPath) || !fs16.existsSync(keyPath)) {
6709
+ fs16.mkdirSync(dir, { recursive: true });
6710
+ try {
6711
+ execFileSync13(
6712
+ "openssl",
6713
+ [
6714
+ "req",
6715
+ "-x509",
6716
+ "-newkey",
6717
+ "rsa:2048",
6718
+ "-keyout",
6719
+ keyPath,
6720
+ "-out",
6721
+ certPath,
6722
+ "-days",
6723
+ "3650",
6724
+ "-nodes",
6725
+ "-subj",
6726
+ "/CN=mesh-local-mock-saml"
6727
+ ],
6728
+ { stdio: "ignore" }
6729
+ );
6730
+ } catch (cause) {
6731
+ throw new MeshCliError("Could not generate the mock SAML signing key.", {
6732
+ remediation: {
6733
+ command: "openssl version # openssl must be on PATH for --with-idps"
6734
+ },
6735
+ cause
6736
+ });
6737
+ }
6738
+ }
6739
+ return {
6740
+ publicKeyB64: fs16.readFileSync(certPath).toString("base64"),
6741
+ privateKeyB64: fs16.readFileSync(keyPath).toString("base64")
6742
+ };
6743
+ }
6744
+ var MOCK_SAML_PORT, MOCK_OIDC_PORT, MOCK_OIDC_SERVICE, idpEndpoints, MOCK_SAML_IDP_NAME, MOCK_OIDC_IDP_NAME, MOCK_OIDC_CLIENT_ID, MOCK_OIDC_CLIENT_SECRET, mockSamlMetadataUrl, mockOidcEndpoints, keyDir, mockIdpComposeEnv, buildMockSamlIdpBody, buildMockOauthIdpBody, missingLoginPolicyIdps;
6745
+ var init_mock_idps = __esm({
6746
+ "libs/mesh-cli/src/commands/local/mock-idps.ts"() {
6747
+ "use strict";
6748
+ init_cache_home();
6749
+ init_errors();
6750
+ MOCK_SAML_PORT = 4569;
6751
+ MOCK_OIDC_PORT = 5556;
6752
+ MOCK_OIDC_SERVICE = "mock-oidc";
6753
+ idpEndpoints = () => [
6754
+ {
6755
+ service: "mock-saml",
6756
+ label: "Mock SAML IdP",
6757
+ url: `http://localhost:${MOCK_SAML_PORT}`,
6758
+ probe: { kind: "http", url: mockSamlMetadataUrl() },
6759
+ hint: "sign in as any email you type; federation metadata at /api/saml/metadata"
6760
+ },
6761
+ {
6762
+ service: MOCK_OIDC_SERVICE,
6763
+ label: "Mock OIDC IdP",
6764
+ url: `http://localhost:${MOCK_OIDC_PORT}/dex`,
6765
+ probe: {
6766
+ kind: "http",
6767
+ url: `http://localhost:${MOCK_OIDC_PORT}/dex/.well-known/openid-configuration`
6768
+ },
6769
+ hint: "dev@local.mesh or ops@local.mesh / password"
6770
+ }
6771
+ ];
6772
+ MOCK_SAML_IDP_NAME = "Mock SAML (local)";
6773
+ MOCK_OIDC_IDP_NAME = "Mock OIDC (local)";
6774
+ MOCK_OIDC_CLIENT_ID = "mesh-local";
6775
+ MOCK_OIDC_CLIENT_SECRET = "mesh-local-secret";
6776
+ mockSamlMetadataUrl = () => `http://localhost:${MOCK_SAML_PORT}/api/saml/metadata`;
6777
+ mockOidcEndpoints = () => ({
6778
+ authorization: `http://localhost:${MOCK_OIDC_PORT}/dex/auth`,
6779
+ token: `http://${MOCK_OIDC_SERVICE}:${MOCK_OIDC_PORT}/dex/token`,
6780
+ user: `http://${MOCK_OIDC_SERVICE}:${MOCK_OIDC_PORT}/dex/userinfo`
6781
+ });
6782
+ keyDir = () => path16.join(meshCacheDir("mesh-local"), "mock-idp");
6783
+ mockIdpComposeEnv = () => {
6784
+ const { publicKeyB64, privateKeyB64 } = ensureMockSamlSigningKey();
6785
+ return {
6786
+ MESH_MOCK_SAML_PUBLIC_KEY: publicKeyB64,
6787
+ MESH_MOCK_SAML_PRIVATE_KEY: privateKeyB64
6788
+ };
6789
+ };
6790
+ buildMockSamlIdpBody = (metadataXml) => ({
6791
+ name: MOCK_SAML_IDP_NAME,
6792
+ metadataXml: Buffer.from(metadataXml, "utf-8").toString("base64"),
6793
+ binding: "SAML_BINDING_POST",
6794
+ withSignedRequest: true,
6795
+ providerOptions: {
6796
+ isLinkingAllowed: true,
6797
+ isCreationAllowed: true,
6798
+ isAutoCreation: true,
6799
+ isAutoUpdate: true,
6800
+ // Matches the component's default: without it a federated sign-in for an
6801
+ // address that already has a Zitadel account fails as a duplicate
6802
+ // instead of linking, which is the behaviour worth being able to see.
6803
+ autoLinking: "AUTO_LINKING_OPTION_EMAIL"
6804
+ }
6805
+ });
6806
+ buildMockOauthIdpBody = () => {
6807
+ const endpoints = mockOidcEndpoints();
6808
+ return {
6809
+ name: MOCK_OIDC_IDP_NAME,
6810
+ clientId: MOCK_OIDC_CLIENT_ID,
6811
+ clientSecret: MOCK_OIDC_CLIENT_SECRET,
6812
+ authorizationEndpoint: endpoints.authorization,
6813
+ tokenEndpoint: endpoints.token,
6814
+ userEndpoint: endpoints.user,
6815
+ scopes: ["openid", "profile", "email"],
6816
+ idAttribute: "sub",
6817
+ providerOptions: {
6818
+ isLinkingAllowed: true,
6819
+ isCreationAllowed: true,
6820
+ isAutoCreation: true,
6821
+ isAutoUpdate: true,
6822
+ autoLinking: "AUTO_LINKING_OPTION_EMAIL"
6823
+ }
6824
+ };
6825
+ };
6826
+ missingLoginPolicyIdps = (attached, wanted) => {
6827
+ const have = new Set(attached);
6828
+ return [...new Set(wanted)].filter((id) => !have.has(id));
6829
+ };
6830
+ }
6831
+ });
6832
+
6833
+ // libs/mesh-cli/src/commands/local/seed-zitadel.ts
6834
+ import * as fs17 from "fs";
6835
+ import * as os5 from "os";
6836
+ import * as path17 from "path";
6681
6837
  function buildCliAppPayload() {
6682
6838
  return {
6683
6839
  name: CLI_APP_NAME,
@@ -6694,10 +6850,10 @@ function buildCliAppPayload() {
6694
6850
  };
6695
6851
  }
6696
6852
  function readSeederPat() {
6697
- const tmp = path16.join(fs16.mkdtempSync(path16.join(os5.tmpdir(), "mesh-zitadel-")), "pat.txt");
6853
+ const tmp = path17.join(fs17.mkdtempSync(path17.join(os5.tmpdir(), "mesh-zitadel-")), "pat.txt");
6698
6854
  try {
6699
6855
  compose(["cp", "zitadel:/machinekey/pat.txt", tmp]);
6700
- const pat = fs16.readFileSync(tmp, "utf-8").trim();
6856
+ const pat = fs17.readFileSync(tmp, "utf-8").trim();
6701
6857
  if (!pat) throw new Error("empty PAT file");
6702
6858
  return pat;
6703
6859
  } catch {
@@ -6706,7 +6862,7 @@ function readSeederPat() {
6706
6862
  { remediation: { command: "mesh stop --destroy && mesh start" } }
6707
6863
  );
6708
6864
  } finally {
6709
- fs16.rmSync(path16.dirname(tmp), { recursive: true, force: true });
6865
+ fs17.rmSync(path17.dirname(tmp), { recursive: true, force: true });
6710
6866
  }
6711
6867
  }
6712
6868
  async function api(pat, method, apiPath, body, orgId) {
@@ -6805,11 +6961,11 @@ async function ensureTestUsers(pat) {
6805
6961
  }
6806
6962
  }
6807
6963
  function hubAuthPath() {
6808
- return path16.join(meshCacheDir("mesh-local"), "hub-auth.json");
6964
+ return path17.join(meshCacheDir("mesh-local"), "hub-auth.json");
6809
6965
  }
6810
6966
  function readHubAuth() {
6811
6967
  try {
6812
- const parsed = JSON.parse(fs16.readFileSync(hubAuthPath(), "utf-8"));
6968
+ const parsed = JSON.parse(fs17.readFileSync(hubAuthPath(), "utf-8"));
6813
6969
  if (parsed?.clientId && parsed?.clientSecret && parsed?.cookieSecret) return parsed;
6814
6970
  return null;
6815
6971
  } catch {
@@ -6948,7 +7104,7 @@ async function seedHubAuth(pat) {
6948
7104
  clientSecret: app.clientSecret ?? persisted?.clientSecret ?? "",
6949
7105
  cookieSecret: persistedCookie ?? (await import("crypto")).randomBytes(16).toString("hex")
6950
7106
  };
6951
- fs16.writeFileSync(hubAuthPath(), JSON.stringify(config, null, 2), { mode: 384 });
7107
+ fs17.writeFileSync(hubAuthPath(), JSON.stringify(config, null, 2), { mode: 384 });
6952
7108
  return config;
6953
7109
  }
6954
7110
  async function publishHubAuthzPointer(projectId, orgId, awsConfig) {
@@ -7104,7 +7260,79 @@ async function seedZitadel(awsConfig) {
7104
7260
  logSuccess(`Login context '${LOGIN_CONTEXT}' configured \u2192 try: mesh login ${LOGIN_CONTEXT}`);
7105
7261
  return { projectId, cliClientId, hubAuth };
7106
7262
  }
7107
- var ZITADEL_ISSUER, LOGIN_CONTEXT, PLATFORM_ORG, CLI_PROJECT_NAME, CLI_APP_NAME, CLI_REDIRECT_URI, HUB_PROJECT_NAME, HUB_APP_NAME, hubRedirectUri, HUB_DEFAULT_REDIRECT_URI, HUB_ROLES, ZITADEL_SSM_PARAM, TEST_USERS_SSM_PREFIX, TEST_USERS, isAlreadyExists, ensureCliProject, ensureHubProject, OPS_HUB_SECRET_ID, LOCAL_SMTP;
7263
+ async function fetchMockSamlMetadata() {
7264
+ const url = mockSamlMetadataUrl();
7265
+ let lastError = "no attempt made";
7266
+ for (let attempt = 0; attempt < 30; attempt++) {
7267
+ try {
7268
+ const res = await fetch(url, { signal: AbortSignal.timeout(5e3) });
7269
+ const body = await res.text();
7270
+ if (res.ok && body.includes("EntityDescriptor")) {
7271
+ if (/<ds:X509Certificate\s*\/>|<ds:X509Certificate>\s*<\/ds:X509Certificate>/.test(body)) {
7272
+ throw new MeshCliError(
7273
+ "The mock SAML IdP served metadata with an empty signing certificate.",
7274
+ {
7275
+ remediation: {
7276
+ command: "rm -rf ~/.cache/mesh/mesh-local/mock-idp && mesh stop && mesh start --with-idps"
7277
+ }
7278
+ }
7279
+ );
7280
+ }
7281
+ return body;
7282
+ }
7283
+ lastError = `HTTP ${res.status}`;
7284
+ } catch (cause) {
7285
+ if (cause instanceof MeshCliError) throw cause;
7286
+ lastError = String(cause);
7287
+ }
7288
+ await new Promise((resolve20) => setTimeout(resolve20, 2e3));
7289
+ }
7290
+ throw new MeshCliError(`Could not read mock SAML metadata from ${url} (${lastError}).`, {
7291
+ remediation: { command: "mesh status # is mock-saml running?" }
7292
+ });
7293
+ }
7294
+ async function attachedLoginPolicyIdps(pat) {
7295
+ const res = await api(pat, "POST", "/admin/v1/policies/login/idps/_search", {});
7296
+ return (res?.result ?? []).map((idp) => String(idp.idpId ?? idp.id)).filter(Boolean);
7297
+ }
7298
+ async function findIdpByName(pat, name) {
7299
+ return pickIdpIdByName(await api(pat, "POST", IDP_SEARCH_PATH, {}), name);
7300
+ }
7301
+ async function seedMockIdps() {
7302
+ const pat = readSeederPat();
7303
+ const metadataXml = await fetchMockSamlMetadata();
7304
+ let samlIdpId = await findIdpByName(pat, MOCK_SAML_IDP_NAME);
7305
+ if (!samlIdpId) {
7306
+ const created = await api(pat, "POST", "/admin/v1/idps/saml", buildMockSamlIdpBody(metadataXml));
7307
+ samlIdpId = String(created.id);
7308
+ }
7309
+ logSuccess(`Mock SAML IdP ready (${MOCK_SAML_IDP_NAME}, id ${samlIdpId})`);
7310
+ let oidcIdpId = await findIdpByName(pat, MOCK_OIDC_IDP_NAME);
7311
+ if (!oidcIdpId) {
7312
+ const created = await api(pat, "POST", "/admin/v1/idps/oauth", buildMockOauthIdpBody());
7313
+ oidcIdpId = String(created.id);
7314
+ }
7315
+ logSuccess(`Mock OIDC IdP ready (${MOCK_OIDC_IDP_NAME}, id ${oidcIdpId})`);
7316
+ const policy = await api(pat, "GET", "/admin/v1/policies/login");
7317
+ if (policy?.policy?.allowExternalIdp !== true) {
7318
+ await api(pat, "PUT", "/admin/v1/policies/login", {
7319
+ ...policy.policy,
7320
+ allowExternalIdp: true
7321
+ });
7322
+ logInfo("Instance login policy: allowExternalIdp turned on (federation buttons were hidden)");
7323
+ }
7324
+ const attached = await attachedLoginPolicyIdps(pat);
7325
+ const toAttach = missingLoginPolicyIdps(attached, [samlIdpId, oidcIdpId]);
7326
+ for (const idpId of toAttach) {
7327
+ await api(pat, "POST", "/admin/v1/policies/login/idps", { idpId, ownerType: "IDP_OWNER_TYPE_SYSTEM" });
7328
+ }
7329
+ const finalIdps = await attachedLoginPolicyIdps(pat);
7330
+ logSuccess(
7331
+ `Login policy carries ${finalIdps.length} federation(s) \u2014 both mocks attached, which is the state a login-policy change has to preserve`
7332
+ );
7333
+ return { samlIdpId, oidcIdpId };
7334
+ }
7335
+ var ZITADEL_ISSUER, LOGIN_CONTEXT, PLATFORM_ORG, CLI_PROJECT_NAME, CLI_APP_NAME, CLI_REDIRECT_URI, HUB_PROJECT_NAME, HUB_APP_NAME, hubRedirectUri, HUB_DEFAULT_REDIRECT_URI, HUB_ROLES, ZITADEL_SSM_PARAM, TEST_USERS_SSM_PREFIX, TEST_USERS, isAlreadyExists, ensureCliProject, ensureHubProject, OPS_HUB_SECRET_ID, LOCAL_SMTP, IDP_SEARCH_PATH, pickIdpIdByName;
7108
7336
  var init_seed_zitadel = __esm({
7109
7337
  "libs/mesh-cli/src/commands/local/seed-zitadel.ts"() {
7110
7338
  "use strict";
@@ -7115,6 +7343,7 @@ var init_seed_zitadel = __esm({
7115
7343
  init_stack();
7116
7344
  init_seed();
7117
7345
  init_cache_home();
7346
+ init_mock_idps();
7118
7347
  ZITADEL_ISSUER = "http://localhost:8080";
7119
7348
  LOGIN_CONTEXT = "local";
7120
7349
  PLATFORM_ORG = "mesh";
@@ -7156,6 +7385,11 @@ var init_seed_zitadel = __esm({
7156
7385
  from: "no-reply@local.mesh",
7157
7386
  fromName: "Mesh (local)"
7158
7387
  };
7388
+ IDP_SEARCH_PATH = "/admin/v1/idps/templates/_search";
7389
+ pickIdpIdByName = (searchResult, name) => {
7390
+ const hit = (searchResult?.result ?? []).find((idp) => idp?.name === name);
7391
+ return hit?.id ? String(hit.id) : void 0;
7392
+ };
7159
7393
  }
7160
7394
  });
7161
7395
 
@@ -7533,17 +7767,17 @@ var init_auth_provision = __esm({
7533
7767
  });
7534
7768
 
7535
7769
  // libs/mesh-cli/src/commands/local/dev-local.ts
7536
- import * as fs17 from "fs";
7537
- import * as path17 from "path";
7770
+ import * as fs18 from "fs";
7771
+ import * as path18 from "path";
7538
7772
  function localAppNamespace(tenant, appName) {
7539
7773
  return `${tenant}-${LOCAL_ENV}-${appName}`;
7540
7774
  }
7541
7775
  function logShipperPath() {
7542
- return path17.join(findPackageRoot(), "assets", "log-shipper.mjs");
7776
+ return path18.join(findPackageRoot(), "assets", "log-shipper.mjs");
7543
7777
  }
7544
7778
  function autoInstrumentationEnv(appRoot, src) {
7545
- const pkgDir = path17.join("node_modules", "@opentelemetry", "auto-instrumentations-node");
7546
- const present = fs17.existsSync(path17.join(appRoot, src, pkgDir)) || fs17.existsSync(path17.join(appRoot, pkgDir));
7779
+ const pkgDir = path18.join("node_modules", "@opentelemetry", "auto-instrumentations-node");
7780
+ const present = fs18.existsSync(path18.join(appRoot, src, pkgDir)) || fs18.existsSync(path18.join(appRoot, pkgDir));
7547
7781
  if (!present) return {};
7548
7782
  return {
7549
7783
  NODE_OPTIONS: { value: "--import @opentelemetry/auto-instrumentations-node/register" },
@@ -7599,26 +7833,26 @@ function localPlatformEnv(tenant, appName, serviceName) {
7599
7833
  return env;
7600
7834
  }
7601
7835
  function isDagsterWorkspaceRoot(appRoot) {
7602
- if (fs17.existsSync(path17.join(appRoot, "dg.toml"))) return true;
7603
- const pyproject = path17.join(appRoot, "pyproject.toml");
7604
- if (!fs17.existsSync(pyproject)) return false;
7836
+ if (fs18.existsSync(path18.join(appRoot, "dg.toml"))) return true;
7837
+ const pyproject = path18.join(appRoot, "pyproject.toml");
7838
+ if (!fs18.existsSync(pyproject)) return false;
7605
7839
  try {
7606
- return /^\s*\[tool\.dg[\].]/m.test(fs17.readFileSync(pyproject, "utf-8"));
7840
+ return /^\s*\[tool\.dg[\].]/m.test(fs18.readFileSync(pyproject, "utf-8"));
7607
7841
  } catch {
7608
7842
  return false;
7609
7843
  }
7610
7844
  }
7611
7845
  function resolveDgBinary(appRoot) {
7612
7846
  for (const candidate of ["deployments/local/.venv/bin/dg", ".venv/bin/dg"]) {
7613
- if (fs17.existsSync(path17.join(appRoot, candidate))) return candidate;
7847
+ if (fs18.existsSync(path18.join(appRoot, candidate))) return candidate;
7614
7848
  }
7615
7849
  return "dg";
7616
7850
  }
7617
7851
  function hasDevScript(dir) {
7618
- const pkgPath = path17.join(dir, "package.json");
7619
- if (!fs17.existsSync(pkgPath)) return false;
7852
+ const pkgPath = path18.join(dir, "package.json");
7853
+ if (!fs18.existsSync(pkgPath)) return false;
7620
7854
  try {
7621
- const pkg = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
7855
+ const pkg = JSON.parse(fs18.readFileSync(pkgPath, "utf-8"));
7622
7856
  return typeof pkg?.scripts?.dev === "string";
7623
7857
  } catch {
7624
7858
  return false;
@@ -7626,14 +7860,14 @@ function hasDevScript(dir) {
7626
7860
  }
7627
7861
  function detectLocalServices(appRoot) {
7628
7862
  const services = {};
7629
- for (const entry of fs17.readdirSync(appRoot, { withFileTypes: true })) {
7863
+ for (const entry of fs18.readdirSync(appRoot, { withFileTypes: true })) {
7630
7864
  if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") continue;
7631
- if (hasDevScript(path17.join(appRoot, entry.name))) {
7865
+ if (hasDevScript(path18.join(appRoot, entry.name))) {
7632
7866
  services[entry.name] = { src: entry.name };
7633
7867
  }
7634
7868
  }
7635
7869
  if (Object.keys(services).length === 0 && hasDevScript(appRoot)) {
7636
- services[path17.basename(appRoot)] = { src: "." };
7870
+ services[path18.basename(appRoot)] = { src: "." };
7637
7871
  }
7638
7872
  return services;
7639
7873
  }
@@ -7647,15 +7881,15 @@ function buildLocalDevOutput(appRoot, tenant, opts = {}) {
7647
7881
  { remediation: { command: "mesh create-app" } }
7648
7882
  );
7649
7883
  }
7650
- let appName = path17.basename(appRoot);
7884
+ let appName = path18.basename(appRoot);
7651
7885
  try {
7652
- const pkg = JSON.parse(fs17.readFileSync(path17.join(appRoot, "package.json"), "utf-8"));
7886
+ const pkg = JSON.parse(fs18.readFileSync(path18.join(appRoot, "package.json"), "utf-8"));
7653
7887
  if (typeof pkg?.name === "string" && pkg.name) appName = pkg.name.replace(/^@[^/]+\//, "");
7654
7888
  } catch {
7655
7889
  }
7656
- const pulumiYaml = path17.join(appRoot, "Pulumi.yaml");
7657
- if (fs17.existsSync(pulumiYaml)) {
7658
- const match = fs17.readFileSync(pulumiYaml, "utf-8").match(/^name:\s*(.+)$/m);
7890
+ const pulumiYaml = path18.join(appRoot, "Pulumi.yaml");
7891
+ if (fs18.existsSync(pulumiYaml)) {
7892
+ const match = fs18.readFileSync(pulumiYaml, "utf-8").match(/^name:\s*(.+)$/m);
7659
7893
  if (match?.[1]?.trim()) appName = match[1].trim();
7660
7894
  }
7661
7895
  const services = {};
@@ -7705,7 +7939,7 @@ function buildLocalDevOutput(appRoot, tenant, opts = {}) {
7705
7939
  command: [resolveDgBinary(appRoot), "dev", "-h", "127.0.0.1", "-p", '"$PORT"'],
7706
7940
  env: {
7707
7941
  PORT: { value: String(port) },
7708
- DAGSTER_HOME: { value: path17.join(appRoot, ".dagster") },
7942
+ DAGSTER_HOME: { value: path18.join(appRoot, ".dagster") },
7709
7943
  ...localPlatformEnv(tenant, appName, "dagster")
7710
7944
  }
7711
7945
  };
@@ -7737,23 +7971,23 @@ function buildLocalDevOutput(appRoot, tenant, opts = {}) {
7737
7971
  };
7738
7972
  }
7739
7973
  function hasStackBacking(appRoot) {
7740
- const hasOwn = fs17.existsSync(path17.join(appRoot, "Pulumi.yaml")) || fs17.readdirSync(appRoot).some((f) => /^Pulumi\..+\.yaml$/.test(f));
7974
+ const hasOwn = fs18.existsSync(path18.join(appRoot, "Pulumi.yaml")) || fs18.readdirSync(appRoot).some((f) => /^Pulumi\..+\.yaml$/.test(f));
7741
7975
  if (hasOwn) return true;
7742
- let dir = path17.dirname(appRoot);
7976
+ let dir = path18.dirname(appRoot);
7743
7977
  while (true) {
7744
- if (fs17.existsSync(path17.join(dir, "Pulumi.yaml"))) return true;
7745
- if (fs17.existsSync(path17.join(dir, ".git")) || fs17.existsSync(path17.join(dir, "pnpm-workspace.yaml"))) {
7746
- return fs17.existsSync(path17.join(dir, "Pulumi.yaml"));
7978
+ if (fs18.existsSync(path18.join(dir, "Pulumi.yaml"))) return true;
7979
+ if (fs18.existsSync(path18.join(dir, ".git")) || fs18.existsSync(path18.join(dir, "pnpm-workspace.yaml"))) {
7980
+ return fs18.existsSync(path18.join(dir, "Pulumi.yaml"));
7747
7981
  }
7748
- const parent = path17.dirname(dir);
7982
+ const parent = path18.dirname(dir);
7749
7983
  if (parent === dir) return false;
7750
7984
  dir = parent;
7751
7985
  }
7752
7986
  }
7753
7987
  function detectLocalTenant(appRoot) {
7754
- for (const file of fs17.readdirSync(appRoot)) {
7988
+ for (const file of fs18.readdirSync(appRoot)) {
7755
7989
  if (!/^Pulumi\..*\.yaml$/.test(file)) continue;
7756
- const match = fs17.readFileSync(path17.join(appRoot, file), "utf-8").match(/^\s*mesh:tenant:\s*["']?([A-Za-z0-9-]+)["']?\s*$/m);
7990
+ const match = fs18.readFileSync(path18.join(appRoot, file), "utf-8").match(/^\s*mesh:tenant:\s*["']?([A-Za-z0-9-]+)["']?\s*$/m);
7757
7991
  if (match) return match[1];
7758
7992
  }
7759
7993
  const recorded = findMeshJson(appRoot);
@@ -7789,9 +8023,9 @@ var init_dev_local = __esm({
7789
8023
  });
7790
8024
 
7791
8025
  // libs/mesh-cli/src/commands/local/docker-runner.ts
7792
- import { execFileSync as execFileSync13 } from "child_process";
7793
- import * as fs18 from "fs";
7794
- import * as path18 from "path";
8026
+ import { execFileSync as execFileSync14 } from "child_process";
8027
+ import * as fs19 from "fs";
8028
+ import * as path19 from "path";
7795
8029
  function sessionDir(sessionName) {
7796
8030
  return meshCacheDir("mesh-local", "dev", sessionName);
7797
8031
  }
@@ -7813,8 +8047,8 @@ function writeDevCompose(sessionName, appRoot, services) {
7813
8047
  ];
7814
8048
  for (const [name, service] of Object.entries(services)) {
7815
8049
  const env = service.env ?? {};
7816
- fs18.writeFileSync(path18.join(dir, `${name}.env`), renderDockerEnvFile(env), { mode: 384 });
7817
- const workdir = path18.posix.join("/workspace", service.src === "." ? "" : service.src);
8050
+ fs19.writeFileSync(path19.join(dir, `${name}.env`), renderDockerEnvFile(env), { mode: 384 });
8051
+ const workdir = path19.posix.join("/workspace", service.src === "." ? "" : service.src);
7818
8052
  const ship = env.OTEL_RESOURCE_ATTRIBUTES ? ` 2>&1 | NODE_OPTIONS= node /mesh-assets/log-shipper.mjs` : "";
7819
8053
  blocks.push(
7820
8054
  ` ${name}:`,
@@ -7823,7 +8057,7 @@ function writeDevCompose(sessionName, appRoot, services) {
7823
8057
  ` working_dir: ${workdir}`,
7824
8058
  ` volumes:`,
7825
8059
  ` - '${appRoot}:/workspace'`,
7826
- ` - '${path18.dirname(shipper)}:/mesh-assets:ro'`,
8060
+ ` - '${path19.dirname(shipper)}:/mesh-assets:ro'`,
7827
8061
  ` environment:`,
7828
8062
  // node_modules is the HOST's bind-mounted install — pnpm inside the
7829
8063
  // container must never "verify" it and try a purge/reinstall (pnpm
@@ -7839,37 +8073,37 @@ function writeDevCompose(sessionName, appRoot, services) {
7839
8073
  ` restart: unless-stopped`
7840
8074
  );
7841
8075
  }
7842
- const composePath = path18.join(dir, "compose.yml");
7843
- fs18.writeFileSync(composePath, blocks.join("\n") + "\n");
8076
+ const composePath = path19.join(dir, "compose.yml");
8077
+ fs19.writeFileSync(composePath, blocks.join("\n") + "\n");
7844
8078
  return composePath;
7845
8079
  }
7846
8080
  function composeArgs(sessionName, args) {
7847
- return ["compose", "-p", sessionName, "-f", path18.join(sessionDir(sessionName), "compose.yml"), ...args];
8081
+ return ["compose", "-p", sessionName, "-f", path19.join(sessionDir(sessionName), "compose.yml"), ...args];
7848
8082
  }
7849
8083
  function dockerDevUp(sessionName) {
7850
- execFileSync13("docker", composeArgs(sessionName, ["up", "-d"]), {
8084
+ execFileSync14("docker", composeArgs(sessionName, ["up", "-d"]), {
7851
8085
  stdio: ["ignore", "inherit", "inherit"]
7852
8086
  });
7853
8087
  }
7854
8088
  function dockerDevDown(sessionName) {
7855
- execFileSync13("docker", composeArgs(sessionName, ["down", "--remove-orphans"]), {
8089
+ execFileSync14("docker", composeArgs(sessionName, ["down", "--remove-orphans"]), {
7856
8090
  stdio: ["ignore", "inherit", "inherit"]
7857
8091
  });
7858
8092
  }
7859
8093
  function dockerDevPs(sessionName) {
7860
- return execFileSync13("docker", composeArgs(sessionName, ["ps", "--format", "table {{.Service}} {{.State}} {{.Status}}"]), {
8094
+ return execFileSync14("docker", composeArgs(sessionName, ["ps", "--format", "table {{.Service}} {{.State}} {{.Status}}"]), {
7861
8095
  encoding: "utf-8",
7862
8096
  stdio: ["ignore", "pipe", "pipe"]
7863
8097
  });
7864
8098
  }
7865
8099
  function dockerDevLogs(sessionName, service, tail) {
7866
- return execFileSync13("docker", composeArgs(sessionName, ["logs", "--tail", String(tail), service]), {
8100
+ return execFileSync14("docker", composeArgs(sessionName, ["logs", "--tail", String(tail), service]), {
7867
8101
  encoding: "utf-8",
7868
8102
  stdio: ["ignore", "pipe", "pipe"]
7869
8103
  });
7870
8104
  }
7871
8105
  function dockerDevRestart(sessionName, service) {
7872
- execFileSync13("docker", composeArgs(sessionName, ["restart", service]), {
8106
+ execFileSync14("docker", composeArgs(sessionName, ["restart", service]), {
7873
8107
  stdio: ["ignore", "inherit", "inherit"]
7874
8108
  });
7875
8109
  }
@@ -7938,9 +8172,9 @@ var init_peer_addressing = __esm({
7938
8172
  });
7939
8173
 
7940
8174
  // libs/mesh-cli/src/utils/worktree-identity.ts
7941
- import { execFileSync as execFileSync14 } from "node:child_process";
8175
+ import { execFileSync as execFileSync15 } from "node:child_process";
7942
8176
  import * as crypto3 from "node:crypto";
7943
- import * as path19 from "node:path";
8177
+ import * as path20 from "node:path";
7944
8178
  function sanitizeSlug(name) {
7945
8179
  const s = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7946
8180
  return s || "wt";
@@ -7958,7 +8192,7 @@ function blockBasePort(block) {
7958
8192
  }
7959
8193
  function withAppScopedPortBlock(wt, appRoot) {
7960
8194
  if (wt.isPrimary) return wt;
7961
- const appHash = worktreeHash(`${wt.worktreeRoot}#${path19.resolve(appRoot)}`);
8195
+ const appHash = worktreeHash(`${wt.worktreeRoot}#${path20.resolve(appRoot)}`);
7962
8196
  return { ...wt, portBlock: portBlockFor(appHash, false) };
7963
8197
  }
7964
8198
  function worktreeStackName(baseName, wt) {
@@ -7973,22 +8207,22 @@ function resolveWorktreeIdentity(cwd = process.cwd(), gitRunner = defaultGitRunn
7973
8207
  let worktreeRoot;
7974
8208
  let isPrimary = true;
7975
8209
  try {
7976
- worktreeRoot = path19.resolve(gitRunner(["rev-parse", "--show-toplevel"], cwd));
8210
+ worktreeRoot = path20.resolve(gitRunner(["rev-parse", "--show-toplevel"], cwd));
7977
8211
  const commonDir = gitRunner(["rev-parse", "--git-common-dir"], cwd);
7978
- const primaryRoot = path19.resolve(path19.dirname(path19.resolve(cwd, commonDir)));
8212
+ const primaryRoot = path20.resolve(path20.dirname(path20.resolve(cwd, commonDir)));
7979
8213
  isPrimary = worktreeRoot === primaryRoot;
7980
8214
  } catch {
7981
8215
  return {
7982
- worktreeRoot: path19.resolve(cwd),
8216
+ worktreeRoot: path20.resolve(cwd),
7983
8217
  isPrimary: true,
7984
- slug: sanitizeSlug(path19.basename(path19.resolve(cwd))),
7985
- hash: worktreeHash(path19.resolve(cwd)),
8218
+ slug: sanitizeSlug(path20.basename(path20.resolve(cwd))),
8219
+ hash: worktreeHash(path20.resolve(cwd)),
7986
8220
  token: "",
7987
8221
  portBlock: 0,
7988
8222
  taskQueueSuffix: ""
7989
8223
  };
7990
8224
  }
7991
- const slug = sanitizeSlug(path19.basename(worktreeRoot));
8225
+ const slug = sanitizeSlug(path20.basename(worktreeRoot));
7992
8226
  const hash = worktreeHash(worktreeRoot);
7993
8227
  const token = isPrimary ? "" : `${slug}-${hash}`;
7994
8228
  return {
@@ -8010,7 +8244,7 @@ var init_worktree_identity = __esm({
8010
8244
  PORT_BLOCK_SIZE = 40;
8011
8245
  PORT_BLOCK_SERVICE_SUBRANGE = 24;
8012
8246
  STACK_SLUG_MAX = 16;
8013
- defaultGitRunner = (args, cwd) => execFileSync14("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
8247
+ defaultGitRunner = (args, cwd) => execFileSync15("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
8014
8248
  }
8015
8249
  });
8016
8250
 
@@ -8072,11 +8306,11 @@ var init_dev_token_server = __esm({
8072
8306
  });
8073
8307
 
8074
8308
  // libs/mesh-cli/src/commands/dev.ts
8075
- import { execFileSync as execFileSync15, spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
8076
- import * as fs19 from "fs";
8309
+ import { execFileSync as execFileSync16, spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
8310
+ import * as fs20 from "fs";
8077
8311
  import * as net8 from "net";
8078
8312
  import * as os6 from "os";
8079
- import * as path20 from "path";
8313
+ import * as path21 from "path";
8080
8314
  import { Option } from "commander";
8081
8315
  import { SecretsManagerClient as SecretsManagerClient2, GetSecretValueCommand as GetSecretValueCommand2 } from "@aws-sdk/client-secrets-manager";
8082
8316
  function registerServiceProbes(devOutput, tenant, probeFiles) {
@@ -8124,9 +8358,9 @@ mesh dev plan \u2014 ${kind}
8124
8358
  console.log(` (none \u2014 all services are deployed/K8s)`);
8125
8359
  } else {
8126
8360
  const monorepoRoot = findMonorepoRoot();
8127
- const wtWithSep = wt.worktreeRoot.endsWith(path20.sep) ? wt.worktreeRoot : wt.worktreeRoot + path20.sep;
8361
+ const wtWithSep = wt.worktreeRoot.endsWith(path21.sep) ? wt.worktreeRoot : wt.worktreeRoot + path21.sep;
8128
8362
  for (const [name, s] of locals) {
8129
- const dir = path20.resolve(appRoot, rebaseServiceSrc(s.src, monorepoRoot));
8363
+ const dir = path21.resolve(appRoot, rebaseServiceSrc(s.src, monorepoRoot));
8130
8364
  const outside = dir !== wt.worktreeRoot && !dir.startsWith(wtWithSep);
8131
8365
  const port = s.port > 0 ? `:${s.port}` : "(no port)";
8132
8366
  console.log(` ${name.padEnd(18)} ${port.padEnd(7)} ${dir}${outside ? " \u26A0 OUTSIDE worktree" : ""}`);
@@ -8135,18 +8369,18 @@ mesh dev plan \u2014 ${kind}
8135
8369
  console.log("");
8136
8370
  }
8137
8371
  function getSessionStatePath(sessionName) {
8138
- const dir = path20.join(os6.tmpdir(), "mesh-dev-sessions");
8139
- if (!fs19.existsSync(dir)) fs19.mkdirSync(dir, { recursive: true });
8140
- return path20.join(dir, `${sessionName}.json`);
8372
+ const dir = path21.join(os6.tmpdir(), "mesh-dev-sessions");
8373
+ if (!fs20.existsSync(dir)) fs20.mkdirSync(dir, { recursive: true });
8374
+ return path21.join(dir, `${sessionName}.json`);
8141
8375
  }
8142
8376
  function saveSessionState(sessionName, state) {
8143
- fs19.writeFileSync(getSessionStatePath(sessionName), JSON.stringify(state, null, 2));
8377
+ fs20.writeFileSync(getSessionStatePath(sessionName), JSON.stringify(state, null, 2));
8144
8378
  }
8145
8379
  function loadSessionState(sessionName) {
8146
8380
  const filePath = getSessionStatePath(sessionName);
8147
- if (!fs19.existsSync(filePath)) return null;
8381
+ if (!fs20.existsSync(filePath)) return null;
8148
8382
  try {
8149
- return JSON.parse(fs19.readFileSync(filePath, "utf-8"));
8383
+ return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
8150
8384
  } catch {
8151
8385
  return null;
8152
8386
  }
@@ -8170,18 +8404,18 @@ function workflowChangeWouldStrand(priorState, appRoot, force) {
8170
8404
  return true;
8171
8405
  }
8172
8406
  function getSessionEnvDir(sessionName) {
8173
- return path20.join(os6.tmpdir(), "mesh-dev-sessions", sessionName);
8407
+ return path21.join(os6.tmpdir(), "mesh-dev-sessions", sessionName);
8174
8408
  }
8175
8409
  function getServiceEnvFilePath(sessionName, serviceName) {
8176
- return path20.join(getSessionEnvDir(sessionName), envFileName(serviceName));
8410
+ return path21.join(getSessionEnvDir(sessionName), envFileName(serviceName));
8177
8411
  }
8178
8412
  function removeSessionState(sessionName) {
8179
8413
  try {
8180
- fs19.unlinkSync(getSessionStatePath(sessionName));
8414
+ fs20.unlinkSync(getSessionStatePath(sessionName));
8181
8415
  } catch {
8182
8416
  }
8183
8417
  try {
8184
- fs19.rmSync(getSessionEnvDir(sessionName), { recursive: true, force: true });
8418
+ fs20.rmSync(getSessionEnvDir(sessionName), { recursive: true, force: true });
8185
8419
  } catch {
8186
8420
  }
8187
8421
  }
@@ -8309,16 +8543,16 @@ function mergePinnedPorts(fresh, pinned) {
8309
8543
  }
8310
8544
  function findMonorepoRoot() {
8311
8545
  let dir = process.cwd();
8312
- const root = path20.parse(dir).root;
8546
+ const root = path21.parse(dir).root;
8313
8547
  while (dir !== root) {
8314
- if (fs19.existsSync(path20.join(dir, "pnpm-workspace.yaml")) || fs19.existsSync(path20.join(dir, "turbo.json"))) {
8548
+ if (fs20.existsSync(path21.join(dir, "pnpm-workspace.yaml")) || fs20.existsSync(path21.join(dir, "turbo.json"))) {
8315
8549
  return dir;
8316
8550
  }
8317
- const gitPath = path20.join(dir, ".git");
8318
- if (fs19.existsSync(gitPath)) {
8551
+ const gitPath = path21.join(dir, ".git");
8552
+ if (fs20.existsSync(gitPath)) {
8319
8553
  return dir;
8320
8554
  }
8321
- dir = path20.dirname(dir);
8555
+ dir = path21.dirname(dir);
8322
8556
  }
8323
8557
  return null;
8324
8558
  }
@@ -8326,40 +8560,40 @@ function discoverApps(monorepoRoot) {
8326
8560
  const apps = [];
8327
8561
  function addApp(appDir, tenant) {
8328
8562
  const projectName = getProjectName(appDir);
8329
- const stacks = fs19.readdirSync(appDir).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml").map((f) => f.replace(/^Pulumi\./, "").replace(/\.yaml$/, ""));
8563
+ const stacks = fs20.readdirSync(appDir).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml").map((f) => f.replace(/^Pulumi\./, "").replace(/\.yaml$/, ""));
8330
8564
  apps.push({
8331
8565
  name: projectName,
8332
8566
  tenant,
8333
8567
  appPath: appDir,
8334
- relativePath: path20.relative(monorepoRoot, appDir),
8568
+ relativePath: path21.relative(monorepoRoot, appDir),
8335
8569
  stacks
8336
8570
  });
8337
8571
  }
8338
8572
  const searchDirs = ["tenants", "tests/tenants"];
8339
8573
  for (const searchDir of searchDirs) {
8340
- const base = path20.join(monorepoRoot, searchDir);
8341
- if (!fs19.existsSync(base)) continue;
8342
- for (const tenant of fs19.readdirSync(base)) {
8343
- const appsDir = path20.join(base, tenant, "apps");
8344
- if (!fs19.existsSync(appsDir) || !fs19.statSync(appsDir).isDirectory()) continue;
8345
- for (const app of fs19.readdirSync(appsDir)) {
8346
- const appDir = path20.join(appsDir, app);
8347
- if (!fs19.existsSync(path20.join(appDir, "Pulumi.yaml"))) continue;
8574
+ const base = path21.join(monorepoRoot, searchDir);
8575
+ if (!fs20.existsSync(base)) continue;
8576
+ for (const tenant of fs20.readdirSync(base)) {
8577
+ const appsDir = path21.join(base, tenant, "apps");
8578
+ if (!fs20.existsSync(appsDir) || !fs20.statSync(appsDir).isDirectory()) continue;
8579
+ for (const app of fs20.readdirSync(appsDir)) {
8580
+ const appDir = path21.join(appsDir, app);
8581
+ if (!fs20.existsSync(path21.join(appDir, "Pulumi.yaml"))) continue;
8348
8582
  addApp(appDir, tenant);
8349
8583
  }
8350
8584
  }
8351
8585
  }
8352
- const flatAppsDir = path20.join(monorepoRoot, "apps");
8353
- if (fs19.existsSync(flatAppsDir) && fs19.statSync(flatAppsDir).isDirectory()) {
8354
- for (const app of fs19.readdirSync(flatAppsDir)) {
8355
- const appDir = path20.join(flatAppsDir, app);
8356
- if (!fs19.statSync(appDir).isDirectory()) continue;
8357
- if (!fs19.existsSync(path20.join(appDir, "Pulumi.yaml"))) continue;
8586
+ const flatAppsDir = path21.join(monorepoRoot, "apps");
8587
+ if (fs20.existsSync(flatAppsDir) && fs20.statSync(flatAppsDir).isDirectory()) {
8588
+ for (const app of fs20.readdirSync(flatAppsDir)) {
8589
+ const appDir = path21.join(flatAppsDir, app);
8590
+ if (!fs20.statSync(appDir).isDirectory()) continue;
8591
+ if (!fs20.existsSync(path21.join(appDir, "Pulumi.yaml"))) continue;
8358
8592
  let tenant = "unknown";
8359
- const stackConfigs = fs19.readdirSync(appDir).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml");
8593
+ const stackConfigs = fs20.readdirSync(appDir).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml");
8360
8594
  if (stackConfigs.length > 0) {
8361
8595
  try {
8362
- const content = fs19.readFileSync(path20.join(appDir, stackConfigs[0]), "utf-8");
8596
+ const content = fs20.readFileSync(path21.join(appDir, stackConfigs[0]), "utf-8");
8363
8597
  const tenantMatch = content.match(/mesh:tenant:\s*(\S+)/);
8364
8598
  if (tenantMatch) tenant = tenantMatch[1];
8365
8599
  } catch {
@@ -8372,38 +8606,38 @@ function discoverApps(monorepoRoot) {
8372
8606
  }
8373
8607
  function findAppRoot2(appPath) {
8374
8608
  if (appPath) {
8375
- const resolved = path20.resolve(appPath);
8376
- if (fs19.existsSync(path20.join(resolved, "Pulumi.yaml"))) return resolved;
8609
+ const resolved = path21.resolve(appPath);
8610
+ if (fs20.existsSync(path21.join(resolved, "Pulumi.yaml"))) return resolved;
8377
8611
  const mono = findMonorepoRoot();
8378
8612
  if (mono) {
8379
- const fromMono = path20.resolve(mono, appPath);
8380
- if (fs19.existsSync(path20.join(fromMono, "Pulumi.yaml"))) return fromMono;
8613
+ const fromMono = path21.resolve(mono, appPath);
8614
+ if (fs20.existsSync(path21.join(fromMono, "Pulumi.yaml"))) return fromMono;
8381
8615
  }
8382
8616
  logError(`No Pulumi.yaml found at: ${appPath}`);
8383
8617
  process.exit(1);
8384
8618
  }
8385
8619
  let dir = process.cwd();
8386
- const root = path20.parse(dir).root;
8620
+ const root = path21.parse(dir).root;
8387
8621
  while (dir !== root) {
8388
- if (fs19.existsSync(path20.join(dir, "Pulumi.yaml"))) {
8622
+ if (fs20.existsSync(path21.join(dir, "Pulumi.yaml"))) {
8389
8623
  return dir;
8390
8624
  }
8391
- dir = path20.dirname(dir);
8625
+ dir = path21.dirname(dir);
8392
8626
  }
8393
8627
  return process.cwd();
8394
8628
  }
8395
8629
  function getProjectName(appRoot) {
8396
- const yamlPath = path20.join(appRoot, "Pulumi.yaml");
8397
- if (!fs19.existsSync(yamlPath)) return path20.basename(appRoot);
8398
- const content = fs19.readFileSync(yamlPath, "utf-8");
8630
+ const yamlPath = path21.join(appRoot, "Pulumi.yaml");
8631
+ if (!fs20.existsSync(yamlPath)) return path21.basename(appRoot);
8632
+ const content = fs20.readFileSync(yamlPath, "utf-8");
8399
8633
  const match = content.match(/^name:\s*(.+)$/m);
8400
- return match?.[1]?.trim() ?? path20.basename(appRoot);
8634
+ return match?.[1]?.trim() ?? path21.basename(appRoot);
8401
8635
  }
8402
8636
  function detectStack(appRoot, stageArg) {
8403
8637
  if (stageArg) return stageArg;
8404
8638
  if (process.env.MESH_STAGE) return process.env.MESH_STAGE;
8405
8639
  try {
8406
- const result = execFileSync15("pulumi", ["stack", "--show-name"], {
8640
+ const result = execFileSync16("pulumi", ["stack", "--show-name"], {
8407
8641
  cwd: appRoot,
8408
8642
  encoding: "utf-8",
8409
8643
  stdio: ["ignore", "pipe", "ignore"]
@@ -8412,7 +8646,7 @@ function detectStack(appRoot, stageArg) {
8412
8646
  } catch {
8413
8647
  }
8414
8648
  try {
8415
- const files = fs19.readdirSync(appRoot).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml");
8649
+ const files = fs20.readdirSync(appRoot).filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml") && f !== "Pulumi.yaml");
8416
8650
  if (files.length === 1) {
8417
8651
  const match = files[0].match(/^Pulumi\.(.+)\.yaml$/);
8418
8652
  if (match?.[1]) {
@@ -8426,7 +8660,7 @@ function detectStack(appRoot, stageArg) {
8426
8660
  }
8427
8661
  function stackArgs(appRoot, stack) {
8428
8662
  try {
8429
- const selected = execFileSync15("pulumi", ["stack", "--show-name"], {
8663
+ const selected = execFileSync16("pulumi", ["stack", "--show-name"], {
8430
8664
  cwd: appRoot,
8431
8665
  encoding: "utf-8",
8432
8666
  stdio: ["ignore", "pipe", "ignore"]
@@ -8435,7 +8669,7 @@ function stackArgs(appRoot, stack) {
8435
8669
  } catch {
8436
8670
  }
8437
8671
  try {
8438
- execFileSync15("pulumi", ["stack", "select", stack], {
8672
+ execFileSync16("pulumi", ["stack", "select", stack], {
8439
8673
  cwd: appRoot,
8440
8674
  encoding: "utf-8",
8441
8675
  stdio: ["ignore", "pipe", "ignore"]
@@ -8464,7 +8698,7 @@ function getDevOutput(appRoot, stack, awsEnv) {
8464
8698
  }
8465
8699
  function hasTmux() {
8466
8700
  try {
8467
- execFileSync15("which", ["tmux"], { stdio: "ignore" });
8701
+ execFileSync16("which", ["tmux"], { stdio: "ignore" });
8468
8702
  return true;
8469
8703
  } catch {
8470
8704
  return false;
@@ -8472,7 +8706,7 @@ function hasTmux() {
8472
8706
  }
8473
8707
  function sessionExists(name) {
8474
8708
  try {
8475
- execFileSync15("tmux", ["has-session", "-t", name], { stdio: "ignore" });
8709
+ execFileSync16("tmux", ["has-session", "-t", name], { stdio: "ignore" });
8476
8710
  return true;
8477
8711
  } catch {
8478
8712
  return false;
@@ -8480,7 +8714,7 @@ function sessionExists(name) {
8480
8714
  }
8481
8715
  function killSession(name) {
8482
8716
  try {
8483
- execFileSync15("tmux", ["kill-session", "-t", name], { stdio: "ignore" });
8717
+ execFileSync16("tmux", ["kill-session", "-t", name], { stdio: "ignore" });
8484
8718
  return true;
8485
8719
  } catch {
8486
8720
  return false;
@@ -8519,9 +8753,9 @@ function buildChildAwsEnv(awsEnv, method, profile, opts) {
8519
8753
  if (method === "zitadel" && opts) {
8520
8754
  const sanitizedContext = opts.context.replace(/[^A-Za-z0-9_-]/g, "-");
8521
8755
  const profileName = `mesh-dev-${sanitizedContext}`;
8522
- const configPath = path20.join(opts.sessionScratchDir, "aws-config");
8756
+ const configPath = path21.join(opts.sessionScratchDir, "aws-config");
8523
8757
  const region = awsEnv.AWS_REGION ?? awsEnv.AWS_DEFAULT_REGION ?? "";
8524
- fs19.mkdirSync(opts.sessionScratchDir, { recursive: true });
8758
+ fs20.mkdirSync(opts.sessionScratchDir, { recursive: true });
8525
8759
  const profileBlock = renderCredentialProcessProfile({
8526
8760
  profileName,
8527
8761
  context: opts.context,
@@ -8529,7 +8763,7 @@ function buildChildAwsEnv(awsEnv, method, profile, opts) {
8529
8763
  region,
8530
8764
  meshBin: opts.meshBin
8531
8765
  });
8532
- const existing = fs19.existsSync(configPath) ? fs19.readFileSync(configPath, "utf8") : "";
8766
+ const existing = fs20.existsSync(configPath) ? fs20.readFileSync(configPath, "utf8") : "";
8533
8767
  const next = upsertManagedAwsConfigSection(
8534
8768
  stripBareProfile(existing, profileName),
8535
8769
  `${opts.context} (mesh dev)`,
@@ -8555,15 +8789,15 @@ function rebaseServiceSrc(src, monorepoRoot) {
8555
8789
  if (!monorepoRoot) return src;
8556
8790
  const rel2 = monorepoRelativeSrc(src);
8557
8791
  if (rel2 === null) return src;
8558
- const rebased = path20.join(monorepoRoot, rel2);
8559
- return fs19.existsSync(rebased) ? rebased : src;
8792
+ const rebased = path21.join(monorepoRoot, rel2);
8793
+ return fs20.existsSync(rebased) ? rebased : src;
8560
8794
  }
8561
8795
  function isLinkedDependencyDir(serviceDir, appRoot) {
8562
8796
  let pkgRoot = null;
8563
8797
  let name = "";
8564
- for (let dir = serviceDir; ; dir = path20.dirname(dir)) {
8798
+ for (let dir = serviceDir; ; dir = path21.dirname(dir)) {
8565
8799
  try {
8566
- const manifest = JSON.parse(fs19.readFileSync(path20.join(dir, "package.json"), "utf8"));
8800
+ const manifest = JSON.parse(fs20.readFileSync(path21.join(dir, "package.json"), "utf8"));
8567
8801
  if (typeof manifest?.name === "string" && manifest.name) {
8568
8802
  pkgRoot = dir;
8569
8803
  name = manifest.name;
@@ -8571,21 +8805,21 @@ function isLinkedDependencyDir(serviceDir, appRoot) {
8571
8805
  }
8572
8806
  } catch {
8573
8807
  }
8574
- const parent = path20.dirname(dir);
8808
+ const parent = path21.dirname(dir);
8575
8809
  if (parent === dir) break;
8576
8810
  }
8577
8811
  if (!pkgRoot) return false;
8578
- for (let dir = appRoot; ; dir = path20.dirname(dir)) {
8812
+ for (let dir = appRoot; ; dir = path21.dirname(dir)) {
8579
8813
  try {
8580
- if (fs19.realpathSync(path20.join(dir, "node_modules", name)) === pkgRoot) return true;
8814
+ if (fs20.realpathSync(path21.join(dir, "node_modules", name)) === pkgRoot) return true;
8581
8815
  } catch {
8582
8816
  }
8583
- const parent = path20.dirname(dir);
8817
+ const parent = path21.dirname(dir);
8584
8818
  if (parent === dir) return false;
8585
8819
  }
8586
8820
  }
8587
8821
  function monorepoRelativeSrc(src) {
8588
- if (!path20.isAbsolute(src)) return src.replace(/^\.\//, "") || ".";
8822
+ if (!path21.isAbsolute(src)) return src.replace(/^\.\//, "") || ".";
8589
8823
  const m = src.match(/^.*\/mesh-platform(?:\/(.*))?$/);
8590
8824
  if (!m) return null;
8591
8825
  const rest = (m[1] ?? "").replace(/^\.worktrees\/[^/]+(?:\/|$)/, "");
@@ -8620,7 +8854,7 @@ function getServiceEnvVars(service, tunnels) {
8620
8854
  }
8621
8855
  function setTmuxEnv(sessionName, vars) {
8622
8856
  for (const [key, value] of Object.entries(vars)) {
8623
- execFileSync15("tmux", ["set-environment", "-t", sessionName, key, value], { stdio: "ignore" });
8857
+ execFileSync16("tmux", ["set-environment", "-t", sessionName, key, value], { stdio: "ignore" });
8624
8858
  }
8625
8859
  }
8626
8860
  function envPrefix(vars) {
@@ -8661,7 +8895,7 @@ function resolveTemporalEncodingKey(tenant, env, appName) {
8661
8895
  const namespace = `${tenant}-${env}-${appName}`;
8662
8896
  const secretName = `${namespace}-temporal-encoding-key`;
8663
8897
  try {
8664
- const b64 = execFileSync15(
8898
+ const b64 = execFileSync16(
8665
8899
  "kubectl",
8666
8900
  [
8667
8901
  "get",
@@ -8697,7 +8931,7 @@ async function resolveTemporalAuthVars(sessionName, devOutput) {
8697
8931
  setTmuxEnv(sessionName, { KUBECONFIG: kubeconfigPath });
8698
8932
  } else if (!process.env.KUBECONFIG) {
8699
8933
  const existing = sessionKubeconfigPath(sessionName);
8700
- if (fs19.existsSync(existing)) {
8934
+ if (fs20.existsSync(existing)) {
8701
8935
  process.env.KUBECONFIG = existing;
8702
8936
  }
8703
8937
  }
@@ -8866,7 +9100,7 @@ async function allocateSsmLocalPort(remotePort, reservedPorts) {
8866
9100
  }
8867
9101
  function hasSessionManagerPlugin() {
8868
9102
  try {
8869
- execFileSync15("which", ["session-manager-plugin"], { stdio: "ignore" });
9103
+ execFileSync16("which", ["session-manager-plugin"], { stdio: "ignore" });
8870
9104
  return true;
8871
9105
  } catch {
8872
9106
  return false;
@@ -8965,13 +9199,13 @@ async function startSsmTunnels(sessionName, devOutput) {
8965
9199
  localPortNumber: [String(localPort)]
8966
9200
  })}'`
8967
9201
  ].join(" ");
8968
- execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", windowName]);
8969
- execFileSync15(
9202
+ execFileSync16("tmux", ["new-window", "-t", sessionName, "-n", windowName]);
9203
+ execFileSync16(
8970
9204
  "tmux",
8971
9205
  ["set-option", "-t", `${sessionName}:${windowName}`, "remain-on-exit", "on"],
8972
9206
  { stdio: "ignore" }
8973
9207
  );
8974
- execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:${windowName}`, ssmCmd, "Enter"]);
9208
+ execFileSync16("tmux", ["send-keys", "-t", `${sessionName}:${windowName}`, ssmCmd, "Enter"]);
8975
9209
  rewritten.tunnels[tunnelName] = {
8976
9210
  host: "localhost",
8977
9211
  port: localPort
@@ -8983,7 +9217,7 @@ async function startSsmTunnels(sessionName, devOutput) {
8983
9217
  return rewritten;
8984
9218
  }
8985
9219
  async function updateDevboxProxy(devOutput, appRoot) {
8986
- const appName = devOutput.app ?? path20.basename(appRoot);
9220
+ const appName = devOutput.app ?? path21.basename(appRoot);
8987
9221
  const tenant = devOutput.platform?.tenant ?? "mesh";
8988
9222
  const env = devOutput.platform?.env ?? "dev";
8989
9223
  const stack = devOutput.stack ?? "dev";
@@ -9015,7 +9249,7 @@ async function updateDevboxProxy(devOutput, appRoot) {
9015
9249
  lines.push("");
9016
9250
  }
9017
9251
  const caddyfile = lines.join("\n");
9018
- execFileSync15(
9252
+ execFileSync16(
9019
9253
  "docker",
9020
9254
  [
9021
9255
  "run",
@@ -9031,7 +9265,7 @@ CADDYEOF`
9031
9265
  ],
9032
9266
  { stdio: "pipe" }
9033
9267
  );
9034
- execFileSync15(
9268
+ execFileSync16(
9035
9269
  "docker",
9036
9270
  [
9037
9271
  "run",
@@ -9061,7 +9295,7 @@ CADDYEOF`
9061
9295
  async function setupSubdomainRouting(devOutput, appRoot) {
9062
9296
  const tsInfo = await getTailscaleInfo();
9063
9297
  if (!tsInfo) return null;
9064
- const appName = devOutput.app ?? path20.basename(appRoot);
9298
+ const appName = devOutput.app ?? path21.basename(appRoot);
9065
9299
  const stack = devOutput.stack ?? "dev";
9066
9300
  const baseDomain = `${appName}.${stack}.${tsInfo.hostname}.vpn.internal`;
9067
9301
  const platform = devOutput.platform ?? { tenant: "mesh", env: "dev" };
@@ -9080,8 +9314,8 @@ async function setupSubdomainRouting(devOutput, appRoot) {
9080
9314
  } catch {
9081
9315
  }
9082
9316
  const caddyDir = "/tmp/mesh-dev-caddy";
9083
- const caddyfile = path20.join(caddyDir, "Caddyfile");
9084
- if (!fs19.existsSync(caddyDir)) fs19.mkdirSync(caddyDir, { recursive: true });
9317
+ const caddyfile = path21.join(caddyDir, "Caddyfile");
9318
+ if (!fs20.existsSync(caddyDir)) fs20.mkdirSync(caddyDir, { recursive: true });
9085
9319
  const caddyLines = [`# mesh-dev: ${appName}/${stack} (${tsInfo.hostname})`, ""];
9086
9320
  for (const [name, service] of Object.entries(devOutput.services)) {
9087
9321
  if (service.port) {
@@ -9099,16 +9333,16 @@ async function setupSubdomainRouting(devOutput, appRoot) {
9099
9333
  caddyLines.push("}");
9100
9334
  caddyLines.push("");
9101
9335
  }
9102
- fs19.writeFileSync(caddyfile, caddyLines.join("\n"));
9336
+ fs20.writeFileSync(caddyfile, caddyLines.join("\n"));
9103
9337
  let caddyRunning = false;
9104
9338
  try {
9105
- execFileSync15("pgrep", ["-f", "caddy run.*mesh-dev-caddy"], { stdio: "pipe" });
9339
+ execFileSync16("pgrep", ["-f", "caddy run.*mesh-dev-caddy"], { stdio: "pipe" });
9106
9340
  caddyRunning = true;
9107
9341
  } catch {
9108
9342
  }
9109
9343
  if (caddyRunning) {
9110
9344
  try {
9111
- execFileSync15("caddy", ["reload", "--config", caddyfile, "--adapter", "caddyfile"], {
9345
+ execFileSync16("caddy", ["reload", "--config", caddyfile, "--adapter", "caddyfile"], {
9112
9346
  stdio: "pipe"
9113
9347
  });
9114
9348
  } catch {
@@ -9117,7 +9351,7 @@ async function setupSubdomainRouting(devOutput, appRoot) {
9117
9351
  }
9118
9352
  } else {
9119
9353
  try {
9120
- execFileSync15("which", ["caddy"], { stdio: "pipe" });
9354
+ execFileSync16("which", ["caddy"], { stdio: "pipe" });
9121
9355
  } catch {
9122
9356
  logWarn(
9123
9357
  "Caddy not found. Install for subdomain routing: curl -fsSL https://caddyserver.com/api/download?os=linux&arch=arm64 -o /usr/local/bin/caddy && chmod +x /usr/local/bin/caddy"
@@ -9159,7 +9393,7 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9159
9393
  return devOutput;
9160
9394
  }
9161
9395
  logInfo(`Creating tmux session: ${sessionName}`);
9162
- execFileSync15("tmux", ["new-session", "-d", "-s", sessionName, "-n", "status", "-c", appRoot]);
9396
+ execFileSync16("tmux", ["new-session", "-d", "-s", sessionName, "-n", "status", "-c", appRoot]);
9163
9397
  setTmuxEnv(sessionName, awsEnv);
9164
9398
  const hasTunnels = Object.keys(devOutput.tunnels).length > 0;
9165
9399
  let effectiveTransport = tunnelPlan.transport;
@@ -9270,13 +9504,13 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9270
9504
  const tokenPort = await findFreePort3();
9271
9505
  const tokenUrl = `http://127.0.0.1:${tokenPort}`;
9272
9506
  setTmuxEnv(sessionName, { DEV_USER_TOKEN_URL: tokenUrl });
9273
- execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", "token-server"]);
9274
- execFileSync15(
9507
+ execFileSync16("tmux", ["new-window", "-t", sessionName, "-n", "token-server"]);
9508
+ execFileSync16(
9275
9509
  "tmux",
9276
9510
  ["set-option", "-t", `${sessionName}:token-server`, "remain-on-exit", "on"],
9277
9511
  { stdio: "ignore" }
9278
9512
  );
9279
- execFileSync15("tmux", [
9513
+ execFileSync16("tmux", [
9280
9514
  "send-keys",
9281
9515
  "-t",
9282
9516
  `${sessionName}:token-server`,
@@ -9299,9 +9533,9 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9299
9533
  logInfo(`Skipped: ${name} (no dev command, deployed to K8s)`);
9300
9534
  continue;
9301
9535
  }
9302
- const serviceDir = path20.resolve(appRoot, rebaseServiceSrc(service.src, monorepoRoot));
9303
- if (worktreeRoot && fs19.existsSync(serviceDir)) {
9304
- const wtRootWithSep = worktreeRoot.endsWith(path20.sep) ? worktreeRoot : worktreeRoot + path20.sep;
9536
+ const serviceDir = path21.resolve(appRoot, rebaseServiceSrc(service.src, monorepoRoot));
9537
+ if (worktreeRoot && fs20.existsSync(serviceDir)) {
9538
+ const wtRootWithSep = worktreeRoot.endsWith(path21.sep) ? worktreeRoot : worktreeRoot + path21.sep;
9305
9539
  const outside = serviceDir !== worktreeRoot && !serviceDir.startsWith(wtRootWithSep);
9306
9540
  if (outside && isLinkedDependencyDir(serviceDir, appRoot)) {
9307
9541
  logInfo(`${name}: source is a dev-linked package (${serviceDir})`);
@@ -9312,7 +9546,7 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9312
9546
  process.exit(1);
9313
9547
  }
9314
9548
  }
9315
- if (!fs19.existsSync(serviceDir)) {
9549
+ if (!fs20.existsSync(serviceDir)) {
9316
9550
  logWarn(
9317
9551
  `Skipped: ${name} (source directory not found: ${serviceDir}${serviceDir !== service.src ? ` \u2014 rebased from ${service.src}` : ""})`
9318
9552
  );
@@ -9352,11 +9586,11 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9352
9586
  cmd,
9353
9587
  service.env?.OTEL_RESOURCE_ATTRIBUTES ? logShipperPath() : void 0
9354
9588
  );
9355
- execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", name, "-c", serviceDir]);
9356
- execFileSync15("tmux", ["set-option", "-t", `${sessionName}:${name}`, "remain-on-exit", "on"], {
9589
+ execFileSync16("tmux", ["new-window", "-t", sessionName, "-n", name, "-c", serviceDir]);
9590
+ execFileSync16("tmux", ["set-option", "-t", `${sessionName}:${name}`, "remain-on-exit", "on"], {
9357
9591
  stdio: "ignore"
9358
9592
  });
9359
- execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:${name}`, launchCmd, "Enter"]);
9593
+ execFileSync16("tmux", ["send-keys", "-t", `${sessionName}:${name}`, launchCmd, "Enter"]);
9360
9594
  logSuccess(`Started: ${name} (${serviceDir}, port ${service.port})`);
9361
9595
  }
9362
9596
  if (process.env.DEVCONTAINER === "1") {
@@ -9367,7 +9601,7 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
9367
9601
  }
9368
9602
  }
9369
9603
  const statusCmd = `watch -n2 -t npx mesh dev --status --session '${sessionName}'`;
9370
- execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:status`, statusCmd, "Enter"]);
9604
+ execFileSync16("tmux", ["send-keys", "-t", `${sessionName}:status`, statusCmd, "Enter"]);
9371
9605
  console.log("");
9372
9606
  logSuccess(`Dev session started: ${sessionName}`);
9373
9607
  console.log("");
@@ -9424,7 +9658,7 @@ async function showStatus2(sessionName, devOutput, asJson) {
9424
9658
  }
9425
9659
  let windows = [];
9426
9660
  try {
9427
- const raw = execFileSync15(
9661
+ const raw = execFileSync16(
9428
9662
  "tmux",
9429
9663
  ["list-windows", "-t", sessionName, "-F", "#{window_name} #{pane_dead}"],
9430
9664
  { encoding: "utf-8" }
@@ -9546,7 +9780,7 @@ async function restartService(sessionName, serviceName, appRoot, devOutput, awsE
9546
9780
  }
9547
9781
  const target = `${sessionName}:${serviceName}`;
9548
9782
  try {
9549
- execFileSync15("tmux", ["respawn-pane", "-k", "-t", target], { stdio: "ignore" });
9783
+ execFileSync16("tmux", ["respawn-pane", "-k", "-t", target], { stdio: "ignore" });
9550
9784
  } catch {
9551
9785
  logError(`Window '${serviceName}' not found in session.`);
9552
9786
  process.exit(1);
@@ -9555,8 +9789,8 @@ async function restartService(sessionName, serviceName, appRoot, devOutput, awsE
9555
9789
  const cmd = service.command.join(" ");
9556
9790
  const envFilePath = getServiceEnvFilePath(sessionName, serviceName);
9557
9791
  let restartCmd;
9558
- if (fs19.existsSync(envFilePath)) {
9559
- const serviceDir = path20.resolve(appRoot, rebaseServiceSrc(service.src, findMonorepoRoot()));
9792
+ if (fs20.existsSync(envFilePath)) {
9793
+ const serviceDir = path21.resolve(appRoot, rebaseServiceSrc(service.src, findMonorepoRoot()));
9560
9794
  restartCmd = buildLaunchCommand(
9561
9795
  envFilePath,
9562
9796
  serviceDir,
@@ -9571,7 +9805,7 @@ async function restartService(sessionName, serviceName, appRoot, devOutput, awsE
9571
9805
  const serviceVars = getServiceEnvVars(service, devOutput.tunnels);
9572
9806
  restartCmd = `${envPrefix(serviceVars)}${cmd}`;
9573
9807
  }
9574
- execFileSync15("tmux", ["send-keys", "-t", target, restartCmd, "Enter"]);
9808
+ execFileSync16("tmux", ["send-keys", "-t", target, restartCmd, "Enter"]);
9575
9809
  logSuccess(`Restarted: ${serviceName}`);
9576
9810
  }
9577
9811
  function showLogs(sessionName, serviceName, tail) {
@@ -9581,7 +9815,7 @@ function showLogs(sessionName, serviceName, tail) {
9581
9815
  }
9582
9816
  const target = `${sessionName}:${serviceName}`;
9583
9817
  try {
9584
- const result = execFileSync15("tmux", ["capture-pane", "-t", target, "-p", "-S", `-${tail}`], {
9818
+ const result = execFileSync16("tmux", ["capture-pane", "-t", target, "-p", "-S", `-${tail}`], {
9585
9819
  encoding: "utf-8"
9586
9820
  });
9587
9821
  process.stdout.write(result);
@@ -9809,7 +10043,7 @@ function registerDevCommand(program2) {
9809
10043
  signInServices = [];
9810
10044
  try {
9811
10045
  const appPkg = JSON.parse(
9812
- fs19.readFileSync(path20.join(appRoot, "package.json"), "utf-8")
10046
+ fs20.readFileSync(path21.join(appRoot, "package.json"), "utf-8")
9813
10047
  );
9814
10048
  if (Array.isArray(appPkg?.mesh?.auth?.roles)) {
9815
10049
  authRoles = appPkg.mesh.auth.roles.filter((r) => typeof r === "string");
@@ -9986,9 +10220,9 @@ function registerDevCommand(program2) {
9986
10220
  logInfo(`Project: ${projectName}, Stack: ${stack}`);
9987
10221
  const monorepoRoot = findMonorepoRoot();
9988
10222
  const looksLikeStandaloneApp = ["api", "worker", "web"].some(
9989
- (dir) => fs19.existsSync(path20.join(appRoot, dir, "package.json"))
10223
+ (dir) => fs20.existsSync(path21.join(appRoot, dir, "package.json"))
9990
10224
  );
9991
- if (monorepoRoot && path20.resolve(appRoot) === path20.resolve(monorepoRoot) && !looksLikeStandaloneApp) {
10225
+ if (monorepoRoot && path21.resolve(appRoot) === path21.resolve(monorepoRoot) && !looksLikeStandaloneApp) {
9992
10226
  logError(`mesh dev should be run from an app directory, not the monorepo root.
9993
10227
  `);
9994
10228
  logInfo("Try:");
@@ -10464,10 +10698,10 @@ var init_dev = __esm({
10464
10698
  });
10465
10699
 
10466
10700
  // libs/mesh-cli/src/commands/dev-doctor.ts
10467
- import { execFileSync as execFileSync16 } from "node:child_process";
10468
- import * as fs20 from "node:fs";
10701
+ import { execFileSync as execFileSync17 } from "node:child_process";
10702
+ import * as fs21 from "node:fs";
10469
10703
  import * as net9 from "node:net";
10470
- import * as path21 from "node:path";
10704
+ import * as path22 from "node:path";
10471
10705
  function aggregateStatus(results) {
10472
10706
  if (results.some((r) => r.status === "error")) return "error";
10473
10707
  if (results.some((r) => r.status === "warn")) return "warn";
@@ -10570,9 +10804,9 @@ function parsePortSquatter(lsofOut, psOut) {
10570
10804
  return { pid, command };
10571
10805
  }
10572
10806
  function sharesWorktreeRoot(serviceSrc, repoRoot2) {
10573
- const src = path21.resolve(serviceSrc);
10574
- const root = path21.resolve(repoRoot2);
10575
- return src === root || src.startsWith(root + path21.sep);
10807
+ const src = path22.resolve(serviceSrc);
10808
+ const root = path22.resolve(repoRoot2);
10809
+ return src === root || src.startsWith(root + path22.sep);
10576
10810
  }
10577
10811
  function classifyPortListener(listenerPid, sessionPids) {
10578
10812
  if (listenerPid === null) return "dead";
@@ -10601,7 +10835,7 @@ function collectSessionPids(panePids, psOut) {
10601
10835
  }
10602
10836
  function whoHasPort(port) {
10603
10837
  try {
10604
- const lsof = execFileSync16("lsof", ["-ti", `:${port}`], {
10838
+ const lsof = execFileSync17("lsof", ["-ti", `:${port}`], {
10605
10839
  encoding: "utf8",
10606
10840
  stdio: ["ignore", "pipe", "ignore"]
10607
10841
  });
@@ -10609,7 +10843,7 @@ function whoHasPort(port) {
10609
10843
  if (!pid) return null;
10610
10844
  let ps = "";
10611
10845
  try {
10612
- ps = execFileSync16("ps", ["-o", "comm=", "-p", pid], {
10846
+ ps = execFileSync17("ps", ["-o", "comm=", "-p", pid], {
10613
10847
  encoding: "utf8",
10614
10848
  stdio: ["ignore", "pipe", "ignore"]
10615
10849
  });
@@ -10623,7 +10857,7 @@ function whoHasPort(port) {
10623
10857
  function sessionProcessTree(sessionName) {
10624
10858
  let panePids;
10625
10859
  try {
10626
- const out = execFileSync16(
10860
+ const out = execFileSync17(
10627
10861
  "tmux",
10628
10862
  ["list-panes", "-s", "-t", sessionName, "-F", "#{pane_pid}"],
10629
10863
  { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
@@ -10635,7 +10869,7 @@ function sessionProcessTree(sessionName) {
10635
10869
  if (panePids.length === 0) return /* @__PURE__ */ new Set();
10636
10870
  let psOut = "";
10637
10871
  try {
10638
- psOut = execFileSync16("ps", ["-eo", "pid=,ppid="], {
10872
+ psOut = execFileSync17("ps", ["-eo", "pid=,ppid="], {
10639
10873
  encoding: "utf8",
10640
10874
  stdio: ["ignore", "pipe", "ignore"]
10641
10875
  });
@@ -10757,7 +10991,7 @@ var init_dev_doctor = __esm({
10757
10991
  phases: ["preflight", "ondemand"],
10758
10992
  async run() {
10759
10993
  try {
10760
- execFileSync16("which", ["tmux"], { stdio: "ignore" });
10994
+ execFileSync17("which", ["tmux"], { stdio: "ignore" });
10761
10995
  return { status: "ok", summary: "installed" };
10762
10996
  } catch {
10763
10997
  return {
@@ -10832,14 +11066,14 @@ var init_dev_doctor = __esm({
10832
11066
  if (!state) {
10833
11067
  return { status: "ok", summary: "no session \u2014 config read fresh at launch" };
10834
11068
  }
10835
- const configPath = path21.join(ctx.appRoot, `Pulumi.${ctx.stack}.yaml`);
10836
- if (!fs20.existsSync(configPath)) {
11069
+ const configPath = path22.join(ctx.appRoot, `Pulumi.${ctx.stack}.yaml`);
11070
+ if (!fs21.existsSync(configPath)) {
10837
11071
  return {
10838
11072
  status: "ok",
10839
11073
  summary: `no Pulumi.${ctx.stack}.yaml to compare`
10840
11074
  };
10841
11075
  }
10842
- const mtimeMs = fs20.statSync(configPath).mtimeMs;
11076
+ const mtimeMs = fs21.statSync(configPath).mtimeMs;
10843
11077
  if (isConfigStale(mtimeMs, state.startedAt)) {
10844
11078
  return {
10845
11079
  status: "warn",
@@ -10862,7 +11096,7 @@ var init_dev_doctor = __esm({
10862
11096
  }
10863
11097
  let repoRoot2;
10864
11098
  try {
10865
- repoRoot2 = execFileSync16("git", ["rev-parse", "--show-toplevel"], {
11099
+ repoRoot2 = execFileSync17("git", ["rev-parse", "--show-toplevel"], {
10866
11100
  cwd: ctx.appRoot,
10867
11101
  encoding: "utf8",
10868
11102
  stdio: ["ignore", "pipe", "ignore"]
@@ -10998,21 +11232,21 @@ var init_dev_doctor = __esm({
10998
11232
  });
10999
11233
 
11000
11234
  // libs/mesh-cli/src/commands/app-check.ts
11001
- import * as fs21 from "node:fs";
11002
- import * as path22 from "node:path";
11235
+ import * as fs22 from "node:fs";
11236
+ import * as path23 from "node:path";
11003
11237
  function rel(root, abs) {
11004
- return path22.relative(root, abs).split(path22.sep).join("/");
11238
+ return path23.relative(root, abs).split(path23.sep).join("/");
11005
11239
  }
11006
11240
  function isDir(p) {
11007
11241
  try {
11008
- return fs21.statSync(p).isDirectory();
11242
+ return fs22.statSync(p).isDirectory();
11009
11243
  } catch {
11010
11244
  return false;
11011
11245
  }
11012
11246
  }
11013
11247
  function readText(p) {
11014
11248
  try {
11015
- return fs21.readFileSync(p, "utf8");
11249
+ return fs22.readFileSync(p, "utf8");
11016
11250
  } catch {
11017
11251
  return "";
11018
11252
  }
@@ -11022,19 +11256,19 @@ function srcFiles(dir) {
11022
11256
  const walk2 = (d) => {
11023
11257
  let entries;
11024
11258
  try {
11025
- entries = fs21.readdirSync(d, { withFileTypes: true });
11259
+ entries = fs22.readdirSync(d, { withFileTypes: true });
11026
11260
  } catch {
11027
11261
  return;
11028
11262
  }
11029
11263
  for (const e of entries) {
11030
- const p = path22.join(d, e.name);
11264
+ const p = path23.join(d, e.name);
11031
11265
  if (e.isDirectory()) {
11032
11266
  if (SKIP_DIRS.has(e.name) || e.name.startsWith("scenario")) continue;
11033
11267
  walk2(p);
11034
11268
  continue;
11035
11269
  }
11036
11270
  if (!e.isFile()) continue;
11037
- if (!SRC_EXT.has(path22.extname(e.name))) continue;
11271
+ if (!SRC_EXT.has(path23.extname(e.name))) continue;
11038
11272
  if (/\.(test|spec)\./.test(e.name) || /\.config\./.test(e.name) || e.name === "build.mjs") continue;
11039
11273
  out.push(p);
11040
11274
  }
@@ -11051,23 +11285,23 @@ function isUiDir(name) {
11051
11285
  function serviceDirs(app) {
11052
11286
  let entries;
11053
11287
  try {
11054
- entries = fs21.readdirSync(app, { withFileTypes: true });
11288
+ entries = fs22.readdirSync(app, { withFileTypes: true });
11055
11289
  } catch {
11056
11290
  return [];
11057
11291
  }
11058
- return entries.filter((e) => e.isDirectory() && !NON_SERVICE_DIRS.has(e.name) && !e.name.startsWith(".") && !isTestHarness(e.name)).map((e) => path22.join(app, e.name)).sort();
11292
+ return entries.filter((e) => e.isDirectory() && !NON_SERVICE_DIRS.has(e.name) && !e.name.startsWith(".") && !isTestHarness(e.name)).map((e) => path23.join(app, e.name)).sort();
11059
11293
  }
11060
11294
  function authzSurface(app) {
11061
11295
  const hits = [];
11062
11296
  const walk2 = (d) => {
11063
11297
  let entries;
11064
11298
  try {
11065
- entries = fs21.readdirSync(d, { withFileTypes: true });
11299
+ entries = fs22.readdirSync(d, { withFileTypes: true });
11066
11300
  } catch {
11067
11301
  return;
11068
11302
  }
11069
11303
  for (const e of entries) {
11070
- const p = path22.join(d, e.name);
11304
+ const p = path23.join(d, e.name);
11071
11305
  if (e.isDirectory()) {
11072
11306
  if (["node_modules", "dist", "build"].includes(e.name)) continue;
11073
11307
  walk2(p);
@@ -11366,32 +11600,32 @@ function docsAudienceUngrantable(text, decl, args, docs, httpText) {
11366
11600
  }
11367
11601
  function listApps(root) {
11368
11602
  const apps = [];
11369
- const appsDir = path22.join(root, "apps");
11603
+ const appsDir = path23.join(root, "apps");
11370
11604
  if (isDir(appsDir)) {
11371
- for (const e of fs21.readdirSync(appsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
11605
+ for (const e of fs22.readdirSync(appsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
11372
11606
  if (!e.isDirectory()) continue;
11373
- const d = path22.join(appsDir, e.name);
11374
- if (fs21.existsSync(path22.join(d, "index.ts")) || fs21.existsSync(path22.join(d, "Pulumi.yaml"))) apps.push(rel(root, d));
11607
+ const d = path23.join(appsDir, e.name);
11608
+ if (fs22.existsSync(path23.join(d, "index.ts")) || fs22.existsSync(path23.join(d, "Pulumi.yaml"))) apps.push(rel(root, d));
11375
11609
  }
11376
11610
  }
11377
- if (fs21.existsSync(path22.join(root, "index.ts")) && fs21.existsSync(path22.join(root, "Pulumi.yaml"))) apps.push(".");
11611
+ if (fs22.existsSync(path23.join(root, "index.ts")) && fs22.existsSync(path23.join(root, "Pulumi.yaml"))) apps.push(".");
11378
11612
  return apps;
11379
11613
  }
11380
11614
  function scanApp(root, appRel) {
11381
- const app = path22.resolve(root, appRel);
11382
- const index = path22.join(app, "index.ts");
11615
+ const app = path23.resolve(root, appRel);
11616
+ const index = path23.join(app, "index.ts");
11383
11617
  const findings = [];
11384
11618
  const hit = (code, p, why) => {
11385
11619
  findings.push({ code, path: p, why });
11386
11620
  };
11387
- const hasProgram = fs21.existsSync(index) || fs21.existsSync(path22.join(app, "Pulumi.yaml"));
11621
+ const hasProgram = fs22.existsSync(index) || fs22.existsSync(path23.join(app, "Pulumi.yaml"));
11388
11622
  if (!hasProgram) return findings;
11389
- if (fs21.existsSync(index)) {
11623
+ if (fs22.existsSync(index)) {
11390
11624
  const indexRel = rel(root, index);
11391
11625
  let servesHtml = false;
11392
11626
  let hasUiService = false;
11393
11627
  for (const svc of serviceDirs(app)) {
11394
- const svcName = path22.basename(svc);
11628
+ const svcName = path23.basename(svc);
11395
11629
  if (isUiDir(svcName)) {
11396
11630
  hasUiService = true;
11397
11631
  continue;
@@ -11435,7 +11669,7 @@ function scanApp(root, appRel) {
11435
11669
  const exposure = first(RE_EXPOSURE);
11436
11670
  const pointer = first(RE_POINTER);
11437
11671
  const metadata = first(RE_METADATA);
11438
- const appLabel = appRel === "." ? "(root)" : path22.basename(appRel);
11672
+ const appLabel = appRel === "." ? "(root)" : path23.basename(appRel);
11439
11673
  if (exposure && !pointer) {
11440
11674
  const at = surface.find((h) => RE_EXPOSURE.test(h.text) && /(^|\/)index\.ts$/.test(h.file)) ?? exposure;
11441
11675
  hit(
@@ -11471,7 +11705,7 @@ function scanApp(root, appRel) {
11471
11705
  }
11472
11706
  function isPlatformPackage(dir) {
11473
11707
  try {
11474
- const pkg = JSON.parse(readText(path22.join(dir, "package.json")));
11708
+ const pkg = JSON.parse(readText(path23.join(dir, "package.json")));
11475
11709
  return typeof pkg.name === "string" && pkg.name.startsWith("@mesh-tech/");
11476
11710
  } catch {
11477
11711
  return false;
@@ -11480,11 +11714,11 @@ function isPlatformPackage(dir) {
11480
11714
  function scanRepo(root) {
11481
11715
  const findings = [];
11482
11716
  for (const parent of ["libs", "packages"]) {
11483
- const dir = path22.join(root, parent);
11717
+ const dir = path23.join(root, parent);
11484
11718
  if (!isDir(dir)) continue;
11485
- for (const e of fs21.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
11719
+ for (const e of fs22.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
11486
11720
  if (!e.isDirectory() || !e.name.includes("auth")) continue;
11487
- const lib = path22.join(dir, e.name);
11721
+ const lib = path23.join(dir, e.name);
11488
11722
  if (isPlatformPackage(lib)) continue;
11489
11723
  const verifies = srcFiles(lib).filter((f) => f.endsWith(".ts")).some((f) => /introspect|jwtVerify|createRemoteJWKSet|from ["']jose["']/.test(readText(f)));
11490
11724
  if (verifies) {
@@ -11521,7 +11755,7 @@ async function runAppCheck(root, apps) {
11521
11755
  if (!isDir(root)) throw new MeshCliError(`no such checkout: ${root}`);
11522
11756
  const targets = apps && apps.length > 0 ? apps.map((a) => a.replace(/\/+$/, "")) : listApps(root);
11523
11757
  for (const a of targets) {
11524
- if (!isDir(path22.resolve(root, a))) throw new MeshCliError(`no such app dir: ${a}`);
11758
+ if (!isDir(path23.resolve(root, a))) throw new MeshCliError(`no such app dir: ${a}`);
11525
11759
  }
11526
11760
  const scopes = [];
11527
11761
  for (const app of targets) {
@@ -11555,7 +11789,7 @@ function registerAppCommands(program2) {
11555
11789
  app.command("check").description(
11556
11790
  "Check tenant apps against the Mesh app contract (@mesh-tech/app-kit skills/apps/references/app-contract.md): a UI is its own service, the app registers with the Hub, sign-in goes through the platform proxy, logs go through @mesh-tech/logger, and people/roles/keys are surfaced through the Hub. Exit 1 on any blocking finding \u2014 the same gate mesh create-app, tenant CI and the platform reviewer run."
11557
11791
  ).argument("[apps...]", "repo-relative app dirs to check (default: every apps/* with a Pulumi program)").option("--root <dir>", "checkout to scan (default: the enclosing git root)").option("--json", "machine-readable output (one report per app plus the repo-scoped checks)", false).option("--verbose", "also print the gates that passed", false).action(async (apps, opts) => {
11558
- const root = path22.resolve(opts.root ?? resolveTargetRoot());
11792
+ const root = path23.resolve(opts.root ?? resolveTargetRoot());
11559
11793
  const report = await runAppCheck(root, apps);
11560
11794
  if (opts.json) {
11561
11795
  emitJsonPayload({ ok: report.status !== "error", ...report });
@@ -11795,14 +12029,14 @@ var init_resolve = __esm({
11795
12029
  });
11796
12030
 
11797
12031
  // packages/agent-targets/src/load.ts
11798
- import { readFileSync as readFileSync18 } from "node:fs";
12032
+ import { readFileSync as readFileSync19 } from "node:fs";
11799
12033
  import { homedir as homedir3 } from "node:os";
11800
- import path23 from "node:path";
12034
+ import path24 from "node:path";
11801
12035
  function loadTargetsFile(env = process.env) {
11802
12036
  const file = env.MESH_AGENT_TARGETS || DEFAULT_REGISTRY_PATH;
11803
12037
  let raw;
11804
12038
  try {
11805
- raw = readFileSync18(file, "utf8");
12039
+ raw = readFileSync19(file, "utf8");
11806
12040
  } catch {
11807
12041
  return { status: "absent", path: file };
11808
12042
  }
@@ -11821,7 +12055,7 @@ var init_load = __esm({
11821
12055
  "use strict";
11822
12056
  init_schema();
11823
12057
  init_resolve();
11824
- DEFAULT_REGISTRY_PATH = path23.join(homedir3(), ".config", "mesh", "agent-targets.json");
12058
+ DEFAULT_REGISTRY_PATH = path24.join(homedir3(), ".config", "mesh", "agent-targets.json");
11825
12059
  }
11826
12060
  });
11827
12061
 
@@ -12053,9 +12287,9 @@ var init_pull = __esm({
12053
12287
 
12054
12288
  // packages/agent-targets/src/pull/write.ts
12055
12289
  import { mkdir, writeFile } from "node:fs/promises";
12056
- import { join as join20, dirname as dirname19 } from "node:path";
12290
+ import { join as join21, dirname as dirname19 } from "node:path";
12057
12291
  async function put(dir, rel2, contents, written) {
12058
- const abs = join20(dir, rel2);
12292
+ const abs = join21(dir, rel2);
12059
12293
  await mkdir(dirname19(abs), { recursive: true });
12060
12294
  await writeFile(abs, contents);
12061
12295
  written.push(rel2);
@@ -12182,7 +12416,7 @@ import { execFile as execFile2 } from "node:child_process";
12182
12416
  import { promisify } from "node:util";
12183
12417
  import { mkdtemp, rm } from "node:fs/promises";
12184
12418
  import { tmpdir as tmpdir4 } from "node:os";
12185
- import { join as join21 } from "node:path";
12419
+ import { join as join22 } from "node:path";
12186
12420
  function deriveVcsBaseUrl(apiBaseUrl) {
12187
12421
  try {
12188
12422
  const u = new URL(apiBaseUrl);
@@ -12241,7 +12475,7 @@ function createVcsFolderReader(opts) {
12241
12475
  let p = clones.get(repo);
12242
12476
  if (!p) {
12243
12477
  p = (async () => {
12244
- const dir = await mkdtemp(join21(tmpdir4(), "mesh-vcs-"));
12478
+ const dir = await mkdtemp(join22(tmpdir4(), "mesh-vcs-"));
12245
12479
  await execFileAsync("git", [
12246
12480
  "clone",
12247
12481
  "--filter=blob:none",
@@ -12258,11 +12492,11 @@ function createVcsFolderReader(opts) {
12258
12492
  }
12259
12493
  return p;
12260
12494
  };
12261
- const readPath = async (repo, path47) => {
12495
+ const readPath = async (repo, path48) => {
12262
12496
  const dir = await cloneRepo(repo);
12263
- const ref = await resolveFolderRef(dir, path47);
12264
- if (!ref) throw new Error(`path "${path47}" not found on any ref of ${repo}`);
12265
- const files = await readFolderAtRef(dir, ref, path47);
12497
+ const ref = await resolveFolderRef(dir, path48);
12498
+ if (!ref) throw new Error(`path "${path48}" not found on any ref of ${repo}`);
12499
+ const files = await readFolderAtRef(dir, ref, path48);
12266
12500
  return { ref, files };
12267
12501
  };
12268
12502
  const cleanup = async () => {
@@ -12453,8 +12687,8 @@ var init_agent_api_client = __esm({
12453
12687
  });
12454
12688
 
12455
12689
  // libs/mesh-cli/src/commands/artifacts.ts
12456
- import * as fs22 from "fs";
12457
- import * as path24 from "path";
12690
+ import * as fs23 from "fs";
12691
+ import * as path25 from "path";
12458
12692
  function parseRef(ref) {
12459
12693
  const colonIdx = ref.indexOf(":");
12460
12694
  if (colonIdx === -1) {
@@ -12477,28 +12711,28 @@ async function getArtifact(ref, options, target) {
12477
12711
  const { conversationId, artifactId } = parseRef(ref);
12478
12712
  logInfo(`Fetching ${conversationId}:${artifactId} from ${target.apiBaseUrl}\u2026`);
12479
12713
  const bundle = await fetchExportBundle(target, conversationId, artifactId);
12480
- const outputDir = options.output ?? path24.join("workflows", bundle.primaryWorkflow);
12481
- fs22.mkdirSync(outputDir, { recursive: true });
12714
+ const outputDir = options.output ?? path25.join("workflows", bundle.primaryWorkflow);
12715
+ fs23.mkdirSync(outputDir, { recursive: true });
12482
12716
  let filesWritten = 0;
12483
12717
  for (const file of bundle.files) {
12484
- const filePath = path24.join(outputDir, file.filename);
12485
- fs22.writeFileSync(filePath, file.code, "utf-8");
12718
+ const filePath = path25.join(outputDir, file.filename);
12719
+ fs23.writeFileSync(filePath, file.code, "utf-8");
12486
12720
  logSuccess(` ${file.filename}`);
12487
12721
  filesWritten++;
12488
12722
  }
12489
12723
  if (bundle.overview) {
12490
- const readmePath = path24.join(outputDir, "README.md");
12491
- fs22.writeFileSync(readmePath, bundle.overview, "utf-8");
12724
+ const readmePath = path25.join(outputDir, "README.md");
12725
+ fs23.writeFileSync(readmePath, bundle.overview, "utf-8");
12492
12726
  logSuccess(` README.md`);
12493
12727
  filesWritten++;
12494
12728
  }
12495
12729
  if (bundle.ir) {
12496
- const irPath = path24.join(outputDir, "workflow-ir.json");
12497
- fs22.writeFileSync(irPath, JSON.stringify(bundle.ir, null, 2), "utf-8");
12730
+ const irPath = path25.join(outputDir, "workflow-ir.json");
12731
+ fs23.writeFileSync(irPath, JSON.stringify(bundle.ir, null, 2), "utf-8");
12498
12732
  logSuccess(` workflow-ir.json`);
12499
12733
  filesWritten++;
12500
12734
  }
12501
- const metaPath = path24.join(outputDir, ".workflow-meta.json");
12735
+ const metaPath = path25.join(outputDir, ".workflow-meta.json");
12502
12736
  const meta = {
12503
12737
  conversationId: bundle.conversationId,
12504
12738
  artifactId,
@@ -12506,7 +12740,7 @@ async function getArtifact(ref, options, target) {
12506
12740
  exportedAt: bundle.exportedAt,
12507
12741
  files: bundle.files.map((f) => f.filename)
12508
12742
  };
12509
- fs22.writeFileSync(metaPath, JSON.stringify(meta, null, 2), "utf-8");
12743
+ fs23.writeFileSync(metaPath, JSON.stringify(meta, null, 2), "utf-8");
12510
12744
  console.log();
12511
12745
  logSuccess(
12512
12746
  `Exported ${filesWritten} files to ${outputDir}/`
@@ -12930,7 +13164,7 @@ var init_conversations = __esm({
12930
13164
  });
12931
13165
 
12932
13166
  // libs/mesh-cli/src/utils/scaffold-versions.ts
12933
- import { execFileSync as execFileSync17 } from "child_process";
13167
+ import { execFileSync as execFileSync18 } from "child_process";
12934
13168
  function isPrerelease(range) {
12935
13169
  return /[-+]/.test(range.replace(/^\^/, ""));
12936
13170
  }
@@ -12940,7 +13174,7 @@ function toCaretRange(version) {
12940
13174
  }
12941
13175
  function resolvePublishedRange(pkg, cwd) {
12942
13176
  try {
12943
- const out = execFileSync17("npm", ["view", pkg, "version"], {
13177
+ const out = execFileSync18("npm", ["view", pkg, "version"], {
12944
13178
  cwd,
12945
13179
  encoding: "utf-8",
12946
13180
  timeout: 15e3,
@@ -12986,23 +13220,23 @@ __export(create_app_exports, {
12986
13220
  shouldBootstrapAppsRepo: () => shouldBootstrapAppsRepo,
12987
13221
  workspaceGlobForApp: () => workspaceGlobForApp
12988
13222
  });
12989
- import * as fs23 from "fs";
13223
+ import * as fs24 from "fs";
12990
13224
  import * as os7 from "os";
12991
- import * as path25 from "path";
13225
+ import * as path26 from "path";
12992
13226
  import { fileURLToPath as fileURLToPath2 } from "url";
12993
13227
  import Handlebars from "handlebars";
12994
13228
  import { parse as parseYaml2 } from "yaml";
12995
13229
  function isInsidePlatformMonorepo(dir) {
12996
- let cur = path25.resolve(dir);
12997
- while (cur !== path25.dirname(cur)) {
12998
- if (fs23.existsSync(path25.join(cur, "pnpm-workspace.yaml"))) {
13230
+ let cur = path26.resolve(dir);
13231
+ while (cur !== path26.dirname(cur)) {
13232
+ if (fs24.existsSync(path26.join(cur, "pnpm-workspace.yaml"))) {
12999
13233
  try {
13000
- const pkg = JSON.parse(fs23.readFileSync(path25.join(cur, "package.json"), "utf-8"));
13234
+ const pkg = JSON.parse(fs24.readFileSync(path26.join(cur, "package.json"), "utf-8"));
13001
13235
  if (pkg?.name === PLATFORM_MONOREPO_NAME) return true;
13002
13236
  } catch {
13003
13237
  }
13004
13238
  }
13005
- cur = path25.dirname(cur);
13239
+ cur = path26.dirname(cur);
13006
13240
  }
13007
13241
  return false;
13008
13242
  }
@@ -13011,46 +13245,46 @@ function resolveDeployerRoleArn(tenant, platformName, env) {
13011
13245
  return `arn:aws:iam::${account}:role/${tenant}-${env}-apps-deployer`;
13012
13246
  }
13013
13247
  function shouldBootstrapAppsRepo(cwd) {
13014
- return fs23.existsSync(path25.join(cwd, ".git")) && !isInsidePlatformMonorepo(cwd) && !fs23.existsSync(path25.join(cwd, "package.json")) && !fs23.existsSync(path25.join(cwd, "tenants")) && !fs23.existsSync(path25.join(cwd, "apps"));
13248
+ return fs24.existsSync(path26.join(cwd, ".git")) && !isInsidePlatformMonorepo(cwd) && !fs24.existsSync(path26.join(cwd, "package.json")) && !fs24.existsSync(path26.join(cwd, "tenants")) && !fs24.existsSync(path26.join(cwd, "apps"));
13015
13249
  }
13016
13250
  function bootstrapAppsRepo(cwd, tenant) {
13017
- const templateDir = path25.join(packageRoot, "templates", "apps-repo");
13251
+ const templateDir = path26.join(packageRoot, "templates", "apps-repo");
13018
13252
  const registryAccount = HUB_ACCOUNTS.mesh;
13019
13253
  const context = {
13020
- repoName: path25.basename(cwd),
13254
+ repoName: path26.basename(cwd),
13021
13255
  tenant,
13022
13256
  tenantTitle: tenant.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "),
13023
13257
  registryUrl: `https://mesh-platform-${registryAccount}.d.codeartifact.us-east-2.amazonaws.com/npm/mesh-packages/`,
13024
13258
  intentRange: INTENT_RANGE
13025
13259
  };
13026
- const staging = fs23.mkdtempSync(path25.join(os7.tmpdir(), "mesh-apps-repo-"));
13260
+ const staging = fs24.mkdtempSync(path26.join(os7.tmpdir(), "mesh-apps-repo-"));
13027
13261
  try {
13028
13262
  copyTemplate(templateDir, staging, context);
13029
13263
  for (const [from, to] of [
13030
13264
  ["gitignore", ".gitignore"],
13031
13265
  ["npmrc", ".npmrc"]
13032
13266
  ]) {
13033
- const p = path25.join(staging, from);
13034
- if (fs23.existsSync(p)) fs23.renameSync(p, path25.join(staging, to));
13267
+ const p = path26.join(staging, from);
13268
+ if (fs24.existsSync(p)) fs24.renameSync(p, path26.join(staging, to));
13035
13269
  }
13036
13270
  const created = [];
13037
- for (const entry of fs23.readdirSync(staging)) {
13038
- const dest = path25.join(cwd, entry);
13039
- if (fs23.existsSync(dest)) continue;
13040
- fs23.cpSync(path25.join(staging, entry), dest, { recursive: true });
13271
+ for (const entry of fs24.readdirSync(staging)) {
13272
+ const dest = path26.join(cwd, entry);
13273
+ if (fs24.existsSync(dest)) continue;
13274
+ fs24.cpSync(path26.join(staging, entry), dest, { recursive: true });
13041
13275
  created.push(entry);
13042
13276
  }
13043
- fs23.mkdirSync(path25.join(cwd, "apps"), { recursive: true });
13277
+ fs24.mkdirSync(path26.join(cwd, "apps"), { recursive: true });
13044
13278
  created.push("apps/");
13045
13279
  return created;
13046
13280
  } finally {
13047
- fs23.rmSync(staging, { recursive: true, force: true });
13281
+ fs24.rmSync(staging, { recursive: true, force: true });
13048
13282
  }
13049
13283
  }
13050
13284
  function ensureWorkspaceGlobs(root, required) {
13051
- const file = path25.join(root, "pnpm-workspace.yaml");
13052
- if (!fs23.existsSync(file)) return [];
13053
- const text = fs23.readFileSync(file, "utf-8");
13285
+ const file = path26.join(root, "pnpm-workspace.yaml");
13286
+ if (!fs24.existsSync(file)) return [];
13287
+ const text = fs24.readFileSync(file, "utf-8");
13054
13288
  let declared;
13055
13289
  try {
13056
13290
  declared = parseYaml2(text)?.packages ?? [];
@@ -13074,13 +13308,13 @@ function ensureWorkspaceGlobs(root, required) {
13074
13308
  }
13075
13309
  const indent = (lines[end] ?? "").match(/^(\s*)-/)?.[1] ?? " ";
13076
13310
  lines.splice(end + 1, 0, ...missing.map((glob) => `${indent}- ${glob}`));
13077
- fs23.writeFileSync(file, lines.join("\n"));
13311
+ fs24.writeFileSync(file, lines.join("\n"));
13078
13312
  return missing;
13079
13313
  }
13080
13314
  function workspaceGlobForApp(root, appDir) {
13081
- const rel2 = path25.relative(root, appDir).split(path25.sep).join("/");
13315
+ const rel2 = path26.relative(root, appDir).split(path26.sep).join("/");
13082
13316
  if (rel2 === "" || rel2.split("/")[0] === "..") return null;
13083
- return `${path25.posix.dirname(rel2)}/*/*`;
13317
+ return `${path26.posix.dirname(rel2)}/*/*`;
13084
13318
  }
13085
13319
  function maybeBootstrapAppsRepo(cwd, tenant, test) {
13086
13320
  if (test || !shouldBootstrapAppsRepo(cwd)) return;
@@ -13130,9 +13364,9 @@ async function promptForOptions(options) {
13130
13364
  return { tenant, name, primitives };
13131
13365
  }
13132
13366
  function copyTemplate(srcDir, destDir, context) {
13133
- const entries = fs23.readdirSync(srcDir, { withFileTypes: true });
13367
+ const entries = fs24.readdirSync(srcDir, { withFileTypes: true });
13134
13368
  for (const entry of entries) {
13135
- const srcPath = path25.join(srcDir, entry.name);
13369
+ const srcPath = path26.join(srcDir, entry.name);
13136
13370
  let destName = entry.name;
13137
13371
  if (destName.endsWith(".hbs")) {
13138
13372
  destName = destName.slice(0, -4);
@@ -13140,17 +13374,17 @@ function copyTemplate(srcDir, destDir, context) {
13140
13374
  if (destName.includes("{{")) {
13141
13375
  destName = Handlebars.compile(destName)(context);
13142
13376
  }
13143
- const destPath = path25.join(destDir, destName);
13377
+ const destPath = path26.join(destDir, destName);
13144
13378
  if (entry.isDirectory()) {
13145
- fs23.mkdirSync(destPath, { recursive: true });
13379
+ fs24.mkdirSync(destPath, { recursive: true });
13146
13380
  copyTemplate(srcPath, destPath, context);
13147
13381
  } else if (entry.name.endsWith(".hbs")) {
13148
- const templateContent = fs23.readFileSync(srcPath, "utf-8");
13382
+ const templateContent = fs24.readFileSync(srcPath, "utf-8");
13149
13383
  const template = Handlebars.compile(templateContent);
13150
13384
  const output = template(context);
13151
- fs23.writeFileSync(destPath, output);
13385
+ fs24.writeFileSync(destPath, output);
13152
13386
  } else {
13153
- fs23.copyFileSync(srcPath, destPath);
13387
+ fs24.copyFileSync(srcPath, destPath);
13154
13388
  }
13155
13389
  }
13156
13390
  }
@@ -13174,72 +13408,72 @@ function describeNoAppsHome(cwd, tenant, baseDir, test) {
13174
13408
  };
13175
13409
  }
13176
13410
  return {
13177
- message: `This directory is not a Mesh apps repo \u2014 no apps/ here${fs23.existsSync(path25.join(cwd, ".git")) ? "" : " and it is not a git repo"}.`,
13411
+ message: `This directory is not a Mesh apps repo \u2014 no apps/ here${fs24.existsSync(path26.join(cwd, ".git")) ? "" : " and it is not a git repo"}.`,
13178
13412
  hint: `Run: mesh init (turns this folder into your ${tenant}-mesh-apps repo), or cd into that repo and re-run mesh create-app.`
13179
13413
  };
13180
13414
  }
13181
13415
  function resolveAppDir(cwd, tenant, name, test) {
13182
13416
  const baseDir = test ? "tests/tenants" : "tenants";
13183
- const possiblePaths = test ? [path25.join(cwd, baseDir, tenant, "apps")] : [
13184
- path25.join(cwd, baseDir, tenant, "apps"),
13185
- path25.join(cwd, "..", tenant, "apps"),
13186
- path25.join(cwd, "apps")
13417
+ const possiblePaths = test ? [path26.join(cwd, baseDir, tenant, "apps")] : [
13418
+ path26.join(cwd, baseDir, tenant, "apps"),
13419
+ path26.join(cwd, "..", tenant, "apps"),
13420
+ path26.join(cwd, "apps")
13187
13421
  ];
13188
- let appsDir = possiblePaths.find((p) => fs23.existsSync(p));
13422
+ let appsDir = possiblePaths.find((p) => fs24.existsSync(p));
13189
13423
  if (!appsDir) {
13190
- appsDir = path25.join(cwd, baseDir, tenant, "apps");
13191
- if (!fs23.existsSync(path25.join(cwd, baseDir, tenant))) {
13424
+ appsDir = path26.join(cwd, baseDir, tenant, "apps");
13425
+ if (!fs24.existsSync(path26.join(cwd, baseDir, tenant))) {
13192
13426
  const { message, hint } = describeNoAppsHome(cwd, tenant, baseDir, test);
13193
13427
  logError(message);
13194
13428
  logInfo(hint);
13195
13429
  process.exit(1);
13196
13430
  }
13197
- if (!fs23.existsSync(appsDir)) {
13431
+ if (!fs24.existsSync(appsDir)) {
13198
13432
  logInfo(`Creating apps directory: ${appsDir}`);
13199
- fs23.mkdirSync(appsDir, { recursive: true });
13433
+ fs24.mkdirSync(appsDir, { recursive: true });
13200
13434
  }
13201
13435
  }
13202
- return path25.join(appsDir, name);
13436
+ return path26.join(appsDir, name);
13203
13437
  }
13204
13438
  function generateComposableApp(appDir, context) {
13205
- const fragmentsDir = path25.join(packageRoot, "fragments");
13206
- const baseDir = path25.join(fragmentsDir, "base");
13207
- if (!fs23.existsSync(baseDir)) {
13439
+ const fragmentsDir = path26.join(packageRoot, "fragments");
13440
+ const baseDir = path26.join(fragmentsDir, "base");
13441
+ if (!fs24.existsSync(baseDir)) {
13208
13442
  logError(`Fragments directory not found: ${baseDir}`);
13209
13443
  logInfo("Make sure the mesh-cli package is installed correctly.");
13210
13444
  process.exit(1);
13211
13445
  }
13212
13446
  copyTemplate(baseDir, appDir, context);
13213
13447
  if (context.service) {
13214
- const serviceDir = path25.join(fragmentsDir, "service");
13215
- if (!fs23.existsSync(serviceDir)) {
13448
+ const serviceDir = path26.join(fragmentsDir, "service");
13449
+ if (!fs24.existsSync(serviceDir)) {
13216
13450
  throw new Error(`Fragment directory not found: ${serviceDir}`);
13217
13451
  }
13218
13452
  copyTemplate(serviceDir, appDir, context);
13219
13453
  }
13220
13454
  if (context.database) {
13221
- const dbDir = path25.join(fragmentsDir, "database");
13222
- if (!fs23.existsSync(dbDir)) {
13455
+ const dbDir = path26.join(fragmentsDir, "database");
13456
+ if (!fs24.existsSync(dbDir)) {
13223
13457
  throw new Error(`Fragment directory not found: ${dbDir}`);
13224
13458
  }
13225
13459
  copyTemplate(dbDir, appDir, context);
13226
13460
  }
13227
13461
  if (context.temporal) {
13228
- const temporalDir = path25.join(fragmentsDir, "temporal");
13229
- if (!fs23.existsSync(temporalDir)) {
13462
+ const temporalDir = path26.join(fragmentsDir, "temporal");
13463
+ if (!fs24.existsSync(temporalDir)) {
13230
13464
  throw new Error(`Fragment directory not found: ${temporalDir}`);
13231
13465
  }
13232
13466
  copyTemplate(temporalDir, appDir, context);
13233
13467
  }
13234
13468
  if (context.bucket) {
13235
- const bucketDir = path25.join(fragmentsDir, "bucket");
13236
- if (!fs23.existsSync(bucketDir)) {
13469
+ const bucketDir = path26.join(fragmentsDir, "bucket");
13470
+ if (!fs24.existsSync(bucketDir)) {
13237
13471
  throw new Error(`Fragment directory not found: ${bucketDir}`);
13238
13472
  }
13239
13473
  copyTemplate(bucketDir, appDir, context);
13240
13474
  }
13241
- const agentsDir = path25.join(fragmentsDir, "agents");
13242
- if (fs23.existsSync(agentsDir)) {
13475
+ const agentsDir = path26.join(fragmentsDir, "agents");
13476
+ if (fs24.existsSync(agentsDir)) {
13243
13477
  copyTemplate(agentsDir, appDir, context);
13244
13478
  }
13245
13479
  }
@@ -13340,22 +13574,22 @@ async function runLegacyTemplate(tenant, name, template, test) {
13340
13574
  }
13341
13575
  maybeBootstrapAppsRepo(process.cwd(), tenant, test);
13342
13576
  const appDir = resolveAppDir(process.cwd(), tenant, name, test);
13343
- if (fs23.existsSync(appDir)) {
13577
+ if (fs24.existsSync(appDir)) {
13344
13578
  logError(`App directory already exists: ${appDir}`);
13345
13579
  process.exit(1);
13346
13580
  }
13347
- const templateDir = path25.join(packageRoot, "templates", template);
13348
- if (!fs23.existsSync(templateDir)) {
13581
+ const templateDir = path26.join(packageRoot, "templates", template);
13582
+ if (!fs24.existsSync(templateDir)) {
13349
13583
  logError(`Template not found: ${templateDir}`);
13350
13584
  process.exit(1);
13351
13585
  }
13352
- fs23.mkdirSync(appDir, { recursive: true });
13586
+ fs24.mkdirSync(appDir, { recursive: true });
13353
13587
  try {
13354
13588
  copyTemplate(templateDir, appDir, { name, tenant });
13355
13589
  logSuccess(`Created app at ${appDir}`);
13356
13590
  } catch (error) {
13357
13591
  logError(`Failed to create app: ${error}`);
13358
- fs23.rmSync(appDir, { recursive: true, force: true });
13592
+ fs24.rmSync(appDir, { recursive: true, force: true });
13359
13593
  process.exit(1);
13360
13594
  }
13361
13595
  autoSyncSkills(appDir, name);
@@ -13370,7 +13604,7 @@ function autoSyncSkills(appDir, appName) {
13370
13604
  logWarn(`Agent-skill sync skipped: ${err instanceof Error ? err.message : err} \u2014 run: mesh skills sync`);
13371
13605
  }
13372
13606
  try {
13373
- const seeded = seedAppSkill(root, appName, path25.relative(root, appDir));
13607
+ const seeded = seedAppSkill(root, appName, path26.relative(root, appDir));
13374
13608
  if (seeded) logSuccess(`seeded: ${seeded} (yours to grow \u2014 not managed by mesh skills sync)`);
13375
13609
  } catch (err) {
13376
13610
  logWarn(`App skill stub skipped: ${err instanceof Error ? err.message : err}`);
@@ -13378,7 +13612,7 @@ function autoSyncSkills(appDir, appName) {
13378
13612
  }
13379
13613
  async function checkScaffoldContract(appDir) {
13380
13614
  const root = resolveTargetRoot(appDir);
13381
- const report = await runAppCheck(root, [path25.relative(root, appDir) || "."]);
13615
+ const report = await runAppCheck(root, [path26.relative(root, appDir) || "."]);
13382
13616
  if (report.status === "ok") {
13383
13617
  logSuccess("app contract: met (mesh app check)");
13384
13618
  return;
@@ -13401,7 +13635,7 @@ async function runComposable(tenant, name, primitives, test) {
13401
13635
  }
13402
13636
  maybeBootstrapAppsRepo(process.cwd(), tenant, test);
13403
13637
  const appDir = resolveAppDir(process.cwd(), tenant, name, test);
13404
- if (fs23.existsSync(appDir)) {
13638
+ if (fs24.existsSync(appDir)) {
13405
13639
  logError(`App directory already exists: ${appDir}`);
13406
13640
  process.exit(1);
13407
13641
  }
@@ -13433,16 +13667,16 @@ async function runComposable(tenant, name, primitives, test) {
13433
13667
  typescriptRange: SCAFFOLD_TOOLCHAIN.typescript,
13434
13668
  deployerRoleArn: resolveDeployerRoleArn(tenant, platformName, platformEnv)
13435
13669
  };
13436
- fs23.mkdirSync(appDir, { recursive: true });
13670
+ fs24.mkdirSync(appDir, { recursive: true });
13437
13671
  try {
13438
13672
  generateComposableApp(appDir, context);
13439
13673
  logSuccess(`Created app at ${appDir}`);
13440
13674
  } catch (error) {
13441
13675
  logError(`Failed to create app: ${error}`);
13442
- fs23.rmSync(appDir, { recursive: true, force: true });
13676
+ fs24.rmSync(appDir, { recursive: true, force: true });
13443
13677
  process.exit(1);
13444
13678
  }
13445
- const nested = fs23.readdirSync(appDir, { withFileTypes: true }).some((entry) => entry.isDirectory() && fs23.existsSync(path25.join(appDir, entry.name, "package.json")));
13679
+ const nested = fs24.readdirSync(appDir, { withFileTypes: true }).some((entry) => entry.isDirectory() && fs24.existsSync(path26.join(appDir, entry.name, "package.json")));
13446
13680
  const glob = workspaceGlobForApp(repoRoot2, appDir);
13447
13681
  if (nested && glob) {
13448
13682
  const added = ensureWorkspaceGlobs(repoRoot2, [glob]);
@@ -13526,7 +13760,7 @@ var init_create_app = __esm({
13526
13760
  init_errors();
13527
13761
  init_mesh_json();
13528
13762
  __filename = fileURLToPath2(import.meta.url);
13529
- __dirname = path25.dirname(__filename);
13763
+ __dirname = path26.dirname(__filename);
13530
13764
  packageRoot = findPackageRoot(__dirname);
13531
13765
  TEMPLATES = {
13532
13766
  workflow: "Hono API + Temporal worker + hello workflow (Pulumi/app-kit)",
@@ -13850,20 +14084,20 @@ var init_psql = __esm({
13850
14084
  // libs/mesh-cli/src/commands/db/exec.ts
13851
14085
  import { spawn as spawn6 } from "child_process";
13852
14086
  import * as net11 from "net";
13853
- import * as fs24 from "fs";
13854
- import * as path26 from "path";
14087
+ import * as fs25 from "fs";
14088
+ import * as path27 from "path";
13855
14089
  import {
13856
14090
  SecretsManagerClient as SecretsManagerClient3,
13857
14091
  GetSecretValueCommand as GetSecretValueCommand3
13858
14092
  } from "@aws-sdk/client-secrets-manager";
13859
14093
  function findSstOutputs() {
13860
14094
  let dir = process.cwd();
13861
- const root = path26.parse(dir).root;
14095
+ const root = path27.parse(dir).root;
13862
14096
  while (dir !== root) {
13863
- const outputsPath = path26.join(dir, ".sst", "outputs.json");
13864
- if (fs24.existsSync(outputsPath)) {
14097
+ const outputsPath = path27.join(dir, ".sst", "outputs.json");
14098
+ if (fs25.existsSync(outputsPath)) {
13865
14099
  try {
13866
- const content = fs24.readFileSync(outputsPath, "utf-8");
14100
+ const content = fs25.readFileSync(outputsPath, "utf-8");
13867
14101
  const outputs = JSON.parse(content);
13868
14102
  if (outputs.databaseUrl) {
13869
14103
  const secretArnMatch = outputs.databaseUrl.match(/secretArn=([^&]+)/);
@@ -13878,7 +14112,7 @@ function findSstOutputs() {
13878
14112
  } catch {
13879
14113
  }
13880
14114
  }
13881
- dir = path26.dirname(dir);
14115
+ dir = path27.dirname(dir);
13882
14116
  }
13883
14117
  return null;
13884
14118
  }
@@ -14137,8 +14371,8 @@ var init_db = __esm({
14137
14371
  });
14138
14372
 
14139
14373
  // libs/mesh-cli/src/utils/deploy-preflight.ts
14140
- import { existsSync as existsSync20, readFileSync as readFileSync21 } from "node:fs";
14141
- import { dirname as dirname22, join as join25, relative as relative7 } from "node:path";
14374
+ import { existsSync as existsSync21, readFileSync as readFileSync22 } from "node:fs";
14375
+ import { dirname as dirname22, join as join26, relative as relative7 } from "node:path";
14142
14376
  import { parse as parseYaml3 } from "yaml";
14143
14377
  function isGated(name) {
14144
14378
  return GATED_PREFIXES.some((p) => name.startsWith(p));
@@ -14176,8 +14410,8 @@ function diffLockVsInstalled(expected, installed) {
14176
14410
  function findPnpmLock(startDir) {
14177
14411
  let dir = startDir;
14178
14412
  for (; ; ) {
14179
- const candidate = join25(dir, "pnpm-lock.yaml");
14180
- if (existsSync20(candidate)) return candidate;
14413
+ const candidate = join26(dir, "pnpm-lock.yaml");
14414
+ if (existsSync21(candidate)) return candidate;
14181
14415
  const parent = dirname22(dir);
14182
14416
  if (parent === dir) return null;
14183
14417
  dir = parent;
@@ -14185,8 +14419,8 @@ function findPnpmLock(startDir) {
14185
14419
  }
14186
14420
  function readInstalledVersion(fromDir, name) {
14187
14421
  try {
14188
- const pkgPath = join25(fromDir, "node_modules", name, "package.json");
14189
- const version = JSON.parse(readFileSync21(pkgPath, "utf8")).version;
14422
+ const pkgPath = join26(fromDir, "node_modules", name, "package.json");
14423
+ const version = JSON.parse(readFileSync22(pkgPath, "utf8")).version;
14190
14424
  return typeof version === "string" ? version : null;
14191
14425
  } catch {
14192
14426
  return null;
@@ -14197,7 +14431,7 @@ function checkDeployDepsFresh(appRoot) {
14197
14431
  if (!lockPath) return null;
14198
14432
  let lockDoc;
14199
14433
  try {
14200
- lockDoc = parseYaml3(readFileSync21(lockPath, "utf8"));
14434
+ lockDoc = parseYaml3(readFileSync22(lockPath, "utf8"));
14201
14435
  } catch {
14202
14436
  logWarn(
14203
14437
  `deploy preflight: could not parse ${lockPath} \u2014 skipping the stale-node_modules check.`
@@ -14253,7 +14487,7 @@ var init_deploy_preflight = __esm({
14253
14487
  });
14254
14488
 
14255
14489
  // libs/mesh-cli/src/commands/deploy.ts
14256
- import { execFileSync as execFileSync18 } from "child_process";
14490
+ import { execFileSync as execFileSync19 } from "child_process";
14257
14491
  function buildPulumiArgs(pulumiArgs, stack) {
14258
14492
  const base = pulumiArgs.length === 0 || pulumiArgs[0]?.startsWith("-") ? ["up", ...pulumiArgs] : [...pulumiArgs];
14259
14493
  const op = base[0];
@@ -14316,7 +14550,7 @@ function registerDeployCommand(program2) {
14316
14550
  delete env.AWS_PROFILE;
14317
14551
  const finalArgs = buildPulumiArgs(pulumiArgs, stack);
14318
14552
  try {
14319
- execFileSync18("pulumi", finalArgs, {
14553
+ execFileSync19("pulumi", finalArgs, {
14320
14554
  cwd: appRoot,
14321
14555
  env,
14322
14556
  stdio: "inherit"
@@ -14421,8 +14655,8 @@ var init_schema2 = __esm({
14421
14655
  });
14422
14656
 
14423
14657
  // libs/mesh-cli/src/docs/discover.ts
14424
- import { existsSync as existsSync21, readdirSync as readdirSync9, readFileSync as readFileSync22, statSync as statSync5 } from "node:fs";
14425
- import path27 from "node:path";
14658
+ import { existsSync as existsSync22, readdirSync as readdirSync9, readFileSync as readFileSync23, statSync as statSync5 } from "node:fs";
14659
+ import path28 from "node:path";
14426
14660
  function routePathFor(relPath) {
14427
14661
  const withoutExt = relPath.replace(/\.md$/i, "");
14428
14662
  const parts = withoutExt.split("/").map(slugify2);
@@ -14442,7 +14676,7 @@ function walkMarkdown(absDir, relDir, errors, rootDir) {
14442
14676
  if (hasReservedSegment(entry.name)) {
14443
14677
  continue;
14444
14678
  }
14445
- const abs = path27.join(absDir, entry.name);
14679
+ const abs = path28.join(absDir, entry.name);
14446
14680
  if (entry.isDirectory()) {
14447
14681
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
14448
14682
  out.push(...walkMarkdown(abs, rel2, errors, rootDir));
@@ -14488,7 +14722,7 @@ function discoverDocRoots(repoRoot2) {
14488
14722
  if (entry.name.startsWith(".")) continue;
14489
14723
  const rel2 = relDir ? `${relDir}/${entry.name}` : entry.name;
14490
14724
  findRoots(
14491
- path27.join(absDir, entry.name),
14725
+ path28.join(absDir, entry.name),
14492
14726
  rel2,
14493
14727
  insideReserved || hasReservedSegment(entry.name)
14494
14728
  );
@@ -14497,7 +14731,7 @@ function discoverDocRoots(repoRoot2) {
14497
14731
  findRoots(repoRoot2, "", false);
14498
14732
  const pages = [];
14499
14733
  for (const root of roots) {
14500
- const absRoot = path27.join(repoRoot2, root.dir);
14734
+ const absRoot = path28.join(repoRoot2, root.dir);
14501
14735
  const relFiles = walkMarkdown(absRoot, "", errors, root.dir);
14502
14736
  for (const relPath of relFiles.sort()) {
14503
14737
  pages.push({
@@ -14521,14 +14755,14 @@ function discoverDocRoots(repoRoot2) {
14521
14755
  );
14522
14756
  continue;
14523
14757
  }
14524
- if (!existsSync21(path27.join(repoRoot2, normalized))) {
14758
+ if (!existsSync22(path28.join(repoRoot2, normalized))) {
14525
14759
  errors.push(
14526
14760
  `${root.dir}/docs.json includes ${normalized}, which does not exist`
14527
14761
  );
14528
14762
  continue;
14529
14763
  }
14530
14764
  if (pages.some((p) => p.source === normalized)) continue;
14531
- const stem = path27.posix.basename(normalized).replace(/\.md$/i, "");
14765
+ const stem = path28.posix.basename(normalized).replace(/\.md$/i, "");
14532
14766
  pages.push({
14533
14767
  source: normalized,
14534
14768
  root,
@@ -14556,10 +14790,10 @@ function discoverDocRoots(repoRoot2) {
14556
14790
  return { roots, pages, errors };
14557
14791
  }
14558
14792
  function loadRoot(absDir, relDir, errors) {
14559
- const configPath = path27.join(absDir, "docs.json");
14793
+ const configPath = path28.join(absDir, "docs.json");
14560
14794
  let raw;
14561
14795
  try {
14562
- raw = JSON.parse(readFileSync22(configPath, "utf-8"));
14796
+ raw = JSON.parse(readFileSync23(configPath, "utf-8"));
14563
14797
  } catch (error) {
14564
14798
  errors.push(
14565
14799
  `${relDir}/docs.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
@@ -14609,9 +14843,9 @@ var init_discover = __esm({
14609
14843
  });
14610
14844
 
14611
14845
  // libs/mesh-cli/src/docs/assemble.ts
14612
- import { execFileSync as execFileSync19 } from "node:child_process";
14613
- import { mkdirSync as mkdirSync11, readFileSync as readFileSync23, rmSync as rmSync5, writeFileSync as writeFileSync15 } from "node:fs";
14614
- import path28 from "node:path";
14846
+ import { execFileSync as execFileSync20 } from "node:child_process";
14847
+ import { mkdirSync as mkdirSync12, readFileSync as readFileSync24, rmSync as rmSync5, writeFileSync as writeFileSync15 } from "node:fs";
14848
+ import path29 from "node:path";
14615
14849
  import { parse as parseYaml4 } from "yaml";
14616
14850
  function splitFrontMatter(markdown) {
14617
14851
  const normalized = markdown.replace(/^\uFEFF/, "");
@@ -14671,7 +14905,7 @@ function deriveTitle(frontMatter, body, source) {
14671
14905
  if (typeof fmTitle === "string" && fmTitle.trim()) return fmTitle.trim();
14672
14906
  const heading = firstHeading(body);
14673
14907
  if (heading) return heading;
14674
- const stem = path28.posix.basename(source).replace(/\.md$/i, "");
14908
+ const stem = path29.posix.basename(source).replace(/\.md$/i, "");
14675
14909
  return titleizeStem(stem);
14676
14910
  }
14677
14911
  function scanLinks(markdown) {
@@ -14803,7 +15037,7 @@ function isAbsoluteHref(href) {
14803
15037
  return /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i.test(href);
14804
15038
  }
14805
15039
  function normalizeRepoPath(value) {
14806
- return path28.posix.normalize(value.replace(/\\/g, "/")).replace(/^\.\//, "").replace(/\/+$/, "");
15040
+ return path29.posix.normalize(value.replace(/\\/g, "/")).replace(/^\.\//, "").replace(/\/+$/, "");
14807
15041
  }
14808
15042
  function splitHash(href) {
14809
15043
  const index = href.indexOf("#");
@@ -14821,7 +15055,7 @@ function resolveLink(args) {
14821
15055
  const route = rawTarget.replace(/\/$/, "") || "/";
14822
15056
  return routes.has(route) ? { href: `${route}${hash}` } : { href, issue: { kind: "broken", page: pageRoute2, href } };
14823
15057
  }
14824
- const repoPath = normalizeRepoPath(path28.posix.join(sourceDir, rawTarget));
15058
+ const repoPath = normalizeRepoPath(path29.posix.join(sourceDir, rawTarget));
14825
15059
  const page = sourceIndex.get(repoPath);
14826
15060
  if (page) return { href: `${page.route}${hash}` };
14827
15061
  for (const candidate of [`${repoPath}/index.md`]) {
@@ -14842,7 +15076,7 @@ function rewriteLinks(args) {
14842
15076
  const issues = [];
14843
15077
  const hits = scanLinks(args.body);
14844
15078
  if (hits.length === 0) return { body: args.body, issues };
14845
- const sourceDir = path28.posix.dirname(args.page.source);
15079
+ const sourceDir = path29.posix.dirname(args.page.source);
14846
15080
  let out = "";
14847
15081
  let cursor = 0;
14848
15082
  for (const hit of hits) {
@@ -14893,9 +15127,9 @@ function assemblePortal(options) {
14893
15127
  const brokenLinks = [];
14894
15128
  const externalLinks = [];
14895
15129
  rmSync5(outDir, { recursive: true, force: true });
14896
- mkdirSync11(outDir, { recursive: true });
15130
+ mkdirSync12(outDir, { recursive: true });
14897
15131
  for (const page of pages) {
14898
- const raw = readFileSync23(path28.join(repoRoot2, page.source), "utf-8");
15132
+ const raw = readFileSync24(path29.join(repoRoot2, page.source), "utf-8");
14899
15133
  const frontMatter = splitFrontMatter(raw);
14900
15134
  const title = deriveTitle(frontMatter.data, frontMatter.body, page.source);
14901
15135
  page.title = title;
@@ -14907,7 +15141,7 @@ function assemblePortal(options) {
14907
15141
  sourceIndex,
14908
15142
  routes,
14909
15143
  ignoreLinkPrefixes,
14910
- pathKind: (rel2) => pathKind(path28.join(repoRoot2, rel2)),
15144
+ pathKind: (rel2) => pathKind(path29.join(repoRoot2, rel2)),
14911
15145
  repoUrl
14912
15146
  });
14913
15147
  for (const issue of rewritten.issues) {
@@ -14921,8 +15155,8 @@ function assemblePortal(options) {
14921
15155
 
14922
15156
  <sub>Source: [\`${page.source}\`](${blobBase}/blob/main/${page.source}) \u2014 edit that file, not this page.</sub>
14923
15157
  `;
14924
- const outFile = path28.join(outDir, page.filePath);
14925
- mkdirSync11(path28.dirname(outFile), { recursive: true });
15158
+ const outFile = path29.join(outDir, page.filePath);
15159
+ mkdirSync12(path29.dirname(outFile), { recursive: true });
14926
15160
  writeFileSync15(
14927
15161
  outFile,
14928
15162
  joinFrontMatter(outData, rewritten.body.trimEnd() + sourceNote)
@@ -15100,7 +15334,7 @@ function renderVersionJson(args) {
15100
15334
  }
15101
15335
  function currentCommit(repoRoot2) {
15102
15336
  try {
15103
- return execFileSync19("git", ["rev-parse", "--short", "HEAD"], {
15337
+ return execFileSync20("git", ["rev-parse", "--short", "HEAD"], {
15104
15338
  cwd: repoRoot2,
15105
15339
  encoding: "utf-8"
15106
15340
  }).trim();
@@ -15111,7 +15345,7 @@ function currentCommit(repoRoot2) {
15111
15345
  function currentBaseline(repoRoot2) {
15112
15346
  try {
15113
15347
  const pkg = JSON.parse(
15114
- readFileSync23(path28.join(repoRoot2, "libs/app-kit/package.json"), "utf-8")
15348
+ readFileSync24(path29.join(repoRoot2, "libs/app-kit/package.json"), "utf-8")
15115
15349
  );
15116
15350
  return pkg.version;
15117
15351
  } catch {
@@ -15119,7 +15353,7 @@ function currentBaseline(repoRoot2) {
15119
15353
  }
15120
15354
  }
15121
15355
  function publishSetAtRef(repoRoot2, ref) {
15122
- const git = (gitArgs) => execFileSync19("git", gitArgs, {
15356
+ const git = (gitArgs) => execFileSync20("git", gitArgs, {
15123
15357
  cwd: repoRoot2,
15124
15358
  encoding: "utf-8",
15125
15359
  maxBuffer: 64 * 1024 * 1024
@@ -15144,7 +15378,7 @@ function publishSetAtRef(repoRoot2, ref) {
15144
15378
  continue;
15145
15379
  const rel2 = file.slice(prefix2.length);
15146
15380
  if (hasReservedSegment(rel2)) continue;
15147
- if (path28.posix.basename(file).toLowerCase() === "readme.md") continue;
15381
+ if (path29.posix.basename(file).toLowerCase() === "readme.md") continue;
15148
15382
  published.add(file);
15149
15383
  }
15150
15384
  for (const include of config.include ?? []) {
@@ -15230,8 +15464,8 @@ function formatDefault(value, paths = currentMachinePaths()) {
15230
15464
  if (typeof value === "boolean" || typeof value === "number") return String(value);
15231
15465
  return normalizeMachinePaths(JSON.stringify(value), paths);
15232
15466
  }
15233
- function slugifyCommandPath(path47) {
15234
- return path47.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
15467
+ function slugifyCommandPath(path48) {
15468
+ return path48.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
15235
15469
  }
15236
15470
  function extractOptions(command) {
15237
15471
  const options = command.options ?? [];
@@ -15265,17 +15499,17 @@ function isUndocumented(command) {
15265
15499
  function extractCommand(command, parentPath, depth) {
15266
15500
  const internals = command;
15267
15501
  const name = internals._name ?? "";
15268
- const path47 = parentPath ? `${parentPath} ${name}` : name;
15502
+ const path48 = parentPath ? `${parentPath} ${name}` : name;
15269
15503
  return {
15270
- path: path47,
15504
+ path: path48,
15271
15505
  name,
15272
15506
  aliases: [...internals._aliases ?? []],
15273
15507
  description: internals._description ?? "",
15274
15508
  args: extractArgs(command),
15275
15509
  options: extractOptions(command),
15276
- slug: slugifyCommandPath(path47),
15510
+ slug: slugifyCommandPath(path48),
15277
15511
  depth,
15278
- subcommands: (internals.commands ?? []).filter((child) => !isUndocumented(child)).map((child) => extractCommand(child, path47, depth + 1))
15512
+ subcommands: (internals.commands ?? []).filter((child) => !isUndocumented(child)).map((child) => extractCommand(child, path48, depth + 1))
15279
15513
  };
15280
15514
  }
15281
15515
  function extractCliReference(program2) {
@@ -15367,14 +15601,14 @@ var init_cli_reference = __esm({
15367
15601
  import { spawn as spawn7 } from "node:child_process";
15368
15602
  import {
15369
15603
  appendFileSync,
15370
- existsSync as existsSync22,
15371
- mkdirSync as mkdirSync12,
15604
+ existsSync as existsSync23,
15605
+ mkdirSync as mkdirSync13,
15372
15606
  mkdtempSync as mkdtempSync3,
15373
- readFileSync as readFileSync24,
15607
+ readFileSync as readFileSync25,
15374
15608
  writeFileSync as writeFileSync16
15375
15609
  } from "node:fs";
15376
15610
  import { tmpdir as tmpdir6 } from "node:os";
15377
- import path29 from "node:path";
15611
+ import path30 from "node:path";
15378
15612
  function runAssemble(args) {
15379
15613
  const discovery = discoverDocRoots(args.repoRoot);
15380
15614
  const assembled = assemblePortal({
@@ -15386,7 +15620,7 @@ function runAssemble(args) {
15386
15620
  });
15387
15621
  const errors = [...discovery.errors];
15388
15622
  if (args.writeFiles !== false) {
15389
- const manifestPath = args.outDir.includes(tmpdir6()) ? path29.join(args.outDir, PUBLISH_MANIFEST) : path29.join(args.outDir, "..", PUBLISH_MANIFEST);
15623
+ const manifestPath = args.outDir.includes(tmpdir6()) ? path30.join(args.outDir, PUBLISH_MANIFEST) : path30.join(args.outDir, "..", PUBLISH_MANIFEST);
15390
15624
  writeFileSync16(
15391
15625
  manifestPath,
15392
15626
  `${JSON.stringify(assembled.publishManifest, null, 2)}
@@ -15403,13 +15637,13 @@ function runAssemble(args) {
15403
15637
  commit: currentCommit(args.repoRoot)
15404
15638
  })
15405
15639
  );
15406
- const versionDir = path29.join(
15407
- path29.dirname(args.configOut),
15640
+ const versionDir = path30.join(
15641
+ path30.dirname(args.configOut),
15408
15642
  VERSION_JSON_DIR
15409
15643
  );
15410
- mkdirSync12(versionDir, { recursive: true });
15644
+ mkdirSync13(versionDir, { recursive: true });
15411
15645
  writeFileSync16(
15412
- path29.join(versionDir, VERSION_JSON),
15646
+ path30.join(versionDir, VERSION_JSON),
15413
15647
  renderVersionJson({
15414
15648
  baseline: currentBaseline(args.repoRoot),
15415
15649
  commit: currentCommit(args.repoRoot),
@@ -15441,7 +15675,7 @@ function reportAssembly(result) {
15441
15675
  }
15442
15676
  }
15443
15677
  async function checkPortal(args) {
15444
- const scratch = mkdtempSync3(path29.join(tmpdir6(), "mesh-docs-check-"));
15678
+ const scratch = mkdtempSync3(path30.join(tmpdir6(), "mesh-docs-check-"));
15445
15679
  const result = runAssemble({ repoRoot: args.repoRoot, outDir: scratch });
15446
15680
  const failures = [...result.errors];
15447
15681
  for (const violation of result.assembled.reservedViolations) {
@@ -15462,7 +15696,7 @@ async function checkPortal(args) {
15462
15696
  );
15463
15697
  }
15464
15698
  if (args.manifestOut) {
15465
- mkdirSync12(path29.dirname(args.manifestOut), { recursive: true });
15699
+ mkdirSync13(path30.dirname(args.manifestOut), { recursive: true });
15466
15700
  writeFileSync16(
15467
15701
  args.manifestOut,
15468
15702
  `${JSON.stringify(result.assembled.publishManifest, null, 2)}
@@ -15532,12 +15766,12 @@ async function runPortalCommand(opts, deps) {
15532
15766
  logSuccess("Docs portal check passed");
15533
15767
  return;
15534
15768
  }
15535
- const appDir = path29.join(repoRoot2, DOCS_APP_DIR);
15536
- const outDir = opts.out ? path29.resolve(repoRoot2, opts.out) : path29.join(appDir, CONTENT_DIR);
15769
+ const appDir = path30.join(repoRoot2, DOCS_APP_DIR);
15770
+ const outDir = opts.out ? path30.resolve(repoRoot2, opts.out) : path30.join(appDir, CONTENT_DIR);
15537
15771
  const result = runAssemble({
15538
15772
  repoRoot: repoRoot2,
15539
15773
  outDir,
15540
- configOut: path29.join(appDir, GENERATED_CONFIG)
15774
+ configOut: path30.join(appDir, GENERATED_CONFIG)
15541
15775
  });
15542
15776
  reportAssembly(result);
15543
15777
  if (result.errors.length > 0) {
@@ -15548,7 +15782,7 @@ async function runPortalCommand(opts, deps) {
15548
15782
  }
15549
15783
  if (opts.assembleOnly || opts.out) {
15550
15784
  logInfo(
15551
- `Assembled content at ${path29.relative(repoRoot2, outDir)} \u2014 build with: pnpm --filter @mesh-tech/docs build`
15785
+ `Assembled content at ${path30.relative(repoRoot2, outDir)} \u2014 build with: pnpm --filter @mesh-tech/docs build`
15552
15786
  );
15553
15787
  return;
15554
15788
  }
@@ -15568,7 +15802,7 @@ async function runPortalCommand(opts, deps) {
15568
15802
  if (code !== 0) throw new Error(`zudoku ${mode} exited with code ${code}`);
15569
15803
  if (mode === "build") {
15570
15804
  logSuccess(
15571
- `Portal built \u2192 ${path29.join(path29.relative(repoRoot2, appDir), "dist")}`
15805
+ `Portal built \u2192 ${path30.join(path30.relative(repoRoot2, appDir), "dist")}`
15572
15806
  );
15573
15807
  }
15574
15808
  }
@@ -15580,11 +15814,11 @@ async function cliReferenceStaleness(repoRoot2) {
15580
15814
  Promise.resolve().then(() => (init_program(), program_exports)),
15581
15815
  Promise.resolve().then(() => (init_cli_reference(), cli_reference_exports))
15582
15816
  ]);
15583
- const outPath = path29.join(repoRoot2, "docs/portal/generated/cli-reference.md");
15817
+ const outPath = path30.join(repoRoot2, "docs/portal/generated/cli-reference.md");
15584
15818
  const markdown = renderCliReferenceMarkdown2(
15585
15819
  extractCliReference2(createProgram2())
15586
15820
  );
15587
- const existing = existsSync22(outPath) ? readFileSync24(outPath, "utf-8") : null;
15821
+ const existing = existsSync23(outPath) ? readFileSync25(outPath, "utf-8") : null;
15588
15822
  if (existing === markdown) return null;
15589
15823
  return `${existing === null ? "CLI reference is missing" : "CLI reference is stale"}: docs/portal/generated/cli-reference.md \u2014 the commander tree changed; regenerate and commit with \`pnpm exec mesh docs cli-reference\``;
15590
15824
  }
@@ -15607,9 +15841,9 @@ var init_portal = __esm({
15607
15841
  });
15608
15842
 
15609
15843
  // libs/mesh-cli/src/utils/build-info.ts
15610
- import { execFileSync as execFileSync20 } from "child_process";
15611
- import * as fs25 from "fs";
15612
- import * as path30 from "path";
15844
+ import { execFileSync as execFileSync21 } from "child_process";
15845
+ import * as fs26 from "fs";
15846
+ import * as path31 from "path";
15613
15847
  import { fileURLToPath as fileURLToPath3 } from "url";
15614
15848
  function detectRuntimeMode(modulePath) {
15615
15849
  return modulePath.split(/[\\/]/).includes("dist") ? "dist" : "source";
@@ -15628,11 +15862,11 @@ function findCliPackageRoot(startDir) {
15628
15862
  let dir = startDir;
15629
15863
  for (let i = 0; i < 8; i++) {
15630
15864
  try {
15631
- const pkg = JSON.parse(fs25.readFileSync(path30.join(dir, "package.json"), "utf-8"));
15865
+ const pkg = JSON.parse(fs26.readFileSync(path31.join(dir, "package.json"), "utf-8"));
15632
15866
  if (pkg.name === "@mesh-tech/mesh-cli") return dir;
15633
15867
  } catch {
15634
15868
  }
15635
- const parent = path30.dirname(dir);
15869
+ const parent = path31.dirname(dir);
15636
15870
  if (parent === dir) break;
15637
15871
  dir = parent;
15638
15872
  }
@@ -15640,13 +15874,13 @@ function findCliPackageRoot(startDir) {
15640
15874
  }
15641
15875
  function resolveCliRuntime(opts) {
15642
15876
  const vcs = opts?.vcs ?? true;
15643
- const here = path30.dirname(fileURLToPath3(import.meta.url));
15877
+ const here = path31.dirname(fileURLToPath3(import.meta.url));
15644
15878
  const mode = detectRuntimeMode(here);
15645
15879
  const root = findCliPackageRoot(here);
15646
15880
  let version = "0.0.0";
15647
15881
  if (root) {
15648
15882
  try {
15649
- version = JSON.parse(fs25.readFileSync(path30.join(root, "package.json"), "utf-8")).version ?? version;
15883
+ version = JSON.parse(fs26.readFileSync(path31.join(root, "package.json"), "utf-8")).version ?? version;
15650
15884
  } catch {
15651
15885
  }
15652
15886
  }
@@ -15655,7 +15889,7 @@ function resolveCliRuntime(opts) {
15655
15889
  if (mode === "dist") {
15656
15890
  try {
15657
15891
  const meta = JSON.parse(
15658
- fs25.readFileSync(path30.join(root, "dist", "build-info.json"), "utf-8")
15892
+ fs26.readFileSync(path31.join(root, "dist", "build-info.json"), "utf-8")
15659
15893
  );
15660
15894
  info.commit = meta.commit;
15661
15895
  info.builtAt = meta.builtAt;
@@ -15665,7 +15899,7 @@ function resolveCliRuntime(opts) {
15665
15899
  }
15666
15900
  if (!vcs) return info;
15667
15901
  try {
15668
- const git = (args) => execFileSync20("git", args, {
15902
+ const git = (args) => execFileSync21("git", args, {
15669
15903
  cwd: root,
15670
15904
  encoding: "utf-8",
15671
15905
  stdio: ["ignore", "pipe", "pipe"]
@@ -15685,7 +15919,7 @@ var init_build_info = __esm({
15685
15919
  // libs/mesh-cli/src/docs/serve.ts
15686
15920
  import { createServer as createServer8 } from "node:http";
15687
15921
  import { readFile } from "node:fs/promises";
15688
- import { extname as extname2, join as join27, normalize, sep as sep5 } from "node:path";
15922
+ import { extname as extname2, join as join28, normalize, sep as sep5 } from "node:path";
15689
15923
  async function serveDocsSite(args) {
15690
15924
  const root = normalize(args.root);
15691
15925
  const rootPrefix = root.endsWith(sep5) ? root : root + sep5;
@@ -15704,7 +15938,7 @@ async function serveDocsSite(args) {
15704
15938
  ];
15705
15939
  if (pathname !== "/") candidates.push("/index.html");
15706
15940
  for (const candidate of candidates) {
15707
- const filePath = normalize(join27(root, candidate));
15941
+ const filePath = normalize(join28(root, candidate));
15708
15942
  if (filePath !== root && !filePath.startsWith(rootPrefix)) continue;
15709
15943
  try {
15710
15944
  const body = await readFile(filePath);
@@ -15762,13 +15996,13 @@ var init_serve = __esm({
15762
15996
  });
15763
15997
 
15764
15998
  // libs/mesh-cli/src/docs/registry-docs.ts
15765
- import { execFileSync as execFileSync21 } from "node:child_process";
15766
- import { existsSync as existsSync23, mkdirSync as mkdirSync13, readFileSync as readFileSync26, renameSync as renameSync3, rmSync as rmSync6, writeFileSync as writeFileSync17 } from "node:fs";
15999
+ import { execFileSync as execFileSync22 } from "node:child_process";
16000
+ import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync27, renameSync as renameSync3, rmSync as rmSync6, writeFileSync as writeFileSync17 } from "node:fs";
15767
16001
  import { tmpdir as tmpdir7 } from "node:os";
15768
- import path31 from "node:path";
16002
+ import path32 from "node:path";
15769
16003
  function readDocsRegistryAuth(npmrcPath2 = homeNpmrcPath()) {
15770
- if (!existsSync23(npmrcPath2)) return null;
15771
- return parseNpmrcRegistryAuth(readFileSync26(npmrcPath2, "utf-8"));
16004
+ if (!existsSync24(npmrcPath2)) return null;
16005
+ return parseNpmrcRegistryAuth(readFileSync27(npmrcPath2, "utf-8"));
15772
16006
  }
15773
16007
  function packumentUrl(endpoint, pkg) {
15774
16008
  return `${endpoint.replace(/\/+$/, "")}/${pkg.replace(/\//g, "%2f")}`;
@@ -15818,15 +16052,15 @@ async function listDocsVersions(auth, fetchImpl = fetch) {
15818
16052
  return { versions, latest: packument["dist-tags"]?.latest };
15819
16053
  }
15820
16054
  function docsCacheRoot() {
15821
- const base = process.env.XDG_CACHE_HOME ?? path31.join(homeDir(), ".cache");
15822
- return path31.join(base, "mesh", "docs");
16055
+ const base = process.env.XDG_CACHE_HOME ?? path32.join(homeDir(), ".cache");
16056
+ return path32.join(base, "mesh", "docs");
15823
16057
  }
15824
16058
  function homeDir() {
15825
16059
  return process.env.HOME ?? tmpdir7();
15826
16060
  }
15827
16061
  async function fetchDocsArtifact(auth, version, cacheRoot = docsCacheRoot(), fetchImpl = fetch) {
15828
- const targetDir = path31.join(cacheRoot, version);
15829
- if (existsSync23(path31.join(targetDir, "dist", "index.html"))) return targetDir;
16062
+ const targetDir = path32.join(cacheRoot, version);
16063
+ if (existsSync24(path32.join(targetDir, "dist", "index.html"))) return targetDir;
15830
16064
  const listResponse = await registryFetch(auth, packumentUrl(auth.endpoint, DOCS_PACKAGE), fetchImpl);
15831
16065
  if (!listResponse.ok) {
15832
16066
  throw new Error(`registry returned ${listResponse.status} for ${DOCS_PACKAGE}`);
@@ -15847,20 +16081,20 @@ async function fetchDocsArtifact(auth, version, cacheRoot = docsCacheRoot(), fet
15847
16081
  if (!tgzResponse.ok) {
15848
16082
  throw new Error(`downloading ${DOCS_PACKAGE}@${version} failed: ${tgzResponse.status}`);
15849
16083
  }
15850
- mkdirSync13(cacheRoot, { recursive: true });
15851
- const tgzPath = path31.join(cacheRoot, `.${version}.tgz`);
16084
+ mkdirSync14(cacheRoot, { recursive: true });
16085
+ const tgzPath = path32.join(cacheRoot, `.${version}.tgz`);
15852
16086
  writeFileSync17(tgzPath, Buffer.from(await tgzResponse.arrayBuffer()));
15853
- const staging = path31.join(cacheRoot, `.staging-${version}`);
16087
+ const staging = path32.join(cacheRoot, `.staging-${version}`);
15854
16088
  rmSync6(staging, { recursive: true, force: true });
15855
- mkdirSync13(staging, { recursive: true });
16089
+ mkdirSync14(staging, { recursive: true });
15856
16090
  try {
15857
- execFileSync21("tar", ["-xzf", tgzPath, "-C", staging, "--strip-components", "1"], {
16091
+ execFileSync22("tar", ["-xzf", tgzPath, "-C", staging, "--strip-components", "1"], {
15858
16092
  stdio: ["pipe", "pipe", "pipe"]
15859
16093
  });
15860
16094
  } finally {
15861
16095
  rmSync6(tgzPath, { force: true });
15862
16096
  }
15863
- if (!existsSync23(path31.join(staging, "dist", "index.html"))) {
16097
+ if (!existsSync24(path32.join(staging, "dist", "index.html"))) {
15864
16098
  rmSync6(staging, { recursive: true, force: true });
15865
16099
  throw new Error(`${DOCS_PACKAGE}@${version} unpacked without a dist/index.html \u2014 the artifact is malformed`);
15866
16100
  }
@@ -15892,9 +16126,9 @@ __export(start_exports, {
15892
16126
  tmuxInstallHint: () => tmuxInstallHint,
15893
16127
  tmuxServeArgs: () => tmuxServeArgs
15894
16128
  });
15895
- import { execFileSync as execFileSync22 } from "node:child_process";
15896
- import { appendFileSync as appendFileSync2, existsSync as existsSync24, writeFileSync as writeFileSync18 } from "node:fs";
15897
- import path32 from "node:path";
16129
+ import { execFileSync as execFileSync23 } from "node:child_process";
16130
+ import { appendFileSync as appendFileSync2, existsSync as existsSync25, writeFileSync as writeFileSync18 } from "node:fs";
16131
+ import path33 from "node:path";
15898
16132
  function registryAuthOrThrow() {
15899
16133
  const auth = readDocsRegistryAuth();
15900
16134
  if (!auth) {
@@ -15925,7 +16159,7 @@ function tmuxInstallHint(platform = process.platform) {
15925
16159
  }
15926
16160
  function tmuxAvailable() {
15927
16161
  try {
15928
- execFileSync22("tmux", ["-V"], { stdio: ["pipe", "pipe", "pipe"] });
16162
+ execFileSync23("tmux", ["-V"], { stdio: ["pipe", "pipe", "pipe"] });
15929
16163
  return true;
15930
16164
  } catch {
15931
16165
  return false;
@@ -15936,7 +16170,7 @@ function shouldDetach(args) {
15936
16170
  }
15937
16171
  function docsSessionExists() {
15938
16172
  try {
15939
- execFileSync22("tmux", ["has-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
16173
+ execFileSync23("tmux", ["has-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
15940
16174
  return true;
15941
16175
  } catch {
15942
16176
  return false;
@@ -15960,12 +16194,12 @@ Or run in the foreground instead: mesh docs start --foreground`
15960
16194
  if (docsSessionExists()) {
15961
16195
  logInfo(`Replacing the docs server already running in tmux session "${DOCS_TMUX_SESSION}".`);
15962
16196
  try {
15963
- execFileSync22("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
16197
+ execFileSync23("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
15964
16198
  } catch {
15965
16199
  }
15966
16200
  }
15967
16201
  const { command, cwd } = tmuxServeArgs(args);
15968
- execFileSync22(
16202
+ execFileSync23(
15969
16203
  "tmux",
15970
16204
  ["new-session", "-d", "-s", DOCS_TMUX_SESSION, "-c", cwd, "--", ...command],
15971
16205
  { stdio: ["pipe", "pipe", "pipe"] }
@@ -16003,7 +16237,7 @@ function printReady(url, label) {
16003
16237
  }
16004
16238
  function runDocsStop() {
16005
16239
  try {
16006
- execFileSync22("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
16240
+ execFileSync23("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
16007
16241
  logSuccess(`Stopped the docs server (tmux session "${DOCS_TMUX_SESSION}").`);
16008
16242
  } catch {
16009
16243
  logInfo(`No docs server is running (no tmux session named "${DOCS_TMUX_SESSION}").`);
@@ -16014,7 +16248,7 @@ async function runDocsServeStatic(args) {
16014
16248
  if (!Number.isInteger(requestedPort) || requestedPort < 0 || requestedPort > 65535) {
16015
16249
  throw new Error(`Invalid --port: ${args.port}`);
16016
16250
  }
16017
- if (!args.root || !existsSync24(path32.join(args.root, "index.html"))) {
16251
+ if (!args.root || !existsSync25(path33.join(args.root, "index.html"))) {
16018
16252
  throw new Error(
16019
16253
  `--root ${args.root || "(empty)"} does not hold a built site (no index.html). This command exists so the detached tmux session can re-enter; you probably want \`mesh docs start\`.`
16020
16254
  );
@@ -16055,19 +16289,19 @@ async function runDocsStart(args) {
16055
16289
  }
16056
16290
  logInfo(`Fetching ${DOCS_PACKAGE}@${version} from the registry\u2026`);
16057
16291
  const artifactDir = await fetchDocsArtifact(auth, version);
16058
- serveRoot = path32.join(artifactDir, "dist");
16292
+ serveRoot = path33.join(artifactDir, "dist");
16059
16293
  label = `@mesh-tech/* ${version} (published artifact)`;
16060
16294
  } else {
16061
16295
  if (localRoots.errors.length > 0) {
16062
16296
  for (const error of localRoots.errors) logError(error);
16063
16297
  throw new Error(`docs discovery failed with ${localRoots.errors.length} problem(s)`);
16064
16298
  }
16065
- const appDir = path32.join(args.repoRoot, DOCS_APP_DIR);
16299
+ const appDir = path33.join(args.repoRoot, DOCS_APP_DIR);
16066
16300
  if (args.dev) {
16067
16301
  const result2 = runAssemble({
16068
16302
  repoRoot: args.repoRoot,
16069
- outDir: path32.join(appDir, "content"),
16070
- configOut: path32.join(appDir, "zudoku.config.ts")
16303
+ outDir: path33.join(appDir, "content"),
16304
+ configOut: path33.join(appDir, "zudoku.config.ts")
16071
16305
  });
16072
16306
  reportAssembly(result2);
16073
16307
  const { spawn: spawn11 } = await import("node:child_process");
@@ -16083,12 +16317,12 @@ async function runDocsStart(args) {
16083
16317
  });
16084
16318
  return;
16085
16319
  }
16086
- const buildLog = path32.join(args.repoRoot, DOCS_APP_DIR, "build.log");
16087
- logInfo(`Preparing the docs from this checkout (assemble + build \u2014 log: ${path32.relative(args.repoRoot, buildLog)})\u2026`);
16320
+ const buildLog = path33.join(args.repoRoot, DOCS_APP_DIR, "build.log");
16321
+ logInfo(`Preparing the docs from this checkout (assemble + build \u2014 log: ${path33.relative(args.repoRoot, buildLog)})\u2026`);
16088
16322
  const result = runAssemble({
16089
16323
  repoRoot: args.repoRoot,
16090
- outDir: path32.join(appDir, "content"),
16091
- configOut: path32.join(appDir, "zudoku.config.ts")
16324
+ outDir: path33.join(appDir, "content"),
16325
+ configOut: path33.join(appDir, "zudoku.config.ts")
16092
16326
  });
16093
16327
  reportAssembly(result);
16094
16328
  const { spawn: spawn10 } = await import("node:child_process");
@@ -16105,7 +16339,7 @@ async function runDocsStart(args) {
16105
16339
  child.on("close", (exitCode) => resolve20(exitCode ?? 1));
16106
16340
  });
16107
16341
  if (code !== 0) throw new Error(`zudoku build exited with code ${code} \u2014 see ${buildLog}`);
16108
- serveRoot = path32.join(appDir, "dist");
16342
+ serveRoot = path33.join(appDir, "dist");
16109
16343
  label = "this checkout";
16110
16344
  }
16111
16345
  if (detached) {
@@ -16145,30 +16379,30 @@ var init_start = __esm({
16145
16379
  });
16146
16380
 
16147
16381
  // libs/mesh-cli/src/commands/docs.ts
16148
- import * as fs26 from "fs";
16149
- import * as path33 from "path";
16382
+ import * as fs27 from "fs";
16383
+ import * as path34 from "path";
16150
16384
  import { createRequire } from "module";
16151
16385
  import { pathToFileURL } from "url";
16152
16386
  function findProjectRoot(start = process.cwd()) {
16153
16387
  let dir = start;
16154
16388
  while (true) {
16155
- if (fs26.existsSync(path33.join(dir, "package.json"))) return dir;
16156
- const parent = path33.dirname(dir);
16389
+ if (fs27.existsSync(path34.join(dir, "package.json"))) return dir;
16390
+ const parent = path34.dirname(dir);
16157
16391
  if (parent === dir) return start;
16158
16392
  dir = parent;
16159
16393
  }
16160
16394
  }
16161
16395
  function resolvePath(projectRoot, candidate) {
16162
- return path33.isAbsolute(candidate) ? candidate : path33.join(projectRoot, candidate);
16396
+ return path34.isAbsolute(candidate) ? candidate : path34.join(projectRoot, candidate);
16163
16397
  }
16164
16398
  function ensureParentDir(filePath) {
16165
- fs26.mkdirSync(path33.dirname(filePath), { recursive: true });
16399
+ fs27.mkdirSync(path34.dirname(filePath), { recursive: true });
16166
16400
  }
16167
16401
  function readConfig2(configPath) {
16168
- if (!fs26.existsSync(configPath)) {
16402
+ if (!fs27.existsSync(configPath)) {
16169
16403
  throw new Error(`Docs config not found: ${configPath}`);
16170
16404
  }
16171
- const raw = fs26.readFileSync(configPath, "utf-8");
16405
+ const raw = fs27.readFileSync(configPath, "utf-8");
16172
16406
  const parsed = JSON.parse(raw);
16173
16407
  if (parsed.openapi && !Array.isArray(parsed.openapi)) {
16174
16408
  throw new Error(`Invalid docs config: 'openapi' must be an array`);
@@ -16176,7 +16410,7 @@ function readConfig2(configPath) {
16176
16410
  return parsed;
16177
16411
  }
16178
16412
  function validateOpenApiSpec(specPath) {
16179
- const content = fs26.readFileSync(specPath, "utf-8");
16413
+ const content = fs27.readFileSync(specPath, "utf-8");
16180
16414
  const parsed = JSON.parse(content);
16181
16415
  if (typeof parsed.openapi !== "string") {
16182
16416
  throw new Error(`Invalid OpenAPI spec (${specPath}): missing 'openapi'`);
@@ -16189,7 +16423,7 @@ function validateOpenApiSpec(specPath) {
16189
16423
  }
16190
16424
  }
16191
16425
  async function loadSymxchangeGenerator(projectRoot) {
16192
- const requireFromProject = createRequire(path33.join(projectRoot, "package.json"));
16426
+ const requireFromProject = createRequire(path34.join(projectRoot, "package.json"));
16193
16427
  const entryPath = requireFromProject.resolve("@mesh-tech/jh-symitar-api");
16194
16428
  const mod = await import(pathToFileURL(entryPath).href);
16195
16429
  const fn = mod.generateSymxchangeOpenApi;
@@ -16202,8 +16436,8 @@ async function loadSymxchangeGenerator(projectRoot) {
16202
16436
  }
16203
16437
  async function buildDocs(configPathArg) {
16204
16438
  const cwd = process.cwd();
16205
- const configPath = path33.isAbsolute(configPathArg ?? "") ? configPathArg : path33.resolve(cwd, configPathArg ?? "docs/docs.config.json");
16206
- const projectRoot = findProjectRoot(path33.dirname(configPath));
16439
+ const configPath = path34.isAbsolute(configPathArg ?? "") ? configPathArg : path34.resolve(cwd, configPathArg ?? "docs/docs.config.json");
16440
+ const projectRoot = findProjectRoot(path34.dirname(configPath));
16207
16441
  const config = readConfig2(configPath);
16208
16442
  logInfo(`Using docs config: ${configPath}`);
16209
16443
  const generatedSpecs = /* @__PURE__ */ new Set();
@@ -16211,15 +16445,15 @@ async function buildDocs(configPathArg) {
16211
16445
  if (task.kind === "file") {
16212
16446
  const inputPath = resolvePath(projectRoot, task.input);
16213
16447
  const outputPath = resolvePath(projectRoot, task.output ?? task.input);
16214
- if (!fs26.existsSync(inputPath)) {
16448
+ if (!fs27.existsSync(inputPath)) {
16215
16449
  throw new Error(`OpenAPI source file not found: ${inputPath}`);
16216
16450
  }
16217
16451
  if (inputPath !== outputPath) {
16218
16452
  ensureParentDir(outputPath);
16219
- fs26.copyFileSync(inputPath, outputPath);
16220
- logSuccess(`Copied OpenAPI spec \u2192 ${path33.relative(projectRoot, outputPath)}`);
16453
+ fs27.copyFileSync(inputPath, outputPath);
16454
+ logSuccess(`Copied OpenAPI spec \u2192 ${path34.relative(projectRoot, outputPath)}`);
16221
16455
  } else {
16222
- logInfo(`Using OpenAPI spec: ${path33.relative(projectRoot, inputPath)}`);
16456
+ logInfo(`Using OpenAPI spec: ${path34.relative(projectRoot, inputPath)}`);
16223
16457
  }
16224
16458
  validateOpenApiSpec(outputPath);
16225
16459
  generatedSpecs.add(outputPath);
@@ -16237,10 +16471,10 @@ async function buildDocs(configPathArg) {
16237
16471
  servers: task.servers
16238
16472
  });
16239
16473
  ensureParentDir(outputPath);
16240
- fs26.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
16474
+ fs27.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
16241
16475
  validateOpenApiSpec(outputPath);
16242
16476
  generatedSpecs.add(outputPath);
16243
- logSuccess(`Generated SymXchange OpenAPI \u2192 ${path33.relative(projectRoot, outputPath)}`);
16477
+ logSuccess(`Generated SymXchange OpenAPI \u2192 ${path34.relative(projectRoot, outputPath)}`);
16244
16478
  continue;
16245
16479
  }
16246
16480
  const exhaustive = task;
@@ -16248,12 +16482,12 @@ async function buildDocs(configPathArg) {
16248
16482
  }
16249
16483
  for (const relPath of config.validate ?? []) {
16250
16484
  const abs = resolvePath(projectRoot, relPath);
16251
- if (!fs26.existsSync(abs)) {
16485
+ if (!fs27.existsSync(abs)) {
16252
16486
  throw new Error(`OpenAPI spec to validate not found: ${abs}`);
16253
16487
  }
16254
16488
  validateOpenApiSpec(abs);
16255
16489
  generatedSpecs.add(abs);
16256
- logSuccess(`Validated OpenAPI spec: ${path33.relative(projectRoot, abs)}`);
16490
+ logSuccess(`Validated OpenAPI spec: ${path34.relative(projectRoot, abs)}`);
16257
16491
  }
16258
16492
  if (generatedSpecs.size === 0) {
16259
16493
  logInfo("No docs tasks configured (nothing to do)");
@@ -16283,20 +16517,20 @@ async function runCliReference(opts) {
16283
16517
  const outPath = resolvePath(repoRoot2, opts.out);
16284
16518
  const markdown = await renderCliReference();
16285
16519
  if (opts.check) {
16286
- const existing = fs26.existsSync(outPath) ? fs26.readFileSync(outPath, "utf-8") : null;
16520
+ const existing = fs27.existsSync(outPath) ? fs27.readFileSync(outPath, "utf-8") : null;
16287
16521
  if (existing === markdown) {
16288
- logSuccess(`CLI reference is up to date (${path33.relative(repoRoot2, outPath)})`);
16522
+ logSuccess(`CLI reference is up to date (${path34.relative(repoRoot2, outPath)})`);
16289
16523
  return;
16290
16524
  }
16291
16525
  throw new Error(
16292
- `${existing === null ? "CLI reference is missing" : "CLI reference is stale"}: ${path33.relative(repoRoot2, outPath)}
16526
+ `${existing === null ? "CLI reference is missing" : "CLI reference is stale"}: ${path34.relative(repoRoot2, outPath)}
16293
16527
  The commander tree changed. Regenerate and commit:
16294
16528
  pnpm exec mesh docs cli-reference`
16295
16529
  );
16296
16530
  }
16297
16531
  ensureParentDir(outPath);
16298
- fs26.writeFileSync(outPath, markdown);
16299
- logSuccess(`CLI reference \u2192 ${path33.relative(repoRoot2, outPath)}`);
16532
+ fs27.writeFileSync(outPath, markdown);
16533
+ logSuccess(`CLI reference \u2192 ${path34.relative(repoRoot2, outPath)}`);
16300
16534
  }
16301
16535
  async function runPortal(opts) {
16302
16536
  const repoRoot2 = findRepoRoot2(process.cwd());
@@ -16376,23 +16610,23 @@ var init_docs = __esm({
16376
16610
  });
16377
16611
 
16378
16612
  // libs/mesh-cli/src/commands/hub/index.ts
16379
- import { execFileSync as execFileSync23 } from "node:child_process";
16380
- import * as fs27 from "node:fs";
16613
+ import { execFileSync as execFileSync24 } from "node:child_process";
16614
+ import * as fs28 from "node:fs";
16381
16615
  import * as net12 from "node:net";
16382
16616
  import * as os9 from "node:os";
16383
- import * as path34 from "node:path";
16617
+ import * as path35 from "node:path";
16384
16618
  import chalk3 from "chalk";
16385
16619
  function devSessionsDir() {
16386
- return path34.join(os9.tmpdir(), "mesh-dev-sessions");
16620
+ return path35.join(os9.tmpdir(), "mesh-dev-sessions");
16387
16621
  }
16388
16622
  function listDevSessions(dir = devSessionsDir()) {
16389
- if (!fs27.existsSync(dir)) return [];
16623
+ if (!fs28.existsSync(dir)) return [];
16390
16624
  const sessions = [];
16391
- for (const entry of fs27.readdirSync(dir)) {
16625
+ for (const entry of fs28.readdirSync(dir)) {
16392
16626
  if (!entry.endsWith(".json")) continue;
16393
16627
  try {
16394
16628
  const state = JSON.parse(
16395
- fs27.readFileSync(path34.join(dir, entry), "utf-8")
16629
+ fs28.readFileSync(path35.join(dir, entry), "utf-8")
16396
16630
  );
16397
16631
  if (state && typeof state === "object" && state.devOutput) {
16398
16632
  sessions.push({ name: entry.slice(0, -".json".length), state });
@@ -16420,8 +16654,8 @@ function pickDevSession(sessions, opts) {
16420
16654
  );
16421
16655
  }
16422
16656
  if (opts.cwdAppRoot) {
16423
- const root = path34.resolve(opts.cwdAppRoot);
16424
- const match = sessions.find((s) => path34.resolve(s.state.appRoot) === root);
16657
+ const root = path35.resolve(opts.cwdAppRoot);
16658
+ const match = sessions.find((s) => path35.resolve(s.state.appRoot) === root);
16425
16659
  if (match) return match;
16426
16660
  }
16427
16661
  if (sessions.length === 1) return sessions[0];
@@ -16442,7 +16676,7 @@ function parseTmuxEnv(output) {
16442
16676
  }
16443
16677
  function readTmuxSessionEnv(sessionName) {
16444
16678
  try {
16445
- const out = execFileSync23("tmux", ["show-environment", "-t", sessionName], {
16679
+ const out = execFileSync24("tmux", ["show-environment", "-t", sessionName], {
16446
16680
  encoding: "utf-8",
16447
16681
  stdio: ["ignore", "pipe", "ignore"]
16448
16682
  });
@@ -16453,7 +16687,7 @@ function readTmuxSessionEnv(sessionName) {
16453
16687
  }
16454
16688
  function tmuxSessionExists(sessionName) {
16455
16689
  try {
16456
- execFileSync23("tmux", ["has-session", "-t", sessionName], { stdio: "ignore" });
16690
+ execFileSync24("tmux", ["has-session", "-t", sessionName], { stdio: "ignore" });
16457
16691
  return true;
16458
16692
  } catch {
16459
16693
  return false;
@@ -16539,11 +16773,11 @@ function assembleHubEnv(session, sessionEnv, opts) {
16539
16773
  return { apiEnv, uiEnv, scope: { hubTenant, scopeEnv, scopeTenants }, temporalAddress, warnings, notes };
16540
16774
  }
16541
16775
  function isPlatformRoot(dir) {
16542
- return fs27.existsSync(path34.join(dir, "apps", "hub", "api", "package.json")) && fs27.existsSync(path34.join(dir, "apps", "hub", "ui", "package.json"));
16776
+ return fs28.existsSync(path35.join(dir, "apps", "hub", "api", "package.json")) && fs28.existsSync(path35.join(dir, "apps", "hub", "ui", "package.json"));
16543
16777
  }
16544
16778
  function resolvePlatformDir(explicit, cwd, env = process.env) {
16545
16779
  if (explicit) {
16546
- const resolved = path34.resolve(explicit);
16780
+ const resolved = path35.resolve(explicit);
16547
16781
  if (isPlatformRoot(resolved)) return resolved;
16548
16782
  throw new MeshCliError(
16549
16783
  `'${resolved}' is not a mesh-platform checkout (apps/hub/{api,ui} not found).`,
@@ -16551,16 +16785,16 @@ function resolvePlatformDir(explicit, cwd, env = process.env) {
16551
16785
  );
16552
16786
  }
16553
16787
  if (env.MESH_PLATFORM_DIR) {
16554
- const resolved = path34.resolve(env.MESH_PLATFORM_DIR);
16788
+ const resolved = path35.resolve(env.MESH_PLATFORM_DIR);
16555
16789
  if (isPlatformRoot(resolved)) return resolved;
16556
16790
  logWarn(
16557
16791
  `MESH_PLATFORM_DIR='${resolved}' is not a mesh-platform checkout (apps/hub/{api,ui} not found) \u2014 ignoring it.`
16558
16792
  );
16559
16793
  }
16560
- let dir = path34.resolve(cwd);
16794
+ let dir = path35.resolve(cwd);
16561
16795
  for (; ; ) {
16562
16796
  if (isPlatformRoot(dir)) return dir;
16563
- const parent = path34.dirname(dir);
16797
+ const parent = path35.dirname(dir);
16564
16798
  if (parent === dir) break;
16565
16799
  dir = parent;
16566
16800
  }
@@ -16599,7 +16833,7 @@ function isPortListening2(port) {
16599
16833
  });
16600
16834
  }
16601
16835
  function hubEnvDir() {
16602
- return path34.join(os9.tmpdir(), "mesh-dev-sessions", HUB_SESSION);
16836
+ return path35.join(os9.tmpdir(), "mesh-dev-sessions", HUB_SESSION);
16603
16837
  }
16604
16838
  function parsePort(raw, fallback, source) {
16605
16839
  if (raw === void 0) return fallback;
@@ -16622,8 +16856,8 @@ function redactEnv(env) {
16622
16856
  async function hubDevAction(opts) {
16623
16857
  if (opts.kill) {
16624
16858
  if (tmuxSessionExists(HUB_SESSION)) {
16625
- execFileSync23("tmux", ["kill-session", "-t", HUB_SESSION], { stdio: "ignore" });
16626
- fs27.rmSync(hubEnvDir(), { recursive: true, force: true });
16859
+ execFileSync24("tmux", ["kill-session", "-t", HUB_SESSION], { stdio: "ignore" });
16860
+ fs28.rmSync(hubEnvDir(), { recursive: true, force: true });
16627
16861
  logSuccess(`Killed Hub session '${HUB_SESSION}'.`);
16628
16862
  } else {
16629
16863
  logInfo(`No '${HUB_SESSION}' tmux session running.`);
@@ -16674,19 +16908,19 @@ async function hubDevAction(opts) {
16674
16908
  logInfo(`Temporal : ${assembled.temporalAddress}`);
16675
16909
  for (const note of assembled.notes) logInfo(note);
16676
16910
  for (const warning of assembled.warnings) logWarn(warning);
16677
- const apiDir = path34.join(platformDir, "apps", "hub", "api");
16678
- const uiDir = path34.join(platformDir, "apps", "hub", "ui");
16679
- execFileSync23("tmux", ["new-session", "-d", "-s", HUB_SESSION, "-n", "api", "-c", apiDir]);
16911
+ const apiDir = path35.join(platformDir, "apps", "hub", "api");
16912
+ const uiDir = path35.join(platformDir, "apps", "hub", "ui");
16913
+ execFileSync24("tmux", ["new-session", "-d", "-s", HUB_SESSION, "-n", "api", "-c", apiDir]);
16680
16914
  if (!assembled.apiEnv.DEV_USER_TOKEN_URL && assembled.apiEnv.DEV_USER_ID_TOKEN) {
16681
16915
  const platform = session.state.devOutput.platform;
16682
16916
  const credContext = `mesh.${platform.env}`;
16683
16917
  const tokenPort = await findFreePort4();
16684
16918
  const tokenUrl = `http://127.0.0.1:${tokenPort}`;
16685
- execFileSync23("tmux", ["new-window", "-t", HUB_SESSION, "-n", "token-server", "-c", platformDir]);
16686
- execFileSync23("tmux", ["set-option", "-t", `${HUB_SESSION}:token-server`, "remain-on-exit", "on"], {
16919
+ execFileSync24("tmux", ["new-window", "-t", HUB_SESSION, "-n", "token-server", "-c", platformDir]);
16920
+ execFileSync24("tmux", ["set-option", "-t", `${HUB_SESSION}:token-server`, "remain-on-exit", "on"], {
16687
16921
  stdio: "ignore"
16688
16922
  });
16689
- execFileSync23("tmux", [
16923
+ execFileSync24("tmux", [
16690
16924
  "send-keys",
16691
16925
  "-t",
16692
16926
  `${HUB_SESSION}:token-server`,
@@ -16701,15 +16935,15 @@ async function hubDevAction(opts) {
16701
16935
  logSuccess(`Dev-user token-server: ${tokenUrl} (context ${credContext})`);
16702
16936
  }
16703
16937
  const launch = (window, dir, env, cmd, createWindow) => {
16704
- const envFile = path34.join(hubEnvDir(), `${window}.env.sh`);
16938
+ const envFile = path35.join(hubEnvDir(), `${window}.env.sh`);
16705
16939
  writeEnvFile(envFile, env);
16706
16940
  if (createWindow) {
16707
- execFileSync23("tmux", ["new-window", "-t", HUB_SESSION, "-n", window, "-c", dir]);
16941
+ execFileSync24("tmux", ["new-window", "-t", HUB_SESSION, "-n", window, "-c", dir]);
16708
16942
  }
16709
- execFileSync23("tmux", ["set-option", "-t", `${HUB_SESSION}:${window}`, "remain-on-exit", "on"], {
16943
+ execFileSync24("tmux", ["set-option", "-t", `${HUB_SESSION}:${window}`, "remain-on-exit", "on"], {
16710
16944
  stdio: "ignore"
16711
16945
  });
16712
- execFileSync23("tmux", ["send-keys", "-t", `${HUB_SESSION}:${window}`, buildLaunchCommand(envFile, dir, cmd), "Enter"]);
16946
+ execFileSync24("tmux", ["send-keys", "-t", `${HUB_SESSION}:${window}`, buildLaunchCommand(envFile, dir, cmd), "Enter"]);
16713
16947
  };
16714
16948
  launch("api", apiDir, assembled.apiEnv, "pnpm dev", false);
16715
16949
  launch("ui", uiDir, assembled.uiEnv, `pnpm dev --port ${uiPort} --strictPort`, true);
@@ -16807,9 +17041,9 @@ __export(platform_setup_exports, {
16807
17041
  validateRegion: () => validateRegion,
16808
17042
  validateStateBucket: () => validateStateBucket
16809
17043
  });
16810
- import * as fs28 from "fs";
16811
- import * as path35 from "path";
16812
- import { execFileSync as execFileSync24 } from "child_process";
17044
+ import * as fs29 from "fs";
17045
+ import * as path36 from "path";
17046
+ import { execFileSync as execFileSync25 } from "child_process";
16813
17047
  function defaultStateBucket(tenant) {
16814
17048
  return `${tenant}-mesh-platform-pulumi-state`;
16815
17049
  }
@@ -16838,8 +17072,8 @@ function validateStateBucket(value) {
16838
17072
  return /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(bucket) && !bucket.includes("..") ? true : "3\u201363 characters: lowercase letters, digits, dots and dashes, starting and ending alphanumeric";
16839
17073
  }
16840
17074
  function resolveTargetDir(tenant, flags, cwd) {
16841
- const dir = path35.resolve(cwd, flags.dir ?? defaultPlatformDir(tenant));
16842
- if (fs28.existsSync(dir) && fs28.readdirSync(dir).length > 0) {
17075
+ const dir = path36.resolve(cwd, flags.dir ?? defaultPlatformDir(tenant));
17076
+ if (fs29.existsSync(dir) && fs29.readdirSync(dir).length > 0) {
16843
17077
  throw new MeshCliError(`Target directory is not empty: ${dir}`, {
16844
17078
  remediation: { command: `mesh init platform ${tenant} --dir <empty-dir>` }
16845
17079
  });
@@ -16893,7 +17127,7 @@ function stateBucketCreateCommand(setup) {
16893
17127
  return `aws s3api create-bucket --bucket ${setup.stateBucket} --region ${setup.region}${location} --profile ${setup.profile}`;
16894
17128
  }
16895
17129
  function awsJson(args, profile) {
16896
- return execFileSync24("aws", [...args, "--profile", profile], {
17130
+ return execFileSync25("aws", [...args, "--profile", profile], {
16897
17131
  encoding: "utf8",
16898
17132
  stdio: ["ignore", "pipe", "pipe"]
16899
17133
  });
@@ -16953,7 +17187,7 @@ function renderPlatformNextSteps(setup, opts = {}) {
16953
17187
  return steps;
16954
17188
  }
16955
17189
  async function scaffoldPlatformRepo(setup) {
16956
- if (fs28.existsSync(setup.dir) && fs28.readdirSync(setup.dir).length > 0) {
17190
+ if (fs29.existsSync(setup.dir) && fs29.readdirSync(setup.dir).length > 0) {
16957
17191
  throw new MeshCliError(`Target directory is not empty: ${setup.dir}`, {
16958
17192
  remediation: { command: `mesh init platform ${setup.tenant} --dir <empty-dir>` }
16959
17193
  });
@@ -16961,8 +17195,8 @@ async function scaffoldPlatformRepo(setup) {
16961
17195
  const { copyTemplate: copyTemplate2 } = await Promise.resolve().then(() => (init_create_app(), create_app_exports));
16962
17196
  const { findPackageRoot: findPackageRoot2 } = await Promise.resolve().then(() => (init_stack(), stack_exports));
16963
17197
  const { syncSkills: syncSkills2 } = await Promise.resolve().then(() => (init_skills(), skills_exports));
16964
- const templateDir = path35.join(findPackageRoot2(), "templates", "platform-repo");
16965
- fs28.mkdirSync(setup.dir, { recursive: true });
17198
+ const templateDir = path36.join(findPackageRoot2(), "templates", "platform-repo");
17199
+ fs29.mkdirSync(setup.dir, { recursive: true });
16966
17200
  copyTemplate2(templateDir, setup.dir, {
16967
17201
  tenant: setup.tenant,
16968
17202
  env: setup.env,
@@ -17009,9 +17243,9 @@ var init_platform_setup = __esm({
17009
17243
  });
17010
17244
 
17011
17245
  // libs/mesh-cli/src/commands/registry-publish.ts
17012
- import { execFileSync as execFileSync25, execSync } from "child_process";
17013
- import * as fs29 from "fs";
17014
- import * as path36 from "path";
17246
+ import { execFileSync as execFileSync26, execSync } from "child_process";
17247
+ import * as fs30 from "fs";
17248
+ import * as path37 from "path";
17015
17249
  function repoRoot() {
17016
17250
  return execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
17017
17251
  }
@@ -17021,9 +17255,9 @@ function computeSnapshotVersion(root) {
17021
17255
  return `0.0.0-dev.${stamp}.${sha}`;
17022
17256
  }
17023
17257
  function setPackageVersion(file, version) {
17024
- const content = fs29.readFileSync(file, "utf-8");
17258
+ const content = fs30.readFileSync(file, "utf-8");
17025
17259
  const next = content.replace(/"version"(\s*:\s*)"[^"]*"/, `"version"$1"${version}"`);
17026
- fs29.writeFileSync(file, next);
17260
+ fs30.writeFileSync(file, next);
17027
17261
  }
17028
17262
  function dirtyPackageJsons(root) {
17029
17263
  const out = execSync("git diff --name-only", { cwd: root, encoding: "utf-8" });
@@ -17056,8 +17290,8 @@ function registerRegistryPublish(registry) {
17056
17290
  logError("CodeArtifact login failed. Run: mesh registry login <context>");
17057
17291
  process.exit(1);
17058
17292
  }
17059
- const listPath = path36.join(root, "scripts/lib/publishable-packages.json");
17060
- const all = JSON.parse(fs29.readFileSync(listPath, "utf-8"));
17293
+ const listPath = path37.join(root, "scripts/lib/publishable-packages.json");
17294
+ const all = JSON.parse(fs30.readFileSync(listPath, "utf-8"));
17061
17295
  const patterns = (opts.only ?? "").split(",").map((s) => s.trim()).filter(Boolean);
17062
17296
  const selected = patterns.length ? all.filter((p) => patterns.some((pat) => p.dir.includes(pat) || p.name.includes(pat))) : all;
17063
17297
  if (selected.length === 0) {
@@ -17069,16 +17303,16 @@ function registerRegistryPublish(registry) {
17069
17303
  const preDirty = dirtyPackageJsons(root);
17070
17304
  const backups = [];
17071
17305
  const stamp = (dir) => {
17072
- const file = path36.join(root, dir, "package.json");
17073
- if (!fs29.existsSync(file)) return;
17074
- backups.push({ file, content: fs29.readFileSync(file, "utf-8") });
17306
+ const file = path37.join(root, dir, "package.json");
17307
+ if (!fs30.existsSync(file)) return;
17308
+ backups.push({ file, content: fs30.readFileSync(file, "utf-8") });
17075
17309
  setPackageVersion(file, version);
17076
17310
  };
17077
17311
  try {
17078
17312
  for (const p of selected) {
17079
17313
  stamp(p.dir);
17080
17314
  for (const sub of p.subPackages ?? []) {
17081
- stamp(path36.join(p.dir, typeof sub === "string" ? sub : sub.dir));
17315
+ stamp(path37.join(p.dir, typeof sub === "string" ? sub : sub.dir));
17082
17316
  }
17083
17317
  }
17084
17318
  const args = [
@@ -17093,14 +17327,14 @@ function registerRegistryPublish(registry) {
17093
17327
  ...opts.dryRun ? ["--dry-run"] : []
17094
17328
  ];
17095
17329
  logInfo(`Publishing ${selected.length} package(s)...`);
17096
- execFileSync25("bash", args, { cwd: root, stdio: "inherit", env: env ?? process.env });
17330
+ execFileSync26("bash", args, { cwd: root, stdio: "inherit", env: env ?? process.env });
17097
17331
  } finally {
17098
- for (const b of backups) fs29.writeFileSync(b.file, b.content);
17332
+ for (const b of backups) fs30.writeFileSync(b.file, b.content);
17099
17333
  logInfo("Restored source package.json versions.");
17100
17334
  const collateral = [...dirtyPackageJsons(root)].filter((f) => !preDirty.has(f));
17101
17335
  if (collateral.length) {
17102
17336
  try {
17103
- execFileSync25("git", ["checkout", "--", ...collateral], { cwd: root, stdio: "inherit" });
17337
+ execFileSync26("git", ["checkout", "--", ...collateral], { cwd: root, stdio: "inherit" });
17104
17338
  logInfo(`Reverted ${collateral.length} package.json file(s) re-vendored by build:publish.`);
17105
17339
  } catch {
17106
17340
  logError(
@@ -17152,12 +17386,12 @@ __export(registry_exports, {
17152
17386
  shouldRemintAfter: () => shouldRemintAfter,
17153
17387
  shouldRepairUserNpmrc: () => shouldRepairUserNpmrc
17154
17388
  });
17155
- import { execFileSync as execFileSync26 } from "child_process";
17156
- import * as fs30 from "fs";
17157
- import * as path37 from "path";
17389
+ import { execFileSync as execFileSync27 } from "child_process";
17390
+ import * as fs31 from "fs";
17391
+ import * as path38 from "path";
17158
17392
  function getEndpoint(env) {
17159
17393
  try {
17160
- const result = execFileSync26("aws", [
17394
+ const result = execFileSync27("aws", [
17161
17395
  "codeartifact",
17162
17396
  "get-repository-endpoint",
17163
17397
  "--domain",
@@ -17184,7 +17418,7 @@ function getEndpoint(env) {
17184
17418
  }
17185
17419
  function codeartifactLogin(env) {
17186
17420
  try {
17187
- execFileSync26("aws", [
17421
+ execFileSync27("aws", [
17188
17422
  "codeartifact",
17189
17423
  "login",
17190
17424
  "--tool",
@@ -17239,7 +17473,7 @@ function resolvePublisherRoleArn({
17239
17473
  }
17240
17474
  function assumeRole2(roleArn) {
17241
17475
  try {
17242
- const result = execFileSync26("aws", [
17476
+ const result = execFileSync27("aws", [
17243
17477
  "sts",
17244
17478
  "assume-role",
17245
17479
  "--role-arn",
@@ -17261,7 +17495,7 @@ function assumeRole2(roleArn) {
17261
17495
  }
17262
17496
  function assumeRoleWithWebIdentity2(roleArn, idToken, sessionName) {
17263
17497
  try {
17264
- const result = execFileSync26("aws", [
17498
+ const result = execFileSync27("aws", [
17265
17499
  "sts",
17266
17500
  "assume-role-with-web-identity",
17267
17501
  "--role-arn",
@@ -17325,50 +17559,50 @@ function resolveCredentials(context, roleArn) {
17325
17559
  function findProjectRoot2() {
17326
17560
  let dir = process.cwd();
17327
17561
  while (true) {
17328
- if (fs30.existsSync(path37.join(dir, "pnpm-workspace.yaml")) || fs30.existsSync(path37.join(dir, "pnpm-lock.yaml")) || fs30.existsSync(path37.join(dir, "Pulumi.yaml")) || fs30.existsSync(path37.join(dir, ".npmrc"))) {
17562
+ if (fs31.existsSync(path38.join(dir, "pnpm-workspace.yaml")) || fs31.existsSync(path38.join(dir, "pnpm-lock.yaml")) || fs31.existsSync(path38.join(dir, "Pulumi.yaml")) || fs31.existsSync(path38.join(dir, ".npmrc"))) {
17329
17563
  return dir;
17330
17564
  }
17331
- const parent = path37.dirname(dir);
17565
+ const parent = path38.dirname(dir);
17332
17566
  if (parent === dir) return null;
17333
17567
  dir = parent;
17334
17568
  }
17335
17569
  }
17336
17570
  function ensureProjectNpmrc(endpoint) {
17337
17571
  const projectRoot = findProjectRoot2() ?? process.cwd();
17338
- const npmrcPath2 = path37.join(projectRoot, ".npmrc");
17572
+ const npmrcPath2 = path38.join(projectRoot, ".npmrc");
17339
17573
  const scopeLine = `${CA_NAMESPACE}:registry=${endpoint}`;
17340
- if (!fs30.existsSync(npmrcPath2)) {
17341
- fs30.writeFileSync(npmrcPath2, scopeLine + "\n", "utf-8");
17574
+ if (!fs31.existsSync(npmrcPath2)) {
17575
+ fs31.writeFileSync(npmrcPath2, scopeLine + "\n", "utf-8");
17342
17576
  return { created: true, updated: false, path: npmrcPath2 };
17343
17577
  }
17344
- const content = fs30.readFileSync(npmrcPath2, "utf-8");
17578
+ const content = fs31.readFileSync(npmrcPath2, "utf-8");
17345
17579
  const scopeRegex = new RegExp(`^${CA_NAMESPACE.replace("/", "\\/")}:registry=.+$`, "m");
17346
17580
  if (scopeRegex.test(content)) {
17347
17581
  if (content.includes(scopeLine)) {
17348
17582
  return { created: false, updated: false, path: npmrcPath2 };
17349
17583
  }
17350
17584
  const updated = content.replace(scopeRegex, scopeLine);
17351
- fs30.writeFileSync(npmrcPath2, updated, "utf-8");
17585
+ fs31.writeFileSync(npmrcPath2, updated, "utf-8");
17352
17586
  return { created: false, updated: true, path: npmrcPath2 };
17353
17587
  }
17354
17588
  const separator = content.endsWith("\n") ? "" : "\n";
17355
- fs30.writeFileSync(npmrcPath2, content + separator + scopeLine + "\n", "utf-8");
17589
+ fs31.writeFileSync(npmrcPath2, content + separator + scopeLine + "\n", "utf-8");
17356
17590
  return { created: false, updated: true, path: npmrcPath2 };
17357
17591
  }
17358
17592
  function applyGrantToUserNpmrc(grant, npmrcPath2 = homeNpmrcPath()) {
17359
17593
  let existing = "";
17360
17594
  try {
17361
- existing = fs30.readFileSync(npmrcPath2, "utf-8");
17595
+ existing = fs31.readFileSync(npmrcPath2, "utf-8");
17362
17596
  } catch {
17363
17597
  }
17364
17598
  const content = upsertNpmrcLines(existing, [
17365
17599
  { key: `${grant.scope}:registry`, value: grant.endpoint },
17366
17600
  { key: `${npmrcAuthKeyForEndpoint(grant.endpoint)}:_authToken`, value: grant.authorizationToken }
17367
17601
  ]);
17368
- fs30.mkdirSync(path37.dirname(npmrcPath2), { recursive: true });
17369
- fs30.writeFileSync(npmrcPath2, content, { mode: 384 });
17602
+ fs31.mkdirSync(path38.dirname(npmrcPath2), { recursive: true });
17603
+ fs31.writeFileSync(npmrcPath2, content, { mode: 384 });
17370
17604
  try {
17371
- fs30.chmodSync(npmrcPath2, 384);
17605
+ fs31.chmodSync(npmrcPath2, 384);
17372
17606
  } catch {
17373
17607
  }
17374
17608
  return { path: npmrcPath2 };
@@ -17491,7 +17725,7 @@ function shouldRepairUserNpmrc(opts) {
17491
17725
  function repairUnscopedRegistry(npmrcPath2 = homeNpmrcPath()) {
17492
17726
  let original;
17493
17727
  try {
17494
- original = fs30.readFileSync(npmrcPath2, "utf-8");
17728
+ original = fs31.readFileSync(npmrcPath2, "utf-8");
17495
17729
  } catch {
17496
17730
  return { removed: null };
17497
17731
  }
@@ -17499,8 +17733,8 @@ function repairUnscopedRegistry(npmrcPath2 = homeNpmrcPath()) {
17499
17733
  if (!removed) return { removed: null };
17500
17734
  const backupPath = `${npmrcPath2}.bak-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
17501
17735
  try {
17502
- fs30.writeFileSync(backupPath, original, "utf-8");
17503
- fs30.writeFileSync(npmrcPath2, content, "utf-8");
17736
+ fs31.writeFileSync(backupPath, original, "utf-8");
17737
+ fs31.writeFileSync(npmrcPath2, content, "utf-8");
17504
17738
  } catch (err) {
17505
17739
  return { removed: null, error: err instanceof Error ? err.message : String(err) };
17506
17740
  }
@@ -17512,9 +17746,9 @@ function renderRegistrySessionLine(session, now = Date.now()) {
17512
17746
  }
17513
17747
  async function checkExistingToken() {
17514
17748
  const npmrcPath2 = homeNpmrcPath();
17515
- if (!fs30.existsSync(npmrcPath2)) return { valid: false, state: "missing", reason: "no ~/.npmrc" };
17749
+ if (!fs31.existsSync(npmrcPath2)) return { valid: false, state: "missing", reason: "no ~/.npmrc" };
17516
17750
  const hijackLine = findUnscopedCodeArtifactRegistry(
17517
- fs30.readFileSync(npmrcPath2, "utf-8")
17751
+ fs31.readFileSync(npmrcPath2, "utf-8")
17518
17752
  ) ?? void 0;
17519
17753
  const probe = await probeRegistryToken({ npmrcPath: npmrcPath2 });
17520
17754
  if (probe.state === "missing") {
@@ -17567,9 +17801,9 @@ async function runRegistryStatus(opts) {
17567
17801
  logInfo(renderRegistrySessionLine(opts?.session ?? readRegistrySession()));
17568
17802
  const projectRoot = findProjectRoot2();
17569
17803
  if (projectRoot) {
17570
- const npmrcPath2 = path37.join(projectRoot, ".npmrc");
17571
- if (fs30.existsSync(npmrcPath2)) {
17572
- const content = fs30.readFileSync(npmrcPath2, "utf-8");
17804
+ const npmrcPath2 = path38.join(projectRoot, ".npmrc");
17805
+ if (fs31.existsSync(npmrcPath2)) {
17806
+ const content = fs31.readFileSync(npmrcPath2, "utf-8");
17573
17807
  if (content.includes(`${CA_NAMESPACE}:registry=`)) {
17574
17808
  logSuccess(`Project .npmrc configured (${npmrcPath2})`);
17575
17809
  } else {
@@ -17603,7 +17837,7 @@ region = us-east-2`,
17603
17837
  { remediation: { command: `aws configure sso --profile ${profile}` } }
17604
17838
  );
17605
17839
  }
17606
- const probe = () => execFileSync26("aws", ["sts", "get-caller-identity", "--profile", profile], {
17840
+ const probe = () => execFileSync27("aws", ["sts", "get-caller-identity", "--profile", profile], {
17607
17841
  stdio: ["ignore", "pipe", "pipe"],
17608
17842
  timeout: 2e4
17609
17843
  });
@@ -17614,7 +17848,7 @@ region = us-east-2`,
17614
17848
  } catch {
17615
17849
  logInfo(`AWS SSO session for profile '${profile}' is stale \u2014 opening browser login\u2026`);
17616
17850
  }
17617
- execFileSync26("aws", ["sso", "login", "--profile", profile], { stdio: "inherit" });
17851
+ execFileSync27("aws", ["sso", "login", "--profile", profile], { stdio: "inherit" });
17618
17852
  try {
17619
17853
  probe();
17620
17854
  } catch (err) {
@@ -17850,9 +18084,9 @@ __export(wizard_exports, {
17850
18084
  wizardExitCode: () => wizardExitCode,
17851
18085
  wizardNextCommands: () => wizardNextCommands
17852
18086
  });
17853
- import * as fs31 from "fs";
17854
- import * as path38 from "path";
17855
- import { execFileSync as execFileSync27 } from "child_process";
18087
+ import * as fs32 from "fs";
18088
+ import * as path39 from "path";
18089
+ import { execFileSync as execFileSync28 } from "child_process";
17856
18090
  import chalk4 from "chalk";
17857
18091
  function isNewPlatform(mode) {
17858
18092
  return typeof mode === "object" && "newPlatform" in mode;
@@ -17929,18 +18163,18 @@ function classifyRepo(cwd) {
17929
18163
  if (isInsidePlatformMonorepo(cwd)) return { kind: "platform-monorepo", root: resolveTargetRoot(cwd) };
17930
18164
  if (shouldBootstrapAppsRepo(cwd)) return { kind: "empty-apps-repo", root: cwd };
17931
18165
  const root = resolveTargetRoot(cwd);
17932
- const inRepo = fs31.existsSync(path38.join(root, ".git"));
18166
+ const inRepo = fs32.existsSync(path39.join(root, ".git"));
17933
18167
  if (!inRepo) {
17934
- const hasContent = fs31.readdirSync(cwd).some((entry) => !entry.startsWith("."));
18168
+ const hasContent = fs32.readdirSync(cwd).some((entry) => !entry.startsWith("."));
17935
18169
  return { kind: hasContent ? "no-repo" : "empty-dir", root: cwd };
17936
18170
  }
17937
- const hasWorkspace = fs31.existsSync(path38.join(root, "pnpm-workspace.yaml")) || fs31.existsSync(path38.join(root, "pnpm-lock.yaml"));
17938
- const hasApps = fs31.existsSync(path38.join(root, "apps")) || fs31.existsSync(path38.join(root, "tenants"));
18171
+ const hasWorkspace = fs32.existsSync(path39.join(root, "pnpm-workspace.yaml")) || fs32.existsSync(path39.join(root, "pnpm-lock.yaml"));
18172
+ const hasApps = fs32.existsSync(path39.join(root, "apps")) || fs32.existsSync(path39.join(root, "tenants"));
17939
18173
  if (hasWorkspace || hasApps) return { kind: "apps-repo", root };
17940
18174
  return { kind: "other-repo", root };
17941
18175
  }
17942
18176
  function gitInit(dir) {
17943
- execFileSync27("git", ["init", "-q"], { cwd: dir, stdio: ["ignore", "ignore", "pipe"] });
18177
+ execFileSync28("git", ["init", "-q"], { cwd: dir, stdio: ["ignore", "ignore", "pipe"] });
17944
18178
  }
17945
18179
  async function runWizardSteps(ctx, steps) {
17946
18180
  const results = [];
@@ -18161,7 +18395,7 @@ var init_wizard = __esm({
18161
18395
  return { name, status: "fail", detail: `platform repo not scaffolded: ${err.message.split("\n")[0]}`, fix: `mesh init platform ${ctx.tenant} --dir <empty-dir>` };
18162
18396
  }
18163
18397
  const bucket = await ensureStateBucket(setup, ctx.seams?.stateBucket);
18164
- const next = renderPlatformNextSteps(setup, { bucket, relativeDir: path38.relative(ctx.cwd, setup.dir) || "." });
18398
+ const next = renderPlatformNextSteps(setup, { bucket, relativeDir: path39.relative(ctx.cwd, setup.dir) || "." });
18165
18399
  return {
18166
18400
  name,
18167
18401
  status: setup.createStateBucket && !bucket.present ? "warn" : "pass",
@@ -18259,8 +18493,8 @@ var init_wizard = __esm({
18259
18493
  }
18260
18494
  case "apps-repo": {
18261
18495
  const missing = [];
18262
- if (!fs31.existsSync(path38.join(root, "package.json"))) missing.push("package.json");
18263
- if (!fs31.existsSync(path38.join(root, "pnpm-workspace.yaml")) && !fs31.existsSync(path38.join(root, "pnpm-lock.yaml"))) {
18496
+ if (!fs32.existsSync(path39.join(root, "package.json"))) missing.push("package.json");
18497
+ if (!fs32.existsSync(path39.join(root, "pnpm-workspace.yaml")) && !fs32.existsSync(path39.join(root, "pnpm-lock.yaml"))) {
18264
18498
  missing.push("pnpm-workspace.yaml");
18265
18499
  }
18266
18500
  if (missing.length) {
@@ -18297,8 +18531,8 @@ var init_wizard = __esm({
18297
18531
 
18298
18532
  // libs/mesh-cli/src/commands/init.ts
18299
18533
  import chalk5 from "chalk";
18300
- import * as fs32 from "fs";
18301
- import * as path39 from "path";
18534
+ import * as fs33 from "fs";
18535
+ import * as path40 from "path";
18302
18536
  async function setupPrompts() {
18303
18537
  const [{ default: input2 }, { default: confirm }] = await Promise.all([
18304
18538
  import("@inquirer/input"),
@@ -18324,7 +18558,7 @@ async function probeHubTenants(hubUrl, accessToken) {
18324
18558
  }
18325
18559
  function readHomeNpmrc() {
18326
18560
  try {
18327
- return fs32.readFileSync(homeNpmrcPath(), "utf-8");
18561
+ return fs33.readFileSync(homeNpmrcPath(), "utf-8");
18328
18562
  } catch {
18329
18563
  return "";
18330
18564
  }
@@ -18448,9 +18682,9 @@ async function runChecks2(args) {
18448
18682
  if (local) {
18449
18683
  checks.push({ name: "Deployer role", status: "pass", detail: "local context \u2014 no deployer role required" });
18450
18684
  } else {
18451
- const stackFiles = fs32.existsSync(root) ? fs32.readdirSync(root).filter((f) => /^Pulumi\..*\.yaml$/.test(f)) : [];
18685
+ const stackFiles = fs33.existsSync(root) ? fs33.readdirSync(root).filter((f) => /^Pulumi\..*\.yaml$/.test(f)) : [];
18452
18686
  const hasRole = stackFiles.some(
18453
- (f) => /mesh:deployerRole/.test(fs32.readFileSync(path39.join(root, f), "utf-8"))
18687
+ (f) => /mesh:deployerRole/.test(fs33.readFileSync(path40.join(root, f), "utf-8"))
18454
18688
  );
18455
18689
  checks.push(
18456
18690
  hasRole ? { name: "Deployer role", status: "pass", detail: "mesh:deployerRole configured in stack config" } : {
@@ -18462,8 +18696,8 @@ async function runChecks2(args) {
18462
18696
  );
18463
18697
  }
18464
18698
  const shapeProblems = [];
18465
- if (!fs32.existsSync(path39.join(root, "package.json"))) shapeProblems.push("package.json");
18466
- const hasWorkspace = fs32.existsSync(path39.join(root, "pnpm-workspace.yaml")) || fs32.existsSync(path39.join(root, "pnpm-lock.yaml"));
18699
+ if (!fs33.existsSync(path40.join(root, "package.json"))) shapeProblems.push("package.json");
18700
+ const hasWorkspace = fs33.existsSync(path40.join(root, "pnpm-workspace.yaml")) || fs33.existsSync(path40.join(root, "pnpm-lock.yaml"));
18467
18701
  if (!hasWorkspace) shapeProblems.push("pnpm-workspace.yaml");
18468
18702
  checks.push(
18469
18703
  shapeProblems.length === 0 ? { name: "Repo shape", status: "pass", detail: "pnpm workspace layout present" } : {
@@ -18519,7 +18753,7 @@ function registerInitCommands(program2) {
18519
18753
  if (bucket.detail !== "not requested") logInfo(`Pulumi state bucket: ${bucket.detail}`);
18520
18754
  console.log("");
18521
18755
  console.log("Next steps:");
18522
- for (const line of renderPlatformNextSteps2(setup, { bucket, relativeDir: path39.relative(process.cwd(), setup.dir) || "." })) {
18756
+ for (const line of renderPlatformNextSteps2(setup, { bucket, relativeDir: path40.relative(process.cwd(), setup.dir) || "." })) {
18523
18757
  console.log(line ? ` ${line}` : "");
18524
18758
  }
18525
18759
  console.log("");
@@ -18587,10 +18821,10 @@ var init_init = __esm({
18587
18821
  });
18588
18822
 
18589
18823
  // libs/mesh-cli/src/commands/install-shim.ts
18590
- import { execFileSync as execFileSync28 } from "child_process";
18591
- import * as fs33 from "fs";
18824
+ import { execFileSync as execFileSync29 } from "child_process";
18825
+ import * as fs34 from "fs";
18592
18826
  import * as os10 from "os";
18593
- import * as path40 from "path";
18827
+ import * as path41 from "path";
18594
18828
  function shimScript() {
18595
18829
  return `#!/bin/sh
18596
18830
  # mesh \u2014 canonical launcher shim (installed by \`mesh install-shim\`).
@@ -18663,25 +18897,25 @@ exit 1
18663
18897
  `;
18664
18898
  }
18665
18899
  function defaultShimDir() {
18666
- return path40.join(os10.homedir(), ".local", "bin");
18900
+ return path41.join(os10.homedir(), ".local", "bin");
18667
18901
  }
18668
18902
  function dirOnPath(dir, pathEnv) {
18669
18903
  if (!pathEnv) return false;
18670
- return pathEnv.split(path40.delimiter).some((p) => p === dir);
18904
+ return pathEnv.split(path41.delimiter).some((p) => p === dir);
18671
18905
  }
18672
18906
  function registerInstallShimCommand(program2) {
18673
18907
  program2.command("install-shim").description("Install a build-free `mesh` shim on your PATH so bare `mesh` runs the local source").option("--dir <dir>", "Directory to install into (must be on your PATH)", defaultShimDir()).option("-f, --force", "Overwrite an existing file at the target path", false).action((opts) => {
18674
- const dir = path40.resolve(opts.dir);
18675
- const target = path40.join(dir, "mesh");
18676
- if (fs33.existsSync(target) && !opts.force) {
18908
+ const dir = path41.resolve(opts.dir);
18909
+ const target = path41.join(dir, "mesh");
18910
+ if (fs34.existsSync(target) && !opts.force) {
18677
18911
  logWarn(`A file already exists at ${target}.`);
18678
18912
  logInfo("Re-run with --force to overwrite it, or pass --dir <other-path-on-PATH>.");
18679
18913
  return;
18680
18914
  }
18681
18915
  try {
18682
- fs33.mkdirSync(dir, { recursive: true });
18683
- fs33.writeFileSync(target, shimScript(), { mode: 493 });
18684
- fs33.chmodSync(target, 493);
18916
+ fs34.mkdirSync(dir, { recursive: true });
18917
+ fs34.writeFileSync(target, shimScript(), { mode: 493 });
18918
+ fs34.chmodSync(target, 493);
18685
18919
  } catch (err) {
18686
18920
  logError(`Could not write the shim to ${target}: ${err.message}`);
18687
18921
  process.exitCode = 1;
@@ -18694,13 +18928,13 @@ function registerInstallShimCommand(program2) {
18694
18928
  } else {
18695
18929
  logInfo("Bare `mesh <cmd>` now runs the local source of whatever workspace you're in.");
18696
18930
  }
18697
- const diagPath = path40.join(os10.tmpdir(), "mesh-shim-selftest.log");
18931
+ const diagPath = path41.join(os10.tmpdir(), "mesh-shim-selftest.log");
18698
18932
  let stdout = "";
18699
18933
  let stderr = "";
18700
18934
  let status = 0;
18701
18935
  let ok = true;
18702
18936
  try {
18703
- stdout = execFileSync28(target, ["--help"], {
18937
+ stdout = execFileSync29(target, ["--help"], {
18704
18938
  cwd: process.cwd(),
18705
18939
  encoding: "utf8",
18706
18940
  stdio: ["ignore", "pipe", "pipe"]
@@ -18727,7 +18961,7 @@ function registerInstallShimCommand(program2) {
18727
18961
  ""
18728
18962
  ].join("\n");
18729
18963
  try {
18730
- fs33.writeFileSync(diagPath, diag);
18964
+ fs34.writeFileSync(diagPath, diag);
18731
18965
  } catch {
18732
18966
  }
18733
18967
  if (ok && /Commands:|Usage:/.test(stdout)) {
@@ -18747,17 +18981,17 @@ var init_install_shim = __esm({
18747
18981
  });
18748
18982
 
18749
18983
  // libs/mesh-cli/src/commands/local/hub-local.ts
18750
- import { execFile as execFile3, execFileSync as execFileSync29 } from "child_process";
18751
- import * as fs34 from "fs";
18984
+ import { execFile as execFile3, execFileSync as execFileSync30 } from "child_process";
18985
+ import * as fs35 from "fs";
18752
18986
  import * as os11 from "os";
18753
- import * as path41 from "path";
18987
+ import * as path42 from "path";
18754
18988
  import { promisify as promisify2 } from "util";
18755
18989
  function cacheDir() {
18756
18990
  return meshCacheDir("hub-local");
18757
18991
  }
18758
18992
  function npmrcPath() {
18759
- const p = path41.join(os11.homedir(), ".npmrc");
18760
- if (!fs34.existsSync(p) || !fs34.readFileSync(p, "utf-8").includes("codeartifact")) {
18993
+ const p = path42.join(os11.homedir(), ".npmrc");
18994
+ if (!fs35.existsSync(p) || !fs35.readFileSync(p, "utf-8").includes("codeartifact")) {
18761
18995
  throw new MeshCliError(
18762
18996
  "The local Hub builds from the published @mesh-tech/hub tarball, which needs registry auth.",
18763
18997
  { remediation: { command: REGISTRY_LOGIN_FIX } }
@@ -18767,7 +19001,7 @@ function npmrcPath() {
18767
19001
  }
18768
19002
  function imageExists(tag) {
18769
19003
  try {
18770
- execFileSync29("docker", ["image", "inspect", tag], { stdio: ["ignore", "pipe", "pipe"] });
19004
+ execFileSync30("docker", ["image", "inspect", tag], { stdio: ["ignore", "pipe", "pipe"] });
18771
19005
  return true;
18772
19006
  } catch {
18773
19007
  return false;
@@ -18776,22 +19010,22 @@ function imageExists(tag) {
18776
19010
  function ensureHubAuthImage() {
18777
19011
  if (imageExists(HUB_AUTH_IMAGE)) return;
18778
19012
  logInfo(`Building ${HUB_AUTH_IMAGE} (Hub auth proxy)\u2026`);
18779
- const hubStackDir = path41.join(findPackageRoot(), "stack", "hub");
18780
- execFileSync29(
19013
+ const hubStackDir = path42.join(findPackageRoot(), "stack", "hub");
19014
+ execFileSync30(
18781
19015
  "docker",
18782
- ["build", "-f", path41.join(hubStackDir, "Dockerfile.auth"), "-t", HUB_AUTH_IMAGE, hubStackDir],
19016
+ ["build", "-f", path42.join(hubStackDir, "Dockerfile.auth"), "-t", HUB_AUTH_IMAGE, hubStackDir],
18783
19017
  { stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
18784
19018
  );
18785
19019
  logSuccess(`Built ${HUB_AUTH_IMAGE}`);
18786
19020
  }
18787
19021
  function hasRegistryAuth() {
18788
- const p = path41.join(os11.homedir(), ".npmrc");
18789
- return fs34.existsSync(p) && fs34.readFileSync(p, "utf-8").includes("codeartifact");
19022
+ const p = path42.join(os11.homedir(), ".npmrc");
19023
+ return fs35.existsSync(p) && fs35.readFileSync(p, "utf-8").includes("codeartifact");
18790
19024
  }
18791
19025
  function localHubVersion() {
18792
19026
  const versions = HUB_IMAGES.map((name) => {
18793
19027
  try {
18794
- const out = execFileSync29("docker", ["images", name, "--format", "{{.Tag}}"], {
19028
+ const out = execFileSync30("docker", ["images", name, "--format", "{{.Tag}}"], {
18795
19029
  encoding: "utf-8",
18796
19030
  stdio: ["ignore", "pipe", "pipe"]
18797
19031
  });
@@ -18817,10 +19051,10 @@ async function fetchTarball() {
18817
19051
  { encoding: "utf-8" }
18818
19052
  );
18819
19053
  const info = JSON.parse(stdout)[0];
18820
- return { tarball: path41.join(dir, info.filename), version: info.version };
19054
+ return { tarball: path42.join(dir, info.filename), version: info.version };
18821
19055
  } catch (err) {
18822
19056
  const authFailure = isNpmAuthError(err);
18823
- const cached = fs34.readdirSync(dir).filter((f) => f.startsWith("mesh-tech-hub-") && f.endsWith(".tgz")).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).at(-1);
19057
+ const cached = fs35.readdirSync(dir).filter((f) => f.startsWith("mesh-tech-hub-") && f.endsWith(".tgz")).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).at(-1);
18824
19058
  if (!cached) {
18825
19059
  if (authFailure) {
18826
19060
  throw new MeshCliError(
@@ -18838,7 +19072,7 @@ async function fetchTarball() {
18838
19072
  } else {
18839
19073
  logInfo(`Registry unavailable \u2014 using the cached hub tarball v${version}`);
18840
19074
  }
18841
- return { tarball: path41.join(dir, cached), version };
19075
+ return { tarball: path42.join(dir, cached), version };
18842
19076
  } finally {
18843
19077
  heartbeat.stop();
18844
19078
  }
@@ -18867,13 +19101,13 @@ async function ensureHubImages() {
18867
19101
  logInfo(`Local Hub images ready (v${version})`);
18868
19102
  return version;
18869
19103
  }
18870
- const context = path41.join(cacheDir(), `context-${version}`);
18871
- fs34.rmSync(context, { recursive: true, force: true });
18872
- fs34.mkdirSync(context, { recursive: true });
18873
- execFileSync29("tar", ["-xzf", tarball, "-C", context, "--strip-components", "1"], {
19104
+ const context = path42.join(cacheDir(), `context-${version}`);
19105
+ fs35.rmSync(context, { recursive: true, force: true });
19106
+ fs35.mkdirSync(context, { recursive: true });
19107
+ execFileSync30("tar", ["-xzf", tarball, "-C", context, "--strip-components", "1"], {
18874
19108
  stdio: ["ignore", "pipe", "pipe"]
18875
19109
  });
18876
- const hubStackDir = path41.join(findPackageRoot(), "stack", "hub");
19110
+ const hubStackDir = path42.join(findPackageRoot(), "stack", "hub");
18877
19111
  for (const [name, dockerfile] of [
18878
19112
  ["mesh-local-hub-api", "Dockerfile.api"],
18879
19113
  ["mesh-local-hub-ui", "Dockerfile.ui"]
@@ -18881,12 +19115,12 @@ async function ensureHubImages() {
18881
19115
  const tag = `${name}:${version}`;
18882
19116
  if (imageExists(tag)) continue;
18883
19117
  logInfo(`Building ${tag} from the published tarball\u2026`);
18884
- execFileSync29(
19118
+ execFileSync30(
18885
19119
  "docker",
18886
19120
  [
18887
19121
  "build",
18888
19122
  "-f",
18889
- path41.join(hubStackDir, dockerfile),
19123
+ path42.join(hubStackDir, dockerfile),
18890
19124
  "-t",
18891
19125
  tag,
18892
19126
  "--secret",
@@ -18904,29 +19138,29 @@ function tarballNameForImageVersion(version) {
18904
19138
  return `mesh-tech-hub-${version.replace(/-r\d+$/, "")}.tgz`;
18905
19139
  }
18906
19140
  function readHubCompiledAuthz(version) {
18907
- const context = path41.join(cacheDir(), `context-${version}`);
18908
- const file = path41.join(context, HUB_COMPILED_AUTHZ_REL);
18909
- if (!fs34.existsSync(file)) {
19141
+ const context = path42.join(cacheDir(), `context-${version}`);
19142
+ const file = path42.join(context, HUB_COMPILED_AUTHZ_REL);
19143
+ if (!fs35.existsSync(file)) {
18910
19144
  const tarball = tarballNameForImageVersion(version);
18911
- if (!tarball || !fs34.existsSync(path41.join(cacheDir(), tarball))) return null;
18912
- fs34.mkdirSync(context, { recursive: true });
19145
+ if (!tarball || !fs35.existsSync(path42.join(cacheDir(), tarball))) return null;
19146
+ fs35.mkdirSync(context, { recursive: true });
18913
19147
  try {
18914
- execFileSync29(
19148
+ execFileSync30(
18915
19149
  "tar",
18916
- ["-xzf", path41.join(cacheDir(), tarball), "-C", context, "--strip-components", "1", `package/${HUB_COMPILED_AUTHZ_REL}`],
19150
+ ["-xzf", path42.join(cacheDir(), tarball), "-C", context, "--strip-components", "1", `package/${HUB_COMPILED_AUTHZ_REL}`],
18917
19151
  { stdio: ["ignore", "pipe", "pipe"] }
18918
19152
  );
18919
19153
  } catch {
18920
19154
  return null;
18921
19155
  }
18922
- if (!fs34.existsSync(file)) return null;
19156
+ if (!fs35.existsSync(file)) return null;
18923
19157
  }
18924
- const parsed = JSON.parse(fs34.readFileSync(file, "utf-8"));
19158
+ const parsed = JSON.parse(fs35.readFileSync(file, "utf-8"));
18925
19159
  if (typeof parsed.zed !== "string" || !parsed.metadata || typeof parsed.metadata !== "object") return null;
18926
19160
  return { zed: parsed.zed, metadata: parsed.metadata };
18927
19161
  }
18928
19162
  function readWorkspaceCatalog(repoRoot2) {
18929
- const text = fs34.readFileSync(path41.join(repoRoot2, "pnpm-workspace.yaml"), "utf-8");
19163
+ const text = fs35.readFileSync(path42.join(repoRoot2, "pnpm-workspace.yaml"), "utf-8");
18930
19164
  const marker = "\ncatalog:\n";
18931
19165
  const at = text.indexOf(marker);
18932
19166
  if (at === -1) return {};
@@ -18941,11 +19175,11 @@ function readWorkspaceCatalog(repoRoot2) {
18941
19175
  function normalizeHubManifests(contextDir, catalog) {
18942
19176
  const DEP_FIELDS = ["dependencies", "optionalDependencies", "peerDependencies"];
18943
19177
  const touched = [];
18944
- for (const entry of fs34.readdirSync(contextDir, { withFileTypes: true })) {
19178
+ for (const entry of fs35.readdirSync(contextDir, { withFileTypes: true })) {
18945
19179
  if (!entry.isDirectory()) continue;
18946
- const manifest = path41.join(contextDir, entry.name, "package.json");
18947
- if (!fs34.existsSync(manifest)) continue;
18948
- const pkg = JSON.parse(fs34.readFileSync(manifest, "utf-8"));
19180
+ const manifest = path42.join(contextDir, entry.name, "package.json");
19181
+ if (!fs35.existsSync(manifest)) continue;
19182
+ const pkg = JSON.parse(fs35.readFileSync(manifest, "utf-8"));
18949
19183
  let changed = false;
18950
19184
  if (pkg.devDependencies) {
18951
19185
  delete pkg.devDependencies;
@@ -18974,7 +19208,7 @@ function normalizeHubManifests(contextDir, catalog) {
18974
19208
  }
18975
19209
  }
18976
19210
  if (changed) {
18977
- fs34.writeFileSync(manifest, `${JSON.stringify(pkg, null, 2)}
19211
+ fs35.writeFileSync(manifest, `${JSON.stringify(pkg, null, 2)}
18978
19212
  `);
18979
19213
  touched.push(`${entry.name}/package.json`);
18980
19214
  }
@@ -18982,15 +19216,15 @@ function normalizeHubManifests(contextDir, catalog) {
18982
19216
  return touched;
18983
19217
  }
18984
19218
  async function buildHubImagesFromSource(repoRoot2) {
18985
- const hubDir = path41.join(repoRoot2, "apps", "hub");
18986
- if (!fs34.existsSync(path41.join(hubDir, "package.json"))) {
19219
+ const hubDir = path42.join(repoRoot2, "apps", "hub");
19220
+ if (!fs35.existsSync(path42.join(hubDir, "package.json"))) {
18987
19221
  throw new MeshCliError(
18988
19222
  `--hub-from-source needs a mesh-platform checkout; no apps/hub under ${repoRoot2}.`,
18989
19223
  { remediation: { command: "Run mesh start from a mesh-platform checkout, or drop --hub-from-source" } }
18990
19224
  );
18991
19225
  }
18992
19226
  const npmrc = npmrcPath();
18993
- const version = `${JSON.parse(fs34.readFileSync(path41.join(hubDir, "package.json"), "utf-8")).version}-src`;
19227
+ const version = `${JSON.parse(fs35.readFileSync(path42.join(hubDir, "package.json"), "utf-8")).version}-src`;
18994
19228
  const build = startHeartbeat("building apps/hub (api + ui) from source");
18995
19229
  try {
18996
19230
  for (const pkg of ["@mesh-tech/hub-api", "@mesh-tech/hub-ui"]) {
@@ -18999,27 +19233,27 @@ async function buildHubImagesFromSource(repoRoot2) {
18999
19233
  } finally {
19000
19234
  build.stop();
19001
19235
  }
19002
- const context = path41.join(cacheDir(), `context-${version}`);
19003
- fs34.rmSync(context, { recursive: true, force: true });
19004
- fs34.mkdirSync(context, { recursive: true });
19236
+ const context = path42.join(cacheDir(), `context-${version}`);
19237
+ fs35.rmSync(context, { recursive: true, force: true });
19238
+ fs35.mkdirSync(context, { recursive: true });
19005
19239
  await execFileAsync2("pnpm", ["pack", "--pack-destination", context], { cwd: hubDir, maxBuffer: 64 * 1024 * 1024 });
19006
- const tarball = fs34.readdirSync(context).find((f) => f.endsWith(".tgz"));
19240
+ const tarball = fs35.readdirSync(context).find((f) => f.endsWith(".tgz"));
19007
19241
  if (!tarball) throw new MeshCliError("pnpm pack produced no tarball for apps/hub");
19008
- execFileSync29("tar", ["-xzf", path41.join(context, tarball), "-C", context, "--strip-components", "1"], {
19242
+ execFileSync30("tar", ["-xzf", path42.join(context, tarball), "-C", context, "--strip-components", "1"], {
19009
19243
  stdio: ["ignore", "pipe", "pipe"]
19010
19244
  });
19011
19245
  const rewritten = normalizeHubManifests(context, readWorkspaceCatalog(repoRoot2));
19012
19246
  if (rewritten.length > 0) logInfo(`Normalized ${rewritten.length} manifest(s) for npm: ${rewritten.join(", ")}`);
19013
- const hubStackDir = path41.join(findPackageRoot(), "stack", "hub");
19247
+ const hubStackDir = path42.join(findPackageRoot(), "stack", "hub");
19014
19248
  for (const [name, dockerfile] of [
19015
19249
  ["mesh-local-hub-api", "Dockerfile.api"],
19016
19250
  ["mesh-local-hub-ui", "Dockerfile.ui"]
19017
19251
  ]) {
19018
19252
  const tag = `${name}:${version}`;
19019
19253
  logInfo(`Building ${tag} from source\u2026`);
19020
- execFileSync29(
19254
+ execFileSync30(
19021
19255
  "docker",
19022
- ["build", "-f", path41.join(hubStackDir, dockerfile), "-t", tag, "--secret", `id=npmrc,src=${npmrc}`, context],
19256
+ ["build", "-f", path42.join(hubStackDir, dockerfile), "-t", tag, "--secret", `id=npmrc,src=${npmrc}`, context],
19023
19257
  { stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
19024
19258
  );
19025
19259
  logSuccess(`Built ${tag}`);
@@ -19104,8 +19338,8 @@ var init_seed_hub_catalog = __esm({
19104
19338
  });
19105
19339
 
19106
19340
  // libs/mesh-cli/src/commands/local/index.ts
19107
- import * as fs35 from "fs";
19108
- import * as path42 from "path";
19341
+ import * as fs36 from "fs";
19342
+ import * as path43 from "path";
19109
19343
  import chalk6 from "chalk";
19110
19344
  function crashError(crashed) {
19111
19345
  return new MeshCliError(
@@ -19117,10 +19351,13 @@ function crashError(crashed) {
19117
19351
  }
19118
19352
  );
19119
19353
  }
19120
- async function waitForStack(io = {
19354
+ async function waitForStack(opts, io = {
19121
19355
  probe: probeEndpoint,
19122
19356
  services: stackServices,
19123
- overlayServices: hubOverlayServices
19357
+ overlays: () => [
19358
+ { services: hubOverlayServices(), started: false },
19359
+ { services: idpsOverlayServices(), started: opts.idpsStarted }
19360
+ ]
19124
19361
  }) {
19125
19362
  const deadline = Date.now() + WAIT_TIMEOUT_MS;
19126
19363
  let pending = STACK_ENDPOINTS.filter((e) => e.probe.kind !== "none");
@@ -19135,10 +19372,7 @@ async function waitForStack(io = {
19135
19372
  }
19136
19373
  }
19137
19374
  pending = stillDown;
19138
- const crashed = crashedServices(io.services(), {
19139
- overlayServices: io.overlayServices(),
19140
- overlayStarted: false
19141
- });
19375
+ const crashed = crashedServices(io.services(), { overlays: io.overlays() });
19142
19376
  if (crashed.length > 0) throw crashError(crashed);
19143
19377
  if (pending.length === 0) break;
19144
19378
  if (Date.now() > deadline) {
@@ -19222,17 +19456,22 @@ function portMoveHints() {
19222
19456
  [
19223
19457
  Number(hubPort()),
19224
19458
  "MESH_HUB_PORT=<free port> mesh start (or mesh start --no-hub, which starts everything else)"
19459
+ ],
19460
+ [MOCK_SAML_PORT, "mesh start (without --with-idps \u2014 the mock identity providers are opt-in)"],
19461
+ [
19462
+ MOCK_OIDC_PORT,
19463
+ "mesh start (without --with-idps; 5556 is Dex's own default port, so a Dex of your own is the usual holder)"
19225
19464
  ]
19226
19465
  ]);
19227
19466
  }
19228
19467
  function repoRootForHubSource() {
19229
19468
  for (let dir = process.cwd(); ; ) {
19230
- if (fs35.existsSync(path42.join(dir, "apps", "hub", "package.json"))) return dir;
19231
- const parent = path42.dirname(dir);
19469
+ if (fs36.existsSync(path43.join(dir, "apps", "hub", "package.json"))) return dir;
19470
+ const parent = path43.dirname(dir);
19232
19471
  if (parent === dir) break;
19233
19472
  dir = parent;
19234
19473
  }
19235
- return path42.resolve(findPackageRoot(), "..", "..");
19474
+ return path43.resolve(findPackageRoot(), "..", "..");
19236
19475
  }
19237
19476
  function registerLocalCommands(program2) {
19238
19477
  program2.command("start").description("Start the full-local Mesh platform (Docker only \u2014 no AWS, no VPN)").option("--no-seed", "skip first-boot seeding (tenant registry, artifacts bucket)").option("--no-hub", "start without the Hub (API + UI)").option(
@@ -19241,6 +19480,10 @@ function registerLocalCommands(program2) {
19241
19480
  ).option(
19242
19481
  "--hub-from-source",
19243
19482
  "build the Hub images from THIS checkout's apps/hub instead of the published tarball (the only way to exercise a Hub change locally)"
19483
+ ).option(
19484
+ "--with-idps",
19485
+ "also run mock SAML and OIDC identity providers, and federate the local Zitadel with both (for testing enterprise SSO without a cloud tenant or an IdP admin)",
19486
+ false
19244
19487
  ).option(
19245
19488
  "--takeover",
19246
19489
  "re-own a stack that another checkout started (may recreate shared containers with THIS checkout's config)",
@@ -19268,7 +19511,11 @@ Re-running start from here may recreate shared containers with this checkout's c
19268
19511
  logWarn(`Taking over the running stack (previously driven from ${foreign}).`);
19269
19512
  }
19270
19513
  if (!opts.skipPortCheck && !stackServices().some((s) => s.state === "running")) {
19271
- const ports = hostPortsOf([...STACK_ENDPOINTS, ...opts.hub ? hubEndpoints() : []]);
19514
+ const ports = hostPortsOf([
19515
+ ...STACK_ENDPOINTS,
19516
+ ...opts.hub ? hubEndpoints() : [],
19517
+ ...opts.withIdps ? idpEndpoints() : []
19518
+ ]);
19272
19519
  const conflicts = await findPortConflicts(ports, `${COMPOSE_PROJECT}-`);
19273
19520
  if (conflicts.length > 0) {
19274
19521
  throw new MeshCliError(describePortConflicts(conflicts, portMoveHints()), {
@@ -19313,9 +19560,10 @@ Re-running start from here may recreate shared containers with this checkout's c
19313
19560
  }
19314
19561
  }
19315
19562
  logInfo("Starting the local Mesh platform (docker compose project: mesh-local)\u2026");
19316
- await composeStreamed(["up", "-d"]);
19563
+ const idpEnv = opts.withIdps ? mockIdpComposeEnv() : void 0;
19564
+ await composeStreamed(["up", "-d"], { idps: opts.withIdps, env: idpEnv });
19317
19565
  compose(["restart", "prometheus", "blackbox-exporter"], { inherit: true });
19318
- await waitForStack();
19566
+ await waitForStack({ idpsStarted: opts.withIdps });
19319
19567
  let hubAuth = readHubAuth();
19320
19568
  if (opts.seed) {
19321
19569
  logInfo("Seeding local platform (tenant registry, artifacts bucket)\u2026");
@@ -19323,6 +19571,16 @@ Re-running start from here may recreate shared containers with this checkout's c
19323
19571
  logInfo("Seeding Zitadel (Platform project, Mesh CLI app, Hub auth, test users)\u2026");
19324
19572
  const zitadel = await seedZitadel(LOCAL_AWS_CONFIG);
19325
19573
  hubAuth = zitadel.hubAuth;
19574
+ if (opts.withIdps) {
19575
+ logInfo("Federating local Zitadel with the mock SAML and OIDC identity providers\u2026");
19576
+ await seedMockIdps();
19577
+ logInfo(
19578
+ `Mock SAML IdP: http://localhost:${MOCK_SAML_PORT} \xB7 mock OIDC IdP: http://localhost:${MOCK_OIDC_PORT}/dex \xB7 sign in at http://localhost:8080 and both federation buttons are offered`
19579
+ );
19580
+ logInfo(
19581
+ "Both are listed in the Zitadel console under Settings \u2192 Identity Providers (owner: Instance): http://localhost:8080/ui/console/org-settings?id=idp"
19582
+ );
19583
+ }
19326
19584
  if (hubVersion) {
19327
19585
  const compiled = readHubCompiledAuthz(hubVersion);
19328
19586
  if (compiled) {
@@ -19365,19 +19623,23 @@ Re-running start from here may recreate shared containers with this checkout's c
19365
19623
  hubEnv.MESH_HUB_OAUTH2_CLIENT_SECRET = hubAuth.clientSecret;
19366
19624
  hubEnv.MESH_HUB_OAUTH2_COOKIE_SECRET = hubAuth.cookieSecret;
19367
19625
  }
19368
- await composeStreamed(["up", "-d"], { hub: true, env: hubEnv });
19626
+ await composeStreamed(["up", "-d"], {
19627
+ hub: true,
19628
+ idps: opts.withIdps,
19629
+ env: { ...idpEnv, ...hubEnv }
19630
+ });
19369
19631
  if (opts.seed) {
19370
19632
  compose(["restart", "hub-api"], { hub: true, env: hubEnv });
19371
19633
  }
19372
- const overlayServices = hubOverlayServices();
19634
+ const overlays = [
19635
+ { services: hubOverlayServices(), started: true },
19636
+ { services: idpsOverlayServices(), started: opts.withIdps }
19637
+ ];
19373
19638
  for (const endpoint of hubEndpoints()) {
19374
19639
  logInfo(`Waiting for ${endpoint.label}\u2026`);
19375
19640
  let up = await probeEndpoint(endpoint);
19376
19641
  for (let i = 0; i < 60 && !up; i++) {
19377
- const crashed = crashedServices(stackServices(), {
19378
- overlayServices,
19379
- overlayStarted: true
19380
- });
19642
+ const crashed = crashedServices(stackServices(), { overlays });
19381
19643
  if (crashed.length > 0) throw crashError(crashed);
19382
19644
  await new Promise((resolve20) => setTimeout(resolve20, 2e3));
19383
19645
  up = await probeEndpoint(endpoint);
@@ -19421,11 +19683,20 @@ Re-running start from here may recreate shared containers with this checkout's c
19421
19683
  remediation: { command: "mesh start" }
19422
19684
  });
19423
19685
  }
19424
- const overlayServices = hubOverlayServices();
19425
- const overlayStarted = hubOverlayRunning(services, overlayServices);
19426
- const notStarted = (s) => !overlayStarted && overlayServices.has(s.name) && s.state === "exited";
19686
+ const hubOverlay = hubOverlayServices();
19687
+ const idpsOverlay = idpsOverlayServices();
19688
+ const idpsStarted = overlayRunning(services, idpsOverlay);
19689
+ const overlays = [
19690
+ { services: hubOverlay, started: overlayRunning(services, hubOverlay) },
19691
+ { services: idpsOverlay, started: idpsStarted }
19692
+ ];
19693
+ const notStarted = (s) => s.state === "exited" && overlays.some((o) => !o.started && o.services.has(s.name));
19427
19694
  const hasHub = hubApiRunning(services);
19428
- const endpoints = hasHub ? [...STACK_ENDPOINTS, ...hubEndpoints()] : STACK_ENDPOINTS;
19695
+ const endpoints = [
19696
+ ...STACK_ENDPOINTS,
19697
+ ...hasHub ? hubEndpoints() : [],
19698
+ ...idpsStarted ? idpEndpoints() : []
19699
+ ];
19429
19700
  const probes = await Promise.all(
19430
19701
  endpoints.map(async (endpoint) => ({
19431
19702
  service: endpoint.service,
@@ -19450,6 +19721,7 @@ Re-running start from here may recreate shared containers with this checkout's c
19450
19721
  services,
19451
19722
  endpoints: probes,
19452
19723
  fabric,
19724
+ mockIdps: idpsStarted,
19453
19725
  awsEnv: localAwsEnv()
19454
19726
  })
19455
19727
  );
@@ -19464,7 +19736,7 @@ Re-running start from here may recreate shared containers with this checkout's c
19464
19736
  const idle = notStarted(service);
19465
19737
  const icon = ok || oneShotDone ? chalk6.green("\u25CF") : idle ? chalk6.dim("\u25CB") : chalk6.red("\u25CF");
19466
19738
  const health = service.health ? ` (${service.health})` : "";
19467
- const note = idle ? chalk6.dim(" (Hub not started this run)") : "";
19739
+ const note = idle ? chalk6.dim(" (not started this run)") : "";
19468
19740
  console.log(` ${icon} ${service.name.padEnd(22)} ${service.state}${health}${note}`);
19469
19741
  }
19470
19742
  console.log("");
@@ -19478,8 +19750,13 @@ Re-running start from here may recreate shared containers with this checkout's c
19478
19750
  const detail = fabric.ok ? "8 KB Advanced-tier round-trip OK" : fabric.error;
19479
19751
  console.log(` ${icon} ${"AWS fabric check".padEnd(34)} ${chalk6.dim(detail ?? "")}`);
19480
19752
  }
19753
+ if (!idpsStarted) {
19754
+ console.log(
19755
+ ` ${chalk6.dim("\u25CB")} ${"Mock IdPs (SAML + OIDC)".padEnd(34)} ${chalk6.dim("not started \u2014 mesh start --with-idps")}`
19756
+ );
19757
+ }
19481
19758
  const down = probes.filter((p) => !p.up);
19482
- const crashed = crashedServices(services, { overlayServices, overlayStarted });
19759
+ const crashed = crashedServices(services, { overlays });
19483
19760
  if (fabric && !fabric.ok) process.exitCode = 1;
19484
19761
  if (down.length > 0 || crashed.length > 0) {
19485
19762
  console.log("");
@@ -19502,6 +19779,7 @@ var init_local = __esm({
19502
19779
  init_auth_provision();
19503
19780
  init_seed();
19504
19781
  init_seed_zitadel();
19782
+ init_mock_idps();
19505
19783
  init_seed_hub_catalog();
19506
19784
  init_helpers();
19507
19785
  WAIT_TIMEOUT_MS = 18e4;
@@ -20492,7 +20770,7 @@ var init_secrets = __esm({
20492
20770
  import { createHash as createHash4 } from "node:crypto";
20493
20771
  import { createReadStream } from "node:fs";
20494
20772
  import { readdir, readFile as readFile2, stat } from "node:fs/promises";
20495
- import { join as join38, relative as relative11, resolve as resolve17, sep as sep6 } from "node:path";
20773
+ import { join as join39, relative as relative11, resolve as resolve17, sep as sep6 } from "node:path";
20496
20774
  async function describeSiteHttpError(res, target, site) {
20497
20775
  if (res.status === 403) {
20498
20776
  return `not allowed to publish "${site}" \u2014 you are authenticated but lack the grant. Need one of: sites:${site}:publish, sites:*:publish, or studio-admin.`;
@@ -20514,7 +20792,7 @@ async function walk(root) {
20514
20792
  async function visit(dir) {
20515
20793
  for (const entry of await readdir(dir, { withFileTypes: true })) {
20516
20794
  if (SKIP_ENTRIES.has(entry.name)) continue;
20517
- const absolute = join38(dir, entry.name);
20795
+ const absolute = join39(dir, entry.name);
20518
20796
  if (entry.isSymbolicLink()) {
20519
20797
  logWarn(`skipping symlink ${relative11(root, absolute)}`);
20520
20798
  continue;
@@ -20709,23 +20987,23 @@ var init_site = __esm({
20709
20987
  });
20710
20988
 
20711
20989
  // libs/mesh-cli/src/commands/stack.ts
20712
- import { execFileSync as execFileSync30 } from "child_process";
20713
- import * as path43 from "path";
20714
- import * as fs36 from "fs";
20990
+ import { execFileSync as execFileSync31 } from "child_process";
20991
+ import * as path44 from "path";
20992
+ import * as fs37 from "fs";
20715
20993
  import { parse as parseYaml5 } from "yaml";
20716
20994
  function readTopLevelYamlKey(appRoot, stack, key) {
20717
- const configFile = path43.join(appRoot, `Pulumi.${stack}.yaml`);
20718
- if (!fs36.existsSync(configFile)) return null;
20719
- const content = fs36.readFileSync(configFile, "utf-8");
20995
+ const configFile = path44.join(appRoot, `Pulumi.${stack}.yaml`);
20996
+ if (!fs37.existsSync(configFile)) return null;
20997
+ const content = fs37.readFileSync(configFile, "utf-8");
20720
20998
  const pattern = new RegExp(`^${key}:\\s*(.+)$`, "m");
20721
20999
  const match = content.match(pattern);
20722
21000
  if (!match) return null;
20723
21001
  return match[1].trim().replace(/^["']|["']$/g, "");
20724
21002
  }
20725
21003
  function readConfigBlockKey(appRoot, stack, key) {
20726
- const configFile = path43.join(appRoot, `Pulumi.${stack}.yaml`);
20727
- if (!fs36.existsSync(configFile)) return null;
20728
- const content = fs36.readFileSync(configFile, "utf-8");
21004
+ const configFile = path44.join(appRoot, `Pulumi.${stack}.yaml`);
21005
+ if (!fs37.existsSync(configFile)) return null;
21006
+ const content = fs37.readFileSync(configFile, "utf-8");
20729
21007
  const pattern = new RegExp(`^\\s{2}${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*(.+)$`, "m");
20730
21008
  const match = content.match(pattern);
20731
21009
  if (!match) return null;
@@ -20785,11 +21063,11 @@ ${records}
20785
21063
  }
20786
21064
  }
20787
21065
  function readBaseConfigFromYaml(appRoot, stack) {
20788
- const file = path43.join(appRoot, `Pulumi.${stack}.yaml`);
20789
- if (!fs36.existsSync(file)) return {};
21066
+ const file = path44.join(appRoot, `Pulumi.${stack}.yaml`);
21067
+ if (!fs37.existsSync(file)) return {};
20790
21068
  let doc;
20791
21069
  try {
20792
- doc = parseYaml5(fs36.readFileSync(file, "utf-8"));
21070
+ doc = parseYaml5(fs37.readFileSync(file, "utf-8"));
20793
21071
  } catch {
20794
21072
  return {};
20795
21073
  }
@@ -20802,7 +21080,7 @@ function readBaseConfigFromYaml(appRoot, stack) {
20802
21080
  }
20803
21081
  function getGitHubUsername() {
20804
21082
  try {
20805
- const result = execFileSync30("gh", ["api", "user", "--jq", ".login"], {
21083
+ const result = execFileSync31("gh", ["api", "user", "--jq", ".login"], {
20806
21084
  encoding: "utf-8",
20807
21085
  stdio: ["pipe", "pipe", "pipe"]
20808
21086
  });
@@ -20811,7 +21089,7 @@ function getGitHubUsername() {
20811
21089
  } catch {
20812
21090
  }
20813
21091
  try {
20814
- const result = execFileSync30("git", ["config", "user.email"], {
21092
+ const result = execFileSync31("git", ["config", "user.email"], {
20815
21093
  encoding: "utf-8",
20816
21094
  stdio: ["pipe", "pipe", "pipe"]
20817
21095
  });
@@ -20866,7 +21144,7 @@ Specify which to base on: mesh stack init --from <stack>`
20866
21144
  }
20867
21145
  }
20868
21146
  const baseConfigPath = `${appRoot}/Pulumi.${baseStack}.yaml`;
20869
- if (!fs36.existsSync(baseConfigPath)) {
21147
+ if (!fs37.existsSync(baseConfigPath)) {
20870
21148
  logError(`Stack config not found: Pulumi.${baseStack}.yaml`);
20871
21149
  process.exit(1);
20872
21150
  }
@@ -20888,8 +21166,8 @@ Specify which to base on: mesh stack init --from <stack>`
20888
21166
  );
20889
21167
  }
20890
21168
  }
20891
- const newConfigPath = path43.join(appRoot, `Pulumi.${newStack}.yaml`);
20892
- const configExists = fs36.existsSync(newConfigPath);
21169
+ const newConfigPath = path44.join(appRoot, `Pulumi.${newStack}.yaml`);
21170
+ const configExists = fs37.existsSync(newConfigPath);
20893
21171
  const secretsProvider = readTopLevelYamlKey(appRoot, baseStack, "secretsprovider");
20894
21172
  const credEnv = await resolvePulumiEnv({ appRoot, stack: baseStack });
20895
21173
  const pulumiEnv = { ...process.env, ...credEnv };
@@ -20897,7 +21175,7 @@ Specify which to base on: mesh stack init --from <stack>`
20897
21175
  if (!opts.adopt) {
20898
21176
  let existing = [];
20899
21177
  try {
20900
- const raw = execFileSync30("pulumi", ["stack", "ls", "--json"], {
21178
+ const raw = execFileSync31("pulumi", ["stack", "ls", "--json"], {
20901
21179
  cwd: appRoot,
20902
21180
  encoding: "utf-8",
20903
21181
  env: pulumiEnv,
@@ -20921,7 +21199,7 @@ Specify which to base on: mesh stack init --from <stack>`
20921
21199
  logInfo(`Using KMS secrets provider: ${secretsProvider}`);
20922
21200
  }
20923
21201
  try {
20924
- execFileSync30("pulumi", initArgs, {
21202
+ execFileSync31("pulumi", initArgs, {
20925
21203
  cwd: appRoot,
20926
21204
  env: pulumiEnv,
20927
21205
  stdio: "inherit"
@@ -20938,7 +21216,7 @@ Specify which to base on: mesh stack init --from <stack>`
20938
21216
  }
20939
21217
  }
20940
21218
  try {
20941
- execFileSync30("pulumi", ["stack", "select", newStack], {
21219
+ execFileSync31("pulumi", ["stack", "select", newStack], {
20942
21220
  cwd: appRoot,
20943
21221
  env: pulumiEnv,
20944
21222
  stdio: ["pipe", "pipe", "pipe"]
@@ -20948,7 +21226,7 @@ Specify which to base on: mesh stack init --from <stack>`
20948
21226
  if (!configExists) {
20949
21227
  let baseConfig = {};
20950
21228
  try {
20951
- const raw = execFileSync30(
21229
+ const raw = execFileSync31(
20952
21230
  "pulumi",
20953
21231
  ["config", "--json", "--stack", baseStack],
20954
21232
  { cwd: appRoot, env: pulumiEnv, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
@@ -20966,19 +21244,19 @@ Specify which to base on: mesh stack init --from <stack>`
20966
21244
  if (key === "mesh:deploy") continue;
20967
21245
  try {
20968
21246
  if (entry.objectValue !== void 0) {
20969
- execFileSync30(
21247
+ execFileSync31(
20970
21248
  "pulumi",
20971
21249
  ["config", "set", key, JSON.stringify(entry.objectValue)],
20972
21250
  { cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
20973
21251
  );
20974
21252
  } else if (entry.value === "true" || entry.value === "false") {
20975
- execFileSync30(
21253
+ execFileSync31(
20976
21254
  "pulumi",
20977
21255
  ["config", "set", "--type", "bool", key, entry.value],
20978
21256
  { cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
20979
21257
  );
20980
21258
  } else {
20981
- execFileSync30(
21259
+ execFileSync31(
20982
21260
  "pulumi",
20983
21261
  ["config", "set", key, entry.value],
20984
21262
  { cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
@@ -20991,7 +21269,7 @@ Specify which to base on: mesh stack init --from <stack>`
20991
21269
  const baseEnv = readConfigBlockKey(appRoot, baseStack, "mesh:coreEnv") ?? (baseTenant && baseStack.startsWith(`${baseTenant}-`) ? baseStack.slice(baseTenant.length + 1) : baseStack);
20992
21270
  const setCfg = (args) => {
20993
21271
  try {
20994
- execFileSync30("pulumi", ["config", "set", ...args], {
21272
+ execFileSync31("pulumi", ["config", "set", ...args], {
20995
21273
  cwd: appRoot,
20996
21274
  env: pulumiEnv,
20997
21275
  stdio: ["pipe", "pipe", "pipe"]
@@ -21040,7 +21318,7 @@ Specify which to base on: mesh stack init --from <stack>`
21040
21318
  `Configured Pulumi.${newStack}.yaml (personal platform env on core '${baseEnv}'${opts.parentZone ? `, DNS zone ${newStack.startsWith(`${baseTenant}-`) ? newStack.slice(baseTenant.length + 1) : newStack}.${opts.parentZone}` : ""})`
21041
21319
  );
21042
21320
  } else {
21043
- execFileSync30("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
21321
+ execFileSync31("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
21044
21322
  cwd: appRoot,
21045
21323
  env: pulumiEnv,
21046
21324
  stdio: ["pipe", "pipe", "pipe"]
@@ -21070,7 +21348,7 @@ Specify which to base on: mesh stack init --from <stack>`
21070
21348
  const args = ["stack", "rm", name];
21071
21349
  if (opts.yes) args.push("--yes");
21072
21350
  try {
21073
- execFileSync30("pulumi", args, { cwd: appRoot, env: pulumiEnv, stdio: "inherit" });
21351
+ execFileSync31("pulumi", args, { cwd: appRoot, env: pulumiEnv, stdio: "inherit" });
21074
21352
  logSuccess(`Removed stack ${name}`);
21075
21353
  } catch (err) {
21076
21354
  process.exit(err.status ?? 1);
@@ -21282,12 +21560,12 @@ var init_recover_conversation = __esm({
21282
21560
  });
21283
21561
 
21284
21562
  // libs/mesh-cli/src/utils/temporal-codec.ts
21285
- import { execFileSync as execFileSync31 } from "child_process";
21563
+ import { execFileSync as execFileSync32 } from "child_process";
21286
21564
  import { webcrypto as crypto4 } from "node:crypto";
21287
21565
  function resolveTemporalEncodingKeyFromK8s(namespace) {
21288
21566
  const secretName = `${namespace}-temporal-encoding-key`;
21289
21567
  try {
21290
- const b64 = execFileSync31(
21568
+ const b64 = execFileSync32(
21291
21569
  "kubectl",
21292
21570
  [
21293
21571
  "get",
@@ -21536,9 +21814,9 @@ var init_capture_history = __esm({
21536
21814
 
21537
21815
  // libs/mesh-cli/src/commands/temporal.ts
21538
21816
  import { spawnSync as spawnSync4 } from "node:child_process";
21539
- import { writeFileSync as writeFileSync24, mkdirSync as mkdirSync19 } from "node:fs";
21817
+ import { writeFileSync as writeFileSync24, mkdirSync as mkdirSync20 } from "node:fs";
21540
21818
  import { homedir as homedir6 } from "node:os";
21541
- import { dirname as dirname28, join as join40, resolve as resolve18 } from "node:path";
21819
+ import { dirname as dirname28, join as join41, resolve as resolve18 } from "node:path";
21542
21820
  async function resolveConnection(options) {
21543
21821
  if (options.address && options.namespace) {
21544
21822
  return { address: options.address, namespace: options.namespace };
@@ -21966,8 +22244,8 @@ async function captureHistory(workflowId, runId, options) {
21966
22244
  }
21967
22245
  const { serializeHistoryToFixture: serializeHistoryToFixture2 } = await Promise.resolve().then(() => (init_capture_history(), capture_history_exports));
21968
22246
  const { fixture, eventCount, decryptedPayloads } = await serializeHistoryToFixture2(events, decrypter);
21969
- const outPath = options.out ?? join40(homedir6(), ".mesh", "replay-histories", `${sanitizeFileId(workflowId)}.json`);
21970
- mkdirSync19(dirname28(outPath), { recursive: true });
22247
+ const outPath = options.out ?? join41(homedir6(), ".mesh", "replay-histories", `${sanitizeFileId(workflowId)}.json`);
22248
+ mkdirSync20(dirname28(outPath), { recursive: true });
21971
22249
  if (options.out) warnIfNotGitIgnored(options.out);
21972
22250
  writeFileSync24(outPath, JSON.stringify(fixture, null, 2) + "\n");
21973
22251
  logSuccess(
@@ -22158,8 +22436,8 @@ var init_temporal = __esm({
22158
22436
 
22159
22437
  // libs/mesh-cli/src/commands/tenant.ts
22160
22438
  import chalk7 from "chalk";
22161
- import * as fs37 from "fs";
22162
- import * as path44 from "path";
22439
+ import * as fs38 from "fs";
22440
+ import * as path45 from "path";
22163
22441
  import { parseDocument, YAMLMap, isMap } from "yaml";
22164
22442
  function validateTenantName(name) {
22165
22443
  return /^[a-z][a-z0-9-]*$/.test(name) && !name.endsWith("-");
@@ -22227,16 +22505,16 @@ function resolveStackConfig(explicitStack) {
22227
22505
  { remediation: { command: "mesh tenant add <name> --stack <stack>" } }
22228
22506
  );
22229
22507
  }
22230
- const file = path44.join(appRoot, `Pulumi.${stack}.yaml`);
22231
- if (!fs37.existsSync(file)) {
22508
+ const file = path45.join(appRoot, `Pulumi.${stack}.yaml`);
22509
+ if (!fs38.existsSync(file)) {
22232
22510
  throw new MeshCliError(`Stack config not found: ${file}`, {
22233
22511
  remediation: { command: "mesh tenant add <name> --stack <stack>" }
22234
22512
  });
22235
22513
  }
22236
- return { appRoot, stack, file, content: fs37.readFileSync(file, "utf-8") };
22514
+ return { appRoot, stack, file, content: fs38.readFileSync(file, "utf-8") };
22237
22515
  }
22238
22516
  function readProjectName(appRoot) {
22239
- const projectDoc = parseDocument(fs37.readFileSync(path44.join(appRoot, "Pulumi.yaml"), "utf-8"));
22517
+ const projectDoc = parseDocument(fs38.readFileSync(path45.join(appRoot, "Pulumi.yaml"), "utf-8"));
22240
22518
  return String(projectDoc.get("name") ?? "");
22241
22519
  }
22242
22520
  function looksLikePlatformLayer(projectName) {
@@ -22279,12 +22557,12 @@ function registerTenantCommands(program2) {
22279
22557
  if (!result.ok) {
22280
22558
  if (result.reason === "exists") {
22281
22559
  throw new MeshCliError(
22282
- `${result.detail} (${path44.basename(resolved.file)}). Edit the existing entry instead of re-adding it.`
22560
+ `${result.detail} (${path45.basename(resolved.file)}). Edit the existing entry instead of re-adding it.`
22283
22561
  );
22284
22562
  }
22285
22563
  throw new MeshCliError(`${resolved.file}: ${result.detail}`);
22286
22564
  }
22287
- atomicWriteFileSync(resolved.file, result.yaml, fs37.statSync(resolved.file).mode & 511);
22565
+ atomicWriteFileSync(resolved.file, result.yaml, fs38.statSync(resolved.file).mode & 511);
22288
22566
  if (opts.json) {
22289
22567
  emitJsonPayload({
22290
22568
  ok: true,
@@ -22297,7 +22575,7 @@ function registerTenantCommands(program2) {
22297
22575
  return;
22298
22576
  }
22299
22577
  logInfo(
22300
- `Tenant '${name}' registered in ${path44.basename(resolved.file)} (mesh:tenants, subdomain '${subdomain}')${result.createdTenantsBlock ? " \u2014 created the mesh:tenants block" : ""}`
22578
+ `Tenant '${name}' registered in ${path45.basename(resolved.file)} (mesh:tenants, subdomain '${subdomain}')${result.createdTenantsBlock ? " \u2014 created the mesh:tenants block" : ""}`
22301
22579
  );
22302
22580
  console.log("");
22303
22581
  console.log("Next steps:");
@@ -22323,7 +22601,7 @@ function registerTenantCommands(program2) {
22323
22601
  `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).`
22324
22602
  );
22325
22603
  }
22326
- logInfo(`No tenants declared in ${path44.basename(resolved.file)}.`);
22604
+ logInfo(`No tenants declared in ${path45.basename(resolved.file)}.`);
22327
22605
  return;
22328
22606
  }
22329
22607
  logInfo(`Tenants on stack '${resolved.stack}':`);
@@ -22345,9 +22623,9 @@ var init_tenant = __esm({
22345
22623
 
22346
22624
  // libs/mesh-cli/src/commands/tunnel/index.ts
22347
22625
  import { spawn as spawn9 } from "child_process";
22348
- import * as fs38 from "fs";
22626
+ import * as fs39 from "fs";
22349
22627
  import * as os12 from "os";
22350
- import * as path45 from "path";
22628
+ import * as path46 from "path";
22351
22629
  import {
22352
22630
  SecretsManagerClient as SecretsManagerClient9,
22353
22631
  GetSecretValueCommand as GetSecretValueCommand9
@@ -22367,9 +22645,9 @@ function readPulumiAwsRegion(stage) {
22367
22645
  const preferred = stage ? `Pulumi.${stage}.yaml` : void 0;
22368
22646
  const rank = (f) => f === preferred ? 0 : f === "Pulumi.yaml" ? 2 : 1;
22369
22647
  try {
22370
- const files = fs38.readdirSync(".").filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml")).sort((a, b) => rank(a) - rank(b));
22648
+ const files = fs39.readdirSync(".").filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml")).sort((a, b) => rank(a) - rank(b));
22371
22649
  for (const f of files) {
22372
- const m = fs38.readFileSync(f, "utf-8").match(/^\s*aws:region:\s*["']?([^"'\n]+)["']?/m);
22650
+ const m = fs39.readFileSync(f, "utf-8").match(/^\s*aws:region:\s*["']?([^"'\n]+)["']?/m);
22373
22651
  if (m?.[1]) return m[1].trim();
22374
22652
  }
22375
22653
  } catch {
@@ -22378,14 +22656,14 @@ function readPulumiAwsRegion(stage) {
22378
22656
  }
22379
22657
  function awsProfileSections(name) {
22380
22658
  return [
22381
- [path45.join(os12.homedir(), ".aws", "config"), `[profile ${name}]`],
22382
- [path45.join(os12.homedir(), ".aws", "credentials"), `[${name}]`]
22659
+ [path46.join(os12.homedir(), ".aws", "config"), `[profile ${name}]`],
22660
+ [path46.join(os12.homedir(), ".aws", "credentials"), `[${name}]`]
22383
22661
  ];
22384
22662
  }
22385
22663
  function awsProfileExists(name) {
22386
22664
  for (const [file, header] of awsProfileSections(name)) {
22387
22665
  try {
22388
- const lines = fs38.readFileSync(file, "utf-8").split("\n");
22666
+ const lines = fs39.readFileSync(file, "utf-8").split("\n");
22389
22667
  if (lines.some((l) => l.trim() === header)) return true;
22390
22668
  } catch {
22391
22669
  }
@@ -22411,7 +22689,7 @@ function awsProfileRegion(profile) {
22411
22689
  if (!profile) return void 0;
22412
22690
  for (const [file, header] of awsProfileSections(profile)) {
22413
22691
  try {
22414
- const region = parseProfileRegion(fs38.readFileSync(file, "utf-8"), header);
22692
+ const region = parseProfileRegion(fs39.readFileSync(file, "utf-8"), header);
22415
22693
  if (region) return region;
22416
22694
  } catch {
22417
22695
  }
@@ -22420,14 +22698,14 @@ function awsProfileRegion(profile) {
22420
22698
  }
22421
22699
  function awsDefaultProfileSections() {
22422
22700
  return [
22423
- [path45.join(os12.homedir(), ".aws", "config"), "[default]"],
22424
- [path45.join(os12.homedir(), ".aws", "credentials"), "[default]"]
22701
+ [path46.join(os12.homedir(), ".aws", "config"), "[default]"],
22702
+ [path46.join(os12.homedir(), ".aws", "credentials"), "[default]"]
22425
22703
  ];
22426
22704
  }
22427
22705
  function awsDefaultProfileRegion() {
22428
22706
  for (const [file, header] of awsDefaultProfileSections()) {
22429
22707
  try {
22430
- const region = parseProfileRegion(fs38.readFileSync(file, "utf-8"), header);
22708
+ const region = parseProfileRegion(fs39.readFileSync(file, "utf-8"), header);
22431
22709
  if (region) return region;
22432
22710
  } catch {
22433
22711
  }
@@ -22814,8 +23092,8 @@ async function resolveToken(opts) {
22814
23092
  "no token: pass --token, set VCS_TOKEN, or pass --context <platform-context> (after mesh login)"
22815
23093
  );
22816
23094
  }
22817
- async function vcsApi(baseUrl, token, path47, method = "GET", body) {
22818
- const res = await fetch(`${baseUrl}${path47}`, {
23095
+ async function vcsApi(baseUrl, token, path48, method = "GET", body) {
23096
+ const res = await fetch(`${baseUrl}${path48}`, {
22819
23097
  method,
22820
23098
  headers: {
22821
23099
  authorization: `Bearer ${token}`,
@@ -22826,7 +23104,7 @@ async function vcsApi(baseUrl, token, path47, method = "GET", body) {
22826
23104
  const data = await res.json().catch(() => ({}));
22827
23105
  if (!res.ok) {
22828
23106
  throw new Error(
22829
- `${method} ${path47} failed (${res.status}): ${String(data.error ?? "unknown error")}`
23107
+ `${method} ${path48} failed (${res.status}): ${String(data.error ?? "unknown error")}`
22830
23108
  );
22831
23109
  }
22832
23110
  return data;
@@ -22872,8 +23150,8 @@ var init_clone = __esm({
22872
23150
 
22873
23151
  // libs/mesh-cli/src/commands/vcs/get.ts
22874
23152
  import { writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
22875
- import { join as join43, dirname as dirname29 } from "node:path";
22876
- async function getCommand(repo, path47, opts) {
23153
+ import { join as join44, dirname as dirname29 } from "node:path";
23154
+ async function getCommand(repo, path48, opts) {
22877
23155
  let vcsBaseUrl;
22878
23156
  let token;
22879
23157
  if (opts.target) {
@@ -22888,18 +23166,18 @@ async function getCommand(repo, path47, opts) {
22888
23166
  if (!token) throw new Error("no token: pass --target (after mesh login), or --token / --context");
22889
23167
  const reader = createVcsFolderReader({ vcsBaseUrl, token });
22890
23168
  try {
22891
- const { ref, files } = await reader.readPath(repo, path47);
23169
+ const { ref, files } = await reader.readPath(repo, path48);
22892
23170
  if (files.length === 0) {
22893
- logInfo(`no files at ${repo}:${path47}`);
23171
+ logInfo(`no files at ${repo}:${path48}`);
22894
23172
  return;
22895
23173
  }
22896
23174
  if (opts.output) {
22897
23175
  for (const f of files) {
22898
- const abs = join43(opts.output, f.path);
23176
+ const abs = join44(opts.output, f.path);
22899
23177
  await mkdir2(dirname29(abs), { recursive: true });
22900
23178
  await writeFile2(abs, f.contents);
22901
23179
  }
22902
- logInfo(`wrote ${files.length} file(s) from ${repo}:${path47} (${ref}) \u2192 ${opts.output}`);
23180
+ logInfo(`wrote ${files.length} file(s) from ${repo}:${path48} (${ref}) \u2192 ${opts.output}`);
22903
23181
  } else {
22904
23182
  for (const f of files) {
22905
23183
  if (files.length > 1) process.stdout.write(`
@@ -22924,10 +23202,10 @@ var init_get = __esm({
22924
23202
  });
22925
23203
 
22926
23204
  // libs/mesh-cli/src/commands/vcs/drafts.ts
22927
- async function call(opts, repo, path47, method = "GET", body) {
23205
+ async function call(opts, repo, path48, method = "GET", body) {
22928
23206
  const target = await resolveTarget2({ ...opts, repo });
22929
23207
  const token = await resolveToken(opts);
22930
- return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path47}`, method, body);
23208
+ return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path48}`, method, body);
22931
23209
  }
22932
23210
  async function draftsListCommand(repo, opts) {
22933
23211
  const data = await call(opts, repo, `/drafts${opts.all ? "?all=true" : ""}`);
@@ -22982,7 +23260,7 @@ var init_drafts = __esm({
22982
23260
 
22983
23261
  // libs/mesh-cli/src/commands/vcs/propose.ts
22984
23262
  import { readFile as readFile3 } from "node:fs/promises";
22985
- import { join as join44 } from "node:path";
23263
+ import { join as join45 } from "node:path";
22986
23264
  function parseStatus(out) {
22987
23265
  const tokens = out.split("\0");
22988
23266
  const changes = [];
@@ -23015,13 +23293,13 @@ function parseStatus(out) {
23015
23293
  }
23016
23294
  return changes;
23017
23295
  }
23018
- async function writeOp(cwd, path47) {
23019
- const buf = await readFile3(join44(cwd, path47));
23296
+ async function writeOp(cwd, path48) {
23297
+ const buf = await readFile3(join45(cwd, path48));
23020
23298
  const asUtf8 = buf.toString("utf8");
23021
23299
  if (Buffer.from(asUtf8, "utf8").equals(buf)) {
23022
- return { op: "write", path: path47, content: asUtf8 };
23300
+ return { op: "write", path: path48, content: asUtf8 };
23023
23301
  }
23024
- return { op: "write", path: path47, content: buf.toString("base64"), encoding: "base64" };
23302
+ return { op: "write", path: path48, content: buf.toString("base64"), encoding: "base64" };
23025
23303
  }
23026
23304
  async function proposeCommand(opts) {
23027
23305
  const cwd = process.cwd();
@@ -23065,8 +23343,8 @@ async function proposeCommand(opts) {
23065
23343
  operations,
23066
23344
  ...opts.mergeParent ? { mergeParent: opts.mergeParent } : {}
23067
23345
  };
23068
- const path47 = opts.revise ? `/v1/repos/${target.repo}/proposals/${opts.revise}/revisions` : `/v1/repos/${target.repo}/proposals`;
23069
- const data = await vcsApi(target.baseUrl, token, path47, "POST", body);
23346
+ const path48 = opts.revise ? `/v1/repos/${target.repo}/proposals/${opts.revise}/revisions` : `/v1/repos/${target.repo}/proposals`;
23347
+ const data = await vcsApi(target.baseUrl, token, path48, "POST", body);
23070
23348
  console.log(
23071
23349
  `proposal ${data.proposalId} @ ${data.sha.slice(0, 8)} \u2014 review: mesh vcs show ${target.repo} ${data.proposalId} --url ${target.baseUrl}`
23072
23350
  );
@@ -23081,28 +23359,28 @@ var init_propose = __esm({
23081
23359
  // libs/mesh-cli/src/commands/vcs/rm.ts
23082
23360
  import { mkdtemp as mkdtemp2, rm as rmrf } from "node:fs/promises";
23083
23361
  import { tmpdir as tmpdir10 } from "node:os";
23084
- import { join as join45 } from "node:path";
23362
+ import { join as join46 } from "node:path";
23085
23363
  function normalize2(p) {
23086
23364
  return p.trim().replace(/^\.\//, "").replace(/\/+$/, "");
23087
23365
  }
23088
23366
  function expandPathsToDeletions(repoFiles, requested) {
23089
23367
  const out = /* @__PURE__ */ new Set();
23090
23368
  for (const raw of requested) {
23091
- const path47 = normalize2(raw);
23092
- if (path47.startsWith("/") || path47.split("/").includes("..")) {
23369
+ const path48 = normalize2(raw);
23370
+ if (path48.startsWith("/") || path48.split("/").includes("..")) {
23093
23371
  throw new Error(
23094
23372
  `"${raw}" is not a repo-relative path \u2014 vcs paths never start with "/" or traverse with "..".`
23095
23373
  );
23096
23374
  }
23097
- const exact = repoFiles.filter((f) => f === path47);
23375
+ const exact = repoFiles.filter((f) => f === path48);
23098
23376
  if (exact.length > 0) {
23099
23377
  for (const f of exact) out.add(f);
23100
23378
  continue;
23101
23379
  }
23102
- const under = repoFiles.filter((f) => f.startsWith(`${path47}/`));
23380
+ const under = repoFiles.filter((f) => f.startsWith(`${path48}/`));
23103
23381
  if (under.length === 0) {
23104
23382
  throw new Error(
23105
- `"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${path47}`
23383
+ `"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${path48}`
23106
23384
  );
23107
23385
  }
23108
23386
  for (const f of under) out.add(f);
@@ -23113,7 +23391,7 @@ async function rmCommand(repo, paths, opts) {
23113
23391
  const baseUrl = (opts.url ?? process.env.VCS_URL)?.replace(/\/$/, "");
23114
23392
  if (!baseUrl) throw new Error("rm requires --url or VCS_URL");
23115
23393
  const token = await resolveToken(opts);
23116
- const dir = await mkdtemp2(join45(tmpdir10(), "mesh-vcs-rm-"));
23394
+ const dir = await mkdtemp2(join46(tmpdir10(), "mesh-vcs-rm-"));
23117
23395
  try {
23118
23396
  const git = (args, cwd) => gitWithAuth(args, token, cwd);
23119
23397
  await git([
@@ -23138,7 +23416,7 @@ async function rmCommand(repo, paths, opts) {
23138
23416
  const body = {
23139
23417
  baseCommit: head.trim(),
23140
23418
  message: opts.message ?? `Delete ${doomed.length} file(s)`,
23141
- operations: doomed.map((path47) => ({ op: "delete", path: path47 }))
23419
+ operations: doomed.map((path48) => ({ op: "delete", path: path48 }))
23142
23420
  };
23143
23421
  const data = await vcsApi(
23144
23422
  baseUrl,
@@ -23164,10 +23442,10 @@ var init_rm = __esm({
23164
23442
  });
23165
23443
 
23166
23444
  // libs/mesh-cli/src/commands/vcs/review.ts
23167
- async function call2(opts, repo, path47, method = "GET", body) {
23445
+ async function call2(opts, repo, path48, method = "GET", body) {
23168
23446
  const target = await resolveTarget2({ ...opts, repo });
23169
23447
  const token = await resolveToken(opts);
23170
- return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path47}`, method, body);
23448
+ return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path48}`, method, body);
23171
23449
  }
23172
23450
  async function proposalsCommand(repo, opts) {
23173
23451
  console.log(JSON.stringify(await call2(opts, repo, "/proposals"), null, 2));
@@ -23314,8 +23592,8 @@ function computeHappyPath(nodes, edges) {
23314
23592
  ];
23315
23593
  const visited = /* @__PURE__ */ new Set([startNode.id]);
23316
23594
  while (queue.length > 0) {
23317
- const { id, path: path47 } = queue.shift();
23318
- if (targetIds.has(id)) return path47;
23595
+ const { id, path: path48 } = queue.shift();
23596
+ if (targetIds.has(id)) return path48;
23319
23597
  const neighbors = adjacency.get(id) ?? [];
23320
23598
  const hasMainEdge = neighbors.some((e) => e.isMainPath);
23321
23599
  const candidates = hasMainEdge ? neighbors.filter((e) => e.isMainPath) : neighbors;
@@ -23335,7 +23613,7 @@ function computeHappyPath(nodes, edges) {
23335
23613
  if (!allowExceptional && (neighbor.isExceptional || neighbor.isTimeout || failureEndIds.has(neighbor.to)))
23336
23614
  continue;
23337
23615
  visited.add(neighbor.to);
23338
- queue.push({ id: neighbor.to, path: [...path47, neighbor.to] });
23616
+ queue.push({ id: neighbor.to, path: [...path48, neighbor.to] });
23339
23617
  }
23340
23618
  }
23341
23619
  return null;
@@ -23620,11 +23898,11 @@ function wrapIntoGroup(workflow, nodeIds, groupId, label, groupType) {
23620
23898
  }
23621
23899
  }
23622
23900
  if (found) {
23623
- const path47 = [];
23624
- for (let c = found; c !== void 0; c = prev.get(c)) path47.unshift(c);
23625
- for (let i = 0; i < path47.length - 1; i++) mainEdgeKeys.add(edgeKey(path47[i], path47[i + 1]));
23901
+ const path48 = [];
23902
+ for (let c = found; c !== void 0; c = prev.get(c)) path48.unshift(c);
23903
+ for (let i = 0; i < path48.length - 1; i++) mainEdgeKeys.add(edgeKey(path48[i], path48[i + 1]));
23626
23904
  mainEdgeKeys.add(edgeKey(found, successExit.id));
23627
- mainBody = path47;
23905
+ mainBody = path48;
23628
23906
  mainTail = [successExit.id];
23629
23907
  }
23630
23908
  }
@@ -24160,11 +24438,11 @@ function buildProcessManifest(artifact, outcomeNodeIds) {
24160
24438
  ...pointOfNoReturnStage ? { pointOfNoReturnStageId: pointOfNoReturnStage.id } : {}
24161
24439
  };
24162
24440
  }
24163
- function formatPath(path47) {
24164
- return path47.length > 0 ? z4.core.toDotPath(path47) : "(root)";
24441
+ function formatPath(path48) {
24442
+ return path48.length > 0 ? z4.core.toDotPath(path48) : "(root)";
24165
24443
  }
24166
24444
  function issueToDiagnostic(issue) {
24167
- const path47 = formatPath(issue.path);
24445
+ const path48 = formatPath(issue.path);
24168
24446
  let code = "SCHEMA_INVALID";
24169
24447
  if (issue.code === "custom") {
24170
24448
  const paramCode = issue.params?.code;
@@ -24175,8 +24453,8 @@ function issueToDiagnostic(issue) {
24175
24453
  return {
24176
24454
  severity: "error",
24177
24455
  code,
24178
- message: `${path47}: ${issue.message}`,
24179
- path: path47
24456
+ message: `${path48}: ${issue.message}`,
24457
+ path: path48
24180
24458
  };
24181
24459
  }
24182
24460
  function upgradeV1(artifact) {
@@ -24343,24 +24621,24 @@ var init_process_artifact = __esm({
24343
24621
  });
24344
24622
  }
24345
24623
  const declaredSelectors = new Set(Object.keys(process2.selectors ?? {}));
24346
- const checkActor = (actorId, path47) => {
24624
+ const checkActor = (actorId, path48) => {
24347
24625
  if (actorId === void 0) return;
24348
24626
  if (!Object.prototype.hasOwnProperty.call(process2.actors, actorId)) {
24349
24627
  ctx.addIssue({
24350
24628
  code: "custom",
24351
- path: path47,
24352
- message: `Actor "${actorId}" is referenced at ${z4.core.toDotPath(path47)} but not declared in process.actors. Declare the actor (label, and optionally category/selector) or fix the reference.`,
24629
+ path: path48,
24630
+ message: `Actor "${actorId}" is referenced at ${z4.core.toDotPath(path48)} but not declared in process.actors. Declare the actor (label, and optionally category/selector) or fix the reference.`,
24353
24631
  params: { code: "UNDECLARED_ACTOR" }
24354
24632
  });
24355
24633
  }
24356
24634
  };
24357
- const checkSelector = (selector, path47) => {
24635
+ const checkSelector = (selector, path48) => {
24358
24636
  if (selector === void 0) return;
24359
24637
  if (!declaredSelectors.has(selector)) {
24360
24638
  ctx.addIssue({
24361
24639
  code: "custom",
24362
- path: path47,
24363
- message: `Selector "${selector}" is referenced at ${z4.core.toDotPath(path47)} but not declared in process.selectors. Declare the selector or fix the reference.`,
24640
+ path: path48,
24641
+ message: `Selector "${selector}" is referenced at ${z4.core.toDotPath(path48)} but not declared in process.selectors. Declare the selector or fix the reference.`,
24364
24642
  params: { code: "UNDECLARED_SELECTOR" }
24365
24643
  });
24366
24644
  }
@@ -24374,20 +24652,20 @@ var init_process_artifact = __esm({
24374
24652
  outcome: "DUPLICATE_OUTCOME_ID"
24375
24653
  };
24376
24654
  const idFirstSeenAt = /* @__PURE__ */ new Map();
24377
- const checkId = (id, kind, path47) => {
24655
+ const checkId = (id, kind, path48) => {
24378
24656
  const first = idFirstSeenAt.get(id);
24379
24657
  if (first) {
24380
24658
  const kindLabel = kind === first.kind ? kind : "process";
24381
24659
  ctx.addIssue({
24382
24660
  code: "custom",
24383
- path: path47,
24384
- message: `Duplicate ${kindLabel} id "${id}": ${kind} at ${z4.core.toDotPath(path47)} collides with ${first.kind} at ${z4.core.toDotPath(first.path)}.`,
24661
+ path: path48,
24662
+ message: `Duplicate ${kindLabel} id "${id}": ${kind} at ${z4.core.toDotPath(path48)} collides with ${first.kind} at ${z4.core.toDotPath(first.path)}.`,
24385
24663
  params: {
24386
24664
  code: kind === first.kind ? SAME_KIND_CODE[kind] : "DUPLICATE_PROCESS_ID"
24387
24665
  }
24388
24666
  });
24389
24667
  } else {
24390
- idFirstSeenAt.set(id, { kind, path: path47 });
24668
+ idFirstSeenAt.set(id, { kind, path: path48 });
24391
24669
  }
24392
24670
  };
24393
24671
  process2.stages.forEach((stage, stageIndex) => {
@@ -24434,13 +24712,13 @@ function lintProcess(artifact, inventory, predicateNames, options = {}) {
24434
24712
  const internalCommands = process2.internalCommands ?? [];
24435
24713
  const internalSet = new Set(internalCommands);
24436
24714
  const boundCommandPaths = /* @__PURE__ */ new Map();
24437
- const checkPredicate = (predicate, path47) => {
24715
+ const checkPredicate = (predicate, path48) => {
24438
24716
  if (!predicateSet.has(predicate)) {
24439
24717
  diagnostics.push({
24440
24718
  severity: "error",
24441
24719
  code: "UNKNOWN_PREDICATE",
24442
- message: `Predicate "${predicate}" referenced at ${path47} is not in the predicate registry.`,
24443
- path: path47
24720
+ message: `Predicate "${predicate}" referenced at ${path48} is not in the predicate registry.`,
24721
+ path: path48
24444
24722
  });
24445
24723
  }
24446
24724
  };
@@ -24500,19 +24778,19 @@ function lintProcess(artifact, inventory, predicateNames, options = {}) {
24500
24778
  process2.outcomes.forEach((outcome, outcomeIndex) => {
24501
24779
  const whenPath = `process.outcomes[${outcomeIndex}].when`;
24502
24780
  outcomeTriggers(outcome).forEach((trigger, triggerIndex) => {
24503
- const path47 = Array.isArray(outcome.when) ? `${whenPath}[${triggerIndex}]` : whenPath;
24781
+ const path48 = Array.isArray(outcome.when) ? `${whenPath}[${triggerIndex}]` : whenPath;
24504
24782
  if (trigger.kind === "predicate") {
24505
- checkPredicate(trigger.name, `${path47}.predicate`);
24783
+ checkPredicate(trigger.name, `${path48}.predicate`);
24506
24784
  } else if (trigger.kind === "command") {
24507
24785
  if (!boundCommandPaths.has(trigger.name)) {
24508
- boundCommandPaths.set(trigger.name, `${path47}.command`);
24786
+ boundCommandPaths.set(trigger.name, `${path48}.command`);
24509
24787
  }
24510
24788
  if (!commandNames.has(trigger.name)) {
24511
24789
  diagnostics.push({
24512
24790
  severity: "error",
24513
24791
  code: "BOUND_COMMAND_NOT_IN_INVENTORY",
24514
- message: `Command "${trigger.name}" triggering outcome "${outcome.id}" (${path47}.command) does not exist in the inventory.`,
24515
- path: `${path47}.command`
24792
+ message: `Command "${trigger.name}" triggering outcome "${outcome.id}" (${path48}.command) does not exist in the inventory.`,
24793
+ path: `${path48}.command`
24516
24794
  });
24517
24795
  }
24518
24796
  }
@@ -24624,10 +24902,10 @@ var init_src4 = __esm({
24624
24902
  });
24625
24903
 
24626
24904
  // libs/mesh-cli/src/commands/workflow.ts
24627
- import * as fs39 from "fs";
24628
- import * as path46 from "path";
24905
+ import * as fs40 from "fs";
24906
+ import * as path47 from "path";
24629
24907
  import { createRequire as createRequire2 } from "module";
24630
- import { execFileSync as execFileSync32 } from "child_process";
24908
+ import { execFileSync as execFileSync33 } from "child_process";
24631
24909
  function resolveExtractorPath() {
24632
24910
  try {
24633
24911
  const require2 = createRequire2(import.meta.url);
@@ -24641,7 +24919,7 @@ function runExtraction(targetPath, extractorPath, explicitProcessPath) {
24641
24919
  let explicitProcessArtifact;
24642
24920
  if (explicitProcessPath) {
24643
24921
  try {
24644
- explicitProcessArtifact = JSON.parse(fs39.readFileSync(explicitProcessPath, "utf-8"));
24922
+ explicitProcessArtifact = JSON.parse(fs40.readFileSync(explicitProcessPath, "utf-8"));
24645
24923
  } catch (err) {
24646
24924
  logError(
24647
24925
  `Could not read/parse --process ${explicitProcessPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -24682,7 +24960,7 @@ for (const file of files) {
24682
24960
  process.stdout.write(JSON.stringify(results));
24683
24961
  `;
24684
24962
  try {
24685
- const result = execFileSync32("npx", ["tsx", "--eval", script], {
24963
+ const result = execFileSync33("npx", ["tsx", "--eval", script], {
24686
24964
  encoding: "utf-8",
24687
24965
  stdio: ["pipe", "pipe", "inherit"],
24688
24966
  maxBuffer: 10 * 1024 * 1024
@@ -24724,7 +25002,7 @@ for (const file of files) {
24724
25002
  process.stdout.write(JSON.stringify(results));
24725
25003
  `;
24726
25004
  try {
24727
- const result = execFileSync32("npx", ["tsx", "--eval", script], {
25005
+ const result = execFileSync33("npx", ["tsx", "--eval", script], {
24728
25006
  encoding: "utf-8",
24729
25007
  stdio: ["pipe", "pipe", "inherit"],
24730
25008
  maxBuffer: 10 * 1024 * 1024
@@ -24741,7 +25019,7 @@ function runLintExtraction(targetPath, extractorPath, explicitProcessPath) {
24741
25019
  let explicitProcessArtifact;
24742
25020
  if (explicitProcessPath) {
24743
25021
  try {
24744
- explicitProcessArtifact = JSON.parse(fs39.readFileSync(explicitProcessPath, "utf-8"));
25022
+ explicitProcessArtifact = JSON.parse(fs40.readFileSync(explicitProcessPath, "utf-8"));
24745
25023
  } catch (err) {
24746
25024
  logError(
24747
25025
  `Could not read/parse --process ${explicitProcessPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -24779,7 +25057,7 @@ for (const file of files) {
24779
25057
  process.stdout.write(JSON.stringify(results));
24780
25058
  `;
24781
25059
  try {
24782
- const result = execFileSync32("npx", ["tsx", "--eval", script], {
25060
+ const result = execFileSync33("npx", ["tsx", "--eval", script], {
24783
25061
  encoding: "utf-8",
24784
25062
  stdio: ["pipe", "pipe", "inherit"],
24785
25063
  maxBuffer: 10 * 1024 * 1024
@@ -24849,16 +25127,16 @@ function registerWorkflowCommands(program2) {
24849
25127
  ).action(
24850
25128
  async (targetPath, opts) => {
24851
25129
  try {
24852
- const resolvedPath = path46.resolve(targetPath);
24853
- if (!fs39.existsSync(resolvedPath)) {
25130
+ const resolvedPath = path47.resolve(targetPath);
25131
+ if (!fs40.existsSync(resolvedPath)) {
24854
25132
  logError(`Path does not exist: ${resolvedPath}`);
24855
25133
  process.exitCode = 1;
24856
25134
  return;
24857
25135
  }
24858
25136
  let resolvedProcessPath;
24859
25137
  if (opts.process) {
24860
- resolvedProcessPath = path46.resolve(opts.process);
24861
- if (!fs39.existsSync(resolvedProcessPath)) {
25138
+ resolvedProcessPath = path47.resolve(opts.process);
25139
+ if (!fs40.existsSync(resolvedProcessPath)) {
24862
25140
  logError(`--process path does not exist: ${resolvedProcessPath}`);
24863
25141
  process.exitCode = 1;
24864
25142
  return;
@@ -24907,8 +25185,8 @@ function registerWorkflowCommands(program2) {
24907
25185
  "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."
24908
25186
  ).action(async (targetPath) => {
24909
25187
  try {
24910
- const resolvedPath = path46.resolve(targetPath);
24911
- if (!fs39.existsSync(resolvedPath)) {
25188
+ const resolvedPath = path47.resolve(targetPath);
25189
+ if (!fs40.existsSync(resolvedPath)) {
24912
25190
  logError(`Path does not exist: ${resolvedPath}`);
24913
25191
  process.exitCode = 1;
24914
25192
  return;
@@ -24954,16 +25232,16 @@ function registerWorkflowCommands(program2) {
24954
25232
  "Comma-separated named-selector registry (enables UNKNOWN_SELECTOR checks)"
24955
25233
  ).action(async (targetPath, opts) => {
24956
25234
  try {
24957
- const resolvedPath = path46.resolve(targetPath);
24958
- if (!fs39.existsSync(resolvedPath)) {
25235
+ const resolvedPath = path47.resolve(targetPath);
25236
+ if (!fs40.existsSync(resolvedPath)) {
24959
25237
  logError(`Path does not exist: ${resolvedPath}`);
24960
25238
  process.exitCode = 1;
24961
25239
  return;
24962
25240
  }
24963
25241
  let resolvedProcessPath;
24964
25242
  if (opts.process) {
24965
- resolvedProcessPath = path46.resolve(opts.process);
24966
- if (!fs39.existsSync(resolvedProcessPath)) {
25243
+ resolvedProcessPath = path47.resolve(opts.process);
25244
+ if (!fs40.existsSync(resolvedProcessPath)) {
24967
25245
  logError(`--process path does not exist: ${resolvedProcessPath}`);
24968
25246
  process.exitCode = 1;
24969
25247
  return;