gm-skill 2.0.1824 → 2.0.1825

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.
@@ -774,71 +774,72 @@ function ensureGmPlugkitVersionFresh() {
774
774
  } catch (_) { return false; }
775
775
  }
776
776
 
777
+ const BOOTSTRAP_JS_BUNDLED_SKILLS = ['gm', 'gm-continue', 'wfgy-method'];
778
+
777
779
  function ensureSkillMdFresh() {
778
- try {
779
- const candidates = [
780
- path.join(__dirname, 'SKILL.md'),
781
- path.join(__dirname, '..', 'gm-skill', 'skills', 'gm', 'SKILL.md'),
782
- path.join(__dirname, '..', '..', 'gm-skill', 'skills', 'gm', 'SKILL.md'),
783
- path.join(__dirname, '..', 'skills', 'gm', 'SKILL.md'),
784
- ];
785
- const bundledPath = candidates.find(p => {
786
- try { return fs.existsSync(p); } catch (_) { return false; }
787
- });
788
- if (!bundledPath) {
789
- try {
790
- obsEvent('bootstrap', 'skill-md.refresh.bundled-not-found', { searched: candidates });
791
- } catch (_) {}
792
- return { skipped: 'bundled-not-found' };
793
- }
794
- const bundled = fs.readFileSync(bundledPath, 'utf-8');
795
- const crypto = require('crypto');
796
- const _norm = s => s.replace(/\r\n/g, '\n');
797
- const bundledHash = crypto.createHash('sha256').update(_norm(bundled)).digest('hex');
798
- const home = process.env.HOME || process.env.USERPROFILE || require('os').homedir();
799
- const targets = [
800
- path.join(home, '.agents', 'skills', 'gm', 'SKILL.md'),
801
- path.join(home, '.claude', 'skills', 'gm', 'SKILL.md'),
802
- ];
803
- for (const legacy of [
804
- path.join(home, '.agents', 'skills', 'gm-skill'),
805
- path.join(home, '.claude', 'skills', 'gm-skill'),
806
- ]) {
807
- try { if (fs.existsSync(legacy)) fs.rmSync(legacy, { recursive: true, force: true }); } catch (_) {}
808
- }
809
- const refreshed = [];
810
- for (const target of targets) {
811
- try {
812
- let needsWrite = true;
813
- if (fs.existsSync(target)) {
814
- const existing = fs.readFileSync(target, 'utf-8');
815
- const existingHash = crypto.createHash('sha256').update(_norm(existing)).digest('hex');
816
- if (existingHash === bundledHash) needsWrite = false;
817
- }
818
- if (needsWrite) {
819
- fs.mkdirSync(path.dirname(target), { recursive: true });
820
- const tmp = target + '.tmp';
821
- fs.writeFileSync(tmp, bundled);
822
- fs.renameSync(tmp, target);
823
- refreshed.push(target);
780
+ const home = process.env.HOME || process.env.USERPROFILE || require('os').homedir();
781
+ const crypto = require('crypto');
782
+ const _norm = s => s.replace(/\r\n/g, '\n');
783
+ const allRefreshed = [];
784
+ const sources = {};
785
+ for (const skillName of BOOTSTRAP_JS_BUNDLED_SKILLS) {
786
+ try {
787
+ const candidates = [
788
+ path.join(__dirname, skillName === 'gm' ? 'SKILL.md' : `SKILL-${skillName}.md`),
789
+ path.join(__dirname, '..', 'gm-skill', 'skills', skillName, 'SKILL.md'),
790
+ path.join(__dirname, '..', '..', 'gm-skill', 'skills', skillName, 'SKILL.md'),
791
+ path.join(__dirname, '..', 'skills', skillName, 'SKILL.md'),
792
+ ];
793
+ const bundledPath = candidates.find(p => {
794
+ try { return fs.existsSync(p); } catch (_) { return false; }
795
+ });
796
+ if (!bundledPath) {
797
+ try { obsEvent('bootstrap', 'skill-md.refresh.bundled-not-found', { skillName, searched: candidates }); } catch (_) {}
798
+ continue;
799
+ }
800
+ const bundled = fs.readFileSync(bundledPath, 'utf-8');
801
+ const bundledHash = crypto.createHash('sha256').update(_norm(bundled)).digest('hex');
802
+ const targets = [
803
+ path.join(home, '.agents', 'skills', skillName, 'SKILL.md'),
804
+ path.join(home, '.claude', 'skills', skillName, 'SKILL.md'),
805
+ ];
806
+ if (skillName === 'gm') {
807
+ for (const legacy of [
808
+ path.join(home, '.agents', 'skills', 'gm-skill'),
809
+ path.join(home, '.claude', 'skills', 'gm-skill'),
810
+ ]) {
811
+ try { if (fs.existsSync(legacy)) fs.rmSync(legacy, { recursive: true, force: true }); } catch (_) {}
824
812
  }
825
- } catch (e) {
813
+ }
814
+ sources[skillName] = bundledPath;
815
+ for (const target of targets) {
826
816
  try {
827
- obsEvent('bootstrap', 'skill-md.refresh.target-failed', { target, error: e.message });
828
- } catch (_) {}
817
+ let needsWrite = true;
818
+ if (fs.existsSync(target)) {
819
+ const existing = fs.readFileSync(target, 'utf-8');
820
+ const existingHash = crypto.createHash('sha256').update(_norm(existing)).digest('hex');
821
+ if (existingHash === bundledHash) needsWrite = false;
822
+ }
823
+ if (needsWrite) {
824
+ fs.mkdirSync(path.dirname(target), { recursive: true });
825
+ const tmp = target + '.tmp';
826
+ fs.writeFileSync(tmp, bundled);
827
+ fs.renameSync(tmp, target);
828
+ allRefreshed.push(target);
829
+ }
830
+ } catch (e) {
831
+ try { obsEvent('bootstrap', 'skill-md.refresh.target-failed', { target, error: e.message }); } catch (_) {}
832
+ }
829
833
  }
834
+ } catch (e) {
835
+ try { obsEvent('bootstrap', 'skill-md.refresh.failed', { skillName, error: e.message }); } catch (_) {}
830
836
  }
831
- if (refreshed.length > 0) {
832
- log(`SKILL.md refreshed (sha=${bundledHash.slice(0, 12)}): ${refreshed.length} target(s)`);
833
- try {
834
- obsEvent('bootstrap', 'skill-md.refreshed', { hash: bundledHash.slice(0, 12), targets: refreshed, source: bundledPath });
835
- } catch (_) {}
836
- }
837
- return { refreshed, bundledHash, source: bundledPath };
838
- } catch (e) {
839
- try { obsEvent('bootstrap', 'skill-md.refresh.failed', { error: e.message }); } catch (_) {}
840
- return { error: e.message };
841
837
  }
838
+ if (allRefreshed.length > 0) {
839
+ log(`SKILL.md refreshed: ${allRefreshed.length} target(s)`);
840
+ try { obsEvent('bootstrap', 'skill-md.refreshed', { targets: allRefreshed, sources }); } catch (_) {}
841
+ }
842
+ return { refreshed: allRefreshed, sources };
842
843
  }
843
844
 
844
845
  function installedVersionAtTools() {
@@ -1103,6 +1104,7 @@ module.exports = {
1103
1104
  daemonVersionSentinel,
1104
1105
  readVersionFile,
1105
1106
  ensureGmPlugkitVersionFresh,
1107
+ ensureSkillMdFresh,
1106
1108
  };
1107
1109
 
1108
1110
  if (require.main === module) {
package/gm-plugkit/cli.js CHANGED
@@ -5,7 +5,7 @@ const fs = require('fs');
5
5
  const os = require('os');
6
6
  const path = require('path');
7
7
  const cp = require('child_process');
8
- const { ensureReady, startSpoolDaemon, gmToolsDir, readVersionFile, ensureGmPlugkitVersionFresh } = require('./bootstrap');
8
+ const { ensureReady, startSpoolDaemon, gmToolsDir, readVersionFile, ensureGmPlugkitVersionFresh, ensureSkillMdFresh } = require('./bootstrap');
9
9
 
10
10
  function readUpdateAvailableMarker(dir) {
11
11
  try {
@@ -215,12 +215,15 @@ function writeCliError(phase, err) {
215
215
  const versionDrifted = localVersionDrifted || remoteVersionDrifted;
216
216
  if (statusServing(already, 12000) && !versionDrifted) {
217
217
  try { ensureGmPlugkitVersionFresh(); } catch (_) {}
218
+ let skillRefresh = null;
219
+ try { skillRefresh = ensureSkillMdFresh(); } catch (_) {}
218
220
  writeCliStatus({ phase: 'ready', already_serving: true, watcher_pid: already.pid });
219
221
  console.log(JSON.stringify({
220
222
  ok: true,
221
223
  already_serving: true,
222
224
  watcher_pid: already.pid,
223
225
  version: already.version,
226
+ skills_refreshed: skillRefresh && skillRefresh.refreshed || [],
224
227
  message: 'plugkit already serving, no bootstrap/spawn needed',
225
228
  }));
226
229
  process.exit(0);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1824",
3
+ "version": "2.0.1825",
4
4
  "description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -17,6 +17,8 @@
17
17
  "plugkit.version",
18
18
  "plugkit.sha256",
19
19
  "SKILL.md",
20
+ "SKILL-gm-continue.md",
21
+ "SKILL-wfgy-method.md",
20
22
  "instructions/"
21
23
  ],
22
24
  "keywords": [
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1824",
3
+ "version": "2.0.1825",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1824",
3
+ "version": "2.0.1825",
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",