@svenroth-ai/shipwright 0.25.0 → 0.26.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/client/dist/assets/{EmbeddedTerminal-5QvKe3_a.js → EmbeddedTerminal-D3wpPNZP.js} +1 -1
- package/client/dist/assets/{abnfDiagram-VRR7QNED-CXi9HegQ.js → abnfDiagram-VRR7QNED-BkLIltB3.js} +1 -1
- package/client/dist/assets/{arc-DLh4GiqR.js → arc-Sw-Gh0nI.js} +1 -1
- package/client/dist/assets/{architectureDiagram-ZJ3FMSHR-DUypQ8dQ.js → architectureDiagram-ZJ3FMSHR-rdxUi9Ks.js} +1 -1
- package/client/dist/assets/{blockDiagram-677ZJIJ3-D2cVMKJG.js → blockDiagram-677ZJIJ3-Ch_9dj8a.js} +1 -1
- package/client/dist/assets/{c4Diagram-LMCZKHZV-DtruBGJw.js → c4Diagram-LMCZKHZV-CkFlO65x.js} +1 -1
- package/client/dist/assets/channel-BYPbLjRl.js +1 -0
- package/client/dist/assets/{chunk-2Q5K7J3B-CAfQkFw2.js → chunk-2Q5K7J3B-CypX83xu.js} +1 -1
- package/client/dist/assets/{chunk-32BRIVSS-CPWXoLnQ.js → chunk-32BRIVSS-DxVLYGdl.js} +1 -1
- package/client/dist/assets/{chunk-5VM5RSS4-xVc3oppQ.js → chunk-5VM5RSS4-Cxk1evhx.js} +1 -1
- package/client/dist/assets/{chunk-EX3LRPZG-CUpl6fRR.js → chunk-EX3LRPZG-n9q5S4yJ.js} +1 -1
- package/client/dist/assets/{chunk-JWPE2WC7-NejUp56x.js → chunk-JWPE2WC7-jeL4xvir.js} +1 -1
- package/client/dist/assets/{chunk-MOJQB5TN-C9-2lLg0.js → chunk-MOJQB5TN-DDSHN0cj.js} +1 -1
- package/client/dist/assets/{chunk-RYQCIY6F-BAPtwABy.js → chunk-RYQCIY6F-C0bo383g.js} +1 -1
- package/client/dist/assets/{chunk-V7JOEXUC-Dwzihw26.js → chunk-V7JOEXUC-C0jDXXAU.js} +1 -1
- package/client/dist/assets/{chunk-VR4S4FIN-9-iArFJM.js → chunk-VR4S4FIN-h-Rr4Pn2.js} +1 -1
- package/client/dist/assets/{chunk-XXDRQBXY-DiWHOrqe.js → chunk-XXDRQBXY-BexSo0-s.js} +1 -1
- package/client/dist/assets/classDiagram-OUVF2IWQ-CsFIeTju.js +1 -0
- package/client/dist/assets/classDiagram-v2-EOCWNBFH-CsFIeTju.js +1 -0
- package/client/dist/assets/{cose-bilkent-JH36ORCC-Cp04EOcH.js → cose-bilkent-JH36ORCC-BQXzaioj.js} +1 -1
- package/client/dist/assets/{cynefin-VYW2F7L2-D--GN1v8.js → cynefin-VYW2F7L2-BJIofhfe.js} +1 -1
- package/client/dist/assets/{cynefinDiagram-TSTJHNR4-BGH0o_qp.js → cynefinDiagram-TSTJHNR4-DmPqTM1T.js} +1 -1
- package/client/dist/assets/{dagre-VKFMJZFB-DSKkIKlj.js → dagre-VKFMJZFB-1xljvw6X.js} +1 -1
- package/client/dist/assets/{diagram-FQU43EPY-Cs_C4lb-.js → diagram-FQU43EPY-iyL9muCG.js} +1 -1
- package/client/dist/assets/{diagram-G47NLZAW-oDtAA8O_.js → diagram-G47NLZAW-DREp2Th6.js} +1 -1
- package/client/dist/assets/{diagram-NH7WQ7WH-BiFMjqSH.js → diagram-NH7WQ7WH-h0X3Is2S.js} +1 -1
- package/client/dist/assets/{diagram-OA4YK3LP-Ccs3thCj.js → diagram-OA4YK3LP-Bj8YZRFJ.js} +1 -1
- package/client/dist/assets/{diagram-WEI45ONY-CdZNqgO3.js → diagram-WEI45ONY-BZOf805d.js} +1 -1
- package/client/dist/assets/{ebnfDiagram-CCIWWBDH-CapTA0VL.js → ebnfDiagram-CCIWWBDH-DO5JnXda.js} +1 -1
- package/client/dist/assets/{erDiagram-Q63AITRT-BcRNEP8s.js → erDiagram-Q63AITRT-DRgcqg1T.js} +1 -1
- package/client/dist/assets/{flowDiagram-23GEKE2U-CJ_zF7e_.js → flowDiagram-23GEKE2U-C3J9QmrW.js} +1 -1
- package/client/dist/assets/{ganttDiagram-NO4QXBWP-CnJdcg9A.js → ganttDiagram-NO4QXBWP-BIEl3Tkm.js} +1 -1
- package/client/dist/assets/{gitGraphDiagram-IHSO6WYX-YTUQ_ELk.js → gitGraphDiagram-IHSO6WYX-BNF0tFWC.js} +1 -1
- package/client/dist/assets/{index-irQhGNpn.js → index-BnTOrFHb.js} +203 -202
- package/client/dist/assets/index-CYPc6qxw.css +1 -0
- package/client/dist/assets/{infoDiagram-FWYZ7A6U-CLOP_ZWD.js → infoDiagram-FWYZ7A6U-DEyFxiyY.js} +1 -1
- package/client/dist/assets/{ishikawaDiagram-FXEZZL3T-aFTIzr7o.js → ishikawaDiagram-FXEZZL3T-B_ehlg3I.js} +1 -1
- package/client/dist/assets/{journeyDiagram-5HDEW3XC-CbPJB4xd.js → journeyDiagram-5HDEW3XC-Dp00FyJS.js} +1 -1
- package/client/dist/assets/{kanban-definition-HUTT4EX6-BoyhytIS.js → kanban-definition-HUTT4EX6-CTAf16q8.js} +1 -1
- package/client/dist/assets/{linear-1VXA-uBg.js → linear-9vNUgmYd.js} +1 -1
- package/client/dist/assets/{mermaid.core-D_lO2yK9.js → mermaid.core-A6tjaEVD.js} +4 -4
- package/client/dist/assets/{mindmap-definition-LN4V7U3C-iFK7LXMx.js → mindmap-definition-LN4V7U3C-DRW3bmCY.js} +1 -1
- package/client/dist/assets/{pegDiagram-2B236MQR-DNmcmfA-.js → pegDiagram-2B236MQR-DJFCjHp2.js} +1 -1
- package/client/dist/assets/{pieDiagram-ENE6RG2P-ekx83O5b.js → pieDiagram-ENE6RG2P-KRd-sGvC.js} +1 -1
- package/client/dist/assets/{quadrantDiagram-ABIIQ3AL-DayyD1l8.js → quadrantDiagram-ABIIQ3AL-9TLZE3Hu.js} +1 -1
- package/client/dist/assets/{railroadDiagram-RFXS5EU6-Bdgz7S6G.js → railroadDiagram-RFXS5EU6-y4tLtjXg.js} +1 -1
- package/client/dist/assets/{requirementDiagram-TGXJPOKE-szP3Muld.js → requirementDiagram-TGXJPOKE-B9EOQDQM.js} +1 -1
- package/client/dist/assets/{sankeyDiagram-HTMAVEWB-Ct3rzgUj.js → sankeyDiagram-HTMAVEWB-zfwiDzkT.js} +1 -1
- package/client/dist/assets/{sequenceDiagram-DBY2YBRQ-_69EfmOU.js → sequenceDiagram-DBY2YBRQ-DW1LWepL.js} +1 -1
- package/client/dist/assets/{sizeCapture-X5ZJPWSS-BSOU06J2.js → sizeCapture-X5ZJPWSS-BM81Mik0.js} +1 -1
- package/client/dist/assets/{stateDiagram-2N3HPSRC-HmOmFwQm.js → stateDiagram-2N3HPSRC-D0EMIw1w.js} +1 -1
- package/client/dist/assets/stateDiagram-v2-6OUMAXLB-B3E4_xxT.js +1 -0
- package/client/dist/assets/{swimlanes-5IMT3BWC-CVg_4oT7.js → swimlanes-5IMT3BWC-CKXNCX6M.js} +2 -2
- package/client/dist/assets/swimlanesDiagram-G3AALYLV-BegQBqnC.js +8 -0
- package/client/dist/assets/{timeline-definition-FHXFAJF6-CBBaDKXm.js → timeline-definition-FHXFAJF6-ByzIfvL5.js} +1 -1
- package/client/dist/assets/{vennDiagram-L72KCM5P-CBXiWPMc.js → vennDiagram-L72KCM5P-Xep38xBH.js} +1 -1
- package/client/dist/assets/{wardleyDiagram-EHGQE667-uhBCZoW0.js → wardleyDiagram-EHGQE667-DKWDpx6g.js} +1 -1
- package/client/dist/assets/{xychartDiagram-FW5EYKEG-xxE_wY5O.js → xychartDiagram-FW5EYKEG-BGcwZTnu.js} +1 -1
- package/client/dist/index.html +27 -27
- package/lib/claude-cli.mjs +173 -173
- package/lib/preflight.mjs +252 -252
- package/lib/probe-path.mjs +84 -84
- package/lib/server.mjs +369 -369
- package/lib/util.mjs +157 -157
- package/lib/win32-spawn.mjs +253 -253
- package/package.json +68 -68
- package/scripts/deploy-procs.mjs +208 -208
- package/scripts/deploy-swap.mjs +276 -276
- package/scripts/kill-targets.js +140 -140
- package/scripts/repair-claude-json.mjs +295 -295
- package/server/dist/config/default-actions.json +90 -90
- package/server/dist/core/mission-context/association.d.ts +46 -0
- package/server/dist/core/mission-context/association.d.ts.map +1 -1
- package/server/dist/core/mission-context/association.js +69 -0
- package/server/dist/core/mission-context/association.js.map +1 -1
- package/server/dist/core/mission-context/resolver-iterate.d.ts +6 -0
- package/server/dist/core/mission-context/resolver-iterate.d.ts.map +1 -0
- package/server/dist/core/mission-context/resolver-iterate.js +202 -0
- package/server/dist/core/mission-context/resolver-iterate.js.map +1 -0
- package/server/dist/core/mission-context/resolver-parts.d.ts +20 -0
- package/server/dist/core/mission-context/resolver-parts.d.ts.map +1 -1
- package/server/dist/core/mission-context/resolver-parts.js +92 -0
- package/server/dist/core/mission-context/resolver-parts.js.map +1 -1
- package/server/dist/core/mission-context/resolver.d.ts +1 -1
- package/server/dist/core/mission-context/resolver.d.ts.map +1 -1
- package/server/dist/core/mission-context/resolver.js +17 -199
- package/server/dist/core/mission-context/resolver.js.map +1 -1
- package/server/dist/core/mission-context/run-id-recovery.d.ts +21 -5
- package/server/dist/core/mission-context/run-id-recovery.d.ts.map +1 -1
- package/server/dist/core/mission-context/run-id-recovery.js +32 -5
- package/server/dist/core/mission-context/run-id-recovery.js.map +1 -1
- package/server/dist/core/mission-context/scenario.d.ts +18 -11
- package/server/dist/core/mission-context/scenario.d.ts.map +1 -1
- package/server/dist/core/mission-context/scenario.js +40 -3
- package/server/dist/core/mission-context/scenario.js.map +1 -1
- package/server/dist/core/path-guard.d.ts +1 -1
- package/server/dist/core/path-guard.d.ts.map +1 -1
- package/server/dist/core/path-guard.js +9 -2
- package/server/dist/core/path-guard.js.map +1 -1
- package/server/dist/core/shipslog-docs-reader.d.ts +4 -0
- package/server/dist/core/shipslog-docs-reader.d.ts.map +1 -0
- package/server/dist/core/shipslog-docs-reader.js +181 -0
- package/server/dist/core/shipslog-docs-reader.js.map +1 -0
- package/server/dist/core/shipslog-docs-types.d.ts +15 -0
- package/server/dist/core/shipslog-docs-types.d.ts.map +1 -0
- package/server/dist/core/shipslog-docs-types.js +14 -0
- package/server/dist/core/shipslog-docs-types.js.map +1 -0
- package/server/dist/external/design-review/serve.js +27 -27
- package/server/dist/external/mission-context/association-write.d.ts +22 -0
- package/server/dist/external/mission-context/association-write.d.ts.map +1 -0
- package/server/dist/external/mission-context/association-write.js +90 -0
- package/server/dist/external/mission-context/association-write.js.map +1 -0
- package/server/dist/external/mission-context/routes.d.ts.map +1 -1
- package/server/dist/external/mission-context/routes.js +18 -31
- package/server/dist/external/mission-context/routes.js.map +1 -1
- package/server/dist/external/routes.d.ts.map +1 -1
- package/server/dist/external/routes.js +9 -6
- package/server/dist/external/routes.js.map +1 -1
- package/server/dist/external/shipslog-docs/routes.d.ts +10 -0
- package/server/dist/external/shipslog-docs/routes.d.ts.map +1 -0
- package/server/dist/external/shipslog-docs/routes.js +41 -0
- package/server/dist/external/shipslog-docs/routes.js.map +1 -0
- package/server/package.json +1 -1
- package/server/profiles/PROFILE_SCHEMA_VERSION +1 -1
- package/server/profiles/README.md +27 -27
- package/server/profiles/python-plugin-monorepo.json +35 -35
- package/server/profiles/supabase-nextjs.json +253 -253
- package/server/profiles/vite-hono.json +92 -92
- package/client/dist/assets/channel-C_k-9jsa.js +0 -1
- package/client/dist/assets/classDiagram-OUVF2IWQ-CsEPq9Ac.js +0 -1
- package/client/dist/assets/classDiagram-v2-EOCWNBFH-CsEPq9Ac.js +0 -1
- package/client/dist/assets/index-6nZ1bt0a.css +0 -1
- package/client/dist/assets/stateDiagram-v2-6OUMAXLB-BW8H33dv.js +0 -1
- package/client/dist/assets/swimlanesDiagram-G3AALYLV-BaRlxcPD.js +0 -8
package/lib/probe-path.mjs
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* probe-path.mjs — where the prerequisite probe LOOKS for a binary.
|
|
3
|
-
*
|
|
4
|
-
* Split out of preflight.mjs (iterate-2026-08-22): the "augment the lookup PATH
|
|
5
|
-
* and resolve a bare name to an absolute executable" concern is cohesive and
|
|
6
|
-
* independently testable, and keeping it here holds preflight.mjs under the
|
|
7
|
-
* 300-line ceiling. preflight.mjs owns the VERDICT; this module owns the LOOKUP.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { accessSync, constants as fsConstants, statSync } from "node:fs";
|
|
11
|
-
import path from "node:path";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Return a copy of `baseEnv` whose PATH also contains the well-known user-level
|
|
15
|
-
* bin dirs that the uv and Claude Code installers write to.
|
|
16
|
-
*
|
|
17
|
-
* WHY (Mac cold-start, iterate-2026-08-22): those installers drop their binary
|
|
18
|
-
* in `~/.local/bin` (and Homebrew in `/opt/homebrew/bin` | `/usr/local/bin`) and
|
|
19
|
-
* only APPEND that dir to the shell rc. The npx process that runs this
|
|
20
|
-
* bootstrapper still carries the PATH captured before the install, so a
|
|
21
|
-
* `shell: false` probe reported a perfectly-installed uv/claude as ABSENT until
|
|
22
|
-
* the user opened a fresh terminal. Augmenting the lookup PATH lets the probe
|
|
23
|
-
* find a just-installed tool without the restart.
|
|
24
|
-
*
|
|
25
|
-
* The extra dirs are APPENDED, never prepended — an explicitly-configured tool
|
|
26
|
-
* on the real PATH always wins; `~/.local/bin` is only a fallback. Bare-name,
|
|
27
|
-
* PATH-only: no cwd is ever added, so the win32-spawn security posture holds.
|
|
28
|
-
*
|
|
29
|
-
* Windows subtlety: `process.env` is case-insensitive but a plain object is not,
|
|
30
|
-
* so we collapse every `path`-cased key into a single canonical `PATH` — never
|
|
31
|
-
* hand spawn both a stale `Path` and an augmented `PATH`.
|
|
32
|
-
*
|
|
33
|
-
* @param {NodeJS.Platform} platform
|
|
34
|
-
* @param {string} homedir
|
|
35
|
-
* @param {Record<string, string | undefined>} [baseEnv]
|
|
36
|
-
* @returns {Record<string, string>}
|
|
37
|
-
*/
|
|
38
|
-
export function probeEnv(platform, homedir, baseEnv = {}) {
|
|
39
|
-
const sep = platform === "win32" ? ";" : ":";
|
|
40
|
-
const extra =
|
|
41
|
-
platform === "win32"
|
|
42
|
-
? [path.win32.join(homedir, ".local", "bin")]
|
|
43
|
-
: [path.posix.join(homedir, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"];
|
|
44
|
-
|
|
45
|
-
const out = {};
|
|
46
|
-
let current = "";
|
|
47
|
-
for (const [k, v] of Object.entries(baseEnv)) {
|
|
48
|
-
if (k.toLowerCase() === "path") {
|
|
49
|
-
if (v != null) current = v;
|
|
50
|
-
continue; // drop every path-cased key; a single PATH is re-added below
|
|
51
|
-
}
|
|
52
|
-
if (v != null) out[k] = v;
|
|
53
|
-
}
|
|
54
|
-
const merged = current ? current.split(sep).filter(Boolean) : [];
|
|
55
|
-
for (const d of extra) if (!merged.includes(d)) merged.push(d);
|
|
56
|
-
out.PATH = merged.join(sep);
|
|
57
|
-
return out;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Resolve a bare command name to an absolute executable path by scanning the
|
|
62
|
-
* (already augmented) PATH — POSIX only. Node's own bare-name lookup does not
|
|
63
|
-
* reliably honour `options.env.PATH`, so we resolve the absolute path ourselves
|
|
64
|
-
* and spawn THAT, making the augmented PATH actually take effect. PATH-only,
|
|
65
|
-
* never cwd. Returns the bare name unchanged when nothing resolves (spawn then
|
|
66
|
-
* yields the same ENOENT → `ok:false` verdict as before).
|
|
67
|
-
* @param {string} name @param {Record<string,string|undefined>} env
|
|
68
|
-
*/
|
|
69
|
-
export function resolvePosixBin(name, env) {
|
|
70
|
-
if (name.includes("/")) return name; // already a path
|
|
71
|
-
for (const dir of (env.PATH ?? "").split(":")) {
|
|
72
|
-
if (!dir) continue;
|
|
73
|
-
const cand = path.posix.join(dir, name);
|
|
74
|
-
try {
|
|
75
|
-
if (statSync(cand).isFile()) {
|
|
76
|
-
accessSync(cand, fsConstants.X_OK);
|
|
77
|
-
return cand;
|
|
78
|
-
}
|
|
79
|
-
} catch {
|
|
80
|
-
// not a usable executable here — keep searching
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return name;
|
|
84
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* probe-path.mjs — where the prerequisite probe LOOKS for a binary.
|
|
3
|
+
*
|
|
4
|
+
* Split out of preflight.mjs (iterate-2026-08-22): the "augment the lookup PATH
|
|
5
|
+
* and resolve a bare name to an absolute executable" concern is cohesive and
|
|
6
|
+
* independently testable, and keeping it here holds preflight.mjs under the
|
|
7
|
+
* 300-line ceiling. preflight.mjs owns the VERDICT; this module owns the LOOKUP.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { accessSync, constants as fsConstants, statSync } from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Return a copy of `baseEnv` whose PATH also contains the well-known user-level
|
|
15
|
+
* bin dirs that the uv and Claude Code installers write to.
|
|
16
|
+
*
|
|
17
|
+
* WHY (Mac cold-start, iterate-2026-08-22): those installers drop their binary
|
|
18
|
+
* in `~/.local/bin` (and Homebrew in `/opt/homebrew/bin` | `/usr/local/bin`) and
|
|
19
|
+
* only APPEND that dir to the shell rc. The npx process that runs this
|
|
20
|
+
* bootstrapper still carries the PATH captured before the install, so a
|
|
21
|
+
* `shell: false` probe reported a perfectly-installed uv/claude as ABSENT until
|
|
22
|
+
* the user opened a fresh terminal. Augmenting the lookup PATH lets the probe
|
|
23
|
+
* find a just-installed tool without the restart.
|
|
24
|
+
*
|
|
25
|
+
* The extra dirs are APPENDED, never prepended — an explicitly-configured tool
|
|
26
|
+
* on the real PATH always wins; `~/.local/bin` is only a fallback. Bare-name,
|
|
27
|
+
* PATH-only: no cwd is ever added, so the win32-spawn security posture holds.
|
|
28
|
+
*
|
|
29
|
+
* Windows subtlety: `process.env` is case-insensitive but a plain object is not,
|
|
30
|
+
* so we collapse every `path`-cased key into a single canonical `PATH` — never
|
|
31
|
+
* hand spawn both a stale `Path` and an augmented `PATH`.
|
|
32
|
+
*
|
|
33
|
+
* @param {NodeJS.Platform} platform
|
|
34
|
+
* @param {string} homedir
|
|
35
|
+
* @param {Record<string, string | undefined>} [baseEnv]
|
|
36
|
+
* @returns {Record<string, string>}
|
|
37
|
+
*/
|
|
38
|
+
export function probeEnv(platform, homedir, baseEnv = {}) {
|
|
39
|
+
const sep = platform === "win32" ? ";" : ":";
|
|
40
|
+
const extra =
|
|
41
|
+
platform === "win32"
|
|
42
|
+
? [path.win32.join(homedir, ".local", "bin")]
|
|
43
|
+
: [path.posix.join(homedir, ".local", "bin"), "/opt/homebrew/bin", "/usr/local/bin"];
|
|
44
|
+
|
|
45
|
+
const out = {};
|
|
46
|
+
let current = "";
|
|
47
|
+
for (const [k, v] of Object.entries(baseEnv)) {
|
|
48
|
+
if (k.toLowerCase() === "path") {
|
|
49
|
+
if (v != null) current = v;
|
|
50
|
+
continue; // drop every path-cased key; a single PATH is re-added below
|
|
51
|
+
}
|
|
52
|
+
if (v != null) out[k] = v;
|
|
53
|
+
}
|
|
54
|
+
const merged = current ? current.split(sep).filter(Boolean) : [];
|
|
55
|
+
for (const d of extra) if (!merged.includes(d)) merged.push(d);
|
|
56
|
+
out.PATH = merged.join(sep);
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a bare command name to an absolute executable path by scanning the
|
|
62
|
+
* (already augmented) PATH — POSIX only. Node's own bare-name lookup does not
|
|
63
|
+
* reliably honour `options.env.PATH`, so we resolve the absolute path ourselves
|
|
64
|
+
* and spawn THAT, making the augmented PATH actually take effect. PATH-only,
|
|
65
|
+
* never cwd. Returns the bare name unchanged when nothing resolves (spawn then
|
|
66
|
+
* yields the same ENOENT → `ok:false` verdict as before).
|
|
67
|
+
* @param {string} name @param {Record<string,string|undefined>} env
|
|
68
|
+
*/
|
|
69
|
+
export function resolvePosixBin(name, env) {
|
|
70
|
+
if (name.includes("/")) return name; // already a path
|
|
71
|
+
for (const dir of (env.PATH ?? "").split(":")) {
|
|
72
|
+
if (!dir) continue;
|
|
73
|
+
const cand = path.posix.join(dir, name);
|
|
74
|
+
try {
|
|
75
|
+
if (statSync(cand).isFile()) {
|
|
76
|
+
accessSync(cand, fsConstants.X_OK);
|
|
77
|
+
return cand;
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
// not a usable executable here — keep searching
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return name;
|
|
84
|
+
}
|