@mesh-tech/mesh-cli 0.34.4 → 0.35.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/assets/app-skill/SKILL.md +1 -1
- package/dist/bin/mesh.js +547 -178
- package/dist/bin/mesh.js.map +3 -3
- package/dist/build-info.json +2 -2
- package/dist/src/commands/cluster.js +2 -2
- package/dist/src/commands/dev.js +4 -2
- package/dist/src/commands/login.js +2 -2
- package/dist/src/commands/skills.d.ts +7 -2
- package/dist/src/commands/skills.js +84 -15
- package/dist/src/commands/stack-status.d.ts +65 -0
- package/dist/src/commands/stack-status.js +285 -0
- package/dist/src/commands/stack.js +15 -1
- package/dist/src/commands/temporal.js +28 -4
- package/dist/src/commands/temporal.js.map +1 -1
- package/dist/src/program.d.ts +1 -1
- package/dist/src/program.js +1 -1
- package/dist/src/utils/aws-auth.d.ts +1 -0
- package/dist/src/utils/aws-auth.js +10 -1
- package/dist/src/utils/first-party-contexts.d.ts +3 -0
- package/dist/src/utils/first-party-contexts.js +12 -0
- package/dist/src/utils/pulumi-run.d.ts +1 -1
- package/dist/src/utils/pulumi-run.js +16 -6
- package/fragments/base/index.ts.hbs +3 -2
- package/package.json +2 -2
- package/skills/{core → mesh}/SKILL.md +106 -100
- package/skills/mesh/references/programmatic-api.md +35 -0
- package/skills/mesh/references/worktrees.md +53 -0
- package/skills/pull-remote-agent-context/SKILL.md +1 -1
package/dist/bin/mesh.js
CHANGED
|
@@ -1712,8 +1712,10 @@ var init_stack = __esm({
|
|
|
1712
1712
|
var skills_exports = {};
|
|
1713
1713
|
__export(skills_exports, {
|
|
1714
1714
|
INTENT_RANGE: () => INTENT_RANGE,
|
|
1715
|
+
installedSkillName: () => installedSkillName,
|
|
1715
1716
|
listPackageSkills: () => listPackageSkills,
|
|
1716
1717
|
registerSkillsCommands: () => registerSkillsCommands,
|
|
1718
|
+
renderManagedSkill: () => renderManagedSkill,
|
|
1717
1719
|
resolveTargetRoot: () => resolveTargetRoot,
|
|
1718
1720
|
seedAppSkill: () => seedAppSkill,
|
|
1719
1721
|
syncSkills: () => syncSkills
|
|
@@ -1738,15 +1740,36 @@ function cliAsset(...segments) {
|
|
|
1738
1740
|
function listBaseSkills() {
|
|
1739
1741
|
const dir = cliAsset("skills");
|
|
1740
1742
|
if (!fs6.existsSync(dir)) return [];
|
|
1741
|
-
return fs6.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && fs6.existsSync(path6.join(dir, entry.name, "SKILL.md"))).map((entry) => ({
|
|
1743
|
+
return fs6.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && fs6.existsSync(path6.join(dir, entry.name, "SKILL.md"))).map((entry) => ({
|
|
1744
|
+
name: installedSkillName([entry.name]),
|
|
1745
|
+
// The CLI's own skill shipped as `skills/core/` and installed as `mesh-core/`.
|
|
1746
|
+
legacyName: entry.name === "mesh" ? "mesh-core" : `mesh-${entry.name}`,
|
|
1747
|
+
source: path6.join(dir, entry.name, "SKILL.md")
|
|
1748
|
+
}));
|
|
1749
|
+
}
|
|
1750
|
+
function installedSkillName(segments) {
|
|
1751
|
+
const parts = ["mesh"];
|
|
1752
|
+
for (const segment of segments) {
|
|
1753
|
+
if (segment === "core") continue;
|
|
1754
|
+
if (segment === parts[parts.length - 1]) continue;
|
|
1755
|
+
parts.push(segment);
|
|
1756
|
+
}
|
|
1757
|
+
return parts.join("-");
|
|
1742
1758
|
}
|
|
1743
|
-
function renderManagedSkill(source) {
|
|
1759
|
+
function renderManagedSkill(source, name) {
|
|
1744
1760
|
const raw = fs6.readFileSync(source, "utf-8");
|
|
1745
1761
|
const frontmatter = raw.match(/^(---\n[\s\S]*?\n---\n)/)?.[1];
|
|
1746
|
-
if (!frontmatter) return
|
|
1762
|
+
if (!frontmatter) return `---
|
|
1763
|
+
name: ${name}
|
|
1764
|
+
---
|
|
1765
|
+
|
|
1766
|
+
${MANAGED_MARKER}
|
|
1747
1767
|
|
|
1748
1768
|
${raw}`;
|
|
1749
|
-
|
|
1769
|
+
const named = /^name:.*$/m.test(frontmatter) ? frontmatter.replace(/^name:.*$/m, `name: ${name}`) : frontmatter.replace(/^---\n/, `---
|
|
1770
|
+
name: ${name}
|
|
1771
|
+
`);
|
|
1772
|
+
return `${named}
|
|
1750
1773
|
${MANAGED_MARKER}
|
|
1751
1774
|
${raw.slice(frontmatter.length)}`;
|
|
1752
1775
|
}
|
|
@@ -1785,13 +1808,31 @@ function listPackageSkills(root) {
|
|
|
1785
1808
|
for (const domain of fs6.readdirSync(skillsDir, { withFileTypes: true })) {
|
|
1786
1809
|
const source = path6.join(skillsDir, domain.name, "SKILL.md");
|
|
1787
1810
|
if (!fs6.existsSync(source)) continue;
|
|
1788
|
-
const name =
|
|
1789
|
-
if (!byName.has(name))
|
|
1811
|
+
const name = installedSkillName([pkg.name, domain.name]);
|
|
1812
|
+
if (!byName.has(name)) {
|
|
1813
|
+
byName.set(name, {
|
|
1814
|
+
name,
|
|
1815
|
+
legacyName: `mesh-${pkg.name}-${domain.name}`,
|
|
1816
|
+
dir: path6.join(skillsDir, domain.name),
|
|
1817
|
+
source
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1790
1820
|
}
|
|
1791
1821
|
}
|
|
1792
1822
|
}
|
|
1793
1823
|
return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
1794
1824
|
}
|
|
1825
|
+
function extrasInSync(sourceDir, targetDir) {
|
|
1826
|
+
for (const entry of fs6.readdirSync(sourceDir, { withFileTypes: true, recursive: true })) {
|
|
1827
|
+
if (!entry.isFile()) continue;
|
|
1828
|
+
const rel2 = path6.relative(sourceDir, path6.join(entry.parentPath, entry.name));
|
|
1829
|
+
if (rel2 === "SKILL.md") continue;
|
|
1830
|
+
const installed = path6.join(targetDir, rel2);
|
|
1831
|
+
if (!fs6.existsSync(installed)) return false;
|
|
1832
|
+
if (!fs6.readFileSync(installed).equals(fs6.readFileSync(path6.join(sourceDir, rel2)))) return false;
|
|
1833
|
+
}
|
|
1834
|
+
return true;
|
|
1835
|
+
}
|
|
1795
1836
|
function copySkillExtras(sourceDir, targetDir) {
|
|
1796
1837
|
for (const entry of fs6.readdirSync(sourceDir, { withFileTypes: true })) {
|
|
1797
1838
|
if (entry.name === "SKILL.md") continue;
|
|
@@ -1809,25 +1850,36 @@ function seedAppSkill(root, appName, appRelPath) {
|
|
|
1809
1850
|
}
|
|
1810
1851
|
function planSync(root) {
|
|
1811
1852
|
const items = [];
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
const
|
|
1815
|
-
const
|
|
1853
|
+
const baseSkills = listBaseSkills();
|
|
1854
|
+
for (const skill of baseSkills) {
|
|
1855
|
+
const targetDir = path6.join(root, ".claude", "skills", skill.name);
|
|
1856
|
+
const target = path6.join(targetDir, "SKILL.md");
|
|
1857
|
+
const sourceDir = path6.dirname(skill.source);
|
|
1858
|
+
const desired = renderManagedSkill(skill.source, skill.name);
|
|
1859
|
+
const label = `.claude/skills/${skill.name}/SKILL.md (base skill)`;
|
|
1816
1860
|
if (!fs6.existsSync(target)) {
|
|
1817
1861
|
items.push({
|
|
1818
1862
|
label,
|
|
1819
1863
|
state: "write",
|
|
1820
1864
|
apply: () => {
|
|
1821
|
-
fs6.mkdirSync(
|
|
1865
|
+
fs6.mkdirSync(targetDir, { recursive: true });
|
|
1822
1866
|
fs6.writeFileSync(target, desired);
|
|
1867
|
+
copySkillExtras(sourceDir, targetDir);
|
|
1823
1868
|
}
|
|
1824
1869
|
});
|
|
1825
1870
|
} else {
|
|
1826
1871
|
const current = fs6.readFileSync(target, "utf-8");
|
|
1827
|
-
if (current === desired) {
|
|
1872
|
+
if (current === desired && extrasInSync(sourceDir, targetDir)) {
|
|
1828
1873
|
items.push({ label, state: "ok" });
|
|
1829
1874
|
} else if (current.includes(MANAGED_MARKER)) {
|
|
1830
|
-
items.push({
|
|
1875
|
+
items.push({
|
|
1876
|
+
label,
|
|
1877
|
+
state: "write",
|
|
1878
|
+
apply: () => {
|
|
1879
|
+
fs6.writeFileSync(target, desired);
|
|
1880
|
+
copySkillExtras(sourceDir, targetDir);
|
|
1881
|
+
}
|
|
1882
|
+
});
|
|
1831
1883
|
} else {
|
|
1832
1884
|
items.push({ label: `${label} \u2014 exists without the managed marker, leaving as-is`, state: "skip" });
|
|
1833
1885
|
}
|
|
@@ -1837,7 +1889,7 @@ function planSync(root) {
|
|
|
1837
1889
|
for (const skill of packageSkills) {
|
|
1838
1890
|
const targetDir = path6.join(root, ".claude", "skills", skill.name);
|
|
1839
1891
|
const target = path6.join(targetDir, "SKILL.md");
|
|
1840
|
-
const desired = renderManagedSkill(skill.source);
|
|
1892
|
+
const desired = renderManagedSkill(skill.source, skill.name);
|
|
1841
1893
|
const label = `.claude/skills/${skill.name}/SKILL.md (platform skill)`;
|
|
1842
1894
|
if (!fs6.existsSync(target)) {
|
|
1843
1895
|
items.push({
|
|
@@ -1870,6 +1922,22 @@ function planSync(root) {
|
|
|
1870
1922
|
if (packageSkills.length === 0 && meshTechScopeDirs(root).length === 0) {
|
|
1871
1923
|
logInfo("No @mesh-tech packages installed yet \u2014 run `pnpm install`, then `mesh skills sync` again for the platform skills.");
|
|
1872
1924
|
}
|
|
1925
|
+
for (const skill of [...baseSkills, ...packageSkills]) {
|
|
1926
|
+
if (skill.legacyName === skill.name) continue;
|
|
1927
|
+
const legacyDir = path6.join(root, ".claude", "skills", skill.legacyName);
|
|
1928
|
+
const legacyFile = path6.join(legacyDir, "SKILL.md");
|
|
1929
|
+
if (!fs6.existsSync(legacyFile)) continue;
|
|
1930
|
+
const label = `.claude/skills/${skill.legacyName}/ (renamed to ${skill.name})`;
|
|
1931
|
+
if (fs6.readFileSync(legacyFile, "utf-8").includes(MANAGED_MARKER)) {
|
|
1932
|
+
items.push({
|
|
1933
|
+
label: `${label} \u2014 removing the old copy`,
|
|
1934
|
+
state: "write",
|
|
1935
|
+
apply: () => fs6.rmSync(legacyDir, { recursive: true, force: true })
|
|
1936
|
+
});
|
|
1937
|
+
} else {
|
|
1938
|
+
items.push({ label: `${label} \u2014 exists without the managed marker, leaving as-is`, state: "skip" });
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1873
1941
|
const hookSource = cliAsset("assets", "intent", "intent-claude-gate.mjs");
|
|
1874
1942
|
const hookTarget = path6.join(root, HOOK_RELATIVE);
|
|
1875
1943
|
const hookDesired = fs6.readFileSync(hookSource, "utf-8");
|
|
@@ -2260,12 +2328,19 @@ var init_app_check_resolve = __esm({
|
|
|
2260
2328
|
});
|
|
2261
2329
|
|
|
2262
2330
|
// packages/mesh-cli/src/utils/first-party-contexts.ts
|
|
2331
|
+
function loginContextForPlatform(platform) {
|
|
2332
|
+
if (!Object.hasOwn(FIRST_PARTY_PLATFORM_CONTEXTS, platform)) return platform;
|
|
2333
|
+
return FIRST_PARTY_PLATFORM_CONTEXTS[platform] || platform;
|
|
2334
|
+
}
|
|
2263
2335
|
function firstPartyDomainFor(context) {
|
|
2264
2336
|
if (!Object.hasOwn(FIRST_PARTY_CONTEXTS, context)) return null;
|
|
2265
2337
|
const domain = FIRST_PARTY_CONTEXTS[context];
|
|
2266
2338
|
return typeof domain === "string" && domain ? domain : null;
|
|
2267
2339
|
}
|
|
2268
|
-
|
|
2340
|
+
function isPlatformLoginAlias(context) {
|
|
2341
|
+
return Object.values(FIRST_PARTY_PLATFORM_CONTEXTS).includes(context);
|
|
2342
|
+
}
|
|
2343
|
+
var FIRST_PARTY_CONTEXTS, FIRST_PARTY_PLATFORM_CONTEXTS;
|
|
2269
2344
|
var init_first_party_contexts = __esm({
|
|
2270
2345
|
"packages/mesh-cli/src/utils/first-party-contexts.ts"() {
|
|
2271
2346
|
"use strict";
|
|
@@ -2276,7 +2351,15 @@ var init_first_party_contexts = __esm({
|
|
|
2276
2351
|
// platform lives in a different AWS account with no registry; the
|
|
2277
2352
|
// platform-dev stack in the registry-owning account is the developer front
|
|
2278
2353
|
// door. mesh-sandbox#32 / #3587.)
|
|
2279
|
-
"mesh.dev": "dev.platform.meshtech.io"
|
|
2354
|
+
"mesh.dev": "dev.platform.meshtech.io",
|
|
2355
|
+
// Verified 2026-09-25: https://cli.dev.mesh-platform.trabian.com/.well-known/mesh.json
|
|
2356
|
+
// answers anonymously with the `mesh` tenant's dev platform issuer
|
|
2357
|
+
// (identity.dev.mesh-platform.trabian.com) — the platform every `mesh`/dev
|
|
2358
|
+
// tenant environment and its `*-apps-deployer` role live on.
|
|
2359
|
+
"mesh-platform.dev": "dev.mesh-platform.trabian.com"
|
|
2360
|
+
});
|
|
2361
|
+
FIRST_PARTY_PLATFORM_CONTEXTS = Object.freeze({
|
|
2362
|
+
"mesh.dev": "mesh-platform.dev"
|
|
2280
2363
|
});
|
|
2281
2364
|
}
|
|
2282
2365
|
});
|
|
@@ -4091,11 +4174,11 @@ function readAllCredentials() {
|
|
|
4091
4174
|
function readCredentials(context) {
|
|
4092
4175
|
return readAllCredentials()[context] ?? null;
|
|
4093
4176
|
}
|
|
4094
|
-
function atomicWriteFileSync(
|
|
4095
|
-
const tmpPath = `${
|
|
4177
|
+
function atomicWriteFileSync(path50, data, mode) {
|
|
4178
|
+
const tmpPath = `${path50}.${process.pid}.${atomicWriteCounter++}.tmp`;
|
|
4096
4179
|
try {
|
|
4097
4180
|
fs11.writeFileSync(tmpPath, data, { mode });
|
|
4098
|
-
fs11.renameSync(tmpPath,
|
|
4181
|
+
fs11.renameSync(tmpPath, path50);
|
|
4099
4182
|
} catch (err) {
|
|
4100
4183
|
try {
|
|
4101
4184
|
fs11.unlinkSync(tmpPath);
|
|
@@ -4830,7 +4913,7 @@ async function ensureLogin(context, opts = {}) {
|
|
|
4830
4913
|
}
|
|
4831
4914
|
async function discoverConfigGuarded(context, opts = {}) {
|
|
4832
4915
|
let config = null;
|
|
4833
|
-
if (parseTenantEnv(context)) {
|
|
4916
|
+
if (parseTenantEnv(context) && !isPlatformLoginAlias(context)) {
|
|
4834
4917
|
config = await discoverConfigFromSsm(context, opts);
|
|
4835
4918
|
}
|
|
4836
4919
|
if (!config) {
|
|
@@ -5501,7 +5584,7 @@ import {
|
|
|
5501
5584
|
GetCallerIdentityCommand,
|
|
5502
5585
|
STSClient
|
|
5503
5586
|
} from "@aws-sdk/client-sts";
|
|
5504
|
-
function
|
|
5587
|
+
function readStackPlatform(appRoot, stack) {
|
|
5505
5588
|
const configFile = path13.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
5506
5589
|
if (!fs13.existsSync(configFile)) return null;
|
|
5507
5590
|
const content = fs13.readFileSync(configFile, "utf-8");
|
|
@@ -5520,6 +5603,12 @@ function derivePlatformContext(appRoot, stack) {
|
|
|
5520
5603
|
}
|
|
5521
5604
|
return null;
|
|
5522
5605
|
}
|
|
5606
|
+
function derivePlatformContext(appRoot, stack) {
|
|
5607
|
+
const explicit = readStackConfig(appRoot, stack, "mesh:loginContext");
|
|
5608
|
+
if (explicit) return explicit;
|
|
5609
|
+
const platform = readStackPlatform(appRoot, stack);
|
|
5610
|
+
return platform ? loginContextForPlatform(platform) : null;
|
|
5611
|
+
}
|
|
5523
5612
|
function quoteCredProcessToken(token) {
|
|
5524
5613
|
return /\s/.test(token) ? `"${token}"` : token;
|
|
5525
5614
|
}
|
|
@@ -5821,6 +5910,8 @@ var init_aws_auth = __esm({
|
|
|
5821
5910
|
init_log();
|
|
5822
5911
|
init_auth_preflight();
|
|
5823
5912
|
init_login();
|
|
5913
|
+
init_first_party_contexts();
|
|
5914
|
+
init_pulumi();
|
|
5824
5915
|
DEFAULT_REGION = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? "us-east-2";
|
|
5825
5916
|
MANAGED_START_PREFIX = `# >>> mesh-cli managed profile `;
|
|
5826
5917
|
MANAGED_START = (context) => `${MANAGED_START_PREFIX}${context} >>>`;
|
|
@@ -5871,7 +5962,9 @@ var init_vpn_join = __esm({
|
|
|
5871
5962
|
});
|
|
5872
5963
|
|
|
5873
5964
|
// packages/mesh-cli/src/utils/pulumi-run.ts
|
|
5874
|
-
function credProbeToPreflightError(probe, context) {
|
|
5965
|
+
function credProbeToPreflightError(probe, context, platform) {
|
|
5966
|
+
const aliasNote = platform && platform !== context && loginContextForPlatform(platform) === context ? `
|
|
5967
|
+
This stack deploys to platform ${platform}, which signs in as ${context} \u2014 a \`mesh login ${platform}\` session is a different platform and is not trusted here.` : "";
|
|
5875
5968
|
switch (probe.state) {
|
|
5876
5969
|
case "ok":
|
|
5877
5970
|
return null;
|
|
@@ -5879,19 +5972,21 @@ function credProbeToPreflightError(probe, context) {
|
|
|
5879
5972
|
return {
|
|
5880
5973
|
fatal: true,
|
|
5881
5974
|
message: `Not logged in for ${context}. Run:
|
|
5882
|
-
mesh login ${context} --device`
|
|
5975
|
+
mesh login ${context} --device` + aliasNote
|
|
5883
5976
|
};
|
|
5884
5977
|
case "expired-session":
|
|
5885
5978
|
return {
|
|
5886
5979
|
fatal: true,
|
|
5887
5980
|
message: `Your mesh login session for ${context} expired. Run:
|
|
5888
|
-
mesh login ${context} --device`
|
|
5981
|
+
mesh login ${context} --device` + aliasNote
|
|
5889
5982
|
};
|
|
5890
5983
|
case "assume-denied":
|
|
5891
5984
|
return {
|
|
5892
5985
|
fatal: true,
|
|
5893
5986
|
message: `Logged in, but couldn't assume the deployer role \u2014 ${probe.detail}
|
|
5894
|
-
|
|
5987
|
+
If you signed in to another platform, sign in to this stack's:
|
|
5988
|
+
mesh login ${context} --device
|
|
5989
|
+
Otherwise check mesh:deployerRole in the stack config and your IAM access.` + aliasNote
|
|
5895
5990
|
};
|
|
5896
5991
|
case "stale-env-override":
|
|
5897
5992
|
return {
|
|
@@ -5921,7 +6016,7 @@ async function resolvePulumiEnv(opts) {
|
|
|
5921
6016
|
const context = derivePlatformContext(appRoot, stack);
|
|
5922
6017
|
if (!hasAmbientCreds && context) {
|
|
5923
6018
|
const probe = await probeCredentials(context, roleArn);
|
|
5924
|
-
const preflight = credProbeToPreflightError(probe, context);
|
|
6019
|
+
const preflight = credProbeToPreflightError(probe, context, readStackPlatform(appRoot, stack));
|
|
5925
6020
|
if (preflight?.fatal) {
|
|
5926
6021
|
logError(preflight.message);
|
|
5927
6022
|
process.exit(1);
|
|
@@ -5945,6 +6040,7 @@ var init_pulumi_run = __esm({
|
|
|
5945
6040
|
init_log();
|
|
5946
6041
|
init_pulumi();
|
|
5947
6042
|
init_aws_auth();
|
|
6043
|
+
init_first_party_contexts();
|
|
5948
6044
|
init_login();
|
|
5949
6045
|
}
|
|
5950
6046
|
});
|
|
@@ -10780,7 +10876,7 @@ function registerDevCommand(program2) {
|
|
|
10780
10876
|
}
|
|
10781
10877
|
const resolved = deployerRole ? await resolveAwsCredentials(deployerRole, appRoot, stack) : null;
|
|
10782
10878
|
if (deployerRole && !resolved && !process.env.AWS_ACCESS_KEY_ID) {
|
|
10783
|
-
const pf = ctx ? credProbeToPreflightError(await probeCredentials(ctx, deployerRole), ctx) : null;
|
|
10879
|
+
const pf = ctx ? credProbeToPreflightError(await probeCredentials(ctx, deployerRole), ctx, readStackPlatform(appRoot, stack)) : null;
|
|
10784
10880
|
logError(
|
|
10785
10881
|
pf?.message ?? `Couldn't resolve AWS credentials to restart '${service}'. Run: mesh login ${ctx ?? "mesh.dev"} --device`
|
|
10786
10882
|
);
|
|
@@ -12873,11 +12969,11 @@ function createVcsFolderReader(opts) {
|
|
|
12873
12969
|
}
|
|
12874
12970
|
return p;
|
|
12875
12971
|
};
|
|
12876
|
-
const readPath = async (repo,
|
|
12972
|
+
const readPath = async (repo, path50) => {
|
|
12877
12973
|
const dir = await cloneRepo(repo);
|
|
12878
|
-
const ref = await resolveFolderRef(dir,
|
|
12879
|
-
if (!ref) throw new Error(`path "${
|
|
12880
|
-
const files = await readFolderAtRef(dir, ref,
|
|
12974
|
+
const ref = await resolveFolderRef(dir, path50);
|
|
12975
|
+
if (!ref) throw new Error(`path "${path50}" not found on any ref of ${repo}`);
|
|
12976
|
+
const files = await readFolderAtRef(dir, ref, path50);
|
|
12881
12977
|
return { ref, files };
|
|
12882
12978
|
};
|
|
12883
12979
|
const cleanup = async () => {
|
|
@@ -13197,7 +13293,7 @@ Use --stack <name> (the deployed stack, e.g. dev).` : "No stack configs found in
|
|
|
13197
13293
|
const ctx = derivePlatformContext(appRoot, stack);
|
|
13198
13294
|
const resolved = deployerRole ? await resolveAwsCredentials(deployerRole, appRoot, stack) : null;
|
|
13199
13295
|
if (deployerRole && !resolved && !process.env.AWS_ACCESS_KEY_ID) {
|
|
13200
|
-
const pf = ctx ? credProbeToPreflightError(await probeCredentials(ctx, deployerRole), ctx) : null;
|
|
13296
|
+
const pf = ctx ? credProbeToPreflightError(await probeCredentials(ctx, deployerRole), ctx, readStackPlatform(appRoot, stack)) : null;
|
|
13201
13297
|
throw new Error(
|
|
13202
13298
|
pf?.message ?? `Couldn't resolve AWS credentials. Run: mesh login ${ctx ?? "mesh.dev"} --device`
|
|
13203
13299
|
);
|
|
@@ -15252,7 +15348,7 @@ var init_discover = __esm({
|
|
|
15252
15348
|
|
|
15253
15349
|
// packages/mesh-cli/src/docs/assemble.ts
|
|
15254
15350
|
import { execFileSync as execFileSync20 } from "node:child_process";
|
|
15255
|
-
import { mkdirSync as mkdirSync12, readFileSync as readFileSync25, rmSync as
|
|
15351
|
+
import { mkdirSync as mkdirSync12, readFileSync as readFileSync25, rmSync as rmSync6, writeFileSync as writeFileSync15 } from "node:fs";
|
|
15256
15352
|
import path30 from "node:path";
|
|
15257
15353
|
import { parse as parseYaml5 } from "yaml";
|
|
15258
15354
|
function splitFrontMatter(markdown) {
|
|
@@ -15534,7 +15630,7 @@ function assemblePortal(options) {
|
|
|
15534
15630
|
const routes = new Set(pages.map((p) => p.route));
|
|
15535
15631
|
const brokenLinks = [];
|
|
15536
15632
|
const externalLinks = [];
|
|
15537
|
-
|
|
15633
|
+
rmSync6(outDir, { recursive: true, force: true });
|
|
15538
15634
|
mkdirSync12(outDir, { recursive: true });
|
|
15539
15635
|
for (const page of pages) {
|
|
15540
15636
|
const raw = readFileSync25(path30.join(repoRoot2, page.source), "utf-8");
|
|
@@ -15872,8 +15968,8 @@ function formatDefault(value, paths = currentMachinePaths()) {
|
|
|
15872
15968
|
if (typeof value === "boolean" || typeof value === "number") return String(value);
|
|
15873
15969
|
return normalizeMachinePaths(JSON.stringify(value), paths);
|
|
15874
15970
|
}
|
|
15875
|
-
function slugifyCommandPath(
|
|
15876
|
-
return
|
|
15971
|
+
function slugifyCommandPath(path50) {
|
|
15972
|
+
return path50.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15877
15973
|
}
|
|
15878
15974
|
function extractOptions(command) {
|
|
15879
15975
|
const options = command.options ?? [];
|
|
@@ -15907,17 +16003,17 @@ function isUndocumented(command) {
|
|
|
15907
16003
|
function extractCommand(command, parentPath, depth) {
|
|
15908
16004
|
const internals = command;
|
|
15909
16005
|
const name = internals._name ?? "";
|
|
15910
|
-
const
|
|
16006
|
+
const path50 = parentPath ? `${parentPath} ${name}` : name;
|
|
15911
16007
|
return {
|
|
15912
|
-
path:
|
|
16008
|
+
path: path50,
|
|
15913
16009
|
name,
|
|
15914
16010
|
aliases: [...internals._aliases ?? []],
|
|
15915
16011
|
description: internals._description ?? "",
|
|
15916
16012
|
args: extractArgs(command),
|
|
15917
16013
|
options: extractOptions(command),
|
|
15918
|
-
slug: slugifyCommandPath(
|
|
16014
|
+
slug: slugifyCommandPath(path50),
|
|
15919
16015
|
depth,
|
|
15920
|
-
subcommands: (internals.commands ?? []).filter((child) => !isUndocumented(child)).map((child) => extractCommand(child,
|
|
16016
|
+
subcommands: (internals.commands ?? []).filter((child) => !isUndocumented(child)).map((child) => extractCommand(child, path50, depth + 1))
|
|
15921
16017
|
};
|
|
15922
16018
|
}
|
|
15923
16019
|
function extractCliReference(program2) {
|
|
@@ -16405,7 +16501,7 @@ var init_serve = __esm({
|
|
|
16405
16501
|
|
|
16406
16502
|
// packages/mesh-cli/src/docs/registry-docs.ts
|
|
16407
16503
|
import { execFileSync as execFileSync22 } from "node:child_process";
|
|
16408
|
-
import { existsSync as existsSync25, mkdirSync as mkdirSync14, readFileSync as readFileSync28, renameSync as renameSync3, rmSync as
|
|
16504
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync14, readFileSync as readFileSync28, renameSync as renameSync3, rmSync as rmSync7, writeFileSync as writeFileSync17 } from "node:fs";
|
|
16409
16505
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
16410
16506
|
import path33 from "node:path";
|
|
16411
16507
|
function readDocsRegistryAuth(npmrcPath2 = homeNpmrcPath()) {
|
|
@@ -16493,20 +16589,20 @@ async function fetchDocsArtifact(auth, version, cacheRoot = docsCacheRoot(), fet
|
|
|
16493
16589
|
const tgzPath = path33.join(cacheRoot, `.${version}.tgz`);
|
|
16494
16590
|
writeFileSync17(tgzPath, Buffer.from(await tgzResponse.arrayBuffer()));
|
|
16495
16591
|
const staging = path33.join(cacheRoot, `.staging-${version}`);
|
|
16496
|
-
|
|
16592
|
+
rmSync7(staging, { recursive: true, force: true });
|
|
16497
16593
|
mkdirSync14(staging, { recursive: true });
|
|
16498
16594
|
try {
|
|
16499
16595
|
execFileSync22("tar", ["-xzf", tgzPath, "-C", staging, "--strip-components", "1"], {
|
|
16500
16596
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16501
16597
|
});
|
|
16502
16598
|
} finally {
|
|
16503
|
-
|
|
16599
|
+
rmSync7(tgzPath, { force: true });
|
|
16504
16600
|
}
|
|
16505
16601
|
if (!existsSync25(path33.join(staging, "dist", "index.html"))) {
|
|
16506
|
-
|
|
16602
|
+
rmSync7(staging, { recursive: true, force: true });
|
|
16507
16603
|
throw new Error(`${DOCS_PACKAGE}@${version} unpacked without a dist/index.html \u2014 the artifact is malformed`);
|
|
16508
16604
|
}
|
|
16509
|
-
|
|
16605
|
+
rmSync7(targetDir, { recursive: true, force: true });
|
|
16510
16606
|
renameSync3(staging, targetDir);
|
|
16511
16607
|
return targetDir;
|
|
16512
16608
|
}
|
|
@@ -21458,24 +21554,290 @@ var init_site = __esm({
|
|
|
21458
21554
|
}
|
|
21459
21555
|
});
|
|
21460
21556
|
|
|
21461
|
-
// packages/mesh-cli/src/commands/stack.ts
|
|
21462
|
-
import { execFileSync as execFileSync31 } from "child_process";
|
|
21463
|
-
import * as path45 from "path";
|
|
21557
|
+
// packages/mesh-cli/src/commands/stack-status.ts
|
|
21464
21558
|
import * as fs38 from "fs";
|
|
21559
|
+
import * as path45 from "path";
|
|
21560
|
+
import { execFileSync as execFileSync31 } from "child_process";
|
|
21561
|
+
function splitLayerStack(stack, tenant) {
|
|
21562
|
+
if (tenant && stack.startsWith(`${tenant}-`)) return { tenant, env: stack.slice(tenant.length + 1) };
|
|
21563
|
+
const cut = stack.indexOf("-");
|
|
21564
|
+
if (cut <= 0) return { tenant: tenant ?? stack, env: stack };
|
|
21565
|
+
return { tenant: tenant ?? stack.slice(0, cut), env: stack.slice(cut + 1) };
|
|
21566
|
+
}
|
|
21567
|
+
function targetForStack(projectDir, stack) {
|
|
21568
|
+
const platform = readStackPlatform(projectDir, stack);
|
|
21569
|
+
if (platform) {
|
|
21570
|
+
const [tenant2, env2] = platform.split(".");
|
|
21571
|
+
return { stack, kind: "app", tenant: tenant2, env: env2, coreTenant: tenant2, coreEnv: env2 };
|
|
21572
|
+
}
|
|
21573
|
+
const declared = readStackConfig(projectDir, stack, "mesh:tenant");
|
|
21574
|
+
const layerDir = ["core", "platform"].includes(path45.basename(projectDir));
|
|
21575
|
+
if (!declared && !layerDir) return null;
|
|
21576
|
+
const { tenant, env } = splitLayerStack(stack, declared);
|
|
21577
|
+
const isCore = path45.basename(projectDir) === "core";
|
|
21578
|
+
return {
|
|
21579
|
+
stack,
|
|
21580
|
+
kind: "layer",
|
|
21581
|
+
tenant,
|
|
21582
|
+
env,
|
|
21583
|
+
coreTenant: readStackConfig(projectDir, stack, "mesh:coreTenant") ?? tenant,
|
|
21584
|
+
coreEnv: readStackConfig(projectDir, stack, "mesh:coreEnv") ?? env,
|
|
21585
|
+
...isCore ? { coreDir: projectDir } : { platformDir: projectDir }
|
|
21586
|
+
};
|
|
21587
|
+
}
|
|
21588
|
+
function findStatusTargets(cwd, stack) {
|
|
21589
|
+
const project = findAppRoot(cwd);
|
|
21590
|
+
let projectDir = project;
|
|
21591
|
+
let repoRoot2 = null;
|
|
21592
|
+
if (!projectDir) {
|
|
21593
|
+
const platformDir = path45.join(cwd, "platform");
|
|
21594
|
+
if (fs38.existsSync(path45.join(platformDir, "Pulumi.yaml"))) {
|
|
21595
|
+
projectDir = platformDir;
|
|
21596
|
+
repoRoot2 = cwd;
|
|
21597
|
+
}
|
|
21598
|
+
} else if (["core", "platform"].includes(path45.basename(projectDir))) {
|
|
21599
|
+
repoRoot2 = path45.dirname(projectDir);
|
|
21600
|
+
}
|
|
21601
|
+
if (!projectDir) return [];
|
|
21602
|
+
const stacks = stack ? [stack] : findStackConfigs(projectDir);
|
|
21603
|
+
const targets = [];
|
|
21604
|
+
for (const name of stacks) {
|
|
21605
|
+
const target = targetForStack(projectDir, name);
|
|
21606
|
+
if (!target) continue;
|
|
21607
|
+
if (repoRoot2 && target.kind === "layer") {
|
|
21608
|
+
const core = path45.join(repoRoot2, "core");
|
|
21609
|
+
const platform = path45.join(repoRoot2, "platform");
|
|
21610
|
+
if (fs38.existsSync(path45.join(core, "package.json"))) target.coreDir = core;
|
|
21611
|
+
if (fs38.existsSync(path45.join(platform, "package.json"))) target.platformDir = platform;
|
|
21612
|
+
}
|
|
21613
|
+
targets.push(target);
|
|
21614
|
+
}
|
|
21615
|
+
return targets;
|
|
21616
|
+
}
|
|
21617
|
+
function pinnedVersion(dir, pkg) {
|
|
21618
|
+
if (!dir) return null;
|
|
21619
|
+
try {
|
|
21620
|
+
const manifest = JSON.parse(fs38.readFileSync(path45.join(dir, "package.json"), "utf-8"));
|
|
21621
|
+
const spec = manifest.dependencies?.[pkg] ?? manifest.devDependencies?.[pkg];
|
|
21622
|
+
return typeof spec === "string" ? spec.replace(/^[\^~=v]+/, "") : null;
|
|
21623
|
+
} catch {
|
|
21624
|
+
return null;
|
|
21625
|
+
}
|
|
21626
|
+
}
|
|
21627
|
+
function compareVersions2(a, b) {
|
|
21628
|
+
const parse4 = (v) => v.split(/[.+-]/).slice(0, 3).map((n) => Number.parseInt(n, 10) || 0);
|
|
21629
|
+
const [x, y] = [parse4(a), parse4(b)];
|
|
21630
|
+
for (let i = 0; i < 3; i++) {
|
|
21631
|
+
const diff = (x[i] ?? 0) - (y[i] ?? 0);
|
|
21632
|
+
if (diff) return diff;
|
|
21633
|
+
}
|
|
21634
|
+
return 0;
|
|
21635
|
+
}
|
|
21636
|
+
function layerState(deployed, latest) {
|
|
21637
|
+
if (!deployed) return "not-deployed";
|
|
21638
|
+
if (!latest) return "unknown";
|
|
21639
|
+
return compareVersions2(deployed, latest) < 0 ? "behind" : "current";
|
|
21640
|
+
}
|
|
21641
|
+
function parseRegistration(raw) {
|
|
21642
|
+
try {
|
|
21643
|
+
const data = JSON.parse(raw);
|
|
21644
|
+
const out = {};
|
|
21645
|
+
if (typeof data.build?.infraVersion === "string") out.infraVersion = data.build.infraVersion;
|
|
21646
|
+
if (typeof data.hub?.hubVersion === "string") out.hubVersion = data.hub.hubVersion;
|
|
21647
|
+
return out;
|
|
21648
|
+
} catch {
|
|
21649
|
+
return {};
|
|
21650
|
+
}
|
|
21651
|
+
}
|
|
21652
|
+
function buildRows(target, deployed, latest) {
|
|
21653
|
+
const corePath = `/mesh-platform/${target.coreTenant}/${target.coreEnv}/core`;
|
|
21654
|
+
const platformPath = `/mesh-platform/${target.tenant}/${target.env}/platform`;
|
|
21655
|
+
const row = (layer, registration, source, field, pinned, latestVersion) => {
|
|
21656
|
+
const value = source && !(source instanceof Error) ? source[field] ?? null : null;
|
|
21657
|
+
const predatesExport = !!source && !(source instanceof Error) && value === null;
|
|
21658
|
+
const note = source instanceof Error ? source.message : source === null ? "no registration \u2014 never deployed, or not readable with these credentials" : predatesExport ? "registration predates version export \u2014 last deployed with an infra-components older than any current release" : void 0;
|
|
21659
|
+
return {
|
|
21660
|
+
layer,
|
|
21661
|
+
registration,
|
|
21662
|
+
pinned,
|
|
21663
|
+
deployed: value,
|
|
21664
|
+
latest: latestVersion,
|
|
21665
|
+
state: source instanceof Error ? "unknown" : predatesExport ? "behind" : layerState(value, latestVersion),
|
|
21666
|
+
undeployedPin: !!pinned && !!value && pinned !== value,
|
|
21667
|
+
...note ? { note } : {}
|
|
21668
|
+
};
|
|
21669
|
+
};
|
|
21670
|
+
return [
|
|
21671
|
+
row("core", corePath, deployed.core, "infraVersion", pinnedVersion(target.coreDir, INFRA_PACKAGE), latest.infra),
|
|
21672
|
+
row(
|
|
21673
|
+
"platform",
|
|
21674
|
+
platformPath,
|
|
21675
|
+
deployed.platform,
|
|
21676
|
+
"infraVersion",
|
|
21677
|
+
pinnedVersion(target.platformDir, INFRA_PACKAGE),
|
|
21678
|
+
latest.infra
|
|
21679
|
+
),
|
|
21680
|
+
row("hub", platformPath, deployed.platform, "hubVersion", pinnedVersion(target.platformDir, HUB_PACKAGE2), latest.hub)
|
|
21681
|
+
];
|
|
21682
|
+
}
|
|
21683
|
+
function renderStatus(reports, cli) {
|
|
21684
|
+
const lines = [];
|
|
21685
|
+
const show = (v) => v ?? "\u2014";
|
|
21686
|
+
for (const { target, rows } of reports) {
|
|
21687
|
+
const what = target.kind === "app" ? `App stack ${target.stack} \u2192 platform ${target.tenant}/${target.env}` : `Platform ${target.tenant}/${target.env} (stack ${target.stack}) on core ${target.coreTenant}/${target.coreEnv}`;
|
|
21688
|
+
lines.push(what);
|
|
21689
|
+
lines.push(` ${"layer".padEnd(9)} ${"pinned".padEnd(10)} ${"deployed".padEnd(10)} ${"latest".padEnd(10)} state`);
|
|
21690
|
+
for (const r of rows) {
|
|
21691
|
+
const flag = r.undeployedPin ? " (pin not deployed)" : "";
|
|
21692
|
+
lines.push(
|
|
21693
|
+
` ${r.layer.padEnd(9)} ${show(r.pinned).padEnd(10)} ${show(r.deployed).padEnd(10)} ${show(r.latest).padEnd(10)} ${r.state}${flag}`
|
|
21694
|
+
);
|
|
21695
|
+
if (r.note) lines.push(` ${r.registration}: ${r.note}`);
|
|
21696
|
+
}
|
|
21697
|
+
if (rows.some((r) => r.state === "behind" || r.undeployedPin)) {
|
|
21698
|
+
lines.push(...upgradeSteps(target, rows));
|
|
21699
|
+
}
|
|
21700
|
+
lines.push("");
|
|
21701
|
+
}
|
|
21702
|
+
lines.push(
|
|
21703
|
+
`CLI ${CLI_PACKAGE} ${cli.running}` + (cli.latest ? ` (latest ${cli.latest})${cli.behind ? " \u2014 behind: pnpm add -D @mesh-tech/mesh-cli@latest" : ""}` : " (latest unknown)")
|
|
21704
|
+
);
|
|
21705
|
+
return lines.join("\n");
|
|
21706
|
+
}
|
|
21707
|
+
function upgradeSteps(target, rows) {
|
|
21708
|
+
const latest = rows.find((r) => r.latest)?.latest;
|
|
21709
|
+
if (target.kind === "app") {
|
|
21710
|
+
return [
|
|
21711
|
+
" This platform is behind. Its operator upgrades it from the org's platform repo:",
|
|
21712
|
+
" run `mesh stack status` there, then upgrade core and platform together."
|
|
21713
|
+
];
|
|
21714
|
+
}
|
|
21715
|
+
const to = latest ? `@${latest}` : "@latest";
|
|
21716
|
+
return [
|
|
21717
|
+
" To upgrade (both layers \u2014 deploying platform/ alone leaves core on the old version):",
|
|
21718
|
+
` 1. core/ and platform/: set ${INFRA_PACKAGE}${to} (and ${HUB_PACKAGE2}${to} in platform/), then pnpm install`,
|
|
21719
|
+
` 2. cd core && mesh deploy preview --stack ${target.coreTenant}-${target.coreEnv} # review: this layer is the VPC/EKS/RDS`,
|
|
21720
|
+
` 3. mesh deploy up --stack ${target.coreTenant}-${target.coreEnv} && cd ../platform && mesh deploy up --stack ${target.stack}`,
|
|
21721
|
+
" 4. mesh stack status # both layers now report the new version"
|
|
21722
|
+
];
|
|
21723
|
+
}
|
|
21724
|
+
function latestPublished(pkg, cwd) {
|
|
21725
|
+
try {
|
|
21726
|
+
const out = execFileSync31("npm", ["view", pkg, "version"], {
|
|
21727
|
+
cwd,
|
|
21728
|
+
encoding: "utf-8",
|
|
21729
|
+
timeout: 2e4,
|
|
21730
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
21731
|
+
}).trim();
|
|
21732
|
+
return /^\d+\.\d+\.\d+$/.test(out) ? out : null;
|
|
21733
|
+
} catch {
|
|
21734
|
+
return null;
|
|
21735
|
+
}
|
|
21736
|
+
}
|
|
21737
|
+
async function readRegistration(name, region, auth) {
|
|
21738
|
+
const { credentials, profile, signInHint } = auth;
|
|
21739
|
+
try {
|
|
21740
|
+
const { SSMClient: SSMClient5, GetParameterCommand: GetParameterCommand2 } = await import("@aws-sdk/client-ssm");
|
|
21741
|
+
const client = new SSMClient5({
|
|
21742
|
+
region,
|
|
21743
|
+
...profile && !credentials?.AWS_ACCESS_KEY_ID ? { profile } : {},
|
|
21744
|
+
...credentials?.AWS_ACCESS_KEY_ID ? {
|
|
21745
|
+
credentials: {
|
|
21746
|
+
accessKeyId: credentials.AWS_ACCESS_KEY_ID,
|
|
21747
|
+
secretAccessKey: credentials.AWS_SECRET_ACCESS_KEY ?? "",
|
|
21748
|
+
sessionToken: credentials.AWS_SESSION_TOKEN
|
|
21749
|
+
}
|
|
21750
|
+
} : {}
|
|
21751
|
+
});
|
|
21752
|
+
const resp = await client.send(new GetParameterCommand2({ Name: name }));
|
|
21753
|
+
return resp.Parameter?.Value ? parseRegistration(resp.Parameter.Value) : null;
|
|
21754
|
+
} catch (err) {
|
|
21755
|
+
const e = err;
|
|
21756
|
+
const kind = e.name || e.__type || e.message || String(err);
|
|
21757
|
+
if (/ParameterNotFound/.test(kind)) return null;
|
|
21758
|
+
if (/credential|ExpiredToken|AccessDenied|UnrecognizedClient|security token/i.test(`${kind} ${e.message ?? ""}`)) {
|
|
21759
|
+
return new Error(`could not read \u2014 no AWS credentials for this account (${signInHint})`);
|
|
21760
|
+
}
|
|
21761
|
+
return new Error(`could not read \u2014 ${e.message ?? kind}`);
|
|
21762
|
+
}
|
|
21763
|
+
}
|
|
21764
|
+
async function runStackStatus(cwd, opts) {
|
|
21765
|
+
const targets = findStatusTargets(cwd, opts.stack);
|
|
21766
|
+
if (targets.length === 0) {
|
|
21767
|
+
logWarn(
|
|
21768
|
+
"No Mesh stack found here. Run from an app directory (a Pulumi.<stack>.yaml naming mesh:platform),\n or from your org's Mesh platform repo (its root, core/ or platform/)."
|
|
21769
|
+
);
|
|
21770
|
+
return true;
|
|
21771
|
+
}
|
|
21772
|
+
const infraLatest = latestPublished(INFRA_PACKAGE, cwd);
|
|
21773
|
+
const hubLatest = latestPublished(HUB_PACKAGE2, cwd);
|
|
21774
|
+
const running = resolveCliRuntime({ vcs: false }).version;
|
|
21775
|
+
const cliLatest = latestPublished(CLI_PACKAGE, cwd);
|
|
21776
|
+
const cli = { running, latest: cliLatest, behind: !!cliLatest && compareVersions2(running, cliLatest) < 0 };
|
|
21777
|
+
if (!infraLatest) logInfo("Registry lookup failed \u2014 `latest` is unknown. Run `mesh registry login` and retry.");
|
|
21778
|
+
const reports = [];
|
|
21779
|
+
for (const target of targets) {
|
|
21780
|
+
const projectDir = findAppRoot(cwd) ?? target.platformDir ?? cwd;
|
|
21781
|
+
const region = opts.region ?? readStackConfig(projectDir, target.stack, "aws:region") ?? "us-east-2";
|
|
21782
|
+
const ambient = !!process.env.AWS_ACCESS_KEY_ID || !!process.env.AWS_PROFILE;
|
|
21783
|
+
let profile = opts.profile;
|
|
21784
|
+
let credentials;
|
|
21785
|
+
if (!profile && !ambient) {
|
|
21786
|
+
profile = readStackConfig(projectDir, target.stack, "aws:profile") ?? void 0;
|
|
21787
|
+
if (!profile && target.kind === "app") {
|
|
21788
|
+
const role = readStackConfig(projectDir, target.stack, "mesh:deployerRole");
|
|
21789
|
+
if (role) credentials = (await resolveAwsCredentials(role, projectDir, target.stack))?.env;
|
|
21790
|
+
}
|
|
21791
|
+
}
|
|
21792
|
+
const loginContext = target.kind === "app" ? derivePlatformContext(projectDir, target.stack) : null;
|
|
21793
|
+
const signInHint = loginContext ? `sign in with \`mesh login ${loginContext} --device\`, or pass --profile` : "set AWS_PROFILE or pass --profile with access to the core's account";
|
|
21794
|
+
const auth = { credentials, profile, signInHint };
|
|
21795
|
+
const [core, platform] = await Promise.all([
|
|
21796
|
+
readRegistration(`/mesh-platform/${target.coreTenant}/${target.coreEnv}/core`, region, auth),
|
|
21797
|
+
readRegistration(`/mesh-platform/${target.tenant}/${target.env}/platform`, region, auth)
|
|
21798
|
+
]);
|
|
21799
|
+
reports.push({ target, rows: buildRows(target, { core, platform }, { infra: infraLatest, hub: hubLatest }) });
|
|
21800
|
+
}
|
|
21801
|
+
if (opts.json) {
|
|
21802
|
+
process.stdout.write(JSON.stringify({ platforms: reports, cli }, null, 2) + "\n");
|
|
21803
|
+
} else {
|
|
21804
|
+
process.stdout.write(renderStatus(reports, cli) + "\n");
|
|
21805
|
+
}
|
|
21806
|
+
const behind = cli.behind || reports.some((r) => r.rows.some((row) => row.state === "behind" || row.undeployedPin));
|
|
21807
|
+
return !behind;
|
|
21808
|
+
}
|
|
21809
|
+
var INFRA_PACKAGE, HUB_PACKAGE2, CLI_PACKAGE;
|
|
21810
|
+
var init_stack_status = __esm({
|
|
21811
|
+
"packages/mesh-cli/src/commands/stack-status.ts"() {
|
|
21812
|
+
"use strict";
|
|
21813
|
+
init_log();
|
|
21814
|
+
init_pulumi();
|
|
21815
|
+
init_aws_auth();
|
|
21816
|
+
init_build_info();
|
|
21817
|
+
INFRA_PACKAGE = "@mesh-tech/infra-components";
|
|
21818
|
+
HUB_PACKAGE2 = "@mesh-tech/hub";
|
|
21819
|
+
CLI_PACKAGE = "@mesh-tech/mesh-cli";
|
|
21820
|
+
}
|
|
21821
|
+
});
|
|
21822
|
+
|
|
21823
|
+
// packages/mesh-cli/src/commands/stack.ts
|
|
21824
|
+
import { execFileSync as execFileSync32 } from "child_process";
|
|
21825
|
+
import * as path46 from "path";
|
|
21826
|
+
import * as fs39 from "fs";
|
|
21465
21827
|
import { parse as parseYaml6 } from "yaml";
|
|
21466
21828
|
function readTopLevelYamlKey(appRoot, stack, key) {
|
|
21467
|
-
const configFile =
|
|
21468
|
-
if (!
|
|
21469
|
-
const content =
|
|
21829
|
+
const configFile = path46.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
21830
|
+
if (!fs39.existsSync(configFile)) return null;
|
|
21831
|
+
const content = fs39.readFileSync(configFile, "utf-8");
|
|
21470
21832
|
const pattern = new RegExp(`^${key}:\\s*(.+)$`, "m");
|
|
21471
21833
|
const match = content.match(pattern);
|
|
21472
21834
|
if (!match) return null;
|
|
21473
21835
|
return match[1].trim().replace(/^["']|["']$/g, "");
|
|
21474
21836
|
}
|
|
21475
21837
|
function readConfigBlockKey(appRoot, stack, key) {
|
|
21476
|
-
const configFile =
|
|
21477
|
-
if (!
|
|
21478
|
-
const content =
|
|
21838
|
+
const configFile = path46.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
21839
|
+
if (!fs39.existsSync(configFile)) return null;
|
|
21840
|
+
const content = fs39.readFileSync(configFile, "utf-8");
|
|
21479
21841
|
const pattern = new RegExp(`^\\s{2}${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}:\\s*(.+)$`, "m");
|
|
21480
21842
|
const match = content.match(pattern);
|
|
21481
21843
|
if (!match) return null;
|
|
@@ -21535,11 +21897,11 @@ ${records}
|
|
|
21535
21897
|
}
|
|
21536
21898
|
}
|
|
21537
21899
|
function readBaseConfigFromYaml(appRoot, stack) {
|
|
21538
|
-
const file =
|
|
21539
|
-
if (!
|
|
21900
|
+
const file = path46.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
21901
|
+
if (!fs39.existsSync(file)) return {};
|
|
21540
21902
|
let doc;
|
|
21541
21903
|
try {
|
|
21542
|
-
doc = parseYaml6(
|
|
21904
|
+
doc = parseYaml6(fs39.readFileSync(file, "utf-8"));
|
|
21543
21905
|
} catch {
|
|
21544
21906
|
return {};
|
|
21545
21907
|
}
|
|
@@ -21552,7 +21914,7 @@ function readBaseConfigFromYaml(appRoot, stack) {
|
|
|
21552
21914
|
}
|
|
21553
21915
|
function getGitHubUsername() {
|
|
21554
21916
|
try {
|
|
21555
|
-
const result =
|
|
21917
|
+
const result = execFileSync32("gh", ["api", "user", "--jq", ".login"], {
|
|
21556
21918
|
encoding: "utf-8",
|
|
21557
21919
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21558
21920
|
});
|
|
@@ -21561,7 +21923,7 @@ function getGitHubUsername() {
|
|
|
21561
21923
|
} catch {
|
|
21562
21924
|
}
|
|
21563
21925
|
try {
|
|
21564
|
-
const result =
|
|
21926
|
+
const result = execFileSync32("git", ["config", "user.email"], {
|
|
21565
21927
|
encoding: "utf-8",
|
|
21566
21928
|
stdio: ["pipe", "pipe", "pipe"]
|
|
21567
21929
|
});
|
|
@@ -21573,7 +21935,7 @@ function getGitHubUsername() {
|
|
|
21573
21935
|
return null;
|
|
21574
21936
|
}
|
|
21575
21937
|
function registerStackCommand(program2) {
|
|
21576
|
-
const stack = program2.command("stack").description("Manage personal Pulumi stacks");
|
|
21938
|
+
const stack = program2.command("stack").description("Manage personal Pulumi stacks and check a Mesh instance against the latest release");
|
|
21577
21939
|
stack.command("init").description("Create a personal dev stack (dev-{github-username})").option("--from <stack>", "Base stack to copy config from").option("--name <name>", "Override stack name (default: dev-{username})").option("--adopt", "resume an EXISTING stack with this name (skips the availability check)", false).option(
|
|
21578
21940
|
"--worktree",
|
|
21579
21941
|
"Isolate this stack per git worktree \u2014 append the worktree token to the name so concurrent worktrees deploy to distinct stacks (no SSM/namespace collisions)"
|
|
@@ -21616,7 +21978,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21616
21978
|
}
|
|
21617
21979
|
}
|
|
21618
21980
|
const baseConfigPath = `${appRoot}/Pulumi.${baseStack}.yaml`;
|
|
21619
|
-
if (!
|
|
21981
|
+
if (!fs39.existsSync(baseConfigPath)) {
|
|
21620
21982
|
logError(`Stack config not found: Pulumi.${baseStack}.yaml`);
|
|
21621
21983
|
process.exit(1);
|
|
21622
21984
|
}
|
|
@@ -21638,8 +22000,8 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21638
22000
|
);
|
|
21639
22001
|
}
|
|
21640
22002
|
}
|
|
21641
|
-
const newConfigPath =
|
|
21642
|
-
const configExists =
|
|
22003
|
+
const newConfigPath = path46.join(appRoot, `Pulumi.${newStack}.yaml`);
|
|
22004
|
+
const configExists = fs39.existsSync(newConfigPath);
|
|
21643
22005
|
const secretsProvider = readTopLevelYamlKey(appRoot, baseStack, "secretsprovider");
|
|
21644
22006
|
const credEnv = await resolvePulumiEnv({ appRoot, stack: baseStack });
|
|
21645
22007
|
const pulumiEnv = { ...process.env, ...credEnv };
|
|
@@ -21647,7 +22009,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21647
22009
|
if (!opts.adopt) {
|
|
21648
22010
|
let existing = [];
|
|
21649
22011
|
try {
|
|
21650
|
-
const raw =
|
|
22012
|
+
const raw = execFileSync32("pulumi", ["stack", "ls", "--json"], {
|
|
21651
22013
|
cwd: appRoot,
|
|
21652
22014
|
encoding: "utf-8",
|
|
21653
22015
|
env: pulumiEnv,
|
|
@@ -21671,7 +22033,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21671
22033
|
logInfo(`Using KMS secrets provider: ${secretsProvider}`);
|
|
21672
22034
|
}
|
|
21673
22035
|
try {
|
|
21674
|
-
|
|
22036
|
+
execFileSync32("pulumi", initArgs, {
|
|
21675
22037
|
cwd: appRoot,
|
|
21676
22038
|
env: pulumiEnv,
|
|
21677
22039
|
stdio: "inherit"
|
|
@@ -21688,7 +22050,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21688
22050
|
}
|
|
21689
22051
|
}
|
|
21690
22052
|
try {
|
|
21691
|
-
|
|
22053
|
+
execFileSync32("pulumi", ["stack", "select", newStack], {
|
|
21692
22054
|
cwd: appRoot,
|
|
21693
22055
|
env: pulumiEnv,
|
|
21694
22056
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -21698,7 +22060,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21698
22060
|
if (!configExists) {
|
|
21699
22061
|
let baseConfig = {};
|
|
21700
22062
|
try {
|
|
21701
|
-
const raw =
|
|
22063
|
+
const raw = execFileSync32(
|
|
21702
22064
|
"pulumi",
|
|
21703
22065
|
["config", "--json", "--stack", baseStack],
|
|
21704
22066
|
{ cwd: appRoot, env: pulumiEnv, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -21716,19 +22078,19 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21716
22078
|
if (key === "mesh:deploy") continue;
|
|
21717
22079
|
try {
|
|
21718
22080
|
if (entry.objectValue !== void 0) {
|
|
21719
|
-
|
|
22081
|
+
execFileSync32(
|
|
21720
22082
|
"pulumi",
|
|
21721
22083
|
["config", "set", key, JSON.stringify(entry.objectValue)],
|
|
21722
22084
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
21723
22085
|
);
|
|
21724
22086
|
} else if (entry.value === "true" || entry.value === "false") {
|
|
21725
|
-
|
|
22087
|
+
execFileSync32(
|
|
21726
22088
|
"pulumi",
|
|
21727
22089
|
["config", "set", "--type", "bool", key, entry.value],
|
|
21728
22090
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
21729
22091
|
);
|
|
21730
22092
|
} else {
|
|
21731
|
-
|
|
22093
|
+
execFileSync32(
|
|
21732
22094
|
"pulumi",
|
|
21733
22095
|
["config", "set", key, entry.value],
|
|
21734
22096
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -21741,7 +22103,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21741
22103
|
const baseEnv = readConfigBlockKey(appRoot, baseStack, "mesh:coreEnv") ?? (baseTenant && baseStack.startsWith(`${baseTenant}-`) ? baseStack.slice(baseTenant.length + 1) : baseStack);
|
|
21742
22104
|
const setCfg = (args) => {
|
|
21743
22105
|
try {
|
|
21744
|
-
|
|
22106
|
+
execFileSync32("pulumi", ["config", "set", ...args], {
|
|
21745
22107
|
cwd: appRoot,
|
|
21746
22108
|
env: pulumiEnv,
|
|
21747
22109
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -21790,7 +22152,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21790
22152
|
`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}` : ""})`
|
|
21791
22153
|
);
|
|
21792
22154
|
} else {
|
|
21793
|
-
|
|
22155
|
+
execFileSync32("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
|
|
21794
22156
|
cwd: appRoot,
|
|
21795
22157
|
env: pulumiEnv,
|
|
21796
22158
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -21820,12 +22182,18 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
21820
22182
|
const args = ["stack", "rm", name];
|
|
21821
22183
|
if (opts.yes) args.push("--yes");
|
|
21822
22184
|
try {
|
|
21823
|
-
|
|
22185
|
+
execFileSync32("pulumi", args, { cwd: appRoot, env: pulumiEnv, stdio: "inherit" });
|
|
21824
22186
|
logSuccess(`Removed stack ${name}`);
|
|
21825
22187
|
} catch (err) {
|
|
21826
22188
|
process.exit(err.status ?? 1);
|
|
21827
22189
|
}
|
|
21828
22190
|
});
|
|
22191
|
+
stack.command("status").description(
|
|
22192
|
+
"Read-only drift check: for each platform this directory deploys (a platform repo's core/platform stacks) or deploys apps to (an app's mesh:platform), compare the pinned, deployed (the core and platform SSM registrations written by the last successful deploy) and latest published @mesh-tech/infra-components and @mesh-tech/hub, plus this CLI against the latest @mesh-tech/mesh-cli, and print the upgrade steps when anything is behind. Changes nothing."
|
|
22193
|
+
).option("--stack <name>", "check one stack (default: every Pulumi.<stack>.yaml here)").option("--profile <profile>", "AWS profile to read the SSM registrations with (default: AWS_PROFILE, else the stack's aws:profile, else an app stack's deployer role)").option("--region <region>", "AWS region of the registrations (default: the stack's aws:region, else us-east-2)").option("--json", "print the report as JSON", false).option("--check", "exit 1 when any layer or the CLI is behind, or a pin is not deployed", false).action(async (opts) => {
|
|
22194
|
+
const ok = await runStackStatus(process.cwd(), opts);
|
|
22195
|
+
if (opts.check && !ok) process.exit(1);
|
|
22196
|
+
});
|
|
21829
22197
|
}
|
|
21830
22198
|
var init_stack2 = __esm({
|
|
21831
22199
|
"packages/mesh-cli/src/commands/stack.ts"() {
|
|
@@ -21834,6 +22202,7 @@ var init_stack2 = __esm({
|
|
|
21834
22202
|
init_pulumi();
|
|
21835
22203
|
init_worktree_identity();
|
|
21836
22204
|
init_pulumi_run();
|
|
22205
|
+
init_stack_status();
|
|
21837
22206
|
}
|
|
21838
22207
|
});
|
|
21839
22208
|
|
|
@@ -22032,12 +22401,12 @@ var init_recover_conversation = __esm({
|
|
|
22032
22401
|
});
|
|
22033
22402
|
|
|
22034
22403
|
// packages/mesh-cli/src/utils/temporal-codec.ts
|
|
22035
|
-
import { execFileSync as
|
|
22404
|
+
import { execFileSync as execFileSync33 } from "child_process";
|
|
22036
22405
|
import { webcrypto as crypto4 } from "node:crypto";
|
|
22037
22406
|
function resolveTemporalEncodingKeyFromK8s(namespace) {
|
|
22038
22407
|
const secretName = `${namespace}-temporal-encoding-key`;
|
|
22039
22408
|
try {
|
|
22040
|
-
const b64 =
|
|
22409
|
+
const b64 = execFileSync33(
|
|
22041
22410
|
"kubectl",
|
|
22042
22411
|
[
|
|
22043
22412
|
"get",
|
|
@@ -22288,7 +22657,7 @@ var init_capture_history = __esm({
|
|
|
22288
22657
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
22289
22658
|
import { writeFileSync as writeFileSync24, mkdirSync as mkdirSync20 } from "node:fs";
|
|
22290
22659
|
import { homedir as homedir6 } from "node:os";
|
|
22291
|
-
import { dirname as
|
|
22660
|
+
import { dirname as dirname30, join as join43, resolve as resolve19 } from "node:path";
|
|
22292
22661
|
async function resolveConnection(options) {
|
|
22293
22662
|
if (options.address && options.namespace) {
|
|
22294
22663
|
return { address: options.address, namespace: options.namespace };
|
|
@@ -22716,8 +23085,8 @@ async function captureHistory(workflowId, runId, options) {
|
|
|
22716
23085
|
}
|
|
22717
23086
|
const { serializeHistoryToFixture: serializeHistoryToFixture2 } = await Promise.resolve().then(() => (init_capture_history(), capture_history_exports));
|
|
22718
23087
|
const { fixture, eventCount, decryptedPayloads } = await serializeHistoryToFixture2(events, decrypter);
|
|
22719
|
-
const outPath = options.out ??
|
|
22720
|
-
mkdirSync20(
|
|
23088
|
+
const outPath = options.out ?? join43(homedir6(), ".mesh", "replay-histories", `${sanitizeFileId(workflowId)}.json`);
|
|
23089
|
+
mkdirSync20(dirname30(outPath), { recursive: true });
|
|
22721
23090
|
if (options.out) warnIfNotGitIgnored(options.out);
|
|
22722
23091
|
writeFileSync24(outPath, JSON.stringify(fixture, null, 2) + "\n");
|
|
22723
23092
|
logSuccess(
|
|
@@ -22736,7 +23105,7 @@ function sanitizeFileId(id) {
|
|
|
22736
23105
|
function warnIfNotGitIgnored(outPath) {
|
|
22737
23106
|
const abs = resolve19(outPath);
|
|
22738
23107
|
try {
|
|
22739
|
-
const res = spawnSync4("git", ["-C",
|
|
23108
|
+
const res = spawnSync4("git", ["-C", dirname30(abs), "check-ignore", "-q", abs], {
|
|
22740
23109
|
stdio: "ignore"
|
|
22741
23110
|
});
|
|
22742
23111
|
if (res.status !== 1) return;
|
|
@@ -22908,8 +23277,8 @@ var init_temporal = __esm({
|
|
|
22908
23277
|
|
|
22909
23278
|
// packages/mesh-cli/src/commands/tenant.ts
|
|
22910
23279
|
import chalk7 from "chalk";
|
|
22911
|
-
import * as
|
|
22912
|
-
import * as
|
|
23280
|
+
import * as fs40 from "fs";
|
|
23281
|
+
import * as path47 from "path";
|
|
22913
23282
|
import { parseDocument, YAMLMap, isMap } from "yaml";
|
|
22914
23283
|
function validateTenantName(name) {
|
|
22915
23284
|
return /^[a-z][a-z0-9-]*$/.test(name) && !name.endsWith("-");
|
|
@@ -22977,16 +23346,16 @@ function resolveStackConfig(explicitStack) {
|
|
|
22977
23346
|
{ remediation: { command: "mesh tenant add <name> --stack <stack>" } }
|
|
22978
23347
|
);
|
|
22979
23348
|
}
|
|
22980
|
-
const file =
|
|
22981
|
-
if (!
|
|
23349
|
+
const file = path47.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
23350
|
+
if (!fs40.existsSync(file)) {
|
|
22982
23351
|
throw new MeshCliError(`Stack config not found: ${file}`, {
|
|
22983
23352
|
remediation: { command: "mesh tenant add <name> --stack <stack>" }
|
|
22984
23353
|
});
|
|
22985
23354
|
}
|
|
22986
|
-
return { appRoot, stack, file, content:
|
|
23355
|
+
return { appRoot, stack, file, content: fs40.readFileSync(file, "utf-8") };
|
|
22987
23356
|
}
|
|
22988
23357
|
function readProjectName(appRoot) {
|
|
22989
|
-
const projectDoc = parseDocument(
|
|
23358
|
+
const projectDoc = parseDocument(fs40.readFileSync(path47.join(appRoot, "Pulumi.yaml"), "utf-8"));
|
|
22990
23359
|
return String(projectDoc.get("name") ?? "");
|
|
22991
23360
|
}
|
|
22992
23361
|
function looksLikePlatformLayer(projectName) {
|
|
@@ -23029,12 +23398,12 @@ function registerTenantCommands(program2) {
|
|
|
23029
23398
|
if (!result.ok) {
|
|
23030
23399
|
if (result.reason === "exists") {
|
|
23031
23400
|
throw new MeshCliError(
|
|
23032
|
-
`${result.detail} (${
|
|
23401
|
+
`${result.detail} (${path47.basename(resolved.file)}). Edit the existing entry instead of re-adding it.`
|
|
23033
23402
|
);
|
|
23034
23403
|
}
|
|
23035
23404
|
throw new MeshCliError(`${resolved.file}: ${result.detail}`);
|
|
23036
23405
|
}
|
|
23037
|
-
atomicWriteFileSync(resolved.file, result.yaml,
|
|
23406
|
+
atomicWriteFileSync(resolved.file, result.yaml, fs40.statSync(resolved.file).mode & 511);
|
|
23038
23407
|
if (opts.json) {
|
|
23039
23408
|
emitJsonPayload({
|
|
23040
23409
|
ok: true,
|
|
@@ -23047,7 +23416,7 @@ function registerTenantCommands(program2) {
|
|
|
23047
23416
|
return;
|
|
23048
23417
|
}
|
|
23049
23418
|
logInfo(
|
|
23050
|
-
`Tenant '${name}' registered in ${
|
|
23419
|
+
`Tenant '${name}' registered in ${path47.basename(resolved.file)} (mesh:tenants, subdomain '${subdomain}')${result.createdTenantsBlock ? " \u2014 created the mesh:tenants block" : ""}`
|
|
23051
23420
|
);
|
|
23052
23421
|
console.log("");
|
|
23053
23422
|
console.log("Next steps:");
|
|
@@ -23073,7 +23442,7 @@ function registerTenantCommands(program2) {
|
|
|
23073
23442
|
`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).`
|
|
23074
23443
|
);
|
|
23075
23444
|
}
|
|
23076
|
-
logInfo(`No tenants declared in ${
|
|
23445
|
+
logInfo(`No tenants declared in ${path47.basename(resolved.file)}.`);
|
|
23077
23446
|
return;
|
|
23078
23447
|
}
|
|
23079
23448
|
logInfo(`Tenants on stack '${resolved.stack}':`);
|
|
@@ -23095,9 +23464,9 @@ var init_tenant = __esm({
|
|
|
23095
23464
|
|
|
23096
23465
|
// packages/mesh-cli/src/commands/tunnel/index.ts
|
|
23097
23466
|
import { spawn as spawn9 } from "child_process";
|
|
23098
|
-
import * as
|
|
23467
|
+
import * as fs41 from "fs";
|
|
23099
23468
|
import * as os12 from "os";
|
|
23100
|
-
import * as
|
|
23469
|
+
import * as path48 from "path";
|
|
23101
23470
|
import {
|
|
23102
23471
|
SecretsManagerClient as SecretsManagerClient9,
|
|
23103
23472
|
GetSecretValueCommand as GetSecretValueCommand9
|
|
@@ -23117,9 +23486,9 @@ function readPulumiAwsRegion(stage) {
|
|
|
23117
23486
|
const preferred = stage ? `Pulumi.${stage}.yaml` : void 0;
|
|
23118
23487
|
const rank = (f) => f === preferred ? 0 : f === "Pulumi.yaml" ? 2 : 1;
|
|
23119
23488
|
try {
|
|
23120
|
-
const files =
|
|
23489
|
+
const files = fs41.readdirSync(".").filter((f) => f.startsWith("Pulumi.") && f.endsWith(".yaml")).sort((a, b) => rank(a) - rank(b));
|
|
23121
23490
|
for (const f of files) {
|
|
23122
|
-
const m =
|
|
23491
|
+
const m = fs41.readFileSync(f, "utf-8").match(/^\s*aws:region:\s*["']?([^"'\n]+)["']?/m);
|
|
23123
23492
|
if (m?.[1]) return m[1].trim();
|
|
23124
23493
|
}
|
|
23125
23494
|
} catch {
|
|
@@ -23128,14 +23497,14 @@ function readPulumiAwsRegion(stage) {
|
|
|
23128
23497
|
}
|
|
23129
23498
|
function awsProfileSections(name) {
|
|
23130
23499
|
return [
|
|
23131
|
-
[
|
|
23132
|
-
[
|
|
23500
|
+
[path48.join(os12.homedir(), ".aws", "config"), `[profile ${name}]`],
|
|
23501
|
+
[path48.join(os12.homedir(), ".aws", "credentials"), `[${name}]`]
|
|
23133
23502
|
];
|
|
23134
23503
|
}
|
|
23135
23504
|
function awsProfileExists(name) {
|
|
23136
23505
|
for (const [file, header] of awsProfileSections(name)) {
|
|
23137
23506
|
try {
|
|
23138
|
-
const lines =
|
|
23507
|
+
const lines = fs41.readFileSync(file, "utf-8").split("\n");
|
|
23139
23508
|
if (lines.some((l) => l.trim() === header)) return true;
|
|
23140
23509
|
} catch {
|
|
23141
23510
|
}
|
|
@@ -23161,7 +23530,7 @@ function awsProfileRegion(profile) {
|
|
|
23161
23530
|
if (!profile) return void 0;
|
|
23162
23531
|
for (const [file, header] of awsProfileSections(profile)) {
|
|
23163
23532
|
try {
|
|
23164
|
-
const region = parseProfileRegion(
|
|
23533
|
+
const region = parseProfileRegion(fs41.readFileSync(file, "utf-8"), header);
|
|
23165
23534
|
if (region) return region;
|
|
23166
23535
|
} catch {
|
|
23167
23536
|
}
|
|
@@ -23170,14 +23539,14 @@ function awsProfileRegion(profile) {
|
|
|
23170
23539
|
}
|
|
23171
23540
|
function awsDefaultProfileSections() {
|
|
23172
23541
|
return [
|
|
23173
|
-
[
|
|
23174
|
-
[
|
|
23542
|
+
[path48.join(os12.homedir(), ".aws", "config"), "[default]"],
|
|
23543
|
+
[path48.join(os12.homedir(), ".aws", "credentials"), "[default]"]
|
|
23175
23544
|
];
|
|
23176
23545
|
}
|
|
23177
23546
|
function awsDefaultProfileRegion() {
|
|
23178
23547
|
for (const [file, header] of awsDefaultProfileSections()) {
|
|
23179
23548
|
try {
|
|
23180
|
-
const region = parseProfileRegion(
|
|
23549
|
+
const region = parseProfileRegion(fs41.readFileSync(file, "utf-8"), header);
|
|
23181
23550
|
if (region) return region;
|
|
23182
23551
|
} catch {
|
|
23183
23552
|
}
|
|
@@ -23564,8 +23933,8 @@ async function resolveToken(opts) {
|
|
|
23564
23933
|
"no token: pass --token, set VCS_TOKEN, or pass --context <platform-context> (after mesh login)"
|
|
23565
23934
|
);
|
|
23566
23935
|
}
|
|
23567
|
-
async function vcsApi(baseUrl, token,
|
|
23568
|
-
const res = await fetch(`${baseUrl}${
|
|
23936
|
+
async function vcsApi(baseUrl, token, path50, method = "GET", body) {
|
|
23937
|
+
const res = await fetch(`${baseUrl}${path50}`, {
|
|
23569
23938
|
method,
|
|
23570
23939
|
headers: {
|
|
23571
23940
|
authorization: `Bearer ${token}`,
|
|
@@ -23576,7 +23945,7 @@ async function vcsApi(baseUrl, token, path49, method = "GET", body) {
|
|
|
23576
23945
|
const data = await res.json().catch(() => ({}));
|
|
23577
23946
|
if (!res.ok) {
|
|
23578
23947
|
throw new Error(
|
|
23579
|
-
`${method} ${
|
|
23948
|
+
`${method} ${path50} failed (${res.status}): ${String(data.error ?? "unknown error")}`
|
|
23580
23949
|
);
|
|
23581
23950
|
}
|
|
23582
23951
|
return data;
|
|
@@ -23622,8 +23991,8 @@ var init_clone = __esm({
|
|
|
23622
23991
|
|
|
23623
23992
|
// packages/mesh-cli/src/commands/vcs/get.ts
|
|
23624
23993
|
import { writeFile as writeFile2, mkdir as mkdir2 } from "node:fs/promises";
|
|
23625
|
-
import { join as
|
|
23626
|
-
async function getCommand(repo,
|
|
23994
|
+
import { join as join46, dirname as dirname31 } from "node:path";
|
|
23995
|
+
async function getCommand(repo, path50, opts) {
|
|
23627
23996
|
let vcsBaseUrl;
|
|
23628
23997
|
let token;
|
|
23629
23998
|
if (opts.target) {
|
|
@@ -23638,18 +24007,18 @@ async function getCommand(repo, path49, opts) {
|
|
|
23638
24007
|
if (!token) throw new Error("no token: pass --target (after mesh login), or --token / --context");
|
|
23639
24008
|
const reader = createVcsFolderReader({ vcsBaseUrl, token });
|
|
23640
24009
|
try {
|
|
23641
|
-
const { ref, files } = await reader.readPath(repo,
|
|
24010
|
+
const { ref, files } = await reader.readPath(repo, path50);
|
|
23642
24011
|
if (files.length === 0) {
|
|
23643
|
-
logInfo(`no files at ${repo}:${
|
|
24012
|
+
logInfo(`no files at ${repo}:${path50}`);
|
|
23644
24013
|
return;
|
|
23645
24014
|
}
|
|
23646
24015
|
if (opts.output) {
|
|
23647
24016
|
for (const f of files) {
|
|
23648
|
-
const abs =
|
|
23649
|
-
await mkdir2(
|
|
24017
|
+
const abs = join46(opts.output, f.path);
|
|
24018
|
+
await mkdir2(dirname31(abs), { recursive: true });
|
|
23650
24019
|
await writeFile2(abs, f.contents);
|
|
23651
24020
|
}
|
|
23652
|
-
logInfo(`wrote ${files.length} file(s) from ${repo}:${
|
|
24021
|
+
logInfo(`wrote ${files.length} file(s) from ${repo}:${path50} (${ref}) \u2192 ${opts.output}`);
|
|
23653
24022
|
} else {
|
|
23654
24023
|
for (const f of files) {
|
|
23655
24024
|
if (files.length > 1) process.stdout.write(`
|
|
@@ -23674,10 +24043,10 @@ var init_get = __esm({
|
|
|
23674
24043
|
});
|
|
23675
24044
|
|
|
23676
24045
|
// packages/mesh-cli/src/commands/vcs/drafts.ts
|
|
23677
|
-
async function call(opts, repo,
|
|
24046
|
+
async function call(opts, repo, path50, method = "GET", body) {
|
|
23678
24047
|
const target = await resolveTarget2({ ...opts, repo });
|
|
23679
24048
|
const token = await resolveToken(opts);
|
|
23680
|
-
return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${
|
|
24049
|
+
return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path50}`, method, body);
|
|
23681
24050
|
}
|
|
23682
24051
|
async function draftsListCommand(repo, opts) {
|
|
23683
24052
|
const data = await call(opts, repo, `/drafts${opts.all ? "?all=true" : ""}`);
|
|
@@ -23732,7 +24101,7 @@ var init_drafts = __esm({
|
|
|
23732
24101
|
|
|
23733
24102
|
// packages/mesh-cli/src/commands/vcs/propose.ts
|
|
23734
24103
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
23735
|
-
import { join as
|
|
24104
|
+
import { join as join47 } from "node:path";
|
|
23736
24105
|
function parseStatus(out) {
|
|
23737
24106
|
const tokens = out.split("\0");
|
|
23738
24107
|
const changes = [];
|
|
@@ -23765,13 +24134,13 @@ function parseStatus(out) {
|
|
|
23765
24134
|
}
|
|
23766
24135
|
return changes;
|
|
23767
24136
|
}
|
|
23768
|
-
async function writeOp(cwd,
|
|
23769
|
-
const buf = await readFile3(
|
|
24137
|
+
async function writeOp(cwd, path50) {
|
|
24138
|
+
const buf = await readFile3(join47(cwd, path50));
|
|
23770
24139
|
const asUtf8 = buf.toString("utf8");
|
|
23771
24140
|
if (Buffer.from(asUtf8, "utf8").equals(buf)) {
|
|
23772
|
-
return { op: "write", path:
|
|
24141
|
+
return { op: "write", path: path50, content: asUtf8 };
|
|
23773
24142
|
}
|
|
23774
|
-
return { op: "write", path:
|
|
24143
|
+
return { op: "write", path: path50, content: buf.toString("base64"), encoding: "base64" };
|
|
23775
24144
|
}
|
|
23776
24145
|
async function proposeCommand(opts) {
|
|
23777
24146
|
const cwd = process.cwd();
|
|
@@ -23815,8 +24184,8 @@ async function proposeCommand(opts) {
|
|
|
23815
24184
|
operations,
|
|
23816
24185
|
...opts.mergeParent ? { mergeParent: opts.mergeParent } : {}
|
|
23817
24186
|
};
|
|
23818
|
-
const
|
|
23819
|
-
const data = await vcsApi(target.baseUrl, token,
|
|
24187
|
+
const path50 = opts.revise ? `/v1/repos/${target.repo}/proposals/${opts.revise}/revisions` : `/v1/repos/${target.repo}/proposals`;
|
|
24188
|
+
const data = await vcsApi(target.baseUrl, token, path50, "POST", body);
|
|
23820
24189
|
console.log(
|
|
23821
24190
|
`proposal ${data.proposalId} @ ${data.sha.slice(0, 8)} \u2014 review: mesh vcs show ${target.repo} ${data.proposalId} --url ${target.baseUrl}`
|
|
23822
24191
|
);
|
|
@@ -23831,28 +24200,28 @@ var init_propose = __esm({
|
|
|
23831
24200
|
// packages/mesh-cli/src/commands/vcs/rm.ts
|
|
23832
24201
|
import { mkdtemp as mkdtemp2, rm as rmrf } from "node:fs/promises";
|
|
23833
24202
|
import { tmpdir as tmpdir10 } from "node:os";
|
|
23834
|
-
import { join as
|
|
24203
|
+
import { join as join48 } from "node:path";
|
|
23835
24204
|
function normalize2(p) {
|
|
23836
24205
|
return p.trim().replace(/^\.\//, "").replace(/\/+$/, "");
|
|
23837
24206
|
}
|
|
23838
24207
|
function expandPathsToDeletions(repoFiles, requested) {
|
|
23839
24208
|
const out = /* @__PURE__ */ new Set();
|
|
23840
24209
|
for (const raw of requested) {
|
|
23841
|
-
const
|
|
23842
|
-
if (
|
|
24210
|
+
const path50 = normalize2(raw);
|
|
24211
|
+
if (path50.startsWith("/") || path50.split("/").includes("..")) {
|
|
23843
24212
|
throw new Error(
|
|
23844
24213
|
`"${raw}" is not a repo-relative path \u2014 vcs paths never start with "/" or traverse with "..".`
|
|
23845
24214
|
);
|
|
23846
24215
|
}
|
|
23847
|
-
const exact = repoFiles.filter((f) => f ===
|
|
24216
|
+
const exact = repoFiles.filter((f) => f === path50);
|
|
23848
24217
|
if (exact.length > 0) {
|
|
23849
24218
|
for (const f of exact) out.add(f);
|
|
23850
24219
|
continue;
|
|
23851
24220
|
}
|
|
23852
|
-
const under = repoFiles.filter((f) => f.startsWith(`${
|
|
24221
|
+
const under = repoFiles.filter((f) => f.startsWith(`${path50}/`));
|
|
23853
24222
|
if (under.length === 0) {
|
|
23854
24223
|
throw new Error(
|
|
23855
|
-
`"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${
|
|
24224
|
+
`"${raw}" matched no files in the repo \u2014 nothing was proposed. Check the path with: mesh vcs get <repo> ${path50}`
|
|
23856
24225
|
);
|
|
23857
24226
|
}
|
|
23858
24227
|
for (const f of under) out.add(f);
|
|
@@ -23863,7 +24232,7 @@ async function rmCommand(repo, paths, opts) {
|
|
|
23863
24232
|
const baseUrl = (opts.url ?? process.env.VCS_URL)?.replace(/\/$/, "");
|
|
23864
24233
|
if (!baseUrl) throw new Error("rm requires --url or VCS_URL");
|
|
23865
24234
|
const token = await resolveToken(opts);
|
|
23866
|
-
const dir = await mkdtemp2(
|
|
24235
|
+
const dir = await mkdtemp2(join48(tmpdir10(), "mesh-vcs-rm-"));
|
|
23867
24236
|
try {
|
|
23868
24237
|
const git = (args, cwd) => gitWithAuth(args, token, cwd);
|
|
23869
24238
|
await git([
|
|
@@ -23888,7 +24257,7 @@ async function rmCommand(repo, paths, opts) {
|
|
|
23888
24257
|
const body = {
|
|
23889
24258
|
baseCommit: head.trim(),
|
|
23890
24259
|
message: opts.message ?? `Delete ${doomed.length} file(s)`,
|
|
23891
|
-
operations: doomed.map((
|
|
24260
|
+
operations: doomed.map((path50) => ({ op: "delete", path: path50 }))
|
|
23892
24261
|
};
|
|
23893
24262
|
const data = await vcsApi(
|
|
23894
24263
|
baseUrl,
|
|
@@ -23914,10 +24283,10 @@ var init_rm = __esm({
|
|
|
23914
24283
|
});
|
|
23915
24284
|
|
|
23916
24285
|
// packages/mesh-cli/src/commands/vcs/review.ts
|
|
23917
|
-
async function call2(opts, repo,
|
|
24286
|
+
async function call2(opts, repo, path50, method = "GET", body) {
|
|
23918
24287
|
const target = await resolveTarget2({ ...opts, repo });
|
|
23919
24288
|
const token = await resolveToken(opts);
|
|
23920
|
-
return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${
|
|
24289
|
+
return vcsApi(target.baseUrl, token, `/v1/repos/${repo}${path50}`, method, body);
|
|
23921
24290
|
}
|
|
23922
24291
|
async function proposalsCommand(repo, opts) {
|
|
23923
24292
|
console.log(JSON.stringify(await call2(opts, repo, "/proposals"), null, 2));
|
|
@@ -24064,8 +24433,8 @@ function computeHappyPath(nodes, edges) {
|
|
|
24064
24433
|
];
|
|
24065
24434
|
const visited = /* @__PURE__ */ new Set([startNode.id]);
|
|
24066
24435
|
while (queue.length > 0) {
|
|
24067
|
-
const { id, path:
|
|
24068
|
-
if (targetIds.has(id)) return
|
|
24436
|
+
const { id, path: path50 } = queue.shift();
|
|
24437
|
+
if (targetIds.has(id)) return path50;
|
|
24069
24438
|
const neighbors = adjacency.get(id) ?? [];
|
|
24070
24439
|
const hasMainEdge = neighbors.some((e) => e.isMainPath);
|
|
24071
24440
|
const candidates = hasMainEdge ? neighbors.filter((e) => e.isMainPath) : neighbors;
|
|
@@ -24085,7 +24454,7 @@ function computeHappyPath(nodes, edges) {
|
|
|
24085
24454
|
if (!allowExceptional && (neighbor.isExceptional || neighbor.isTimeout || failureEndIds.has(neighbor.to)))
|
|
24086
24455
|
continue;
|
|
24087
24456
|
visited.add(neighbor.to);
|
|
24088
|
-
queue.push({ id: neighbor.to, path: [...
|
|
24457
|
+
queue.push({ id: neighbor.to, path: [...path50, neighbor.to] });
|
|
24089
24458
|
}
|
|
24090
24459
|
}
|
|
24091
24460
|
return null;
|
|
@@ -24370,11 +24739,11 @@ function wrapIntoGroup(workflow, nodeIds, groupId, label, groupType) {
|
|
|
24370
24739
|
}
|
|
24371
24740
|
}
|
|
24372
24741
|
if (found) {
|
|
24373
|
-
const
|
|
24374
|
-
for (let c = found; c !== void 0; c = prev.get(c))
|
|
24375
|
-
for (let i = 0; i <
|
|
24742
|
+
const path50 = [];
|
|
24743
|
+
for (let c = found; c !== void 0; c = prev.get(c)) path50.unshift(c);
|
|
24744
|
+
for (let i = 0; i < path50.length - 1; i++) mainEdgeKeys.add(edgeKey(path50[i], path50[i + 1]));
|
|
24376
24745
|
mainEdgeKeys.add(edgeKey(found, successExit.id));
|
|
24377
|
-
mainBody =
|
|
24746
|
+
mainBody = path50;
|
|
24378
24747
|
mainTail = [successExit.id];
|
|
24379
24748
|
}
|
|
24380
24749
|
}
|
|
@@ -24910,11 +25279,11 @@ function buildProcessManifest(artifact, outcomeNodeIds) {
|
|
|
24910
25279
|
...pointOfNoReturnStage ? { pointOfNoReturnStageId: pointOfNoReturnStage.id } : {}
|
|
24911
25280
|
};
|
|
24912
25281
|
}
|
|
24913
|
-
function formatPath(
|
|
24914
|
-
return
|
|
25282
|
+
function formatPath(path50) {
|
|
25283
|
+
return path50.length > 0 ? z4.core.toDotPath(path50) : "(root)";
|
|
24915
25284
|
}
|
|
24916
25285
|
function issueToDiagnostic(issue) {
|
|
24917
|
-
const
|
|
25286
|
+
const path50 = formatPath(issue.path);
|
|
24918
25287
|
let code = "SCHEMA_INVALID";
|
|
24919
25288
|
if (issue.code === "custom") {
|
|
24920
25289
|
const paramCode = issue.params?.code;
|
|
@@ -24925,8 +25294,8 @@ function issueToDiagnostic(issue) {
|
|
|
24925
25294
|
return {
|
|
24926
25295
|
severity: "error",
|
|
24927
25296
|
code,
|
|
24928
|
-
message: `${
|
|
24929
|
-
path:
|
|
25297
|
+
message: `${path50}: ${issue.message}`,
|
|
25298
|
+
path: path50
|
|
24930
25299
|
};
|
|
24931
25300
|
}
|
|
24932
25301
|
function upgradeV1(artifact) {
|
|
@@ -25093,24 +25462,24 @@ var init_process_artifact = __esm({
|
|
|
25093
25462
|
});
|
|
25094
25463
|
}
|
|
25095
25464
|
const declaredSelectors = new Set(Object.keys(process2.selectors ?? {}));
|
|
25096
|
-
const checkActor = (actorId,
|
|
25465
|
+
const checkActor = (actorId, path50) => {
|
|
25097
25466
|
if (actorId === void 0) return;
|
|
25098
25467
|
if (!Object.prototype.hasOwnProperty.call(process2.actors, actorId)) {
|
|
25099
25468
|
ctx.addIssue({
|
|
25100
25469
|
code: "custom",
|
|
25101
|
-
path:
|
|
25102
|
-
message: `Actor "${actorId}" is referenced at ${z4.core.toDotPath(
|
|
25470
|
+
path: path50,
|
|
25471
|
+
message: `Actor "${actorId}" is referenced at ${z4.core.toDotPath(path50)} but not declared in process.actors. Declare the actor (label, and optionally category/selector) or fix the reference.`,
|
|
25103
25472
|
params: { code: "UNDECLARED_ACTOR" }
|
|
25104
25473
|
});
|
|
25105
25474
|
}
|
|
25106
25475
|
};
|
|
25107
|
-
const checkSelector = (selector,
|
|
25476
|
+
const checkSelector = (selector, path50) => {
|
|
25108
25477
|
if (selector === void 0) return;
|
|
25109
25478
|
if (!declaredSelectors.has(selector)) {
|
|
25110
25479
|
ctx.addIssue({
|
|
25111
25480
|
code: "custom",
|
|
25112
|
-
path:
|
|
25113
|
-
message: `Selector "${selector}" is referenced at ${z4.core.toDotPath(
|
|
25481
|
+
path: path50,
|
|
25482
|
+
message: `Selector "${selector}" is referenced at ${z4.core.toDotPath(path50)} but not declared in process.selectors. Declare the selector or fix the reference.`,
|
|
25114
25483
|
params: { code: "UNDECLARED_SELECTOR" }
|
|
25115
25484
|
});
|
|
25116
25485
|
}
|
|
@@ -25124,20 +25493,20 @@ var init_process_artifact = __esm({
|
|
|
25124
25493
|
outcome: "DUPLICATE_OUTCOME_ID"
|
|
25125
25494
|
};
|
|
25126
25495
|
const idFirstSeenAt = /* @__PURE__ */ new Map();
|
|
25127
|
-
const checkId = (id, kind,
|
|
25496
|
+
const checkId = (id, kind, path50) => {
|
|
25128
25497
|
const first = idFirstSeenAt.get(id);
|
|
25129
25498
|
if (first) {
|
|
25130
25499
|
const kindLabel = kind === first.kind ? kind : "process";
|
|
25131
25500
|
ctx.addIssue({
|
|
25132
25501
|
code: "custom",
|
|
25133
|
-
path:
|
|
25134
|
-
message: `Duplicate ${kindLabel} id "${id}": ${kind} at ${z4.core.toDotPath(
|
|
25502
|
+
path: path50,
|
|
25503
|
+
message: `Duplicate ${kindLabel} id "${id}": ${kind} at ${z4.core.toDotPath(path50)} collides with ${first.kind} at ${z4.core.toDotPath(first.path)}.`,
|
|
25135
25504
|
params: {
|
|
25136
25505
|
code: kind === first.kind ? SAME_KIND_CODE[kind] : "DUPLICATE_PROCESS_ID"
|
|
25137
25506
|
}
|
|
25138
25507
|
});
|
|
25139
25508
|
} else {
|
|
25140
|
-
idFirstSeenAt.set(id, { kind, path:
|
|
25509
|
+
idFirstSeenAt.set(id, { kind, path: path50 });
|
|
25141
25510
|
}
|
|
25142
25511
|
};
|
|
25143
25512
|
process2.stages.forEach((stage, stageIndex) => {
|
|
@@ -25184,13 +25553,13 @@ function lintProcess(artifact, inventory, predicateNames, options = {}) {
|
|
|
25184
25553
|
const internalCommands = process2.internalCommands ?? [];
|
|
25185
25554
|
const internalSet = new Set(internalCommands);
|
|
25186
25555
|
const boundCommandPaths = /* @__PURE__ */ new Map();
|
|
25187
|
-
const checkPredicate = (predicate,
|
|
25556
|
+
const checkPredicate = (predicate, path50) => {
|
|
25188
25557
|
if (!predicateSet.has(predicate)) {
|
|
25189
25558
|
diagnostics.push({
|
|
25190
25559
|
severity: "error",
|
|
25191
25560
|
code: "UNKNOWN_PREDICATE",
|
|
25192
|
-
message: `Predicate "${predicate}" referenced at ${
|
|
25193
|
-
path:
|
|
25561
|
+
message: `Predicate "${predicate}" referenced at ${path50} is not in the predicate registry.`,
|
|
25562
|
+
path: path50
|
|
25194
25563
|
});
|
|
25195
25564
|
}
|
|
25196
25565
|
};
|
|
@@ -25250,19 +25619,19 @@ function lintProcess(artifact, inventory, predicateNames, options = {}) {
|
|
|
25250
25619
|
process2.outcomes.forEach((outcome, outcomeIndex) => {
|
|
25251
25620
|
const whenPath = `process.outcomes[${outcomeIndex}].when`;
|
|
25252
25621
|
outcomeTriggers(outcome).forEach((trigger, triggerIndex) => {
|
|
25253
|
-
const
|
|
25622
|
+
const path50 = Array.isArray(outcome.when) ? `${whenPath}[${triggerIndex}]` : whenPath;
|
|
25254
25623
|
if (trigger.kind === "predicate") {
|
|
25255
|
-
checkPredicate(trigger.name, `${
|
|
25624
|
+
checkPredicate(trigger.name, `${path50}.predicate`);
|
|
25256
25625
|
} else if (trigger.kind === "command") {
|
|
25257
25626
|
if (!boundCommandPaths.has(trigger.name)) {
|
|
25258
|
-
boundCommandPaths.set(trigger.name, `${
|
|
25627
|
+
boundCommandPaths.set(trigger.name, `${path50}.command`);
|
|
25259
25628
|
}
|
|
25260
25629
|
if (!commandNames.has(trigger.name)) {
|
|
25261
25630
|
diagnostics.push({
|
|
25262
25631
|
severity: "error",
|
|
25263
25632
|
code: "BOUND_COMMAND_NOT_IN_INVENTORY",
|
|
25264
|
-
message: `Command "${trigger.name}" triggering outcome "${outcome.id}" (${
|
|
25265
|
-
path: `${
|
|
25633
|
+
message: `Command "${trigger.name}" triggering outcome "${outcome.id}" (${path50}.command) does not exist in the inventory.`,
|
|
25634
|
+
path: `${path50}.command`
|
|
25266
25635
|
});
|
|
25267
25636
|
}
|
|
25268
25637
|
}
|
|
@@ -25374,10 +25743,10 @@ var init_src4 = __esm({
|
|
|
25374
25743
|
});
|
|
25375
25744
|
|
|
25376
25745
|
// packages/mesh-cli/src/commands/workflow.ts
|
|
25377
|
-
import * as
|
|
25378
|
-
import * as
|
|
25746
|
+
import * as fs42 from "fs";
|
|
25747
|
+
import * as path49 from "path";
|
|
25379
25748
|
import { createRequire as createRequire2 } from "module";
|
|
25380
|
-
import { execFileSync as
|
|
25749
|
+
import { execFileSync as execFileSync34 } from "child_process";
|
|
25381
25750
|
function resolveExtractorPath() {
|
|
25382
25751
|
try {
|
|
25383
25752
|
const require2 = createRequire2(import.meta.url);
|
|
@@ -25391,7 +25760,7 @@ function runExtraction(targetPath, extractorPath, explicitProcessPath) {
|
|
|
25391
25760
|
let explicitProcessArtifact;
|
|
25392
25761
|
if (explicitProcessPath) {
|
|
25393
25762
|
try {
|
|
25394
|
-
explicitProcessArtifact = JSON.parse(
|
|
25763
|
+
explicitProcessArtifact = JSON.parse(fs42.readFileSync(explicitProcessPath, "utf-8"));
|
|
25395
25764
|
} catch (err) {
|
|
25396
25765
|
logError(
|
|
25397
25766
|
`Could not read/parse --process ${explicitProcessPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -25432,7 +25801,7 @@ for (const file of files) {
|
|
|
25432
25801
|
process.stdout.write(JSON.stringify(results));
|
|
25433
25802
|
`;
|
|
25434
25803
|
try {
|
|
25435
|
-
const result =
|
|
25804
|
+
const result = execFileSync34("npx", ["tsx", "--eval", script], {
|
|
25436
25805
|
encoding: "utf-8",
|
|
25437
25806
|
stdio: ["pipe", "pipe", "inherit"],
|
|
25438
25807
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -25474,7 +25843,7 @@ for (const file of files) {
|
|
|
25474
25843
|
process.stdout.write(JSON.stringify(results));
|
|
25475
25844
|
`;
|
|
25476
25845
|
try {
|
|
25477
|
-
const result =
|
|
25846
|
+
const result = execFileSync34("npx", ["tsx", "--eval", script], {
|
|
25478
25847
|
encoding: "utf-8",
|
|
25479
25848
|
stdio: ["pipe", "pipe", "inherit"],
|
|
25480
25849
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -25491,7 +25860,7 @@ function runLintExtraction(targetPath, extractorPath, explicitProcessPath) {
|
|
|
25491
25860
|
let explicitProcessArtifact;
|
|
25492
25861
|
if (explicitProcessPath) {
|
|
25493
25862
|
try {
|
|
25494
|
-
explicitProcessArtifact = JSON.parse(
|
|
25863
|
+
explicitProcessArtifact = JSON.parse(fs42.readFileSync(explicitProcessPath, "utf-8"));
|
|
25495
25864
|
} catch (err) {
|
|
25496
25865
|
logError(
|
|
25497
25866
|
`Could not read/parse --process ${explicitProcessPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -25529,7 +25898,7 @@ for (const file of files) {
|
|
|
25529
25898
|
process.stdout.write(JSON.stringify(results));
|
|
25530
25899
|
`;
|
|
25531
25900
|
try {
|
|
25532
|
-
const result =
|
|
25901
|
+
const result = execFileSync34("npx", ["tsx", "--eval", script], {
|
|
25533
25902
|
encoding: "utf-8",
|
|
25534
25903
|
stdio: ["pipe", "pipe", "inherit"],
|
|
25535
25904
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -25599,16 +25968,16 @@ function registerWorkflowCommands(program2) {
|
|
|
25599
25968
|
).action(
|
|
25600
25969
|
async (targetPath, opts) => {
|
|
25601
25970
|
try {
|
|
25602
|
-
const resolvedPath =
|
|
25603
|
-
if (!
|
|
25971
|
+
const resolvedPath = path49.resolve(targetPath);
|
|
25972
|
+
if (!fs42.existsSync(resolvedPath)) {
|
|
25604
25973
|
logError(`Path does not exist: ${resolvedPath}`);
|
|
25605
25974
|
process.exitCode = 1;
|
|
25606
25975
|
return;
|
|
25607
25976
|
}
|
|
25608
25977
|
let resolvedProcessPath;
|
|
25609
25978
|
if (opts.process) {
|
|
25610
|
-
resolvedProcessPath =
|
|
25611
|
-
if (!
|
|
25979
|
+
resolvedProcessPath = path49.resolve(opts.process);
|
|
25980
|
+
if (!fs42.existsSync(resolvedProcessPath)) {
|
|
25612
25981
|
logError(`--process path does not exist: ${resolvedProcessPath}`);
|
|
25613
25982
|
process.exitCode = 1;
|
|
25614
25983
|
return;
|
|
@@ -25657,8 +26026,8 @@ function registerWorkflowCommands(program2) {
|
|
|
25657
26026
|
"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."
|
|
25658
26027
|
).action(async (targetPath) => {
|
|
25659
26028
|
try {
|
|
25660
|
-
const resolvedPath =
|
|
25661
|
-
if (!
|
|
26029
|
+
const resolvedPath = path49.resolve(targetPath);
|
|
26030
|
+
if (!fs42.existsSync(resolvedPath)) {
|
|
25662
26031
|
logError(`Path does not exist: ${resolvedPath}`);
|
|
25663
26032
|
process.exitCode = 1;
|
|
25664
26033
|
return;
|
|
@@ -25704,16 +26073,16 @@ function registerWorkflowCommands(program2) {
|
|
|
25704
26073
|
"Comma-separated named-selector registry (enables UNKNOWN_SELECTOR checks)"
|
|
25705
26074
|
).action(async (targetPath, opts) => {
|
|
25706
26075
|
try {
|
|
25707
|
-
const resolvedPath =
|
|
25708
|
-
if (!
|
|
26076
|
+
const resolvedPath = path49.resolve(targetPath);
|
|
26077
|
+
if (!fs42.existsSync(resolvedPath)) {
|
|
25709
26078
|
logError(`Path does not exist: ${resolvedPath}`);
|
|
25710
26079
|
process.exitCode = 1;
|
|
25711
26080
|
return;
|
|
25712
26081
|
}
|
|
25713
26082
|
let resolvedProcessPath;
|
|
25714
26083
|
if (opts.process) {
|
|
25715
|
-
resolvedProcessPath =
|
|
25716
|
-
if (!
|
|
26084
|
+
resolvedProcessPath = path49.resolve(opts.process);
|
|
26085
|
+
if (!fs42.existsSync(resolvedProcessPath)) {
|
|
25717
26086
|
logError(`--process path does not exist: ${resolvedProcessPath}`);
|
|
25718
26087
|
process.exitCode = 1;
|
|
25719
26088
|
return;
|
|
@@ -25967,7 +26336,7 @@ var init_program = __esm({
|
|
|
25967
26336
|
init_vpn2();
|
|
25968
26337
|
init_workflow();
|
|
25969
26338
|
CLI_NAME = "mesh";
|
|
25970
|
-
CLI_DESCRIPTION = "
|
|
26339
|
+
CLI_DESCRIPTION = "Build, run and deploy apps on a Mesh platform";
|
|
25971
26340
|
}
|
|
25972
26341
|
});
|
|
25973
26342
|
|