@mesh-tech/mesh-cli 0.20.4 → 0.22.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/README.md +12 -0
- package/dist/bin/mesh.js +554 -174
- package/dist/bin/mesh.js.map +2 -2
- package/dist/build-info.json +2 -2
- package/dist/src/commands/app-check.d.ts +16 -1
- package/dist/src/commands/app-check.js +260 -0
- package/dist/src/commands/create-app.d.ts +1 -0
- package/dist/src/commands/create-app.js +24 -9
- package/dist/src/commands/local/helpers.d.ts +18 -0
- package/dist/src/commands/local/helpers.js +96 -0
- package/dist/src/commands/local/index.d.ts +1 -0
- package/dist/src/commands/local/index.js +40 -3
- package/dist/src/commands/login.d.ts +1 -0
- package/dist/src/commands/login.js +8 -1
- package/dist/src/commands/temporal.js +11 -2
- package/dist/src/commands/temporal.js.map +1 -1
- package/fragments/agents/AGENTS.md.hbs +13 -0
- package/fragments/base/README.md.hbs +9 -0
- package/fragments/base/index.ts.hbs +27 -0
- package/fragments/service/api/openapi.json.hbs +42 -0
- package/fragments/service/docs/pages/getting-started.md.hbs +15 -0
- package/package.json +2 -2
- package/skills/core/SKILL.md +21 -4
package/dist/bin/mesh.js
CHANGED
|
@@ -838,6 +838,7 @@ var init_seed = __esm({
|
|
|
838
838
|
|
|
839
839
|
// libs/mesh-cli/src/commands/local/helpers.ts
|
|
840
840
|
import * as net from "net";
|
|
841
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
841
842
|
async function upsertLocalSecret(secretId, value, client) {
|
|
842
843
|
const { SecretsManagerClient: SecretsManagerClient10, CreateSecretCommand: CreateSecretCommand4, PutSecretValueCommand: PutSecretValueCommand4 } = await import("@aws-sdk/client-secrets-manager");
|
|
843
844
|
const sm = client ?? new SecretsManagerClient10(LOCAL_AWS_CONFIG);
|
|
@@ -867,10 +868,91 @@ function probeTcp(port, opts = {}) {
|
|
|
867
868
|
});
|
|
868
869
|
});
|
|
869
870
|
}
|
|
871
|
+
function hostPortsOf(endpoints) {
|
|
872
|
+
const ports = /* @__PURE__ */ new Set();
|
|
873
|
+
const fromUrl = (raw) => {
|
|
874
|
+
try {
|
|
875
|
+
const u = new URL(raw.includes("://") ? raw : `tcp://${raw}`);
|
|
876
|
+
const port = Number(u.port || (u.protocol === "https:" ? 443 : u.protocol === "http:" ? 80 : NaN));
|
|
877
|
+
if (Number.isInteger(port) && port > 0) ports.add(port);
|
|
878
|
+
} catch {
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
for (const e of endpoints) {
|
|
882
|
+
if (e.probe.kind === "tcp") ports.add(e.probe.port);
|
|
883
|
+
else if (e.probe.kind === "http") fromUrl(e.probe.url);
|
|
884
|
+
fromUrl(e.url);
|
|
885
|
+
}
|
|
886
|
+
return [...ports].sort((a, b) => a - b);
|
|
887
|
+
}
|
|
888
|
+
function parseDockerPsPorts(output, ignorePrefix) {
|
|
889
|
+
const held = /* @__PURE__ */ new Map();
|
|
890
|
+
for (const line of output.split("\n")) {
|
|
891
|
+
const tab = line.indexOf(" ");
|
|
892
|
+
if (tab < 0) continue;
|
|
893
|
+
const name = line.slice(0, tab).trim();
|
|
894
|
+
if (!name || name.startsWith(ignorePrefix)) continue;
|
|
895
|
+
for (const m of line.slice(tab + 1).matchAll(/:(\d+)->\d+\/(?:tcp|udp)/g)) {
|
|
896
|
+
const port = Number(m[1]);
|
|
897
|
+
if (!held.has(port)) held.set(port, name);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
return held;
|
|
901
|
+
}
|
|
902
|
+
async function findPortConflicts(ports, ignorePrefix, io = defaultPortConflictIo) {
|
|
903
|
+
const unique = [...new Set(ports)].sort((a, b) => a - b);
|
|
904
|
+
const bound = (await Promise.all(unique.map(async (port) => await io.listening(port) ? port : null))).filter(
|
|
905
|
+
(p) => p !== null
|
|
906
|
+
);
|
|
907
|
+
if (bound.length === 0) return [];
|
|
908
|
+
const containers = parseDockerPsPorts(io.dockerPs(), ignorePrefix);
|
|
909
|
+
return bound.map((port) => {
|
|
910
|
+
const container = containers.get(port);
|
|
911
|
+
if (container) return { port, holder: { kind: "container", name: container } };
|
|
912
|
+
const process2 = io.processOn(port);
|
|
913
|
+
return { port, holder: process2 ? { kind: "process", name: process2 } : null };
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
function describePortConflicts(conflicts, moveHints = /* @__PURE__ */ new Map()) {
|
|
917
|
+
const lines = conflicts.flatMap(({ port, holder }) => {
|
|
918
|
+
const remedy = holder?.kind === "container" ? `docker stop ${holder.name}` : `lsof -nP -iTCP:${port} -sTCP:LISTEN, then stop what it names`;
|
|
919
|
+
const what = holder ? `held by ${holder.kind} ${holder.name}` : "held by something lsof would not name";
|
|
920
|
+
const move = moveHints.get(port);
|
|
921
|
+
return move ? [` ${String(port).padEnd(5)} ${what.padEnd(38)} (${remedy})`, ` ${"".padEnd(5)} or: ${move}`] : [` ${String(port).padEnd(5)} ${what.padEnd(38)} (${remedy})`];
|
|
922
|
+
});
|
|
923
|
+
return `Cannot start the local platform \u2014 ${conflicts.length === 1 ? "a host port it needs is" : "host ports it needs are"} already in use:
|
|
924
|
+
` + lines.join("\n") + '\nStop what holds the port (or move it), then run mesh start again. A port lost this way does not fail as "port in use": the container never joins the network and a later service reports an unrelated error.\nIf the port is held by something you cannot stop and the stack can live without it: mesh start --skip-port-check';
|
|
925
|
+
}
|
|
926
|
+
var defaultPortConflictIo;
|
|
870
927
|
var init_helpers = __esm({
|
|
871
928
|
"libs/mesh-cli/src/commands/local/helpers.ts"() {
|
|
872
929
|
"use strict";
|
|
873
930
|
init_seed();
|
|
931
|
+
defaultPortConflictIo = {
|
|
932
|
+
dockerPs: () => {
|
|
933
|
+
try {
|
|
934
|
+
return execFileSync3("docker", ["ps", "--format", "{{.Names}} {{.Ports}}"], {
|
|
935
|
+
encoding: "utf-8",
|
|
936
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
937
|
+
});
|
|
938
|
+
} catch {
|
|
939
|
+
return "";
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
processOn: (port) => {
|
|
943
|
+
try {
|
|
944
|
+
const out = execFileSync3("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-Fc"], {
|
|
945
|
+
encoding: "utf-8",
|
|
946
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
947
|
+
});
|
|
948
|
+
const cmd = out.split("\n").find((l) => l.startsWith("c"));
|
|
949
|
+
return cmd ? cmd.slice(1) : null;
|
|
950
|
+
} catch {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
listening: (port) => probeTcp(port, { timeoutMs: 300 })
|
|
955
|
+
};
|
|
874
956
|
}
|
|
875
957
|
});
|
|
876
958
|
|
|
@@ -922,7 +1004,7 @@ __export(stack_exports, {
|
|
|
922
1004
|
summarizeComposeFailure: () => summarizeComposeFailure,
|
|
923
1005
|
writeAppServiceProbes: () => writeAppServiceProbes
|
|
924
1006
|
});
|
|
925
|
-
import { execFileSync as
|
|
1007
|
+
import { execFileSync as execFileSync4, spawn, spawnSync } from "child_process";
|
|
926
1008
|
import * as fs4 from "fs";
|
|
927
1009
|
import * as path4 from "path";
|
|
928
1010
|
import { fileURLToPath } from "url";
|
|
@@ -1028,7 +1110,7 @@ function stackOwnedElsewhere() {
|
|
|
1028
1110
|
try {
|
|
1029
1111
|
const first = compose(["ps", "-q"]).trim().split("\n").filter(Boolean)[0];
|
|
1030
1112
|
if (!first) return void 0;
|
|
1031
|
-
const label =
|
|
1113
|
+
const label = execFileSync4(
|
|
1032
1114
|
"docker",
|
|
1033
1115
|
["inspect", first, "--format", '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}'],
|
|
1034
1116
|
{ encoding: "utf-8" }
|
|
@@ -1061,7 +1143,7 @@ function compose(args, opts = {}) {
|
|
|
1061
1143
|
const files = ["-f", path4.join(dir, "docker-compose.yml")];
|
|
1062
1144
|
if (opts.hub) files.push("-f", path4.join(dir, "docker-compose.hub.yml"));
|
|
1063
1145
|
const fullArgs = ["compose", "-p", COMPOSE_PROJECT, ...files, ...args];
|
|
1064
|
-
return
|
|
1146
|
+
return execFileSync4("docker", fullArgs, {
|
|
1065
1147
|
cwd: dir,
|
|
1066
1148
|
encoding: "utf-8",
|
|
1067
1149
|
// MESH_LOCAL_LOGS on every call: the compose file mounts it into the
|
|
@@ -1320,10 +1402,10 @@ var init_stack = __esm({
|
|
|
1320
1402
|
// libs/mesh-cli/src/commands/skills.ts
|
|
1321
1403
|
import * as fs5 from "fs";
|
|
1322
1404
|
import * as path5 from "path";
|
|
1323
|
-
import { execFileSync as
|
|
1405
|
+
import { execFileSync as execFileSync5 } from "child_process";
|
|
1324
1406
|
function resolveTargetRoot(startDir = process.cwd()) {
|
|
1325
1407
|
try {
|
|
1326
|
-
return
|
|
1408
|
+
return execFileSync5("git", ["rev-parse", "--show-toplevel"], {
|
|
1327
1409
|
cwd: startDir,
|
|
1328
1410
|
encoding: "utf-8",
|
|
1329
1411
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -1686,7 +1768,7 @@ var init_pid = __esm({
|
|
|
1686
1768
|
});
|
|
1687
1769
|
|
|
1688
1770
|
// libs/mesh-cli/src/utils/tailscale-targets.ts
|
|
1689
|
-
import { execFileSync as
|
|
1771
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
1690
1772
|
import * as fs6 from "node:fs";
|
|
1691
1773
|
import * as path6 from "node:path";
|
|
1692
1774
|
function tenantPortIndex(tenant, registryPath) {
|
|
@@ -1723,7 +1805,7 @@ function resolveTunnelTargets(services, resolveIp, portOffset = 0) {
|
|
|
1723
1805
|
}
|
|
1724
1806
|
function resolveElbIp(host) {
|
|
1725
1807
|
try {
|
|
1726
|
-
const out =
|
|
1808
|
+
const out = execFileSync6("dig", ["+short", host, "@1.1.1.1"], {
|
|
1727
1809
|
encoding: "utf8",
|
|
1728
1810
|
stdio: ["ignore", "pipe", "ignore"]
|
|
1729
1811
|
});
|
|
@@ -1830,7 +1912,7 @@ import * as crypto from "node:crypto";
|
|
|
1830
1912
|
import * as fs7 from "node:fs";
|
|
1831
1913
|
import * as net3 from "node:net";
|
|
1832
1914
|
import * as path7 from "node:path";
|
|
1833
|
-
import { execFileSync as
|
|
1915
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
1834
1916
|
function mintRunnerToken() {
|
|
1835
1917
|
return crypto.randomBytes(16).toString("hex");
|
|
1836
1918
|
}
|
|
@@ -1855,7 +1937,7 @@ function clearRunnerManifest(file, token) {
|
|
|
1855
1937
|
}
|
|
1856
1938
|
function getProcessGroupId(pid) {
|
|
1857
1939
|
try {
|
|
1858
|
-
const out =
|
|
1940
|
+
const out = execFileSync7("ps", ["-o", "pgid=", "-p", String(pid)], {
|
|
1859
1941
|
encoding: "utf8",
|
|
1860
1942
|
stdio: ["ignore", "pipe", "ignore"]
|
|
1861
1943
|
}).trim();
|
|
@@ -1881,7 +1963,7 @@ function parseRunnerPidsFromPs(psOutput, tenant, exclude) {
|
|
|
1881
1963
|
}
|
|
1882
1964
|
function discoverRunnerPids(tenant, exclude) {
|
|
1883
1965
|
try {
|
|
1884
|
-
const out =
|
|
1966
|
+
const out = execFileSync7("ps", ["ax", "-o", "pid=,command="], {
|
|
1885
1967
|
encoding: "utf8",
|
|
1886
1968
|
stdio: ["ignore", "pipe", "ignore"]
|
|
1887
1969
|
});
|
|
@@ -1973,7 +2055,7 @@ async function pollOwnership(check, deadlineMs) {
|
|
|
1973
2055
|
}
|
|
1974
2056
|
function describePortOwner(port) {
|
|
1975
2057
|
try {
|
|
1976
|
-
const out =
|
|
2058
|
+
const out = execFileSync7("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-Fcp"], {
|
|
1977
2059
|
encoding: "utf8",
|
|
1978
2060
|
stdio: ["ignore", "pipe", "ignore"]
|
|
1979
2061
|
});
|
|
@@ -2022,7 +2104,7 @@ import * as fs8 from "node:fs";
|
|
|
2022
2104
|
import * as net4 from "node:net";
|
|
2023
2105
|
import * as os2 from "node:os";
|
|
2024
2106
|
import * as path8 from "node:path";
|
|
2025
|
-
import { spawn as spawn2, execFileSync as
|
|
2107
|
+
import { spawn as spawn2, execFileSync as execFileSync8 } from "node:child_process";
|
|
2026
2108
|
function tenantStateDir(tenant) {
|
|
2027
2109
|
return path8.join(CONFIG_DIR, "tailscale", tenant);
|
|
2028
2110
|
}
|
|
@@ -2097,7 +2179,7 @@ function resolveBrewBin(name) {
|
|
|
2097
2179
|
const brew = `/opt/homebrew/bin/${name}`;
|
|
2098
2180
|
if (fs8.existsSync(brew)) return brew;
|
|
2099
2181
|
try {
|
|
2100
|
-
const p =
|
|
2182
|
+
const p = execFileSync8("which", [name], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
2101
2183
|
if (p) return p;
|
|
2102
2184
|
} catch {
|
|
2103
2185
|
}
|
|
@@ -2106,7 +2188,7 @@ function resolveBrewBin(name) {
|
|
|
2106
2188
|
function daemonState(tenant) {
|
|
2107
2189
|
if (!fs8.existsSync(socketPath(tenant))) return { backendState: "Down" };
|
|
2108
2190
|
try {
|
|
2109
|
-
const out =
|
|
2191
|
+
const out = execFileSync8(
|
|
2110
2192
|
tailscaleBinPath(),
|
|
2111
2193
|
["--socket", socketPath(tenant), "status", "--json"],
|
|
2112
2194
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
|
|
@@ -2126,7 +2208,7 @@ function findRunningDaemon(tenant) {
|
|
|
2126
2208
|
const sock = socketPath(tenant);
|
|
2127
2209
|
let out;
|
|
2128
2210
|
try {
|
|
2129
|
-
out =
|
|
2211
|
+
out = execFileSync8("ps", ["ax", "-o", "pid=,command="], {
|
|
2130
2212
|
encoding: "utf8",
|
|
2131
2213
|
stdio: ["ignore", "pipe", "ignore"]
|
|
2132
2214
|
});
|
|
@@ -2290,7 +2372,7 @@ async function joinHeadscale(tenant, loginServer, opts = {}) {
|
|
|
2290
2372
|
}
|
|
2291
2373
|
function logout(tenant) {
|
|
2292
2374
|
try {
|
|
2293
|
-
|
|
2375
|
+
execFileSync8(tailscaleBinPath(), ["--socket", socketPath(tenant), "logout"], { stdio: "ignore" });
|
|
2294
2376
|
} catch {
|
|
2295
2377
|
}
|
|
2296
2378
|
}
|
|
@@ -2531,8 +2613,8 @@ function guiDomain() {
|
|
|
2531
2613
|
function launchdAvailable() {
|
|
2532
2614
|
if (_launchdAvailable !== void 0) return _launchdAvailable;
|
|
2533
2615
|
try {
|
|
2534
|
-
|
|
2535
|
-
|
|
2616
|
+
execFileSync8("which", ["launchctl"], { stdio: "ignore" });
|
|
2617
|
+
execFileSync8("launchctl", ["print", guiDomain()], { stdio: "ignore" });
|
|
2536
2618
|
_launchdAvailable = true;
|
|
2537
2619
|
} catch {
|
|
2538
2620
|
_launchdAvailable = false;
|
|
@@ -2564,10 +2646,10 @@ function installLaunchAgent(tenant, meshBin) {
|
|
|
2564
2646
|
})
|
|
2565
2647
|
);
|
|
2566
2648
|
try {
|
|
2567
|
-
|
|
2649
|
+
execFileSync8("launchctl", ["bootout", guiDomain(), plistPath], { stdio: "ignore" });
|
|
2568
2650
|
} catch {
|
|
2569
2651
|
}
|
|
2570
|
-
|
|
2652
|
+
execFileSync8("launchctl", ["bootstrap", guiDomain(), plistPath], { stdio: "ignore" });
|
|
2571
2653
|
return true;
|
|
2572
2654
|
} catch {
|
|
2573
2655
|
return false;
|
|
@@ -2576,7 +2658,7 @@ function installLaunchAgent(tenant, meshBin) {
|
|
|
2576
2658
|
function uninstallLaunchAgent(tenant) {
|
|
2577
2659
|
const plistPath = launchAgentPath(tenant);
|
|
2578
2660
|
try {
|
|
2579
|
-
|
|
2661
|
+
execFileSync8("launchctl", ["bootout", guiDomain(), plistPath], { stdio: "ignore" });
|
|
2580
2662
|
} catch {
|
|
2581
2663
|
}
|
|
2582
2664
|
try {
|
|
@@ -2816,7 +2898,7 @@ var init_tunnel = __esm({
|
|
|
2816
2898
|
});
|
|
2817
2899
|
|
|
2818
2900
|
// libs/mesh-cli/src/commands/vpn/index.ts
|
|
2819
|
-
import { execFileSync as
|
|
2901
|
+
import { execFileSync as execFileSync9 } from "child_process";
|
|
2820
2902
|
import * as net6 from "node:net";
|
|
2821
2903
|
function defaultNamespace(tenant, env) {
|
|
2822
2904
|
return `${tenant}-${env}-headscale`;
|
|
@@ -2834,7 +2916,7 @@ function headscaleExec(namespace, args, opts) {
|
|
|
2834
2916
|
stdio: ["pipe", "pipe", "pipe"]
|
|
2835
2917
|
};
|
|
2836
2918
|
try {
|
|
2837
|
-
const result =
|
|
2919
|
+
const result = execFileSync9(
|
|
2838
2920
|
"kubectl",
|
|
2839
2921
|
[
|
|
2840
2922
|
"exec",
|
|
@@ -2863,7 +2945,7 @@ function clusterName(tenant, env) {
|
|
|
2863
2945
|
}
|
|
2864
2946
|
function assertPodReady(namespace, options) {
|
|
2865
2947
|
try {
|
|
2866
|
-
const output =
|
|
2948
|
+
const output = execFileSync9(
|
|
2867
2949
|
"kubectl",
|
|
2868
2950
|
[
|
|
2869
2951
|
"get",
|
|
@@ -2898,7 +2980,7 @@ async function vpnStatus(options) {
|
|
|
2898
2980
|
const ns = resolveNamespace(options);
|
|
2899
2981
|
logInfo(`Checking Headscale in namespace ${ns}...`);
|
|
2900
2982
|
assertPodReady(ns, options);
|
|
2901
|
-
const podJson =
|
|
2983
|
+
const podJson = execFileSync9(
|
|
2902
2984
|
"kubectl",
|
|
2903
2985
|
[
|
|
2904
2986
|
"get",
|
|
@@ -2920,7 +3002,7 @@ async function vpnStatus(options) {
|
|
|
2920
3002
|
const restarts = container?.restartCount ?? 0;
|
|
2921
3003
|
let endpoint = "unknown";
|
|
2922
3004
|
try {
|
|
2923
|
-
endpoint =
|
|
3005
|
+
endpoint = execFileSync9(
|
|
2924
3006
|
"kubectl",
|
|
2925
3007
|
[
|
|
2926
3008
|
"get",
|
|
@@ -3075,7 +3157,7 @@ function findFreePort2() {
|
|
|
3075
3157
|
}
|
|
3076
3158
|
function findTailscale() {
|
|
3077
3159
|
try {
|
|
3078
|
-
return
|
|
3160
|
+
return execFileSync9("which", ["tailscale"], {
|
|
3079
3161
|
encoding: "utf-8",
|
|
3080
3162
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3081
3163
|
}).trim() || null;
|
|
@@ -3085,7 +3167,7 @@ function findTailscale() {
|
|
|
3085
3167
|
}
|
|
3086
3168
|
function tailscaleStatus() {
|
|
3087
3169
|
try {
|
|
3088
|
-
const json =
|
|
3170
|
+
const json = execFileSync9("tailscale", ["status", "--json"], {
|
|
3089
3171
|
encoding: "utf-8",
|
|
3090
3172
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3091
3173
|
});
|
|
@@ -3166,7 +3248,7 @@ async function vpnConnectSystem(endpoint) {
|
|
|
3166
3248
|
"--accept-routes"
|
|
3167
3249
|
];
|
|
3168
3250
|
try {
|
|
3169
|
-
|
|
3251
|
+
execFileSync9("tailscale", upArgs, { stdio: "inherit" });
|
|
3170
3252
|
console.log("");
|
|
3171
3253
|
logSuccess("VPN connected.");
|
|
3172
3254
|
} catch (error) {
|
|
@@ -3193,7 +3275,7 @@ async function vpnDisconnect(opts) {
|
|
|
3193
3275
|
}
|
|
3194
3276
|
logInfo("Disconnecting system VPN\u2026");
|
|
3195
3277
|
try {
|
|
3196
|
-
|
|
3278
|
+
execFileSync9("tailscale", ["down"], { stdio: "inherit" });
|
|
3197
3279
|
logSuccess("VPN disconnected.");
|
|
3198
3280
|
} catch (error) {
|
|
3199
3281
|
const code = error.status;
|
|
@@ -3278,6 +3360,7 @@ __export(login_exports, {
|
|
|
3278
3360
|
getContextConfig: () => getContextConfig,
|
|
3279
3361
|
getValidToken: () => getValidToken,
|
|
3280
3362
|
isRemoteEnvironment: () => isRemoteEnvironment,
|
|
3363
|
+
loginTimeoutMessage: () => loginTimeoutMessage,
|
|
3281
3364
|
probeCredentials: () => probeCredentials,
|
|
3282
3365
|
readAllContextConfigs: () => readAllContextConfigs,
|
|
3283
3366
|
readAllCredentials: () => readAllCredentials,
|
|
@@ -3298,7 +3381,7 @@ import * as http from "http";
|
|
|
3298
3381
|
import * as crypto2 from "crypto";
|
|
3299
3382
|
import * as fs9 from "fs";
|
|
3300
3383
|
import * as path9 from "path";
|
|
3301
|
-
import { execFileSync as
|
|
3384
|
+
import { execFileSync as execFileSync10 } from "child_process";
|
|
3302
3385
|
function readConfig() {
|
|
3303
3386
|
if (!fs9.existsSync(CONFIG_FILE)) return {};
|
|
3304
3387
|
try {
|
|
@@ -3613,9 +3696,9 @@ function login(context, config) {
|
|
|
3613
3696
|
const url = authUrl.toString();
|
|
3614
3697
|
try {
|
|
3615
3698
|
if (process.platform === "darwin") {
|
|
3616
|
-
|
|
3699
|
+
execFileSync10("open", [url], { stdio: "ignore" });
|
|
3617
3700
|
} else if (process.platform === "linux") {
|
|
3618
|
-
|
|
3701
|
+
execFileSync10("xdg-open", [url], { stdio: "ignore" });
|
|
3619
3702
|
} else {
|
|
3620
3703
|
logInfo(`Open this URL in your browser:
|
|
3621
3704
|
${url}`);
|
|
@@ -3627,7 +3710,7 @@ ${url}`);
|
|
|
3627
3710
|
});
|
|
3628
3711
|
timeoutId = setTimeout(() => {
|
|
3629
3712
|
teardown();
|
|
3630
|
-
reject(new Error(
|
|
3713
|
+
reject(new Error(loginTimeoutMessage(context)));
|
|
3631
3714
|
}, 12e4);
|
|
3632
3715
|
});
|
|
3633
3716
|
}
|
|
@@ -3668,9 +3751,9 @@ async function attemptDeviceCode(context, config) {
|
|
|
3668
3751
|
logInfo("Waiting for authorization...");
|
|
3669
3752
|
try {
|
|
3670
3753
|
if (process.platform === "darwin") {
|
|
3671
|
-
|
|
3754
|
+
execFileSync10("open", [openUrl], { stdio: "ignore" });
|
|
3672
3755
|
} else if (process.platform === "linux") {
|
|
3673
|
-
|
|
3756
|
+
execFileSync10("xdg-open", [openUrl], { stdio: "ignore" });
|
|
3674
3757
|
}
|
|
3675
3758
|
} catch {
|
|
3676
3759
|
}
|
|
@@ -3731,6 +3814,11 @@ async function attemptDeviceCode(context, config) {
|
|
|
3731
3814
|
}
|
|
3732
3815
|
return "expired";
|
|
3733
3816
|
}
|
|
3817
|
+
function loginTimeoutMessage(context) {
|
|
3818
|
+
const base = "Login timed out (2 minutes)";
|
|
3819
|
+
if (context !== "local") return base;
|
|
3820
|
+
return `${base}. The local platform already has a signed-up user \u2014 sign in as dev@local.mesh / LocalDev1! instead of registering. If you did register, its confirmation email is in the local mailbox at http://localhost:8025; confirm it there and run the command again.`;
|
|
3821
|
+
}
|
|
3734
3822
|
function isRemoteEnvironment() {
|
|
3735
3823
|
if (process.env.REMOTE_CONTAINERS || process.env.CODESPACES) return true;
|
|
3736
3824
|
if (fs9.existsSync("/.dockerenv")) return true;
|
|
@@ -5306,7 +5394,7 @@ var init_kubeconfig = __esm({
|
|
|
5306
5394
|
});
|
|
5307
5395
|
|
|
5308
5396
|
// libs/mesh-cli/src/utils/temporal-auth.ts
|
|
5309
|
-
import { execFileSync as
|
|
5397
|
+
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
5310
5398
|
async function resolveTemporalAuth(tenant, env, platformName = tenant) {
|
|
5311
5399
|
const { SSMClient: SSMClient5, GetParameterCommand: GetParameterCommand2 } = await import("@aws-sdk/client-ssm");
|
|
5312
5400
|
const ssm = new SSMClient5({ region: process.env.AWS_REGION || "us-east-2" });
|
|
@@ -5350,7 +5438,7 @@ async function resolveTemporalAuth(tenant, env, platformName = tenant) {
|
|
|
5350
5438
|
}
|
|
5351
5439
|
if (!results.ZITADEL_ISSUER) {
|
|
5352
5440
|
try {
|
|
5353
|
-
const podEnv =
|
|
5441
|
+
const podEnv = execFileSync11(
|
|
5354
5442
|
"kubectl",
|
|
5355
5443
|
[
|
|
5356
5444
|
"get",
|
|
@@ -5625,7 +5713,7 @@ var init_dev_launch = __esm({
|
|
|
5625
5713
|
});
|
|
5626
5714
|
|
|
5627
5715
|
// libs/mesh-cli/src/commands/local/mocks.ts
|
|
5628
|
-
import { execFileSync as
|
|
5716
|
+
import { execFileSync as execFileSync12 } from "child_process";
|
|
5629
5717
|
import * as fs14 from "fs";
|
|
5630
5718
|
import * as path14 from "path";
|
|
5631
5719
|
function externalMode(name, decl) {
|
|
@@ -5778,7 +5866,7 @@ async function composeExternalUp(appRoot, sessionName, name, decl, probes = dock
|
|
|
5778
5866
|
if (plan.action === "adopt-stopped") {
|
|
5779
5867
|
const { container } = plan;
|
|
5780
5868
|
logInfo(`External '${name}': container '${container}' exists from another checkout \u2014 starting and adopting it.`);
|
|
5781
|
-
|
|
5869
|
+
execFileSync12("docker", ["start", container], { stdio: ["ignore", "ignore", "inherit"] });
|
|
5782
5870
|
if (!await waitForPort2(decl.port, 3e5)) {
|
|
5783
5871
|
throw new MeshCliError(
|
|
5784
5872
|
`External '${name}': adopted container '${container}' never served localhost:${decl.port}.`,
|
|
@@ -5787,7 +5875,7 @@ async function composeExternalUp(appRoot, sessionName, name, decl, probes = dock
|
|
|
5787
5875
|
}
|
|
5788
5876
|
return void 0;
|
|
5789
5877
|
}
|
|
5790
|
-
|
|
5878
|
+
execFileSync12(
|
|
5791
5879
|
"docker",
|
|
5792
5880
|
["compose", "-p", project, "-f", composeFile, "up", "-d", "--wait", "--wait-timeout", "300"],
|
|
5793
5881
|
{ stdio: ["ignore", "inherit", "inherit"] }
|
|
@@ -5796,7 +5884,7 @@ async function composeExternalUp(appRoot, sessionName, name, decl, probes = dock
|
|
|
5796
5884
|
}
|
|
5797
5885
|
function ownsRunningRealization(composeFile, project) {
|
|
5798
5886
|
try {
|
|
5799
|
-
const out =
|
|
5887
|
+
const out = execFileSync12(
|
|
5800
5888
|
"docker",
|
|
5801
5889
|
["compose", "-p", project, "-f", composeFile, "ps", "--format", "json"],
|
|
5802
5890
|
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
|
|
@@ -5809,7 +5897,7 @@ function ownsRunningRealization(composeFile, project) {
|
|
|
5809
5897
|
function composeServices(composeFile) {
|
|
5810
5898
|
try {
|
|
5811
5899
|
const config = JSON.parse(
|
|
5812
|
-
|
|
5900
|
+
execFileSync12("docker", ["compose", "-f", composeFile, "config", "--format", "json"], {
|
|
5813
5901
|
encoding: "utf-8",
|
|
5814
5902
|
stdio: ["ignore", "pipe", "ignore"]
|
|
5815
5903
|
})
|
|
@@ -5822,7 +5910,7 @@ function composeServices(composeFile) {
|
|
|
5822
5910
|
}
|
|
5823
5911
|
function portPublisher(port) {
|
|
5824
5912
|
try {
|
|
5825
|
-
const out =
|
|
5913
|
+
const out = execFileSync12(
|
|
5826
5914
|
"docker",
|
|
5827
5915
|
[
|
|
5828
5916
|
"ps",
|
|
@@ -5869,7 +5957,7 @@ function foreignPinnedContainer(composeFile, project) {
|
|
|
5869
5957
|
const pinned = svc?.container_name;
|
|
5870
5958
|
if (!pinned) continue;
|
|
5871
5959
|
try {
|
|
5872
|
-
const owner =
|
|
5960
|
+
const owner = execFileSync12(
|
|
5873
5961
|
"docker",
|
|
5874
5962
|
["inspect", pinned, "--format", '{{ index .Config.Labels "com.docker.compose.project" }}'],
|
|
5875
5963
|
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
|
|
@@ -5883,7 +5971,7 @@ function foreignPinnedContainer(composeFile, project) {
|
|
|
5883
5971
|
function composeExternalsDown(refs) {
|
|
5884
5972
|
for (const ref of refs ?? []) {
|
|
5885
5973
|
try {
|
|
5886
|
-
|
|
5974
|
+
execFileSync12("docker", ["compose", "-p", ref.project, "-f", ref.composeFile, "down", "--remove-orphans"], {
|
|
5887
5975
|
stdio: ["ignore", "inherit", "inherit"]
|
|
5888
5976
|
});
|
|
5889
5977
|
} catch {
|
|
@@ -6212,7 +6300,11 @@ var init_src = __esm({
|
|
|
6212
6300
|
description: z.string().optional(),
|
|
6213
6301
|
surfaces: apiSurfaceSchema,
|
|
6214
6302
|
credentials: z.object({ keyedBy: z.string().nullish() }).optional(),
|
|
6215
|
-
docs: z.object({
|
|
6303
|
+
docs: z.object({
|
|
6304
|
+
url: z.string().min(1),
|
|
6305
|
+
contentHash: z.string().min(1),
|
|
6306
|
+
siteUrl: z.string().min(1).optional()
|
|
6307
|
+
}),
|
|
6216
6308
|
enabledOps: z.array(z.string()),
|
|
6217
6309
|
// The consumer schema strips unknown keys, so a producer-side field that is
|
|
6218
6310
|
// not mirrored here never reaches a consumer — mirror every addition.
|
|
@@ -7409,7 +7501,7 @@ var init_dev_local = __esm({
|
|
|
7409
7501
|
});
|
|
7410
7502
|
|
|
7411
7503
|
// libs/mesh-cli/src/commands/local/docker-runner.ts
|
|
7412
|
-
import { execFileSync as
|
|
7504
|
+
import { execFileSync as execFileSync13 } from "child_process";
|
|
7413
7505
|
import * as fs18 from "fs";
|
|
7414
7506
|
import * as path18 from "path";
|
|
7415
7507
|
function sessionDir(sessionName) {
|
|
@@ -7467,29 +7559,29 @@ function composeArgs(sessionName, args) {
|
|
|
7467
7559
|
return ["compose", "-p", sessionName, "-f", path18.join(sessionDir(sessionName), "compose.yml"), ...args];
|
|
7468
7560
|
}
|
|
7469
7561
|
function dockerDevUp(sessionName) {
|
|
7470
|
-
|
|
7562
|
+
execFileSync13("docker", composeArgs(sessionName, ["up", "-d"]), {
|
|
7471
7563
|
stdio: ["ignore", "inherit", "inherit"]
|
|
7472
7564
|
});
|
|
7473
7565
|
}
|
|
7474
7566
|
function dockerDevDown(sessionName) {
|
|
7475
|
-
|
|
7567
|
+
execFileSync13("docker", composeArgs(sessionName, ["down", "--remove-orphans"]), {
|
|
7476
7568
|
stdio: ["ignore", "inherit", "inherit"]
|
|
7477
7569
|
});
|
|
7478
7570
|
}
|
|
7479
7571
|
function dockerDevPs(sessionName) {
|
|
7480
|
-
return
|
|
7572
|
+
return execFileSync13("docker", composeArgs(sessionName, ["ps", "--format", "table {{.Service}} {{.State}} {{.Status}}"]), {
|
|
7481
7573
|
encoding: "utf-8",
|
|
7482
7574
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7483
7575
|
});
|
|
7484
7576
|
}
|
|
7485
7577
|
function dockerDevLogs(sessionName, service, tail) {
|
|
7486
|
-
return
|
|
7578
|
+
return execFileSync13("docker", composeArgs(sessionName, ["logs", "--tail", String(tail), service]), {
|
|
7487
7579
|
encoding: "utf-8",
|
|
7488
7580
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7489
7581
|
});
|
|
7490
7582
|
}
|
|
7491
7583
|
function dockerDevRestart(sessionName, service) {
|
|
7492
|
-
|
|
7584
|
+
execFileSync13("docker", composeArgs(sessionName, ["restart", service]), {
|
|
7493
7585
|
stdio: ["ignore", "inherit", "inherit"]
|
|
7494
7586
|
});
|
|
7495
7587
|
}
|
|
@@ -7558,7 +7650,7 @@ var init_peer_addressing = __esm({
|
|
|
7558
7650
|
});
|
|
7559
7651
|
|
|
7560
7652
|
// libs/mesh-cli/src/utils/worktree-identity.ts
|
|
7561
|
-
import { execFileSync as
|
|
7653
|
+
import { execFileSync as execFileSync14 } from "node:child_process";
|
|
7562
7654
|
import * as crypto3 from "node:crypto";
|
|
7563
7655
|
import * as path19 from "node:path";
|
|
7564
7656
|
function sanitizeSlug(name) {
|
|
@@ -7630,7 +7722,7 @@ var init_worktree_identity = __esm({
|
|
|
7630
7722
|
PORT_BLOCK_SIZE = 40;
|
|
7631
7723
|
PORT_BLOCK_SERVICE_SUBRANGE = 24;
|
|
7632
7724
|
STACK_SLUG_MAX = 16;
|
|
7633
|
-
defaultGitRunner = (args, cwd) =>
|
|
7725
|
+
defaultGitRunner = (args, cwd) => execFileSync14("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
7634
7726
|
}
|
|
7635
7727
|
});
|
|
7636
7728
|
|
|
@@ -7692,7 +7784,7 @@ var init_dev_token_server = __esm({
|
|
|
7692
7784
|
});
|
|
7693
7785
|
|
|
7694
7786
|
// libs/mesh-cli/src/commands/dev.ts
|
|
7695
|
-
import { execFileSync as
|
|
7787
|
+
import { execFileSync as execFileSync15, spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
|
|
7696
7788
|
import * as fs19 from "fs";
|
|
7697
7789
|
import * as net8 from "net";
|
|
7698
7790
|
import * as os6 from "os";
|
|
@@ -8023,7 +8115,7 @@ function detectStack(appRoot, stageArg) {
|
|
|
8023
8115
|
if (stageArg) return stageArg;
|
|
8024
8116
|
if (process.env.MESH_STAGE) return process.env.MESH_STAGE;
|
|
8025
8117
|
try {
|
|
8026
|
-
const result =
|
|
8118
|
+
const result = execFileSync15("pulumi", ["stack", "--show-name"], {
|
|
8027
8119
|
cwd: appRoot,
|
|
8028
8120
|
encoding: "utf-8",
|
|
8029
8121
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -8046,7 +8138,7 @@ function detectStack(appRoot, stageArg) {
|
|
|
8046
8138
|
}
|
|
8047
8139
|
function stackArgs(appRoot, stack) {
|
|
8048
8140
|
try {
|
|
8049
|
-
const selected =
|
|
8141
|
+
const selected = execFileSync15("pulumi", ["stack", "--show-name"], {
|
|
8050
8142
|
cwd: appRoot,
|
|
8051
8143
|
encoding: "utf-8",
|
|
8052
8144
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -8055,7 +8147,7 @@ function stackArgs(appRoot, stack) {
|
|
|
8055
8147
|
} catch {
|
|
8056
8148
|
}
|
|
8057
8149
|
try {
|
|
8058
|
-
|
|
8150
|
+
execFileSync15("pulumi", ["stack", "select", stack], {
|
|
8059
8151
|
cwd: appRoot,
|
|
8060
8152
|
encoding: "utf-8",
|
|
8061
8153
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -8084,7 +8176,7 @@ function getDevOutput(appRoot, stack, awsEnv) {
|
|
|
8084
8176
|
}
|
|
8085
8177
|
function hasTmux() {
|
|
8086
8178
|
try {
|
|
8087
|
-
|
|
8179
|
+
execFileSync15("which", ["tmux"], { stdio: "ignore" });
|
|
8088
8180
|
return true;
|
|
8089
8181
|
} catch {
|
|
8090
8182
|
return false;
|
|
@@ -8092,7 +8184,7 @@ function hasTmux() {
|
|
|
8092
8184
|
}
|
|
8093
8185
|
function sessionExists(name) {
|
|
8094
8186
|
try {
|
|
8095
|
-
|
|
8187
|
+
execFileSync15("tmux", ["has-session", "-t", name], { stdio: "ignore" });
|
|
8096
8188
|
return true;
|
|
8097
8189
|
} catch {
|
|
8098
8190
|
return false;
|
|
@@ -8100,7 +8192,7 @@ function sessionExists(name) {
|
|
|
8100
8192
|
}
|
|
8101
8193
|
function killSession(name) {
|
|
8102
8194
|
try {
|
|
8103
|
-
|
|
8195
|
+
execFileSync15("tmux", ["kill-session", "-t", name], { stdio: "ignore" });
|
|
8104
8196
|
return true;
|
|
8105
8197
|
} catch {
|
|
8106
8198
|
return false;
|
|
@@ -8240,7 +8332,7 @@ function getServiceEnvVars(service, tunnels) {
|
|
|
8240
8332
|
}
|
|
8241
8333
|
function setTmuxEnv(sessionName, vars) {
|
|
8242
8334
|
for (const [key, value] of Object.entries(vars)) {
|
|
8243
|
-
|
|
8335
|
+
execFileSync15("tmux", ["set-environment", "-t", sessionName, key, value], { stdio: "ignore" });
|
|
8244
8336
|
}
|
|
8245
8337
|
}
|
|
8246
8338
|
function envPrefix(vars) {
|
|
@@ -8281,7 +8373,7 @@ function resolveTemporalEncodingKey(tenant, env, appName) {
|
|
|
8281
8373
|
const namespace = `${tenant}-${env}-${appName}`;
|
|
8282
8374
|
const secretName = `${namespace}-temporal-encoding-key`;
|
|
8283
8375
|
try {
|
|
8284
|
-
const b64 =
|
|
8376
|
+
const b64 = execFileSync15(
|
|
8285
8377
|
"kubectl",
|
|
8286
8378
|
[
|
|
8287
8379
|
"get",
|
|
@@ -8486,7 +8578,7 @@ async function allocateSsmLocalPort(remotePort, reservedPorts) {
|
|
|
8486
8578
|
}
|
|
8487
8579
|
function hasSessionManagerPlugin() {
|
|
8488
8580
|
try {
|
|
8489
|
-
|
|
8581
|
+
execFileSync15("which", ["session-manager-plugin"], { stdio: "ignore" });
|
|
8490
8582
|
return true;
|
|
8491
8583
|
} catch {
|
|
8492
8584
|
return false;
|
|
@@ -8585,13 +8677,13 @@ async function startSsmTunnels(sessionName, devOutput) {
|
|
|
8585
8677
|
localPortNumber: [String(localPort)]
|
|
8586
8678
|
})}'`
|
|
8587
8679
|
].join(" ");
|
|
8588
|
-
|
|
8589
|
-
|
|
8680
|
+
execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", windowName]);
|
|
8681
|
+
execFileSync15(
|
|
8590
8682
|
"tmux",
|
|
8591
8683
|
["set-option", "-t", `${sessionName}:${windowName}`, "remain-on-exit", "on"],
|
|
8592
8684
|
{ stdio: "ignore" }
|
|
8593
8685
|
);
|
|
8594
|
-
|
|
8686
|
+
execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:${windowName}`, ssmCmd, "Enter"]);
|
|
8595
8687
|
rewritten.tunnels[tunnelName] = {
|
|
8596
8688
|
host: "localhost",
|
|
8597
8689
|
port: localPort
|
|
@@ -8635,7 +8727,7 @@ async function updateDevboxProxy(devOutput, appRoot) {
|
|
|
8635
8727
|
lines.push("");
|
|
8636
8728
|
}
|
|
8637
8729
|
const caddyfile = lines.join("\n");
|
|
8638
|
-
|
|
8730
|
+
execFileSync15(
|
|
8639
8731
|
"docker",
|
|
8640
8732
|
[
|
|
8641
8733
|
"run",
|
|
@@ -8651,7 +8743,7 @@ CADDYEOF`
|
|
|
8651
8743
|
],
|
|
8652
8744
|
{ stdio: "pipe" }
|
|
8653
8745
|
);
|
|
8654
|
-
|
|
8746
|
+
execFileSync15(
|
|
8655
8747
|
"docker",
|
|
8656
8748
|
[
|
|
8657
8749
|
"run",
|
|
@@ -8722,13 +8814,13 @@ async function setupSubdomainRouting(devOutput, appRoot) {
|
|
|
8722
8814
|
fs19.writeFileSync(caddyfile, caddyLines.join("\n"));
|
|
8723
8815
|
let caddyRunning = false;
|
|
8724
8816
|
try {
|
|
8725
|
-
|
|
8817
|
+
execFileSync15("pgrep", ["-f", "caddy run.*mesh-dev-caddy"], { stdio: "pipe" });
|
|
8726
8818
|
caddyRunning = true;
|
|
8727
8819
|
} catch {
|
|
8728
8820
|
}
|
|
8729
8821
|
if (caddyRunning) {
|
|
8730
8822
|
try {
|
|
8731
|
-
|
|
8823
|
+
execFileSync15("caddy", ["reload", "--config", caddyfile, "--adapter", "caddyfile"], {
|
|
8732
8824
|
stdio: "pipe"
|
|
8733
8825
|
});
|
|
8734
8826
|
} catch {
|
|
@@ -8737,7 +8829,7 @@ async function setupSubdomainRouting(devOutput, appRoot) {
|
|
|
8737
8829
|
}
|
|
8738
8830
|
} else {
|
|
8739
8831
|
try {
|
|
8740
|
-
|
|
8832
|
+
execFileSync15("which", ["caddy"], { stdio: "pipe" });
|
|
8741
8833
|
} catch {
|
|
8742
8834
|
logWarn(
|
|
8743
8835
|
"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"
|
|
@@ -8779,7 +8871,7 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
|
|
|
8779
8871
|
return devOutput;
|
|
8780
8872
|
}
|
|
8781
8873
|
logInfo(`Creating tmux session: ${sessionName}`);
|
|
8782
|
-
|
|
8874
|
+
execFileSync15("tmux", ["new-session", "-d", "-s", sessionName, "-n", "status", "-c", appRoot]);
|
|
8783
8875
|
setTmuxEnv(sessionName, awsEnv);
|
|
8784
8876
|
const hasTunnels = Object.keys(devOutput.tunnels).length > 0;
|
|
8785
8877
|
let effectiveTransport = tunnelPlan.transport;
|
|
@@ -8890,13 +8982,13 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
|
|
|
8890
8982
|
const tokenPort = await findFreePort3();
|
|
8891
8983
|
const tokenUrl = `http://127.0.0.1:${tokenPort}`;
|
|
8892
8984
|
setTmuxEnv(sessionName, { DEV_USER_TOKEN_URL: tokenUrl });
|
|
8893
|
-
|
|
8894
|
-
|
|
8985
|
+
execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", "token-server"]);
|
|
8986
|
+
execFileSync15(
|
|
8895
8987
|
"tmux",
|
|
8896
8988
|
["set-option", "-t", `${sessionName}:token-server`, "remain-on-exit", "on"],
|
|
8897
8989
|
{ stdio: "ignore" }
|
|
8898
8990
|
);
|
|
8899
|
-
|
|
8991
|
+
execFileSync15("tmux", [
|
|
8900
8992
|
"send-keys",
|
|
8901
8993
|
"-t",
|
|
8902
8994
|
`${sessionName}:token-server`,
|
|
@@ -8972,11 +9064,11 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
|
|
|
8972
9064
|
cmd,
|
|
8973
9065
|
service.env?.OTEL_RESOURCE_ATTRIBUTES ? logShipperPath() : void 0
|
|
8974
9066
|
);
|
|
8975
|
-
|
|
8976
|
-
|
|
9067
|
+
execFileSync15("tmux", ["new-window", "-t", sessionName, "-n", name, "-c", serviceDir]);
|
|
9068
|
+
execFileSync15("tmux", ["set-option", "-t", `${sessionName}:${name}`, "remain-on-exit", "on"], {
|
|
8977
9069
|
stdio: "ignore"
|
|
8978
9070
|
});
|
|
8979
|
-
|
|
9071
|
+
execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:${name}`, launchCmd, "Enter"]);
|
|
8980
9072
|
logSuccess(`Started: ${name} (${serviceDir}, port ${service.port})`);
|
|
8981
9073
|
}
|
|
8982
9074
|
if (process.env.DEVCONTAINER === "1") {
|
|
@@ -8987,7 +9079,7 @@ async function startServices(sessionName, appRoot, devOutput, headless, awsEnv,
|
|
|
8987
9079
|
}
|
|
8988
9080
|
}
|
|
8989
9081
|
const statusCmd = `watch -n2 -t npx mesh dev --status --session '${sessionName}'`;
|
|
8990
|
-
|
|
9082
|
+
execFileSync15("tmux", ["send-keys", "-t", `${sessionName}:status`, statusCmd, "Enter"]);
|
|
8991
9083
|
console.log("");
|
|
8992
9084
|
logSuccess(`Dev session started: ${sessionName}`);
|
|
8993
9085
|
console.log("");
|
|
@@ -9044,7 +9136,7 @@ async function showStatus2(sessionName, devOutput, asJson) {
|
|
|
9044
9136
|
}
|
|
9045
9137
|
let windows = [];
|
|
9046
9138
|
try {
|
|
9047
|
-
const raw =
|
|
9139
|
+
const raw = execFileSync15(
|
|
9048
9140
|
"tmux",
|
|
9049
9141
|
["list-windows", "-t", sessionName, "-F", "#{window_name} #{pane_dead}"],
|
|
9050
9142
|
{ encoding: "utf-8" }
|
|
@@ -9166,7 +9258,7 @@ async function restartService(sessionName, serviceName, appRoot, devOutput, awsE
|
|
|
9166
9258
|
}
|
|
9167
9259
|
const target = `${sessionName}:${serviceName}`;
|
|
9168
9260
|
try {
|
|
9169
|
-
|
|
9261
|
+
execFileSync15("tmux", ["respawn-pane", "-k", "-t", target], { stdio: "ignore" });
|
|
9170
9262
|
} catch {
|
|
9171
9263
|
logError(`Window '${serviceName}' not found in session.`);
|
|
9172
9264
|
process.exit(1);
|
|
@@ -9191,7 +9283,7 @@ async function restartService(sessionName, serviceName, appRoot, devOutput, awsE
|
|
|
9191
9283
|
const serviceVars = getServiceEnvVars(service, devOutput.tunnels);
|
|
9192
9284
|
restartCmd = `${envPrefix(serviceVars)}${cmd}`;
|
|
9193
9285
|
}
|
|
9194
|
-
|
|
9286
|
+
execFileSync15("tmux", ["send-keys", "-t", target, restartCmd, "Enter"]);
|
|
9195
9287
|
logSuccess(`Restarted: ${serviceName}`);
|
|
9196
9288
|
}
|
|
9197
9289
|
function showLogs(sessionName, serviceName, tail) {
|
|
@@ -9201,7 +9293,7 @@ function showLogs(sessionName, serviceName, tail) {
|
|
|
9201
9293
|
}
|
|
9202
9294
|
const target = `${sessionName}:${serviceName}`;
|
|
9203
9295
|
try {
|
|
9204
|
-
const result =
|
|
9296
|
+
const result = execFileSync15("tmux", ["capture-pane", "-t", target, "-p", "-S", `-${tail}`], {
|
|
9205
9297
|
encoding: "utf-8"
|
|
9206
9298
|
});
|
|
9207
9299
|
process.stdout.write(result);
|
|
@@ -10084,7 +10176,7 @@ var init_dev = __esm({
|
|
|
10084
10176
|
});
|
|
10085
10177
|
|
|
10086
10178
|
// libs/mesh-cli/src/commands/dev-doctor.ts
|
|
10087
|
-
import { execFileSync as
|
|
10179
|
+
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
10088
10180
|
import * as fs20 from "node:fs";
|
|
10089
10181
|
import * as net9 from "node:net";
|
|
10090
10182
|
import * as path21 from "node:path";
|
|
@@ -10221,7 +10313,7 @@ function collectSessionPids(panePids, psOut) {
|
|
|
10221
10313
|
}
|
|
10222
10314
|
function whoHasPort(port) {
|
|
10223
10315
|
try {
|
|
10224
|
-
const lsof =
|
|
10316
|
+
const lsof = execFileSync16("lsof", ["-ti", `:${port}`], {
|
|
10225
10317
|
encoding: "utf8",
|
|
10226
10318
|
stdio: ["ignore", "pipe", "ignore"]
|
|
10227
10319
|
});
|
|
@@ -10229,7 +10321,7 @@ function whoHasPort(port) {
|
|
|
10229
10321
|
if (!pid) return null;
|
|
10230
10322
|
let ps = "";
|
|
10231
10323
|
try {
|
|
10232
|
-
ps =
|
|
10324
|
+
ps = execFileSync16("ps", ["-o", "comm=", "-p", pid], {
|
|
10233
10325
|
encoding: "utf8",
|
|
10234
10326
|
stdio: ["ignore", "pipe", "ignore"]
|
|
10235
10327
|
});
|
|
@@ -10243,7 +10335,7 @@ function whoHasPort(port) {
|
|
|
10243
10335
|
function sessionProcessTree(sessionName) {
|
|
10244
10336
|
let panePids;
|
|
10245
10337
|
try {
|
|
10246
|
-
const out =
|
|
10338
|
+
const out = execFileSync16(
|
|
10247
10339
|
"tmux",
|
|
10248
10340
|
["list-panes", "-s", "-t", sessionName, "-F", "#{pane_pid}"],
|
|
10249
10341
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }
|
|
@@ -10255,7 +10347,7 @@ function sessionProcessTree(sessionName) {
|
|
|
10255
10347
|
if (panePids.length === 0) return /* @__PURE__ */ new Set();
|
|
10256
10348
|
let psOut = "";
|
|
10257
10349
|
try {
|
|
10258
|
-
psOut =
|
|
10350
|
+
psOut = execFileSync16("ps", ["-eo", "pid=,ppid="], {
|
|
10259
10351
|
encoding: "utf8",
|
|
10260
10352
|
stdio: ["ignore", "pipe", "ignore"]
|
|
10261
10353
|
});
|
|
@@ -10377,7 +10469,7 @@ var init_dev_doctor = __esm({
|
|
|
10377
10469
|
phases: ["preflight", "ondemand"],
|
|
10378
10470
|
async run() {
|
|
10379
10471
|
try {
|
|
10380
|
-
|
|
10472
|
+
execFileSync16("which", ["tmux"], { stdio: "ignore" });
|
|
10381
10473
|
return { status: "ok", summary: "installed" };
|
|
10382
10474
|
} catch {
|
|
10383
10475
|
return {
|
|
@@ -10482,7 +10574,7 @@ var init_dev_doctor = __esm({
|
|
|
10482
10574
|
}
|
|
10483
10575
|
let repoRoot2;
|
|
10484
10576
|
try {
|
|
10485
|
-
repoRoot2 =
|
|
10577
|
+
repoRoot2 = execFileSync16("git", ["rev-parse", "--show-toplevel"], {
|
|
10486
10578
|
cwd: ctx.appRoot,
|
|
10487
10579
|
encoding: "utf8",
|
|
10488
10580
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -10705,6 +10797,209 @@ function authzSurface(app) {
|
|
|
10705
10797
|
walk2(app);
|
|
10706
10798
|
return hits;
|
|
10707
10799
|
}
|
|
10800
|
+
function balancedSpan(text, open) {
|
|
10801
|
+
const closers = { "(": ")", "{": "}", "[": "]" };
|
|
10802
|
+
const stack = [];
|
|
10803
|
+
let quote;
|
|
10804
|
+
for (let i = open; i < text.length; i++) {
|
|
10805
|
+
const ch = text[i];
|
|
10806
|
+
if (quote) {
|
|
10807
|
+
if (ch === "\\") i++;
|
|
10808
|
+
else if (ch === quote) quote = void 0;
|
|
10809
|
+
continue;
|
|
10810
|
+
}
|
|
10811
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
10812
|
+
quote = ch;
|
|
10813
|
+
continue;
|
|
10814
|
+
}
|
|
10815
|
+
if (ch === "/" && text[i + 1] === "/") {
|
|
10816
|
+
const eol = text.indexOf("\n", i);
|
|
10817
|
+
if (eol === -1) return "";
|
|
10818
|
+
i = eol;
|
|
10819
|
+
continue;
|
|
10820
|
+
}
|
|
10821
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
10822
|
+
const end = text.indexOf("*/", i + 2);
|
|
10823
|
+
if (end === -1) return "";
|
|
10824
|
+
i = end + 1;
|
|
10825
|
+
continue;
|
|
10826
|
+
}
|
|
10827
|
+
if (closers[ch]) stack.push(closers[ch]);
|
|
10828
|
+
else if (ch === ")" || ch === "}" || ch === "]") {
|
|
10829
|
+
if (stack.pop() !== ch) return "";
|
|
10830
|
+
if (stack.length === 0) return text.slice(open, i + 1);
|
|
10831
|
+
}
|
|
10832
|
+
}
|
|
10833
|
+
return "";
|
|
10834
|
+
}
|
|
10835
|
+
function splitTopLevel(inner) {
|
|
10836
|
+
const parts = [];
|
|
10837
|
+
let depth = 0;
|
|
10838
|
+
let quote;
|
|
10839
|
+
let start = 0;
|
|
10840
|
+
for (let i = 0; i < inner.length; i++) {
|
|
10841
|
+
const ch = inner[i];
|
|
10842
|
+
if (quote) {
|
|
10843
|
+
if (ch === "\\") i++;
|
|
10844
|
+
else if (ch === quote) quote = void 0;
|
|
10845
|
+
continue;
|
|
10846
|
+
}
|
|
10847
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
10848
|
+
quote = ch;
|
|
10849
|
+
continue;
|
|
10850
|
+
}
|
|
10851
|
+
if (ch === "/" && inner[i + 1] === "/") {
|
|
10852
|
+
const eol = inner.indexOf("\n", i);
|
|
10853
|
+
if (eol === -1) break;
|
|
10854
|
+
i = eol;
|
|
10855
|
+
continue;
|
|
10856
|
+
}
|
|
10857
|
+
if (ch === "/" && inner[i + 1] === "*") {
|
|
10858
|
+
const end = inner.indexOf("*/", i + 2);
|
|
10859
|
+
if (end === -1) break;
|
|
10860
|
+
i = end + 1;
|
|
10861
|
+
continue;
|
|
10862
|
+
}
|
|
10863
|
+
if (ch === "(" || ch === "{" || ch === "[") depth++;
|
|
10864
|
+
else if (ch === ")" || ch === "}" || ch === "]") depth--;
|
|
10865
|
+
else if (ch === "," && depth === 0) {
|
|
10866
|
+
parts.push(inner.slice(start, i));
|
|
10867
|
+
start = i + 1;
|
|
10868
|
+
}
|
|
10869
|
+
}
|
|
10870
|
+
const last = inner.slice(start);
|
|
10871
|
+
if (last.trim()) parts.push(last);
|
|
10872
|
+
return parts;
|
|
10873
|
+
}
|
|
10874
|
+
function stripLeadingComments(entry) {
|
|
10875
|
+
let text = entry;
|
|
10876
|
+
for (; ; ) {
|
|
10877
|
+
const next = text.replace(/^\s*(?:\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)/, "");
|
|
10878
|
+
if (next === text) return text;
|
|
10879
|
+
text = next;
|
|
10880
|
+
}
|
|
10881
|
+
}
|
|
10882
|
+
function stripTrailingComments(value) {
|
|
10883
|
+
let out = "";
|
|
10884
|
+
let depth = 0;
|
|
10885
|
+
let quote;
|
|
10886
|
+
for (let i = 0; i < value.length; i++) {
|
|
10887
|
+
const ch = value[i];
|
|
10888
|
+
if (quote) {
|
|
10889
|
+
out += ch;
|
|
10890
|
+
if (ch === "\\") {
|
|
10891
|
+
out += value[i + 1] ?? "";
|
|
10892
|
+
i++;
|
|
10893
|
+
} else if (ch === quote) quote = void 0;
|
|
10894
|
+
continue;
|
|
10895
|
+
}
|
|
10896
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
10897
|
+
quote = ch;
|
|
10898
|
+
out += ch;
|
|
10899
|
+
continue;
|
|
10900
|
+
}
|
|
10901
|
+
if (depth === 0 && ch === "/" && value[i + 1] === "/") {
|
|
10902
|
+
const eol = value.indexOf("\n", i);
|
|
10903
|
+
if (eol === -1) break;
|
|
10904
|
+
i = eol;
|
|
10905
|
+
out += "\n";
|
|
10906
|
+
continue;
|
|
10907
|
+
}
|
|
10908
|
+
if (depth === 0 && ch === "/" && value[i + 1] === "*") {
|
|
10909
|
+
const end = value.indexOf("*/", i + 2);
|
|
10910
|
+
if (end === -1) break;
|
|
10911
|
+
i = end + 1;
|
|
10912
|
+
continue;
|
|
10913
|
+
}
|
|
10914
|
+
if (ch === "(" || ch === "{" || ch === "[") depth++;
|
|
10915
|
+
else if (ch === ")" || ch === "}" || ch === "]") depth--;
|
|
10916
|
+
out += ch;
|
|
10917
|
+
}
|
|
10918
|
+
return out.trim();
|
|
10919
|
+
}
|
|
10920
|
+
function topLevelProperties(objectText) {
|
|
10921
|
+
const props = /* @__PURE__ */ new Map();
|
|
10922
|
+
if (!objectText.startsWith("{") || !objectText.endsWith("}")) return props;
|
|
10923
|
+
for (const entry of splitTopLevel(objectText.slice(1, -1))) {
|
|
10924
|
+
const text = stripLeadingComments(entry).trim();
|
|
10925
|
+
if (!text || text.startsWith("...")) continue;
|
|
10926
|
+
const m = RE_PROPERTY.exec(text);
|
|
10927
|
+
if (!m) continue;
|
|
10928
|
+
const key = m[1] ?? m[2] ?? m[3];
|
|
10929
|
+
props.set(key, stripTrailingComments(m[4] ?? key));
|
|
10930
|
+
}
|
|
10931
|
+
return props;
|
|
10932
|
+
}
|
|
10933
|
+
function objectLiteralOf(value, program2) {
|
|
10934
|
+
if (!value) return void 0;
|
|
10935
|
+
if (value.startsWith("{")) return balancedSpan(value, 0) || void 0;
|
|
10936
|
+
const id = /^[A-Za-z_$][\w$]*$/.exec(value)?.[0];
|
|
10937
|
+
if (!id) return void 0;
|
|
10938
|
+
const decl = new RegExp(`\\bconst\\s+${id}\\s*(?::[^=]+)?=\\s*\\{`).exec(program2);
|
|
10939
|
+
return decl ? balancedSpan(program2, decl.index + decl[0].length - 1) || void 0 : void 0;
|
|
10940
|
+
}
|
|
10941
|
+
function optionsObject(body) {
|
|
10942
|
+
for (const arg of splitTopLevel(body.slice(1, -1))) {
|
|
10943
|
+
const trimmed = arg.trim();
|
|
10944
|
+
if (trimmed.startsWith("{")) return balancedSpan(trimmed, 0) || void 0;
|
|
10945
|
+
}
|
|
10946
|
+
return void 0;
|
|
10947
|
+
}
|
|
10948
|
+
function surfaceDeclarations(text, pattern = RE_SURFACE_NEW) {
|
|
10949
|
+
const out = [];
|
|
10950
|
+
for (const m of text.matchAll(pattern)) {
|
|
10951
|
+
const body = balancedSpan(text, m.index + m[0].length - 1);
|
|
10952
|
+
if (!body) continue;
|
|
10953
|
+
out.push({ ctor: m[1] ?? "ApiDocs", body, line: text.slice(0, m.index).split("\n").length });
|
|
10954
|
+
}
|
|
10955
|
+
return out;
|
|
10956
|
+
}
|
|
10957
|
+
function isClientAuth(value) {
|
|
10958
|
+
return value !== void 0 && value !== "undefined" && !RE_DEV_BYPASS.test(value);
|
|
10959
|
+
}
|
|
10960
|
+
function docsSiteFindings(text) {
|
|
10961
|
+
const findings = [];
|
|
10962
|
+
for (const decl of surfaceDeclarations(text)) {
|
|
10963
|
+
const options = optionsObject(decl.body);
|
|
10964
|
+
if (!options) continue;
|
|
10965
|
+
const args = topLevelProperties(options);
|
|
10966
|
+
const docsText = objectLiteralOf(args.get("docs"), text);
|
|
10967
|
+
if (!docsText) continue;
|
|
10968
|
+
const docs = topLevelProperties(docsText);
|
|
10969
|
+
if (docs.get("site") === "false") continue;
|
|
10970
|
+
if (docs.get("site") !== "true" && !DOCS_SITE_FIELDS.some((f) => docs.has(f))) continue;
|
|
10971
|
+
const httpText = objectLiteralOf(topLevelProperties(objectLiteralOf(args.get("surfaces"), text) ?? "{}").get("http"), text);
|
|
10972
|
+
const hasClient = isClientAuth(docs.get("auth")) || isClientAuth(topLevelProperties(httpText ?? "{}").get("auth"));
|
|
10973
|
+
if (!hasClient) {
|
|
10974
|
+
findings.push({
|
|
10975
|
+
code: "DOCS_SITE_UNAUTHED",
|
|
10976
|
+
line: decl.line,
|
|
10977
|
+
why: `mesh.apps.${decl.ctor} declares a docs site with no OIDC client \u2014 the site is served behind the platform sign-in proxy, which needs one (docs.auth, or a client on surfaces.http.auth)`
|
|
10978
|
+
});
|
|
10979
|
+
}
|
|
10980
|
+
const kindStated = decl.ctor === "AppApiSurface" || decl.ctor === "VendorApiSurface" || args.has("kind");
|
|
10981
|
+
if (!kindStated && !docs.has("audience")) {
|
|
10982
|
+
findings.push({
|
|
10983
|
+
code: "DOCS_AUDIENCE_IMPLICIT",
|
|
10984
|
+
line: decl.line,
|
|
10985
|
+
why: `mesh.apps.${decl.ctor} declares a docs site but neither its kind nor its audience \u2014 who may read it would fall out of the name heuristic, and a vendor surface must never default to partner-readable that way`
|
|
10986
|
+
});
|
|
10987
|
+
}
|
|
10988
|
+
}
|
|
10989
|
+
for (const decl of surfaceDeclarations(text, RE_APIDOCS_NEW)) {
|
|
10990
|
+
const options = optionsObject(decl.body);
|
|
10991
|
+
if (!options) continue;
|
|
10992
|
+
const args = topLevelProperties(options);
|
|
10993
|
+
if (!args.has("ingress") || args.get("ingress") === "undefined") continue;
|
|
10994
|
+
if (isClientAuth(args.get("auth"))) continue;
|
|
10995
|
+
findings.push({
|
|
10996
|
+
code: "DOCS_SITE_UNAUTHED",
|
|
10997
|
+
line: decl.line,
|
|
10998
|
+
why: `mesh.apps.ApiDocs is published on an ingress with no auth \u2014 the site (reference and playground) is reachable by anyone; put the platform sign-in proxy in front of it, or drop the ingress`
|
|
10999
|
+
});
|
|
11000
|
+
}
|
|
11001
|
+
return findings;
|
|
11002
|
+
}
|
|
10708
11003
|
function listApps(root) {
|
|
10709
11004
|
const apps = [];
|
|
10710
11005
|
const appsDir = path22.join(root, "apps");
|
|
@@ -10753,6 +11048,7 @@ function scanApp(root, appRel) {
|
|
|
10753
11048
|
if (!/env\.register\(|\.annotate\(/.test(readText(index))) {
|
|
10754
11049
|
hit("NO_REGISTER", indexRel, "never calls env.register({\u2026}) \u2014 the Hub cannot list this app");
|
|
10755
11050
|
}
|
|
11051
|
+
for (const f of docsSiteFindings(readText(index))) hit(f.code, `${indexRel}:${f.line}`, f.why);
|
|
10756
11052
|
for (const svc of serviceDirs(app)) {
|
|
10757
11053
|
for (const f of srcFiles(svc)) {
|
|
10758
11054
|
const text = readText(f);
|
|
@@ -10909,7 +11205,7 @@ function registerAppCommands(program2) {
|
|
|
10909
11205
|
}
|
|
10910
11206
|
});
|
|
10911
11207
|
}
|
|
10912
|
-
var APP_CHECK_RULES, APP_CHECK_CODES, SRC_EXT, SKIP_DIRS, NON_SERVICE_DIRS, RE_HTML, RE_OIDC, RE_COOKIE, RE_LOGGER, RE_EXPOSURE, RE_POINTER, RE_METADATA, RE_IAC_GRANT, RE_POINTER_OVERRIDE, RE_PASSWORD, RE_ALLOWLIST, RE_USERS_TABLE;
|
|
11208
|
+
var APP_CHECK_RULES, APP_CHECK_CODES, SRC_EXT, SKIP_DIRS, NON_SERVICE_DIRS, RE_HTML, RE_OIDC, RE_COOKIE, RE_LOGGER, RE_EXPOSURE, RE_POINTER, RE_METADATA, RE_IAC_GRANT, RE_POINTER_OVERRIDE, RE_PASSWORD, RE_ALLOWLIST, RE_USERS_TABLE, RE_SURFACE_NEW, RE_APIDOCS_NEW, DOCS_SITE_FIELDS, RE_DEV_BYPASS, RE_PROPERTY;
|
|
10913
11209
|
var init_app_check = __esm({
|
|
10914
11210
|
"libs/mesh-cli/src/commands/app-check.ts"() {
|
|
10915
11211
|
"use strict";
|
|
@@ -11008,6 +11304,20 @@ var init_app_check = __esm({
|
|
|
11008
11304
|
severity: "block",
|
|
11009
11305
|
remediation: "drop the table; people and roles live in Zitadel and are administered from the Hub",
|
|
11010
11306
|
scope: "app"
|
|
11307
|
+
},
|
|
11308
|
+
DOCS_SITE_UNAUTHED: {
|
|
11309
|
+
gate: "0.3",
|
|
11310
|
+
title: "Docs site behind the platform sign-in",
|
|
11311
|
+
severity: "block",
|
|
11312
|
+
remediation: 'on an API surface: docs: { auth: { clientId, clientSecret } } (or a client on surfaces.http.auth), or opt out with docs: { site: false }; on a mesh.apps.ApiDocs: auth: { provider: "mesh", clientId, clientSecret }, or drop the ingress (an in-cluster site is reachable through mesh dev)',
|
|
11313
|
+
scope: "app"
|
|
11314
|
+
},
|
|
11315
|
+
DOCS_AUDIENCE_IMPLICIT: {
|
|
11316
|
+
gate: "H",
|
|
11317
|
+
title: "Docs audience stated, not derived",
|
|
11318
|
+
severity: "block",
|
|
11319
|
+
remediation: 'declare the surface as mesh.apps.AppApiSurface or VendorApiSurface (or pass kind: "app" | "vendor"), or state docs: { audience: { roles: [\u2026] } }',
|
|
11320
|
+
scope: "app"
|
|
11011
11321
|
}
|
|
11012
11322
|
};
|
|
11013
11323
|
APP_CHECK_CODES = Object.keys(APP_CHECK_RULES);
|
|
@@ -11039,6 +11349,11 @@ var init_app_check = __esm({
|
|
|
11039
11349
|
RE_PASSWORD = /(^|[^a-z])(bcrypt|argon2)|password_hash|passwordHash|hashPassword|temporaryPassword.*(send|mail)|(send|mail).*temporaryPassword/;
|
|
11040
11350
|
RE_ALLOWLIST = /ADMIN_EMAILS|ALLOWED_EMAILS|allowedEmails|adminEmails/;
|
|
11041
11351
|
RE_USERS_TABLE = /create table (if not exists )?"?(users|roles|user_roles|permissions)"?/i;
|
|
11352
|
+
RE_SURFACE_NEW = /new\s+mesh\.apps\.(ApiSurface|AppApiSurface|VendorApiSurface|Integration)\s*\(/g;
|
|
11353
|
+
RE_APIDOCS_NEW = /new\s+mesh\.apps\.ApiDocs\s*\(/g;
|
|
11354
|
+
DOCS_SITE_FIELDS = ["pages", "playground", "audience", "basePath", "ingress", "auth"];
|
|
11355
|
+
RE_DEV_BYPASS = /^["']dev-bypass["']$/;
|
|
11356
|
+
RE_PROPERTY = /^(?:"([^"]+)"|'([^']+)'|([A-Za-z_$][\w$]*))\s*(?::\s*([\s\S]*))?$/;
|
|
11042
11357
|
}
|
|
11043
11358
|
});
|
|
11044
11359
|
|
|
@@ -12229,7 +12544,7 @@ var init_conversations = __esm({
|
|
|
12229
12544
|
});
|
|
12230
12545
|
|
|
12231
12546
|
// libs/mesh-cli/src/utils/scaffold-versions.ts
|
|
12232
|
-
import { execFileSync as
|
|
12547
|
+
import { execFileSync as execFileSync17 } from "child_process";
|
|
12233
12548
|
function isPrerelease(range) {
|
|
12234
12549
|
return /[-+]/.test(range.replace(/^\^/, ""));
|
|
12235
12550
|
}
|
|
@@ -12239,7 +12554,7 @@ function toCaretRange(version) {
|
|
|
12239
12554
|
}
|
|
12240
12555
|
function resolvePublishedRange(pkg, cwd) {
|
|
12241
12556
|
try {
|
|
12242
|
-
const out =
|
|
12557
|
+
const out = execFileSync17("npm", ["view", pkg, "version"], {
|
|
12243
12558
|
cwd,
|
|
12244
12559
|
encoding: "utf-8",
|
|
12245
12560
|
timeout: 15e3,
|
|
@@ -12273,6 +12588,7 @@ __export(create_app_exports, {
|
|
|
12273
12588
|
NO_REGISTRY_ACCESS_MESSAGE: () => NO_REGISTRY_ACCESS_MESSAGE,
|
|
12274
12589
|
PLATFORM_MONOREPO_NAME: () => PLATFORM_MONOREPO_NAME,
|
|
12275
12590
|
bootstrapAppsRepo: () => bootstrapAppsRepo,
|
|
12591
|
+
composableNextSteps: () => composableNextSteps,
|
|
12276
12592
|
copyTemplate: () => copyTemplate,
|
|
12277
12593
|
describeNoAppsHome: () => describeNoAppsHome,
|
|
12278
12594
|
ensureRegistryAccess: () => ensureRegistryAccess,
|
|
@@ -12786,15 +13102,30 @@ function printComposableNextSteps(appDir, context) {
|
|
|
12786
13102
|
console.log(" api/src/storage.ts S3 helpers");
|
|
12787
13103
|
}
|
|
12788
13104
|
console.log("");
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
13105
|
+
for (const line of composableNextSteps(appDir, findMeshJson(process.cwd())?.data.platform ?? null)) {
|
|
13106
|
+
console.log(line);
|
|
13107
|
+
}
|
|
13108
|
+
}
|
|
13109
|
+
function composableNextSteps(appDir, platform) {
|
|
13110
|
+
const common = [
|
|
13111
|
+
"Next steps:",
|
|
13112
|
+
` cd ${appDir}`,
|
|
13113
|
+
" pnpm install",
|
|
13114
|
+
" mesh skills sync # re-run once deps are installed: picks up package skills + Intent",
|
|
13115
|
+
" pnpm install # again only if skills sync reports it added @tanstack/intent"
|
|
13116
|
+
];
|
|
13117
|
+
const local = [
|
|
13118
|
+
" mesh start # the local Mesh platform (once; Docker \u2014 from anywhere)",
|
|
13119
|
+
" mesh dev # run the app against it"
|
|
13120
|
+
];
|
|
13121
|
+
const deploy = [
|
|
13122
|
+
" mesh stack init # personal dev stack (deploy: false)",
|
|
13123
|
+
" mesh deploy up --yes # deploy via the stack's deployer role"
|
|
13124
|
+
];
|
|
13125
|
+
if (platform === null || platform === "local") {
|
|
13126
|
+
return [...common, ...local, "", "When you deploy to a Mesh platform:", ...deploy];
|
|
13127
|
+
}
|
|
13128
|
+
return [...common, ...deploy, " mesh dev # run locally against the platform"];
|
|
12798
13129
|
}
|
|
12799
13130
|
var __filename, __dirname, packageRoot, TEMPLATES, REMOVED_TEMPLATES, PRIMITIVES, HUB_ACCOUNTS, PLATFORM_MONOREPO_NAME, VALID_PRIMITIVES, NO_REGISTRY_ACCESS_MESSAGE;
|
|
12800
13131
|
var init_create_app = __esm({
|
|
@@ -13558,7 +13889,7 @@ var init_deploy_preflight = __esm({
|
|
|
13558
13889
|
});
|
|
13559
13890
|
|
|
13560
13891
|
// libs/mesh-cli/src/commands/deploy.ts
|
|
13561
|
-
import { execFileSync as
|
|
13892
|
+
import { execFileSync as execFileSync18 } from "child_process";
|
|
13562
13893
|
function buildPulumiArgs(pulumiArgs, stack) {
|
|
13563
13894
|
const base = pulumiArgs.length === 0 || pulumiArgs[0]?.startsWith("-") ? ["up", ...pulumiArgs] : [...pulumiArgs];
|
|
13564
13895
|
const op = base[0];
|
|
@@ -13621,7 +13952,7 @@ function registerDeployCommand(program2) {
|
|
|
13621
13952
|
delete env.AWS_PROFILE;
|
|
13622
13953
|
const finalArgs = buildPulumiArgs(pulumiArgs, stack);
|
|
13623
13954
|
try {
|
|
13624
|
-
|
|
13955
|
+
execFileSync18("pulumi", finalArgs, {
|
|
13625
13956
|
cwd: appRoot,
|
|
13626
13957
|
env,
|
|
13627
13958
|
stdio: "inherit"
|
|
@@ -13914,7 +14245,7 @@ var init_discover = __esm({
|
|
|
13914
14245
|
});
|
|
13915
14246
|
|
|
13916
14247
|
// libs/mesh-cli/src/docs/assemble.ts
|
|
13917
|
-
import { execFileSync as
|
|
14248
|
+
import { execFileSync as execFileSync19 } from "node:child_process";
|
|
13918
14249
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync23, rmSync as rmSync5, writeFileSync as writeFileSync15 } from "node:fs";
|
|
13919
14250
|
import path28 from "node:path";
|
|
13920
14251
|
import { parse as parseYaml4 } from "yaml";
|
|
@@ -14405,7 +14736,7 @@ function renderVersionJson(args) {
|
|
|
14405
14736
|
}
|
|
14406
14737
|
function currentCommit(repoRoot2) {
|
|
14407
14738
|
try {
|
|
14408
|
-
return
|
|
14739
|
+
return execFileSync19("git", ["rev-parse", "--short", "HEAD"], {
|
|
14409
14740
|
cwd: repoRoot2,
|
|
14410
14741
|
encoding: "utf-8"
|
|
14411
14742
|
}).trim();
|
|
@@ -14424,7 +14755,7 @@ function currentBaseline(repoRoot2) {
|
|
|
14424
14755
|
}
|
|
14425
14756
|
}
|
|
14426
14757
|
function publishSetAtRef(repoRoot2, ref) {
|
|
14427
|
-
const git = (gitArgs) =>
|
|
14758
|
+
const git = (gitArgs) => execFileSync19("git", gitArgs, {
|
|
14428
14759
|
cwd: repoRoot2,
|
|
14429
14760
|
encoding: "utf-8",
|
|
14430
14761
|
maxBuffer: 64 * 1024 * 1024
|
|
@@ -14912,7 +15243,7 @@ var init_portal = __esm({
|
|
|
14912
15243
|
});
|
|
14913
15244
|
|
|
14914
15245
|
// libs/mesh-cli/src/utils/build-info.ts
|
|
14915
|
-
import { execFileSync as
|
|
15246
|
+
import { execFileSync as execFileSync20 } from "child_process";
|
|
14916
15247
|
import * as fs25 from "fs";
|
|
14917
15248
|
import * as path30 from "path";
|
|
14918
15249
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -14970,7 +15301,7 @@ function resolveCliRuntime(opts) {
|
|
|
14970
15301
|
}
|
|
14971
15302
|
if (!vcs) return info;
|
|
14972
15303
|
try {
|
|
14973
|
-
const git = (args) =>
|
|
15304
|
+
const git = (args) => execFileSync20("git", args, {
|
|
14974
15305
|
cwd: root,
|
|
14975
15306
|
encoding: "utf-8",
|
|
14976
15307
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -15067,7 +15398,7 @@ var init_serve = __esm({
|
|
|
15067
15398
|
});
|
|
15068
15399
|
|
|
15069
15400
|
// libs/mesh-cli/src/docs/registry-docs.ts
|
|
15070
|
-
import { execFileSync as
|
|
15401
|
+
import { execFileSync as execFileSync21 } from "node:child_process";
|
|
15071
15402
|
import { existsSync as existsSync23, mkdirSync as mkdirSync13, readFileSync as readFileSync26, renameSync as renameSync3, rmSync as rmSync6, writeFileSync as writeFileSync17 } from "node:fs";
|
|
15072
15403
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
15073
15404
|
import path31 from "node:path";
|
|
@@ -15159,7 +15490,7 @@ async function fetchDocsArtifact(auth, version, cacheRoot = docsCacheRoot(), fet
|
|
|
15159
15490
|
rmSync6(staging, { recursive: true, force: true });
|
|
15160
15491
|
mkdirSync13(staging, { recursive: true });
|
|
15161
15492
|
try {
|
|
15162
|
-
|
|
15493
|
+
execFileSync21("tar", ["-xzf", tgzPath, "-C", staging, "--strip-components", "1"], {
|
|
15163
15494
|
stdio: ["pipe", "pipe", "pipe"]
|
|
15164
15495
|
});
|
|
15165
15496
|
} finally {
|
|
@@ -15197,7 +15528,7 @@ __export(start_exports, {
|
|
|
15197
15528
|
tmuxInstallHint: () => tmuxInstallHint,
|
|
15198
15529
|
tmuxServeArgs: () => tmuxServeArgs
|
|
15199
15530
|
});
|
|
15200
|
-
import { execFileSync as
|
|
15531
|
+
import { execFileSync as execFileSync22 } from "node:child_process";
|
|
15201
15532
|
import { appendFileSync as appendFileSync2, existsSync as existsSync24, writeFileSync as writeFileSync18 } from "node:fs";
|
|
15202
15533
|
import path32 from "node:path";
|
|
15203
15534
|
function registryAuthOrThrow() {
|
|
@@ -15230,7 +15561,7 @@ function tmuxInstallHint(platform = process.platform) {
|
|
|
15230
15561
|
}
|
|
15231
15562
|
function tmuxAvailable() {
|
|
15232
15563
|
try {
|
|
15233
|
-
|
|
15564
|
+
execFileSync22("tmux", ["-V"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
15234
15565
|
return true;
|
|
15235
15566
|
} catch {
|
|
15236
15567
|
return false;
|
|
@@ -15241,7 +15572,7 @@ function shouldDetach(args) {
|
|
|
15241
15572
|
}
|
|
15242
15573
|
function docsSessionExists() {
|
|
15243
15574
|
try {
|
|
15244
|
-
|
|
15575
|
+
execFileSync22("tmux", ["has-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
|
|
15245
15576
|
return true;
|
|
15246
15577
|
} catch {
|
|
15247
15578
|
return false;
|
|
@@ -15265,12 +15596,12 @@ Or run in the foreground instead: mesh docs start --foreground`
|
|
|
15265
15596
|
if (docsSessionExists()) {
|
|
15266
15597
|
logInfo(`Replacing the docs server already running in tmux session "${DOCS_TMUX_SESSION}".`);
|
|
15267
15598
|
try {
|
|
15268
|
-
|
|
15599
|
+
execFileSync22("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
|
|
15269
15600
|
} catch {
|
|
15270
15601
|
}
|
|
15271
15602
|
}
|
|
15272
15603
|
const { command, cwd } = tmuxServeArgs(args);
|
|
15273
|
-
|
|
15604
|
+
execFileSync22(
|
|
15274
15605
|
"tmux",
|
|
15275
15606
|
["new-session", "-d", "-s", DOCS_TMUX_SESSION, "-c", cwd, "--", ...command],
|
|
15276
15607
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -15308,7 +15639,7 @@ function printReady(url, label) {
|
|
|
15308
15639
|
}
|
|
15309
15640
|
function runDocsStop() {
|
|
15310
15641
|
try {
|
|
15311
|
-
|
|
15642
|
+
execFileSync22("tmux", ["kill-session", "-t", DOCS_TMUX_SESSION], { stdio: ["pipe", "pipe", "pipe"] });
|
|
15312
15643
|
logSuccess(`Stopped the docs server (tmux session "${DOCS_TMUX_SESSION}").`);
|
|
15313
15644
|
} catch {
|
|
15314
15645
|
logInfo(`No docs server is running (no tmux session named "${DOCS_TMUX_SESSION}").`);
|
|
@@ -15681,7 +16012,7 @@ var init_docs = __esm({
|
|
|
15681
16012
|
});
|
|
15682
16013
|
|
|
15683
16014
|
// libs/mesh-cli/src/commands/hub/index.ts
|
|
15684
|
-
import { execFileSync as
|
|
16015
|
+
import { execFileSync as execFileSync23 } from "node:child_process";
|
|
15685
16016
|
import * as fs27 from "node:fs";
|
|
15686
16017
|
import * as net12 from "node:net";
|
|
15687
16018
|
import * as os9 from "node:os";
|
|
@@ -15747,7 +16078,7 @@ function parseTmuxEnv(output) {
|
|
|
15747
16078
|
}
|
|
15748
16079
|
function readTmuxSessionEnv(sessionName) {
|
|
15749
16080
|
try {
|
|
15750
|
-
const out =
|
|
16081
|
+
const out = execFileSync23("tmux", ["show-environment", "-t", sessionName], {
|
|
15751
16082
|
encoding: "utf-8",
|
|
15752
16083
|
stdio: ["ignore", "pipe", "ignore"]
|
|
15753
16084
|
});
|
|
@@ -15758,7 +16089,7 @@ function readTmuxSessionEnv(sessionName) {
|
|
|
15758
16089
|
}
|
|
15759
16090
|
function tmuxSessionExists(sessionName) {
|
|
15760
16091
|
try {
|
|
15761
|
-
|
|
16092
|
+
execFileSync23("tmux", ["has-session", "-t", sessionName], { stdio: "ignore" });
|
|
15762
16093
|
return true;
|
|
15763
16094
|
} catch {
|
|
15764
16095
|
return false;
|
|
@@ -15927,7 +16258,7 @@ function redactEnv(env) {
|
|
|
15927
16258
|
async function hubDevAction(opts) {
|
|
15928
16259
|
if (opts.kill) {
|
|
15929
16260
|
if (tmuxSessionExists(HUB_SESSION)) {
|
|
15930
|
-
|
|
16261
|
+
execFileSync23("tmux", ["kill-session", "-t", HUB_SESSION], { stdio: "ignore" });
|
|
15931
16262
|
fs27.rmSync(hubEnvDir(), { recursive: true, force: true });
|
|
15932
16263
|
logSuccess(`Killed Hub session '${HUB_SESSION}'.`);
|
|
15933
16264
|
} else {
|
|
@@ -15981,17 +16312,17 @@ async function hubDevAction(opts) {
|
|
|
15981
16312
|
for (const warning of assembled.warnings) logWarn(warning);
|
|
15982
16313
|
const apiDir = path34.join(platformDir, "apps", "hub", "api");
|
|
15983
16314
|
const uiDir = path34.join(platformDir, "apps", "hub", "ui");
|
|
15984
|
-
|
|
16315
|
+
execFileSync23("tmux", ["new-session", "-d", "-s", HUB_SESSION, "-n", "api", "-c", apiDir]);
|
|
15985
16316
|
if (!assembled.apiEnv.DEV_USER_TOKEN_URL && assembled.apiEnv.DEV_USER_ID_TOKEN) {
|
|
15986
16317
|
const platform = session.state.devOutput.platform;
|
|
15987
16318
|
const credContext = `mesh.${platform.env}`;
|
|
15988
16319
|
const tokenPort = await findFreePort4();
|
|
15989
16320
|
const tokenUrl = `http://127.0.0.1:${tokenPort}`;
|
|
15990
|
-
|
|
15991
|
-
|
|
16321
|
+
execFileSync23("tmux", ["new-window", "-t", HUB_SESSION, "-n", "token-server", "-c", platformDir]);
|
|
16322
|
+
execFileSync23("tmux", ["set-option", "-t", `${HUB_SESSION}:token-server`, "remain-on-exit", "on"], {
|
|
15992
16323
|
stdio: "ignore"
|
|
15993
16324
|
});
|
|
15994
|
-
|
|
16325
|
+
execFileSync23("tmux", [
|
|
15995
16326
|
"send-keys",
|
|
15996
16327
|
"-t",
|
|
15997
16328
|
`${HUB_SESSION}:token-server`,
|
|
@@ -16009,12 +16340,12 @@ async function hubDevAction(opts) {
|
|
|
16009
16340
|
const envFile = path34.join(hubEnvDir(), `${window}.env.sh`);
|
|
16010
16341
|
writeEnvFile(envFile, env);
|
|
16011
16342
|
if (createWindow) {
|
|
16012
|
-
|
|
16343
|
+
execFileSync23("tmux", ["new-window", "-t", HUB_SESSION, "-n", window, "-c", dir]);
|
|
16013
16344
|
}
|
|
16014
|
-
|
|
16345
|
+
execFileSync23("tmux", ["set-option", "-t", `${HUB_SESSION}:${window}`, "remain-on-exit", "on"], {
|
|
16015
16346
|
stdio: "ignore"
|
|
16016
16347
|
});
|
|
16017
|
-
|
|
16348
|
+
execFileSync23("tmux", ["send-keys", "-t", `${HUB_SESSION}:${window}`, buildLaunchCommand(envFile, dir, cmd), "Enter"]);
|
|
16018
16349
|
};
|
|
16019
16350
|
launch("api", apiDir, assembled.apiEnv, "pnpm dev", false);
|
|
16020
16351
|
launch("ui", uiDir, assembled.uiEnv, `pnpm dev --port ${uiPort} --strictPort`, true);
|
|
@@ -16093,7 +16424,7 @@ var init_hub = __esm({
|
|
|
16093
16424
|
});
|
|
16094
16425
|
|
|
16095
16426
|
// libs/mesh-cli/src/commands/registry-publish.ts
|
|
16096
|
-
import { execFileSync as
|
|
16427
|
+
import { execFileSync as execFileSync24, execSync } from "child_process";
|
|
16097
16428
|
import * as fs28 from "fs";
|
|
16098
16429
|
import * as path35 from "path";
|
|
16099
16430
|
function repoRoot() {
|
|
@@ -16177,14 +16508,14 @@ function registerRegistryPublish(registry) {
|
|
|
16177
16508
|
...opts.dryRun ? ["--dry-run"] : []
|
|
16178
16509
|
];
|
|
16179
16510
|
logInfo(`Publishing ${selected.length} package(s)...`);
|
|
16180
|
-
|
|
16511
|
+
execFileSync24("bash", args, { cwd: root, stdio: "inherit", env: env ?? process.env });
|
|
16181
16512
|
} finally {
|
|
16182
16513
|
for (const b of backups) fs28.writeFileSync(b.file, b.content);
|
|
16183
16514
|
logInfo("Restored source package.json versions.");
|
|
16184
16515
|
const collateral = [...dirtyPackageJsons(root)].filter((f) => !preDirty.has(f));
|
|
16185
16516
|
if (collateral.length) {
|
|
16186
16517
|
try {
|
|
16187
|
-
|
|
16518
|
+
execFileSync24("git", ["checkout", "--", ...collateral], { cwd: root, stdio: "inherit" });
|
|
16188
16519
|
logInfo(`Reverted ${collateral.length} package.json file(s) re-vendored by build:publish.`);
|
|
16189
16520
|
} catch {
|
|
16190
16521
|
logError(
|
|
@@ -16236,12 +16567,12 @@ __export(registry_exports, {
|
|
|
16236
16567
|
shouldRemintAfter: () => shouldRemintAfter,
|
|
16237
16568
|
shouldRepairUserNpmrc: () => shouldRepairUserNpmrc
|
|
16238
16569
|
});
|
|
16239
|
-
import { execFileSync as
|
|
16570
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
16240
16571
|
import * as fs29 from "fs";
|
|
16241
16572
|
import * as path36 from "path";
|
|
16242
16573
|
function getEndpoint(env) {
|
|
16243
16574
|
try {
|
|
16244
|
-
const result =
|
|
16575
|
+
const result = execFileSync25("aws", [
|
|
16245
16576
|
"codeartifact",
|
|
16246
16577
|
"get-repository-endpoint",
|
|
16247
16578
|
"--domain",
|
|
@@ -16268,7 +16599,7 @@ function getEndpoint(env) {
|
|
|
16268
16599
|
}
|
|
16269
16600
|
function codeartifactLogin(env) {
|
|
16270
16601
|
try {
|
|
16271
|
-
|
|
16602
|
+
execFileSync25("aws", [
|
|
16272
16603
|
"codeartifact",
|
|
16273
16604
|
"login",
|
|
16274
16605
|
"--tool",
|
|
@@ -16323,7 +16654,7 @@ function resolvePublisherRoleArn({
|
|
|
16323
16654
|
}
|
|
16324
16655
|
function assumeRole2(roleArn) {
|
|
16325
16656
|
try {
|
|
16326
|
-
const result =
|
|
16657
|
+
const result = execFileSync25("aws", [
|
|
16327
16658
|
"sts",
|
|
16328
16659
|
"assume-role",
|
|
16329
16660
|
"--role-arn",
|
|
@@ -16345,7 +16676,7 @@ function assumeRole2(roleArn) {
|
|
|
16345
16676
|
}
|
|
16346
16677
|
function assumeRoleWithWebIdentity2(roleArn, idToken, sessionName) {
|
|
16347
16678
|
try {
|
|
16348
|
-
const result =
|
|
16679
|
+
const result = execFileSync25("aws", [
|
|
16349
16680
|
"sts",
|
|
16350
16681
|
"assume-role-with-web-identity",
|
|
16351
16682
|
"--role-arn",
|
|
@@ -16681,7 +17012,7 @@ region = us-east-2`,
|
|
|
16681
17012
|
{ remediation: { command: `aws configure sso --profile ${profile}` } }
|
|
16682
17013
|
);
|
|
16683
17014
|
}
|
|
16684
|
-
const probe = () =>
|
|
17015
|
+
const probe = () => execFileSync25("aws", ["sts", "get-caller-identity", "--profile", profile], {
|
|
16685
17016
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16686
17017
|
timeout: 2e4
|
|
16687
17018
|
});
|
|
@@ -16692,7 +17023,7 @@ region = us-east-2`,
|
|
|
16692
17023
|
} catch {
|
|
16693
17024
|
logInfo(`AWS SSO session for profile '${profile}' is stale \u2014 opening browser login\u2026`);
|
|
16694
17025
|
}
|
|
16695
|
-
|
|
17026
|
+
execFileSync25("aws", ["sso", "login", "--profile", profile], { stdio: "inherit" });
|
|
16696
17027
|
try {
|
|
16697
17028
|
probe();
|
|
16698
17029
|
} catch (err) {
|
|
@@ -16922,7 +17253,7 @@ __export(wizard_exports, {
|
|
|
16922
17253
|
});
|
|
16923
17254
|
import * as fs30 from "fs";
|
|
16924
17255
|
import * as path37 from "path";
|
|
16925
|
-
import { execFileSync as
|
|
17256
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
16926
17257
|
import chalk4 from "chalk";
|
|
16927
17258
|
function wizardExitCode(steps) {
|
|
16928
17259
|
return steps.some((s) => s.status === "fail") ? 1 : 0;
|
|
@@ -16989,7 +17320,7 @@ function classifyRepo(cwd) {
|
|
|
16989
17320
|
return { kind: "other-repo", root };
|
|
16990
17321
|
}
|
|
16991
17322
|
function gitInit(dir) {
|
|
16992
|
-
|
|
17323
|
+
execFileSync26("git", ["init", "-q"], { cwd: dir, stdio: ["ignore", "ignore", "pipe"] });
|
|
16993
17324
|
}
|
|
16994
17325
|
async function runWizardSteps(ctx, steps) {
|
|
16995
17326
|
const results = [];
|
|
@@ -17584,7 +17915,7 @@ var init_init = __esm({
|
|
|
17584
17915
|
});
|
|
17585
17916
|
|
|
17586
17917
|
// libs/mesh-cli/src/commands/install-shim.ts
|
|
17587
|
-
import { execFileSync as
|
|
17918
|
+
import { execFileSync as execFileSync27 } from "child_process";
|
|
17588
17919
|
import * as fs32 from "fs";
|
|
17589
17920
|
import * as os10 from "os";
|
|
17590
17921
|
import * as path39 from "path";
|
|
@@ -17697,7 +18028,7 @@ function registerInstallShimCommand(program2) {
|
|
|
17697
18028
|
let status = 0;
|
|
17698
18029
|
let ok = true;
|
|
17699
18030
|
try {
|
|
17700
|
-
stdout =
|
|
18031
|
+
stdout = execFileSync27(target, ["--help"], {
|
|
17701
18032
|
cwd: process.cwd(),
|
|
17702
18033
|
encoding: "utf8",
|
|
17703
18034
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -17744,7 +18075,7 @@ var init_install_shim = __esm({
|
|
|
17744
18075
|
});
|
|
17745
18076
|
|
|
17746
18077
|
// libs/mesh-cli/src/commands/local/hub-local.ts
|
|
17747
|
-
import { execFile as execFile3, execFileSync as
|
|
18078
|
+
import { execFile as execFile3, execFileSync as execFileSync28 } from "child_process";
|
|
17748
18079
|
import * as fs33 from "fs";
|
|
17749
18080
|
import * as os11 from "os";
|
|
17750
18081
|
import * as path40 from "path";
|
|
@@ -17764,7 +18095,7 @@ function npmrcPath() {
|
|
|
17764
18095
|
}
|
|
17765
18096
|
function imageExists(tag) {
|
|
17766
18097
|
try {
|
|
17767
|
-
|
|
18098
|
+
execFileSync28("docker", ["image", "inspect", tag], { stdio: ["ignore", "pipe", "pipe"] });
|
|
17768
18099
|
return true;
|
|
17769
18100
|
} catch {
|
|
17770
18101
|
return false;
|
|
@@ -17774,7 +18105,7 @@ function ensureHubAuthImage() {
|
|
|
17774
18105
|
if (imageExists(HUB_AUTH_IMAGE)) return;
|
|
17775
18106
|
logInfo(`Building ${HUB_AUTH_IMAGE} (Hub auth proxy)\u2026`);
|
|
17776
18107
|
const hubStackDir = path40.join(findPackageRoot(), "stack", "hub");
|
|
17777
|
-
|
|
18108
|
+
execFileSync28(
|
|
17778
18109
|
"docker",
|
|
17779
18110
|
["build", "-f", path40.join(hubStackDir, "Dockerfile.auth"), "-t", HUB_AUTH_IMAGE, hubStackDir],
|
|
17780
18111
|
{ stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
|
|
@@ -17788,7 +18119,7 @@ function hasRegistryAuth() {
|
|
|
17788
18119
|
function localHubVersion() {
|
|
17789
18120
|
const versions = HUB_IMAGES.map((name) => {
|
|
17790
18121
|
try {
|
|
17791
|
-
const out =
|
|
18122
|
+
const out = execFileSync28("docker", ["images", name, "--format", "{{.Tag}}"], {
|
|
17792
18123
|
encoding: "utf-8",
|
|
17793
18124
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17794
18125
|
});
|
|
@@ -17867,7 +18198,7 @@ async function ensureHubImages() {
|
|
|
17867
18198
|
const context = path40.join(cacheDir(), `context-${version}`);
|
|
17868
18199
|
fs33.rmSync(context, { recursive: true, force: true });
|
|
17869
18200
|
fs33.mkdirSync(context, { recursive: true });
|
|
17870
|
-
|
|
18201
|
+
execFileSync28("tar", ["-xzf", tarball, "-C", context, "--strip-components", "1"], {
|
|
17871
18202
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17872
18203
|
});
|
|
17873
18204
|
const hubStackDir = path40.join(findPackageRoot(), "stack", "hub");
|
|
@@ -17878,7 +18209,7 @@ async function ensureHubImages() {
|
|
|
17878
18209
|
const tag = `${name}:${version}`;
|
|
17879
18210
|
if (imageExists(tag)) continue;
|
|
17880
18211
|
logInfo(`Building ${tag} from the published tarball\u2026`);
|
|
17881
|
-
|
|
18212
|
+
execFileSync28(
|
|
17882
18213
|
"docker",
|
|
17883
18214
|
[
|
|
17884
18215
|
"build",
|
|
@@ -17908,7 +18239,7 @@ function readHubCompiledAuthz(version) {
|
|
|
17908
18239
|
if (!tarball || !fs33.existsSync(path40.join(cacheDir(), tarball))) return null;
|
|
17909
18240
|
fs33.mkdirSync(context, { recursive: true });
|
|
17910
18241
|
try {
|
|
17911
|
-
|
|
18242
|
+
execFileSync28(
|
|
17912
18243
|
"tar",
|
|
17913
18244
|
["-xzf", path40.join(cacheDir(), tarball), "-C", context, "--strip-components", "1", `package/${HUB_COMPILED_AUTHZ_REL}`],
|
|
17914
18245
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -18002,7 +18333,7 @@ async function buildHubImagesFromSource(repoRoot2) {
|
|
|
18002
18333
|
await execFileAsync2("pnpm", ["pack", "--pack-destination", context], { cwd: hubDir, maxBuffer: 64 * 1024 * 1024 });
|
|
18003
18334
|
const tarball = fs33.readdirSync(context).find((f) => f.endsWith(".tgz"));
|
|
18004
18335
|
if (!tarball) throw new MeshCliError("pnpm pack produced no tarball for apps/hub");
|
|
18005
|
-
|
|
18336
|
+
execFileSync28("tar", ["-xzf", path40.join(context, tarball), "-C", context, "--strip-components", "1"], {
|
|
18006
18337
|
stdio: ["ignore", "pipe", "pipe"]
|
|
18007
18338
|
});
|
|
18008
18339
|
const rewritten = normalizeHubManifests(context, readWorkspaceCatalog(repoRoot2));
|
|
@@ -18014,7 +18345,7 @@ async function buildHubImagesFromSource(repoRoot2) {
|
|
|
18014
18345
|
]) {
|
|
18015
18346
|
const tag = `${name}:${version}`;
|
|
18016
18347
|
logInfo(`Building ${tag} from source\u2026`);
|
|
18017
|
-
|
|
18348
|
+
execFileSync28(
|
|
18018
18349
|
"docker",
|
|
18019
18350
|
["build", "-f", path40.join(hubStackDir, dockerfile), "-t", tag, "--secret", `id=npmrc,src=${npmrc}`, context],
|
|
18020
18351
|
{ stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
|
|
@@ -18185,8 +18516,42 @@ function printEndpoints(hubRunning) {
|
|
|
18185
18516
|
console.log(
|
|
18186
18517
|
` ${chalk6.dim(`test users: ${TEST_USERS.map((u) => u.email).join(", ")} (password: ${TEST_USERS[0].password})`)}`
|
|
18187
18518
|
);
|
|
18188
|
-
|
|
18189
|
-
|
|
18519
|
+
printStartHere(hubRunning);
|
|
18520
|
+
}
|
|
18521
|
+
function startHereLines(hubRunning, up) {
|
|
18522
|
+
const dev = TEST_USERS[0];
|
|
18523
|
+
const mailbox = STACK_ENDPOINTS.find((e) => e.service === "mailpit");
|
|
18524
|
+
const flag = (service) => up?.get(service) === false ? chalk6.red(" (not responding \u2014 see Endpoints below)") : "";
|
|
18525
|
+
const lines = ["", chalk6.bold.cyan("\u2605 Start here")];
|
|
18526
|
+
if (hubRunning) {
|
|
18527
|
+
lines.push(
|
|
18528
|
+
` ${"Hub".padEnd(10)} ${chalk6.bold.cyan(`http://localhost:${hubPort()}`)}${flag("hub-ui")}`,
|
|
18529
|
+
` ${"".padEnd(10)} ${chalk6.dim(`sign in as ${dev.email} / ${dev.password} \u2014 an account already exists; do not Register`)}`
|
|
18530
|
+
);
|
|
18531
|
+
}
|
|
18532
|
+
if (mailbox) {
|
|
18533
|
+
lines.push(
|
|
18534
|
+
` ${"Mailbox".padEnd(10)} ${chalk6.cyan(mailbox.url)}${flag("mailpit")}`,
|
|
18535
|
+
` ${"".padEnd(10)} ${chalk6.dim("every email the local platform sends (sign-up, verification, password reset) lands here \u2014 nothing leaves your machine")}`
|
|
18536
|
+
);
|
|
18537
|
+
}
|
|
18538
|
+
lines.push(
|
|
18539
|
+
` ${"Your app".padEnd(10)} ${chalk6.cyan("cd apps/<name> && mesh dev")} ${chalk6.dim("no app yet? mesh create-app")}`,
|
|
18540
|
+
` ${"Check-up".padEnd(10)} ${chalk6.cyan("mesh status")}`,
|
|
18541
|
+
""
|
|
18542
|
+
);
|
|
18543
|
+
return lines;
|
|
18544
|
+
}
|
|
18545
|
+
function printStartHere(hubRunning, up) {
|
|
18546
|
+
for (const line of startHereLines(hubRunning, up)) console.log(line);
|
|
18547
|
+
}
|
|
18548
|
+
function portMoveHints() {
|
|
18549
|
+
return /* @__PURE__ */ new Map([
|
|
18550
|
+
[
|
|
18551
|
+
Number(hubPort()),
|
|
18552
|
+
"MESH_HUB_PORT=<free port> mesh start (or mesh start --no-hub, which starts everything else)"
|
|
18553
|
+
]
|
|
18554
|
+
]);
|
|
18190
18555
|
}
|
|
18191
18556
|
function repoRootForHubSource() {
|
|
18192
18557
|
for (let dir = process.cwd(); ; ) {
|
|
@@ -18208,6 +18573,10 @@ function registerLocalCommands(program2) {
|
|
|
18208
18573
|
"--takeover",
|
|
18209
18574
|
"re-own a stack that another checkout started (may recreate shared containers with THIS checkout's config)",
|
|
18210
18575
|
false
|
|
18576
|
+
).option(
|
|
18577
|
+
"--skip-port-check",
|
|
18578
|
+
"start even though a host port the stack wants is already held (the service that loses the bind will be broken \u2014 use when the holder is something you cannot stop)",
|
|
18579
|
+
false
|
|
18211
18580
|
).action(async (opts) => {
|
|
18212
18581
|
ensureDockerAvailable();
|
|
18213
18582
|
const foreign = stackOwnedElsewhere();
|
|
@@ -18226,6 +18595,15 @@ Re-running start from here may recreate shared containers with this checkout's c
|
|
|
18226
18595
|
if (foreign && opts.takeover) {
|
|
18227
18596
|
logWarn(`Taking over the running stack (previously driven from ${foreign}).`);
|
|
18228
18597
|
}
|
|
18598
|
+
if (!opts.skipPortCheck && !stackServices().some((s) => s.state === "running")) {
|
|
18599
|
+
const ports = hostPortsOf([...STACK_ENDPOINTS, ...opts.hub ? hubEndpoints() : []]);
|
|
18600
|
+
const conflicts = await findPortConflicts(ports, `${COMPOSE_PROJECT}-`);
|
|
18601
|
+
if (conflicts.length > 0) {
|
|
18602
|
+
throw new MeshCliError(describePortConflicts(conflicts, portMoveHints()), {
|
|
18603
|
+
remediation: { command: "mesh start # once the port is free" }
|
|
18604
|
+
});
|
|
18605
|
+
}
|
|
18606
|
+
}
|
|
18229
18607
|
let hubVersion;
|
|
18230
18608
|
if (opts.hub) {
|
|
18231
18609
|
if (opts.hubFromSource) {
|
|
@@ -18406,6 +18784,7 @@ Re-running start from here may recreate shared containers with this checkout's c
|
|
|
18406
18784
|
if (fabric && !fabric.ok) process.exitCode = 1;
|
|
18407
18785
|
return;
|
|
18408
18786
|
}
|
|
18787
|
+
printStartHere(hasHub, new Map(probes.map((p) => [p.service, p.up])));
|
|
18409
18788
|
console.log(chalk6.bold("Containers"));
|
|
18410
18789
|
for (const service of services) {
|
|
18411
18790
|
const ok = service.state === "running" && (service.health === void 0 || service.health === "healthy");
|
|
@@ -18452,6 +18831,7 @@ var init_local = __esm({
|
|
|
18452
18831
|
init_seed();
|
|
18453
18832
|
init_seed_zitadel();
|
|
18454
18833
|
init_seed_hub_catalog();
|
|
18834
|
+
init_helpers();
|
|
18455
18835
|
WAIT_TIMEOUT_MS = 18e4;
|
|
18456
18836
|
WAIT_POLL_MS = 3e3;
|
|
18457
18837
|
}
|
|
@@ -19646,7 +20026,7 @@ var init_site = __esm({
|
|
|
19646
20026
|
});
|
|
19647
20027
|
|
|
19648
20028
|
// libs/mesh-cli/src/commands/stack.ts
|
|
19649
|
-
import { execFileSync as
|
|
20029
|
+
import { execFileSync as execFileSync29 } from "child_process";
|
|
19650
20030
|
import * as path42 from "path";
|
|
19651
20031
|
import * as fs35 from "fs";
|
|
19652
20032
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -19739,7 +20119,7 @@ function readBaseConfigFromYaml(appRoot, stack) {
|
|
|
19739
20119
|
}
|
|
19740
20120
|
function getGitHubUsername() {
|
|
19741
20121
|
try {
|
|
19742
|
-
const result =
|
|
20122
|
+
const result = execFileSync29("gh", ["api", "user", "--jq", ".login"], {
|
|
19743
20123
|
encoding: "utf-8",
|
|
19744
20124
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19745
20125
|
});
|
|
@@ -19748,7 +20128,7 @@ function getGitHubUsername() {
|
|
|
19748
20128
|
} catch {
|
|
19749
20129
|
}
|
|
19750
20130
|
try {
|
|
19751
|
-
const result =
|
|
20131
|
+
const result = execFileSync29("git", ["config", "user.email"], {
|
|
19752
20132
|
encoding: "utf-8",
|
|
19753
20133
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19754
20134
|
});
|
|
@@ -19834,7 +20214,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19834
20214
|
if (!opts.adopt) {
|
|
19835
20215
|
let existing = [];
|
|
19836
20216
|
try {
|
|
19837
|
-
const raw =
|
|
20217
|
+
const raw = execFileSync29("pulumi", ["stack", "ls", "--json"], {
|
|
19838
20218
|
cwd: appRoot,
|
|
19839
20219
|
encoding: "utf-8",
|
|
19840
20220
|
env: pulumiEnv,
|
|
@@ -19858,7 +20238,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19858
20238
|
logInfo(`Using KMS secrets provider: ${secretsProvider}`);
|
|
19859
20239
|
}
|
|
19860
20240
|
try {
|
|
19861
|
-
|
|
20241
|
+
execFileSync29("pulumi", initArgs, {
|
|
19862
20242
|
cwd: appRoot,
|
|
19863
20243
|
env: pulumiEnv,
|
|
19864
20244
|
stdio: "inherit"
|
|
@@ -19875,7 +20255,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19875
20255
|
}
|
|
19876
20256
|
}
|
|
19877
20257
|
try {
|
|
19878
|
-
|
|
20258
|
+
execFileSync29("pulumi", ["stack", "select", newStack], {
|
|
19879
20259
|
cwd: appRoot,
|
|
19880
20260
|
env: pulumiEnv,
|
|
19881
20261
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19885,7 +20265,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19885
20265
|
if (!configExists) {
|
|
19886
20266
|
let baseConfig = {};
|
|
19887
20267
|
try {
|
|
19888
|
-
const raw =
|
|
20268
|
+
const raw = execFileSync29(
|
|
19889
20269
|
"pulumi",
|
|
19890
20270
|
["config", "--json", "--stack", baseStack],
|
|
19891
20271
|
{ cwd: appRoot, env: pulumiEnv, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -19903,19 +20283,19 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19903
20283
|
if (key === "mesh:deploy") continue;
|
|
19904
20284
|
try {
|
|
19905
20285
|
if (entry.objectValue !== void 0) {
|
|
19906
|
-
|
|
20286
|
+
execFileSync29(
|
|
19907
20287
|
"pulumi",
|
|
19908
20288
|
["config", "set", key, JSON.stringify(entry.objectValue)],
|
|
19909
20289
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
19910
20290
|
);
|
|
19911
20291
|
} else if (entry.value === "true" || entry.value === "false") {
|
|
19912
|
-
|
|
20292
|
+
execFileSync29(
|
|
19913
20293
|
"pulumi",
|
|
19914
20294
|
["config", "set", "--type", "bool", key, entry.value],
|
|
19915
20295
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
19916
20296
|
);
|
|
19917
20297
|
} else {
|
|
19918
|
-
|
|
20298
|
+
execFileSync29(
|
|
19919
20299
|
"pulumi",
|
|
19920
20300
|
["config", "set", key, entry.value],
|
|
19921
20301
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -19928,7 +20308,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19928
20308
|
const baseEnv = readConfigBlockKey(appRoot, baseStack, "mesh:coreEnv") ?? (baseTenant && baseStack.startsWith(`${baseTenant}-`) ? baseStack.slice(baseTenant.length + 1) : baseStack);
|
|
19929
20309
|
const setCfg = (args) => {
|
|
19930
20310
|
try {
|
|
19931
|
-
|
|
20311
|
+
execFileSync29("pulumi", ["config", "set", ...args], {
|
|
19932
20312
|
cwd: appRoot,
|
|
19933
20313
|
env: pulumiEnv,
|
|
19934
20314
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19977,7 +20357,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19977
20357
|
`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}` : ""})`
|
|
19978
20358
|
);
|
|
19979
20359
|
} else {
|
|
19980
|
-
|
|
20360
|
+
execFileSync29("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
|
|
19981
20361
|
cwd: appRoot,
|
|
19982
20362
|
env: pulumiEnv,
|
|
19983
20363
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -20007,7 +20387,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
20007
20387
|
const args = ["stack", "rm", name];
|
|
20008
20388
|
if (opts.yes) args.push("--yes");
|
|
20009
20389
|
try {
|
|
20010
|
-
|
|
20390
|
+
execFileSync29("pulumi", args, { cwd: appRoot, env: pulumiEnv, stdio: "inherit" });
|
|
20011
20391
|
logSuccess(`Removed stack ${name}`);
|
|
20012
20392
|
} catch (err) {
|
|
20013
20393
|
process.exit(err.status ?? 1);
|
|
@@ -20219,12 +20599,12 @@ var init_recover_conversation = __esm({
|
|
|
20219
20599
|
});
|
|
20220
20600
|
|
|
20221
20601
|
// libs/mesh-cli/src/utils/temporal-codec.ts
|
|
20222
|
-
import { execFileSync as
|
|
20602
|
+
import { execFileSync as execFileSync30 } from "child_process";
|
|
20223
20603
|
import { webcrypto as crypto4 } from "node:crypto";
|
|
20224
20604
|
function resolveTemporalEncodingKeyFromK8s(namespace) {
|
|
20225
20605
|
const secretName = `${namespace}-temporal-encoding-key`;
|
|
20226
20606
|
try {
|
|
20227
|
-
const b64 =
|
|
20607
|
+
const b64 = execFileSync30(
|
|
20228
20608
|
"kubectl",
|
|
20229
20609
|
[
|
|
20230
20610
|
"get",
|
|
@@ -23564,7 +23944,7 @@ var init_src4 = __esm({
|
|
|
23564
23944
|
import * as fs38 from "fs";
|
|
23565
23945
|
import * as path45 from "path";
|
|
23566
23946
|
import { createRequire as createRequire2 } from "module";
|
|
23567
|
-
import { execFileSync as
|
|
23947
|
+
import { execFileSync as execFileSync31 } from "child_process";
|
|
23568
23948
|
function resolveExtractorPath() {
|
|
23569
23949
|
try {
|
|
23570
23950
|
const require2 = createRequire2(import.meta.url);
|
|
@@ -23619,7 +23999,7 @@ for (const file of files) {
|
|
|
23619
23999
|
process.stdout.write(JSON.stringify(results));
|
|
23620
24000
|
`;
|
|
23621
24001
|
try {
|
|
23622
|
-
const result =
|
|
24002
|
+
const result = execFileSync31("npx", ["tsx", "--eval", script], {
|
|
23623
24003
|
encoding: "utf-8",
|
|
23624
24004
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23625
24005
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -23661,7 +24041,7 @@ for (const file of files) {
|
|
|
23661
24041
|
process.stdout.write(JSON.stringify(results));
|
|
23662
24042
|
`;
|
|
23663
24043
|
try {
|
|
23664
|
-
const result =
|
|
24044
|
+
const result = execFileSync31("npx", ["tsx", "--eval", script], {
|
|
23665
24045
|
encoding: "utf-8",
|
|
23666
24046
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23667
24047
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -23716,7 +24096,7 @@ for (const file of files) {
|
|
|
23716
24096
|
process.stdout.write(JSON.stringify(results));
|
|
23717
24097
|
`;
|
|
23718
24098
|
try {
|
|
23719
|
-
const result =
|
|
24099
|
+
const result = execFileSync31("npx", ["tsx", "--eval", script], {
|
|
23720
24100
|
encoding: "utf-8",
|
|
23721
24101
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23722
24102
|
maxBuffer: 10 * 1024 * 1024
|