fraim 2.0.283 → 2.0.284

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.
@@ -14,6 +14,7 @@ exports.ensureFraimMcpLatestLauncher = ensureFraimMcpLatestLauncher;
14
14
  const fs_1 = __importDefault(require("fs"));
15
15
  const os_1 = __importDefault(require("os"));
16
16
  const path_1 = __importDefault(require("path"));
17
+ const windows_shim_path_search_1 = require("../../core/utils/windows-shim-path-search");
17
18
  const LAUNCHER_VERSION = 1;
18
19
  const PACKAGED_RUNTIME_VERSION = 1;
19
20
  const launcherSource = `#!/usr/bin/env node
@@ -194,9 +195,9 @@ function packagedFraimShimSource(command, runtime) {
194
195
  const windowsFraimMcpShimSource = `@echo off
195
196
  setlocal
196
197
  for %%I in ("%~dp0..") do set "FRAIM_USER_DIR_VALUE=%%~fI"
197
- where node >nul 2>nul
198
- if not errorlevel 1 (
199
- node "%FRAIM_USER_DIR_VALUE%\\bin\\fraim-mcp-latest.js" %*
198
+ ${(0, windows_shim_path_search_1.windowsPathSearchLines)('NODE_EXE', 'node').join('\n')}
199
+ if defined NODE_EXE (
200
+ "%NODE_EXE%" "%FRAIM_USER_DIR_VALUE%\\bin\\fraim-mcp-latest.js" %*
200
201
  exit /b %ERRORLEVEL%
201
202
  )
202
203
  if exist "%FRAIM_USER_DIR_VALUE%\\node\\node.exe" (
@@ -217,9 +218,9 @@ exit /b 1
217
218
  const windowsFraimNpxShimSource = `@echo off
218
219
  setlocal
219
220
  for %%I in ("%~dp0..") do set "FRAIM_USER_DIR_VALUE=%%~fI"
220
- where npx >nul 2>nul
221
- if not errorlevel 1 (
222
- npx %*
221
+ ${(0, windows_shim_path_search_1.windowsPathSearchLines)('NPX_CMD', 'npx').join('\n')}
222
+ if defined NPX_CMD (
223
+ "%NPX_CMD%" %*
223
224
  exit /b %ERRORLEVEL%
224
225
  )
225
226
  if exist "%FRAIM_USER_DIR_VALUE%\\node\\npx.cmd" (
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /**
3
+ * Shared Windows batch-script primitive for resolving an executable on `PATH` without
4
+ * depending on `where.exe`.
5
+ *
6
+ * Issue #1375: every generated `.cmd` launcher in this repo used to probe for `node`/`npx`
7
+ * with `where <name> >nul 2>nul`. `where.exe` itself lives in `C:\Windows\System32`, so on a
8
+ * launching process whose `PATH` omits `System32` — the normal case for a shell started from
9
+ * the VS Code integrated Git Bash terminal — the probe is unresolvable and falsely reports the
10
+ * target missing even when it is on `PATH`. cmd.exe's own command dispatch resolves external
11
+ * commands strictly through `PATH` (not the OS's default `CreateProcess` search order, which
12
+ * would fall back to the system directory automatically), so this is a real, reproducible gap,
13
+ * not a theoretical one.
14
+ *
15
+ * `for %%X in (<name>) do set "VAR=%%~$PATH:X"` is cmd.exe's native argument-expansion PATH
16
+ * search. It needs no external binary — the direct analogue of a POSIX shell's `command -v`
17
+ * builtin — and resolves to an absolute path the caller can invoke directly. Unlike `where`, it
18
+ * needs an exact filename (no `%PATHEXT%` extension search of its own), so this module tries
19
+ * `.exe` then `.cmd` in turn to match `where`'s original extension-agnostic behavior.
20
+ *
21
+ * Every `.cmd` generator in this repo that needs to resolve node/npx/git on Windows should call
22
+ * this instead of hand-rolling its own `where` probe: three independent reimplementations of this
23
+ * exact check (`src/cli/mcp/fraim-mcp-latest-launcher.ts`, `src/ai-hub/hub-launcher.ts`, and
24
+ * `scripts/installer/fraim-install-win.template.cmd`) is exactly how the `where`-based bug shipped
25
+ * on Windows only while the POSIX shim's single `command -v` call stayed correct.
26
+ *
27
+ * `scripts/installer/fraim-install-win.template.cmd` is a static text file, not generated from
28
+ * this module (it is read verbatim and two tokens substituted, not built from TypeScript), so it
29
+ * cannot import this function. It re-implements the identical pattern as literal batch text —
30
+ * keep both in sync when this logic changes.
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.windowsPathSearchLines = windowsPathSearchLines;
34
+ /**
35
+ * Extensions tried, in order, when resolving a bare command name — mirrors the two extensions
36
+ * every tool this repo probes for actually ships as: `node.exe`/`git.exe`/`winget.exe` are native
37
+ * PE binaries, `npx.cmd` is npm's batch shim. `%%~$PATH:X` needs an exact filename (unlike `where`,
38
+ * it does not consult `%PATHEXT%` itself), so trying each extension in turn is what restores
39
+ * `where`'s original extension-agnostic behavior.
40
+ */
41
+ const WINDOWS_EXECUTABLE_EXTENSIONS = ['.exe', '.cmd'];
42
+ /**
43
+ * Returns the batch-script lines that resolve `targetBaseName` (no extension) on `PATH` into
44
+ * `varName`, trying each of `WINDOWS_EXECUTABLE_EXTENSIONS` in turn, or leave `varName` undefined
45
+ * if none match. Caller decides line joining (`\n` vs `\r\n`) and what to do with the result —
46
+ * typically `if defined <varName> ( "%<varName>%" ... )`.
47
+ *
48
+ * @param varName Batch variable to receive the resolved absolute path, e.g. `NODE_EXE`.
49
+ * @param targetBaseName Command name without extension, e.g. `node`, `npx`, `git`, `winget`.
50
+ */
51
+ function windowsPathSearchLines(varName, targetBaseName) {
52
+ return [
53
+ `set "${varName}="`,
54
+ ...WINDOWS_EXECUTABLE_EXTENSIONS.map((ext) => `if not defined ${varName} for %%X in (${targetBaseName}${ext}) do set "${varName}=%%~$PATH:X"`),
55
+ ];
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim",
3
- "version": "2.0.283",
3
+ "version": "2.0.284",
4
4
  "description": "FRAIM core CLI and MCP package.",
5
5
  "main": "index.js",
6
6
  "bin": {