gm-skill 2.0.1127 → 2.0.1129

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
@@ -1,18 +1,18 @@
1
1
  # gm-skill — Canonical Universal Harness
2
2
 
3
- The single canonical body of the gm skill-driven orchestration harness. All 15 platform-specific `gm-<platform>` packages re-export this surface; this is the source of truth.
3
+ The single shipped skill for gm. Install into any harness that loads Claude-style skill directories Claude Code, OpenCode, Cursor, Zed, VS Code, Codex, Kilo, JetBrains, Copilot CLI, Antigravity, Windsurf, Gemini CLI — and plugkit serves every phase instruction, mutables row, and guardrail on demand via the spool.
4
4
 
5
5
  ## What this is
6
6
 
7
- AI-native software engineering orchestrated as a continuous chain — PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCSbootstrapped on top of `plugkit` for task execution and session isolation. Spool-driven, daemonize-by-default, end-to-end chained.
7
+ AI-native software engineering orchestrated as a state machine — PLAN → EXECUTE → EMIT → VERIFY → COMPLETEbacked by the `plugkit` WASM orchestrator. Spool-driven dispatch, no daemon, no native binaries.
8
8
 
9
9
  ## Install
10
10
 
11
11
  ```bash
12
- npm install gm-skill
12
+ npm install -g gm-skill
13
13
  ```
14
14
 
15
- Then point your AI coding agent host (Claude Code, OpenCode, Cursor, Zed, VS Code, Codex, Kilo, JetBrains, Copilot CLI, Hermes, etc.) at the included `skills/` directory, or invoke the bootstrap directly:
15
+ Then point your AI coding agent host at the included `skills/` directory, or invoke the bootstrap directly:
16
16
 
17
17
  ```bash
18
18
  npx gm-skill-bootstrap
@@ -20,15 +20,20 @@ npx gm-skill-bootstrap
20
20
 
21
21
  ## What's inside
22
22
 
23
- - `skills/` — every shared skill (gm, gm-execute, gm-emit, gm-complete, planning, update-docs, browser, code-search, create-lang-plugin, governance, pages, research, ssh, textprocessing, gm-skill itself)
24
- - `bin/bootstrap.js`plugkit downloader + daemon launcher
25
- - `gm-plugkit/` — spool watcher and WASM wrapper
26
- - `lib/`daemon-bootstrap, skill-bootstrap, spool-dispatch, git, codeinsight modules
27
- - `agents/`, `prompts/`, `scripts/`, `lang/` — supporting surface
23
+ - `skills/gm-skill/` — the canonical universal harness (`SKILL.md` is the ~12-line entry point)
24
+ - `gm-plugkit/`WASM bootstrap and spool watcher wrapper
25
+ - `lib/` — skill-bootstrap, spool-dispatch, daemon-bootstrap, git, codeinsight modules
26
+ - `bin/plugkit.wasm.sha256`pinned hash of the plugkit WASM artifact
27
+
28
+ ## Architecture
29
+
30
+ All orchestration lives in `rs-plugkit/src/orchestrator/` as native Rust, compiled to a single `plugkit.wasm` (~<200KB). The agent dispatches verbs by writing to `.gm/exec-spool/in/<verb>/<N>.txt` and reading responses from `.gm/exec-spool/out/`. See [AGENTS.md](https://github.com/AnEntrypoint/gm/blob/main/AGENTS.md) for the full design.
31
+
32
+ An earlier generation fanned out fifteen per-platform downstream repos (gm-cc, gm-gc, gm-oc, gm-kilo, gm-codex, gm-qwen, gm-copilot-cli, gm-hermes, gm-thebird, gm-vscode, gm-cursor, gm-zed, gm-jetbrains, gm-antigravity, gm-windsurf). Those are archived; `gm-skill` is the single source of truth.
28
33
 
29
34
  ## Version
30
35
 
31
- `2.0.1127` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` republishes this package alongside all 15 platform packages.
36
+ `2.0.1129` — auto-bumped from the canonical `gm` repo. Every push to `AnEntrypoint/gm` (or any cascading sibling crate) republishes this package.
32
37
 
33
38
  ## Source of truth
34
39
 
@@ -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.1127",
3
+ "version": "2.0.1129",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -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.1127",
3
+ "version": "2.0.1129",
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.1127"
42
+ "gm-plugkit": "^2.0.1129"
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.