gm-skill 2.0.1283 → 2.0.1285

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 CHANGED
@@ -35,7 +35,7 @@ An earlier generation fanned out fifteen per-platform downstream repos (gm-cc, g
35
35
 
36
36
  ## Version
37
37
 
38
- `2.0.1283` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` (or any cascading sibling crate) republishes this package.
38
+ `2.0.1285` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` (or any cascading sibling crate) republishes this package.
39
39
 
40
40
  ## Source of truth
41
41
 
package/bin/bootstrap.js CHANGED
@@ -258,9 +258,12 @@ async function extractNpmPackageWasm(destPath, version) {
258
258
 
259
259
  const npxResolved = resolveWindowsExe('npx');
260
260
  const isCmdShim = process.platform === 'win32' && /\.(cmd|bat)$/i.test(npxResolved);
261
+ const rawArgs = [NPM_PACKAGE + '@' + version, '--prefix', tempDir];
262
+ const spawnCmd = isCmdShim && /\s/.test(npxResolved) ? `"${npxResolved}"` : npxResolved;
263
+ const spawnArgs = isCmdShim ? rawArgs.map(a => /[\s"]/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a) : rawArgs;
261
264
  const result = spawnSync(
262
- npxResolved,
263
- [NPM_PACKAGE + '@' + version, '--prefix', tempDir],
265
+ spawnCmd,
266
+ spawnArgs,
264
267
  {
265
268
  stdio: ['ignore', 'pipe', 'pipe'],
266
269
  timeout: ATTEMPT_TIMEOUT_MS,
@@ -1 +1 @@
1
- 0.1.475
1
+ 0.1.476
package/bin/plugkit.wasm CHANGED
Binary file
@@ -1 +1 @@
1
- 357a9a30b53595578a4aba6aec254613c47221055b299d42986fe1052cb19ee2 plugkit.wasm
1
+ 627006998cb293c98a69e06affaeace13a996e69c08cb63b44362b7a630ffc5e plugkit.wasm
@@ -207,7 +207,10 @@ async function extractNpmPackageWasm(destPath, version) {
207
207
  const args = ['install', '--no-audit', '--no-fund', '--no-save', NPM_PACKAGE + '@' + version];
208
208
  const isCmdShim = process.platform === 'win32' && /\.(cmd|bat)$/i.test(cmd);
209
209
 
210
- const result = spawnSync(cmd, args, {
210
+ const spawnCmd = isCmdShim ? `"${cmd}"` : cmd;
211
+ const spawnArgs = isCmdShim ? args.map(a => /[\s"]/.test(a) ? `"${a.replace(/"/g, '\\"')}"` : a) : args;
212
+
213
+ const result = spawnSync(spawnCmd, spawnArgs, {
211
214
  cwd: tempDir,
212
215
  stdio: ['ignore', 'pipe', 'pipe'],
213
216
  timeout: ATTEMPT_TIMEOUT_MS,
@@ -638,10 +638,15 @@ function sleepSync(ms) {
638
638
  }
639
639
 
640
640
  function runPlaywriter(pw, args, timeoutMs) {
641
- return spawnSync(pw.cmd, [...pw.baseArgs, ...args], {
641
+ const allArgs = [...pw.baseArgs, ...args];
642
+ const useShell = !!pw.shell;
643
+ const spawnCmd = useShell && /\s/.test(pw.cmd) ? `"${pw.cmd}"` : pw.cmd;
644
+ const spawnArgs = useShell ? allArgs.map(a => /[\s"]/.test(String(a)) ? `"${String(a).replace(/"/g, '\\"')}"` : a) : allArgs;
645
+ return spawnSync(spawnCmd, spawnArgs, {
642
646
  encoding: 'utf-8',
643
647
  timeout: timeoutMs,
644
- shell: pw.shell,
648
+ shell: useShell,
649
+ windowsHide: true,
645
650
  env: process.env,
646
651
  });
647
652
  }
@@ -736,6 +741,27 @@ function isColdRunProfile(profileDir) {
736
741
  }
737
742
  }
738
743
 
744
+ function resolveManagedBrowserKey(pw) {
745
+ if (process.env.PLAYWRITER_BROWSER_KEY) {
746
+ const k = process.env.PLAYWRITER_BROWSER_KEY;
747
+ if (/^profile:/.test(k)) {
748
+ throw new Error(`PLAYWRITER_BROWSER_KEY=${k} points at a user OS browser profile; refusing — managed sessions must use install:Chromium:*`);
749
+ }
750
+ return k;
751
+ }
752
+ let text = '';
753
+ try {
754
+ const r = runPlaywriter(pw, ['browser', 'list'], 8000);
755
+ text = (r && (r.stdout || r.stderr)) || '';
756
+ } catch (e) {
757
+ throw new Error(`playwriter browser list failed: ${e.message}`);
758
+ }
759
+ const lines = text.split(/\r?\n/);
760
+ const installChromium = lines.map(l => (l.match(/\b(install:Chromium:[A-Za-z0-9_-]+)\b/) || [])[1]).find(Boolean);
761
+ if (installChromium) return installChromium;
762
+ throw new Error(`no managed Chromium install detected; playwriter browser list returned: ${scrubBrowserRunnerText(text).trim()}`);
763
+ }
764
+
739
765
  function waitForExtensionReady(pw, profileDir, opts) {
740
766
  const cold = (opts && typeof opts.cold === 'boolean') ? opts.cold : isColdRunProfile(profileDir);
741
767
  const timeoutMs = (opts && opts.timeoutMs) || (cold ? 180000 : 30000);
@@ -745,10 +771,11 @@ function waitForExtensionReady(pw, profileDir, opts) {
745
771
  let attempt = 0;
746
772
  let lastErr = '';
747
773
  let lastProgressAt = start;
774
+ const browserKey = resolveManagedBrowserKey(pw);
748
775
  while (Date.now() < deadline) {
749
776
  const remaining = deadline - Date.now();
750
777
  const innerTimeout = Math.max(28000, Math.min(remaining, 30000));
751
- const r = runPlaywriter(pw, ['session', 'new'], innerTimeout);
778
+ const r = runPlaywriter(pw, ['session', 'new', '--browser', browserKey], innerTimeout);
752
779
  if (r && r.status === 0) return r;
753
780
  lastErr = scrubBrowserRunnerText((r && (r.stderr || r.stdout)) || '');
754
781
  const now = Date.now();
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1283",
3
+ "version": "2.0.1285",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -17,5 +17,5 @@
17
17
  "publishConfig": {
18
18
  "access": "public"
19
19
  },
20
- "plugkitVersion": "0.1.475"
20
+ "plugkitVersion": "0.1.476"
21
21
  }
@@ -28,6 +28,15 @@ function resolveWindowsExe(cmd) {
28
28
  }
29
29
  }
30
30
 
31
+ // When spawning a .cmd/.bat shim with shell:true on Windows, cmd.exe re-parses
32
+ // the command string and breaks on unquoted spaces (e.g. "C:\Program Files\...").
33
+ // Quote the cmd and any space-containing args so cmd.exe sees them as single tokens.
34
+ function shellQuoteWin(cmdOrArg) {
35
+ const s = String(cmdOrArg);
36
+ if (!/[\s"]/.test(s)) return s;
37
+ return `"${s.replace(/"/g, '\\"')}"`;
38
+ }
39
+
31
40
  const LOG_DIR = path.join(os.homedir(), '.claude', 'gm-log');
32
41
  const GM_STATE_DIR = path.join(os.homedir(), '.gm');
33
42
 
@@ -187,14 +196,19 @@ async function ensureRsLearningDaemonRunning() {
187
196
  // DETACHED_PROCESS (0x00000008) detaches the process group. Windows-only;
188
197
  // Node ignores creationFlags on POSIX.
189
198
  const bunExe = resolveWindowsExe('bun');
190
- const proc = spawn(bunExe, ['x', 'rs-learn@latest'], {
191
- detached: true,
192
- stdio: 'ignore',
193
- windowsHide: true,
194
- env,
195
- ...(process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe) ? { shell: true } : {}),
196
- creationFlags: 0x08000000 | 0x00000008,
197
- });
199
+ const useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe);
200
+ const proc = spawn(
201
+ useShell ? shellQuoteWin(bunExe) : bunExe,
202
+ useShell ? ['x', 'rs-learn@latest'].map(shellQuoteWin) : ['x', 'rs-learn@latest'],
203
+ {
204
+ detached: true,
205
+ stdio: 'ignore',
206
+ windowsHide: true,
207
+ env,
208
+ ...(useShell ? { shell: true } : {}),
209
+ creationFlags: 0x08000000 | 0x00000008,
210
+ }
211
+ );
198
212
 
199
213
  const pid = proc.pid;
200
214
  proc.unref();
@@ -240,14 +254,19 @@ async function ensureRsCodeinsightDaemonRunning() {
240
254
  });
241
255
 
242
256
  const bunExe = resolveWindowsExe('bun');
243
- const proc = spawn(bunExe, ['x', 'rs-codeinsight@latest'], {
244
- detached: true,
245
- stdio: 'ignore',
246
- windowsHide: true,
247
- env,
248
- ...(process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe) ? { shell: true } : {}),
249
- creationFlags: 0x08000000 | 0x00000008,
250
- });
257
+ const useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe);
258
+ const proc = spawn(
259
+ useShell ? shellQuoteWin(bunExe) : bunExe,
260
+ useShell ? ['x', 'rs-codeinsight@latest'].map(shellQuoteWin) : ['x', 'rs-codeinsight@latest'],
261
+ {
262
+ detached: true,
263
+ stdio: 'ignore',
264
+ windowsHide: true,
265
+ env,
266
+ ...(useShell ? { shell: true } : {}),
267
+ creationFlags: 0x08000000 | 0x00000008,
268
+ }
269
+ );
251
270
 
252
271
  const pid = proc.pid;
253
272
  proc.unref();
@@ -288,14 +307,19 @@ async function ensureRsSearchDaemonRunning() {
288
307
  });
289
308
 
290
309
  const bunExe = resolveWindowsExe('bun');
291
- const proc = spawn(bunExe, ['x', 'rs-search@latest'], {
292
- detached: true,
293
- stdio: 'ignore',
294
- windowsHide: true,
295
- env,
296
- ...(process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe) ? { shell: true } : {}),
297
- creationFlags: 0x08000000 | 0x00000008,
298
- });
310
+ const useShell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(bunExe);
311
+ const proc = spawn(
312
+ useShell ? shellQuoteWin(bunExe) : bunExe,
313
+ useShell ? ['x', 'rs-search@latest'].map(shellQuoteWin) : ['x', 'rs-search@latest'],
314
+ {
315
+ detached: true,
316
+ stdio: 'ignore',
317
+ windowsHide: true,
318
+ env,
319
+ ...(useShell ? { shell: true } : {}),
320
+ creationFlags: 0x08000000 | 0x00000008,
321
+ }
322
+ );
299
323
 
300
324
  const pid = proc.pid;
301
325
  proc.unref();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1283",
3
+ "version": "2.0.1285",
4
4
  "description": "Canonical universal harness — AI-native software engineering via skill-driven orchestration; bootstraps plugkit for task execution and session isolation. Install in any AI coding agent host.",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "gm.json"
40
40
  ],
41
41
  "dependencies": {
42
- "gm-plugkit": "^2.0.1283"
42
+ "gm-plugkit": "^2.0.1285"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=16.0.0"