gm-skill 2.0.1126 → 2.0.1128

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
@@ -28,7 +28,7 @@ npx gm-skill-bootstrap
28
28
 
29
29
  ## Version
30
30
 
31
- `2.0.1126` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
31
+ `2.0.1128` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
32
32
 
33
33
  ## Source of truth
34
34
 
@@ -1 +1 @@
1
- 0.1.396
1
+ 0.1.397
package/bin/plugkit.wasm CHANGED
Binary file
@@ -1 +1 @@
1
- 874f5a3524d8a080a2880567cc3808ae727f4c2b4f35ad6fc33e932fd6c4c567 plugkit.wasm
1
+ 52e42c938d42102bf0ac396528a3824f881b2644539e76b4fd43b7d29e6a88ba plugkit.wasm
@@ -90,12 +90,14 @@ function isProfileLocked(profileDir) {
90
90
  }
91
91
 
92
92
  function acquireProfileDir(cwd) {
93
- const primary = path.join(cwd, '.plugkit-browser-profile');
94
- ensureGitignored(cwd, '.plugkit-browser-profile/');
95
- ensureGitignored(cwd, '.plugkit-browser-profile-*/');
93
+ const gmDir = path.join(cwd, '.gm');
94
+ try { fs.mkdirSync(gmDir, { recursive: true }); } catch (_) {}
95
+ const primary = path.join(gmDir, 'browser-profile');
96
+ ensureGitignored(cwd, '.gm/browser-profile/');
97
+ ensureGitignored(cwd, '.gm/browser-profile-*/');
96
98
  try { fs.mkdirSync(primary, { recursive: true }); } catch (_) {}
97
99
  if (!isProfileLocked(primary)) return primary;
98
- const fallback = path.join(cwd, `.plugkit-browser-profile-${process.pid}`);
100
+ const fallback = path.join(gmDir, `browser-profile-${process.pid}`);
99
101
  try { fs.mkdirSync(fallback, { recursive: true }); } catch (_) {}
100
102
  return fallback;
101
103
  }
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1126",
3
+ "version": "2.0.1128",
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.396"
20
+ "plugkitVersion": "0.1.397"
21
21
  }
@@ -182,6 +182,9 @@ function getManagedGitignoreEntries() {
182
182
  '.gm/ingest-drafts/',
183
183
  '.gm/prd-state.json',
184
184
  '.gm/subagent-*.json',
185
+ '.gm/browser-profile/',
186
+ '.gm/browser-profile-*/',
187
+ '.gm/build-tool-ignores.md',
185
188
  '.plugkit-browser-profile/',
186
189
  '.plugkit-browser-profile-*/',
187
190
  ];
@@ -200,6 +203,123 @@ function getMustStayTracked() {
200
203
  ];
201
204
  }
202
205
 
206
+ function detectBuildToolConfigs(cwd) {
207
+ const detectors = [
208
+ { tool: 'vite', patterns: ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.cjs'] },
209
+ { tool: 'vitest', patterns: ['vitest.config.js', 'vitest.config.ts', 'vitest.config.mjs'] },
210
+ { tool: 'astro', patterns: ['astro.config.js', 'astro.config.ts', 'astro.config.mjs'] },
211
+ { tool: 'next', patterns: ['next.config.js', 'next.config.ts', 'next.config.mjs', 'next.config.cjs'] },
212
+ { tool: 'jest', patterns: ['jest.config.js', 'jest.config.ts', 'jest.config.mjs', 'jest.config.cjs', 'jest.config.json'] },
213
+ { tool: 'webpack', patterns: ['webpack.config.js', 'webpack.config.ts', 'webpack.config.cjs', 'webpack.config.mjs'] },
214
+ { tool: 'rollup', patterns: ['rollup.config.js', 'rollup.config.ts', 'rollup.config.mjs'] },
215
+ { tool: 'nuxt', patterns: ['nuxt.config.js', 'nuxt.config.ts', 'nuxt.config.mjs'] },
216
+ ];
217
+ const found = [];
218
+ for (const d of detectors) {
219
+ for (const p of d.patterns) {
220
+ const fp = path.join(cwd, p);
221
+ if (fs.existsSync(fp)) {
222
+ found.push({ tool: d.tool, file: p, fullPath: fp });
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ return found;
228
+ }
229
+
230
+ function patchJestJsonConfig(filePath) {
231
+ const raw = fs.readFileSync(filePath, 'utf-8');
232
+ const cfg = JSON.parse(raw);
233
+ const want = '<rootDir>/.gm/';
234
+ const existing = Array.isArray(cfg.watchPathIgnorePatterns) ? cfg.watchPathIgnorePatterns : [];
235
+ if (existing.includes(want)) return false;
236
+ cfg.watchPathIgnorePatterns = [...existing, want];
237
+ fs.writeFileSync(filePath, JSON.stringify(cfg, null, 2) + '\n');
238
+ return true;
239
+ }
240
+
241
+ function patchPackageJsonJest(cwd) {
242
+ const pkgPath = path.join(cwd, 'package.json');
243
+ if (!fs.existsSync(pkgPath)) return null;
244
+ const raw = fs.readFileSync(pkgPath, 'utf-8');
245
+ let pkg;
246
+ try { pkg = JSON.parse(raw); } catch (_) { return null; }
247
+ if (!pkg.jest || typeof pkg.jest !== 'object') return null;
248
+ const want = '<rootDir>/.gm/';
249
+ const existing = Array.isArray(pkg.jest.watchPathIgnorePatterns) ? pkg.jest.watchPathIgnorePatterns : [];
250
+ if (existing.includes(want)) return false;
251
+ pkg.jest.watchPathIgnorePatterns = [...existing, want];
252
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
253
+ return true;
254
+ }
255
+
256
+ function ensureBuildToolIgnores(cwd) {
257
+ try {
258
+ const found = detectBuildToolConfigs(cwd);
259
+ const automated = [];
260
+ const advisory = [];
261
+
262
+ for (const f of found) {
263
+ if (f.tool === 'jest' && f.file.endsWith('.json')) {
264
+ try {
265
+ const changed = patchJestJsonConfig(f.fullPath);
266
+ automated.push({ tool: 'jest', file: f.file, changed });
267
+ } catch (e) {
268
+ advisory.push({ ...f, reason: `patch failed: ${e.message}` });
269
+ }
270
+ } else {
271
+ advisory.push(f);
272
+ }
273
+ }
274
+
275
+ try {
276
+ const pkgChanged = patchPackageJsonJest(cwd);
277
+ if (pkgChanged !== null) automated.push({ tool: 'jest', file: 'package.json#jest', changed: pkgChanged });
278
+ } catch (_) {}
279
+
280
+ const snippets = {
281
+ vite: "server: { watch: { ignored: ['**/.gm/**'] } }",
282
+ vitest: "test: { watchExclude: ['**/.gm/**'] }",
283
+ astro: "vite: { server: { watch: { ignored: ['**/.gm/**'] } } }",
284
+ next: "webpack: (config) => { config.watchOptions = { ...config.watchOptions, ignored: ['**/.gm/**', ...(config.watchOptions?.ignored || [])] }; return config; }",
285
+ jest: "watchPathIgnorePatterns: ['<rootDir>/.gm/']",
286
+ webpack: "watchOptions: { ignored: ['**/.gm/**', '**/node_modules/**'] }",
287
+ rollup: "watch: { exclude: ['.gm/**'] }",
288
+ nuxt: "vite: { server: { watch: { ignored: ['**/.gm/**'] } } }",
289
+ };
290
+
291
+ const gmDir = path.join(cwd, '.gm');
292
+ const advisoryPath = path.join(gmDir, 'build-tool-ignores.md');
293
+ if (advisory.length === 0) {
294
+ try { if (fs.existsSync(advisoryPath)) fs.unlinkSync(advisoryPath); } catch (_) {}
295
+ } else {
296
+ fs.mkdirSync(gmDir, { recursive: true });
297
+ const lines = [
298
+ '# Build-tool ignore advisories',
299
+ '',
300
+ '`.gitignore` already excludes `.gm/`. Tools whose watchers honor `.gitignore` (vite, vitest, astro, nuxt with chokidar defaults) need no further action.',
301
+ '',
302
+ 'For watchers that do NOT honor `.gitignore` automatically, paste these snippets into the corresponding config file:',
303
+ '',
304
+ ];
305
+ for (const f of advisory) {
306
+ const snip = snippets[f.tool];
307
+ if (!snip) continue;
308
+ lines.push(`## ${f.tool} (\`${f.file}\`)`, '', '```', snip, '```', '');
309
+ }
310
+ lines.push('---', '', 'Regenerated each bootstrap. Delete after applying — file is gitignored.');
311
+ fs.writeFileSync(advisoryPath, lines.join('\n'));
312
+ }
313
+
314
+ emitBootstrapEvent('info', 'Build-tool ignore handling complete', {
315
+ automated: automated.map(a => ({ tool: a.tool, file: a.file, changed: a.changed })),
316
+ advisory: advisory.map(a => ({ tool: a.tool, file: a.file })),
317
+ });
318
+ } catch (e) {
319
+ emitBootstrapEvent('warn', 'ensureBuildToolIgnores failed', { error: e.message });
320
+ }
321
+ }
322
+
203
323
  function ensureManagedGitignore(cwd) {
204
324
  try {
205
325
  const gi = gitignorePath(cwd);
@@ -429,6 +549,7 @@ async function bootstrapPlugkit(sessionId, options) {
429
549
  emitBootstrapEvent('info', 'Bootstrap started', { forceLatest });
430
550
 
431
551
  ensureManagedGitignore(process.cwd());
552
+ ensureBuildToolIgnores(process.cwd());
432
553
 
433
554
  const manifest = readManifest();
434
555
  let targetVersion = manifest.version;
@@ -616,9 +737,12 @@ async function getSnapshot(sessionId, cwd) {
616
737
  }
617
738
  }
618
739
 
619
- module.exports = {
740
+ module.exports = {
620
741
  bootstrapPlugkit,
621
742
  bootstrapAcptoapi,
622
743
  getSnapshot,
623
- checkPortReachable
744
+ checkPortReachable,
745
+ ensureBuildToolIgnores,
746
+ detectBuildToolConfigs,
747
+ ensureManagedGitignore,
624
748
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1126",
3
+ "version": "2.0.1128",
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.1126"
42
+ "gm-plugkit": "^2.0.1128"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=16.0.0"
@@ -100,8 +100,8 @@ Stop when `next_phase_hint` is null or phase is `COMPLETE`.
100
100
 
101
101
  ### Browser
102
102
 
103
- Dispatch `.gm/exec-spool/in/browser/<N>.txt` with raw JavaScript as the body. The wrapper spawns Chrome (managed profile at `<cwd>/.plugkit-browser-profile/`) and runs the JS via playwriter. Globals available inside the body: `page` (playwright Page), `snapshot` (accessibility snapshot), `screenshotWithAccessibilityLabels` (screenshot helper), `state` (per-session state object).
103
+ Dispatch `.gm/exec-spool/in/browser/<N>.txt` with raw JavaScript as the body. The wrapper spawns Chrome (managed profile at `<cwd>/.gm/browser-profile/`) and runs the JS via playwriter. Globals available inside the body: `page` (playwright Page), `snapshot` (accessibility snapshot), `screenshotWithAccessibilityLabels` (screenshot helper), `state` (per-session state object).
104
104
 
105
105
  Special commands (body starts with `session `): `session new`, `session list`, `session close <id>` pass through to playwriter directly.
106
106
 
107
- Chrome is detected from system install paths; profile dir is project-scoped so cookies/login persist per project. The wrapper auto-adds `.plugkit-browser-profile/` to `.gitignore`.
107
+ Chrome is detected from system install paths; profile dir is project-scoped so cookies/login persist per project. The wrapper writes the managed gitignore block (which includes `.gm/browser-profile/`) on first launch.