gm-cc 2.0.552 → 2.0.553

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.
@@ -4,7 +4,7 @@
4
4
  "name": "AnEntrypoint"
5
5
  },
6
6
  "description": "State machine agent with hooks, skills, and automated git enforcement",
7
- "version": "2.0.552",
7
+ "version": "2.0.553",
8
8
  "metadata": {
9
9
  "description": "State machine agent with hooks, skills, and automated git enforcement"
10
10
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-cc",
3
- "version": "2.0.552",
3
+ "version": "2.0.553",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.552",
3
+ "version": "2.0.553",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": {
6
6
  "name": "AnEntrypoint",
@@ -3,10 +3,5 @@ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT}}"
3
3
  [ -z "$PLUGIN_ROOT" ] && exit 0
4
4
  PLUGKIT="$PLUGIN_ROOT/bin/plugkit"
5
5
  [ -f "$PLUGIN_ROOT/bin/plugkit.exe" ] && PLUGKIT="$PLUGIN_ROOT/bin/plugkit.exe"
6
- if [ ! -f "$PLUGKIT" ]; then
7
- sh "$PLUGIN_ROOT/scripts/bootstrap.sh"
8
- PLUGKIT="$PLUGIN_ROOT/bin/plugkit"
9
- [ -f "$PLUGIN_ROOT/bin/plugkit.exe" ] && PLUGKIT="$PLUGIN_ROOT/bin/plugkit.exe"
10
- fi
11
6
  [ ! -f "$PLUGKIT" ] && exit 0
12
7
  "$PLUGKIT" hook "$1"
@@ -1,14 +0,0 @@
1
- @echo off
2
- setlocal
3
- set "PLUGKIT=%CLAUDE_PLUGIN_ROOT%\bin\plugkit.exe"
4
- set "BINDIR=%CLAUDE_PLUGIN_ROOT%\bin"
5
- set "VERFILE=%BINDIR%\.plugkit-version"
6
- if not exist "%BINDIR%" mkdir "%BINDIR%"
7
- if not exist "%PLUGKIT%" (
8
- powershell -NoProfile -ExecutionPolicy Bypass -Command "$g=ConvertFrom-Json(Get-Content '%CLAUDE_PLUGIN_ROOT%\gm.json' -Raw);$v=$g.plugkitVersion;[Net.ServicePointManager]::SecurityProtocol='Tls12';$r=[Net.HttpWebRequest]::Create(\"https://github.com/AnEntrypoint/rs-plugkit/releases/download/v$v/plugkit-win32-x64.exe\");$r.Timeout=1000;$r.AllowAutoRedirect=$true;try{$rs=$r.GetResponse();$s=$rs.GetResponseStream();$f=[IO.File]::Create('%PLUGKIT%');$s.CopyTo($f);$f.Dispose();$rs.Dispose();Set-Content -NoNewline '%VERFILE%' $v}catch{}" 2>nul
9
- )
10
- if exist "%PLUGKIT%" (
11
- powershell -NoProfile -ExecutionPolicy Bypass -Command "try{$p=Split-Path '%CLAUDE_PLUGIN_ROOT%';Get-ChildItem $p -Directory|Where-Object{$_.FullName -ne '%CLAUDE_PLUGIN_ROOT%'}|ForEach-Object{Remove-Item $_.FullName -Recurse -Force -ErrorAction SilentlyContinue}}catch{}" 2>nul
12
- "%PLUGKIT%" bootstrap
13
- )
14
- endlocal
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
- const fs = require('fs');
4
- const path = require('path');
5
- const https = require('https');
6
- const { execFileSync } = require('child_process');
7
-
8
- const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || process.env.CODEX_PLUGIN_ROOT || process.env.KILO_PLUGIN_ROOT || process.env.OC_PLUGIN_ROOT || process.env.extensionPath;
9
- if (!pluginRoot) process.exit(0);
10
-
11
- const IS_WIN = process.platform === 'win32';
12
- const binDir = path.join(pluginRoot, 'bin');
13
- const binPath = path.join(binDir, IS_WIN ? 'plugkit.exe' : 'plugkit');
14
- const pendingPath = binPath + '.pending';
15
- const versionFile = path.join(binDir, '.plugkit-version');
16
- const pendingVersionFile = pendingPath + '.version';
17
-
18
- function getAssetName() {
19
- const os = process.platform === 'win32' ? 'win32' : process.platform === 'darwin' ? 'darwin' : 'linux';
20
- const cpu = process.arch === 'arm64' ? 'arm64' : 'x64';
21
- const ext = process.platform === 'win32' ? '.exe' : '';
22
- return `plugkit-${os}-${cpu}${ext}`;
23
- }
24
-
25
- function killDaemon() {
26
- try {
27
- execFileSync(binPath, ['runner', 'stop'], { timeout: 5000, stdio: 'ignore' });
28
- } catch {}
29
- if (IS_WIN) {
30
- try { execFileSync('taskkill', ['/F', '/IM', 'plugkit.exe'], { timeout: 3000, stdio: 'ignore' }); } catch {}
31
- }
32
- }
33
-
34
- function applyPending() {
35
- if (!fs.existsSync(pendingPath)) return;
36
- killDaemon();
37
- const oldPath = binPath + '.old';
38
- try { fs.unlinkSync(oldPath); } catch {}
39
- try { fs.renameSync(binPath, oldPath); } catch {}
40
- try {
41
- fs.renameSync(pendingPath, binPath);
42
- if (fs.existsSync(pendingVersionFile)) {
43
- try { fs.renameSync(pendingVersionFile, versionFile); } catch {}
44
- }
45
- } catch {
46
- try { if (!fs.existsSync(binPath)) fs.renameSync(oldPath, binPath); } catch {}
47
- }
48
- }
49
-
50
- applyPending();
51
-
52
- function getRequiredVersion() {
53
- try {
54
- return JSON.parse(fs.readFileSync(path.join(pluginRoot, 'gm.json'), 'utf8')).plugkitVersion || null;
55
- } catch { return null; }
56
- }
57
-
58
- function getCurrentVersion() {
59
- try { return fs.readFileSync(versionFile, 'utf8').trim() || null; } catch { return null; }
60
- }
61
-
62
- const required = getRequiredVersion();
63
- const current = getCurrentVersion();
64
- if (current && current === required) process.exit(0);
65
-
66
- function download(version, dest, cb) {
67
- const asset = getAssetName();
68
- const urlPath = `/AnEntrypoint/rs-plugkit/releases/download/v${version}/${asset}`;
69
- if (!fs.existsSync(path.dirname(dest))) fs.mkdirSync(path.dirname(dest), { recursive: true });
70
- const follow = (url) => {
71
- const mod = url.startsWith('https') ? https : require('http');
72
- const opts = { ...require('url').parse(url), headers: { 'User-Agent': 'gm-bootstrap' } };
73
- mod.get(opts, res => {
74
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return follow(res.headers.location);
75
- if (res.statusCode !== 200) return cb(new Error(`HTTP ${res.statusCode}`));
76
- const chunks = [];
77
- res.on('data', c => chunks.push(c));
78
- res.on('end', () => {
79
- try {
80
- fs.writeFileSync(dest, Buffer.concat(chunks));
81
- try { fs.chmodSync(dest, 0o755); } catch {}
82
- cb(null);
83
- } catch (e) { cb(e); }
84
- });
85
- }).on('error', cb);
86
- };
87
- follow(`https://github.com${urlPath}`);
88
- }
89
-
90
- killDaemon();
91
-
92
- download(required, binPath, (err) => {
93
- if (err && err.code === 'EBUSY') {
94
- download(required, pendingPath, (err2) => {
95
- if (err2) {
96
- process.stderr.write(`bootstrap: pending failed: ${err2.message}\n`);
97
- process.exit(fs.existsSync(binPath) ? 0 : 1);
98
- }
99
- try { fs.writeFileSync(pendingVersionFile, required); } catch {}
100
- process.exit(0);
101
- });
102
- return;
103
- }
104
- if (err) {
105
- process.stderr.write(`bootstrap: ${err.message}\n`);
106
- process.exit(fs.existsSync(binPath) ? 0 : 1);
107
- }
108
- try { fs.writeFileSync(versionFile, required); } catch {}
109
- process.exit(0);
110
- });
@@ -1,28 +0,0 @@
1
- #!/bin/sh
2
- set -e
3
- PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT}}"
4
- [ -z "$PLUGIN_ROOT" ] && exit 0
5
- BINDIR="$PLUGIN_ROOT/bin"
6
- VERFILE="$BINDIR/.plugkit-version"
7
- IS_WIN=0
8
- case "$(uname -s 2>/dev/null)" in MINGW*|CYGWIN*|MSYS*) IS_WIN=1;; esac
9
- [ -f /proc/version ] && grep -qi microsoft /proc/version 2>/dev/null && IS_WIN=1
10
- if [ $IS_WIN -eq 1 ]; then EXT=".exe"; OS="win32"; else EXT=""; OS="$(uname -s | tr '[:upper:]' '[:lower:]')"; fi
11
- case "$(uname -m 2>/dev/null)" in arm64|aarch64) ARCH="arm64";; *) ARCH="x64";; esac
12
- ASSET="plugkit-${OS}-${ARCH}${EXT}"
13
- PLUGKIT="$BINDIR/plugkit${EXT}"
14
- mkdir -p "$BINDIR"
15
- if [ ! -f "$PLUGKIT" ]; then
16
- VER="$(node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('$PLUGIN_ROOT/gm.json','utf8')).plugkitVersion)" 2>/dev/null || python3 -c "import json,sys;d=json.load(open('$PLUGIN_ROOT/gm.json'));sys.stdout.write(d['plugkitVersion'])" 2>/dev/null || python -c "import json,sys;d=json.load(open('$PLUGIN_ROOT/gm.json'));sys.stdout.write(d['plugkitVersion'])" 2>/dev/null || sed -n 's/.*"plugkitVersion"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$PLUGIN_ROOT/gm.json" | head -1)"
17
- [ -z "$VER" ] && exit 0
18
- URL="https://github.com/AnEntrypoint/rs-plugkit/releases/download/v${VER}/${ASSET}"
19
- curl -fsSL --location --max-time 30 "$URL" -o "$PLUGKIT" 2>/dev/null || exit 0
20
- chmod +x "$PLUGKIT" 2>/dev/null || true
21
- printf '%s' "$VER" > "$VERFILE"
22
- fi
23
- PARENT="$(dirname "$PLUGIN_ROOT")"
24
- for d in "$PARENT"/*/; do
25
- [ "$d" = "$PLUGIN_ROOT/" ] && continue
26
- rm -rf "$d" 2>/dev/null || true
27
- done
28
- "$PLUGKIT" bootstrap
@@ -1,130 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const https = require('https');
6
-
7
- function isInsideNodeModules() {
8
- return __dirname.includes(path.sep + 'node_modules' + path.sep);
9
- }
10
-
11
- function getProjectRoot() {
12
- if (!isInsideNodeModules()) return null;
13
- let current = __dirname;
14
- while (current !== path.dirname(current)) {
15
- current = path.dirname(current);
16
- if (path.basename(current) === 'node_modules') return path.dirname(current);
17
- }
18
- return null;
19
- }
20
-
21
- function safeCopyFile(src, dst) {
22
- try {
23
- const dstDir = path.dirname(dst);
24
- if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
25
- fs.writeFileSync(dst, fs.readFileSync(src));
26
- return true;
27
- } catch { return false; }
28
- }
29
-
30
- function safeCopyDirectory(src, dst) {
31
- try {
32
- if (!fs.existsSync(src)) return false;
33
- fs.mkdirSync(dst, { recursive: true });
34
- fs.readdirSync(src, { withFileTypes: true }).forEach(entry => {
35
- const srcPath = path.join(src, entry.name);
36
- const dstPath = path.join(dst, entry.name);
37
- if (entry.isDirectory()) safeCopyDirectory(srcPath, dstPath);
38
- else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
39
- });
40
- return true;
41
- } catch { return false; }
42
- }
43
-
44
- function updateGitignore(projectRoot) {
45
- try {
46
- const gitignorePath = path.join(projectRoot, '.gitignore');
47
- const entry = '.gm/';
48
- let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
49
- if (content.includes(entry)) return;
50
- if (content && !content.endsWith('\n')) content += '\n';
51
- fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
52
- } catch {}
53
- }
54
-
55
- function getRequiredVersion(sourceDir) {
56
- try {
57
- const gm = JSON.parse(fs.readFileSync(path.join(sourceDir, 'gm.json'), 'utf-8'));
58
- return gm.plugkitVersion || null;
59
- } catch { return null; }
60
- }
61
-
62
- function getInstalledVersion(binPath) {
63
- try {
64
- const { spawnSync } = require('child_process');
65
- const r = spawnSync(binPath, ['--version'], { encoding: 'utf8', timeout: 5000 });
66
- const m = (r.stdout || '').trim().match(/(\d+\.\d+\.\d+)/);
67
- return m ? m[1] : null;
68
- } catch { return null; }
69
- }
70
-
71
- function downloadBin(version, dest, callback) {
72
- const IS_WIN = process.platform === 'win32';
73
- const asset = IS_WIN ? 'plugkit.exe' : 'plugkit';
74
- const urlPath = version
75
- ? `/AnEntrypoint/rs-plugkit/releases/download/v${version}/${asset}`
76
- : `/AnEntrypoint/rs-plugkit/releases/latest/download/${asset}`;
77
- const destDir = path.dirname(dest);
78
- if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
79
- const follow = (url) => {
80
- const mod = url.startsWith('https') ? https : require('http');
81
- const opts = { ...require('url').parse(url), headers: { 'User-Agent': 'gm-postinstall' } };
82
- mod.get(opts, res => {
83
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return follow(res.headers.location);
84
- if (res.statusCode !== 200) return callback(new Error(`HTTP ${res.statusCode}`));
85
- const chunks = [];
86
- res.on('data', c => chunks.push(c));
87
- res.on('end', () => { try { fs.writeFileSync(dest, Buffer.concat(chunks)); try { fs.chmodSync(dest, 0o755); } catch {} callback(null); } catch (e) { callback(e); } });
88
- }).on('error', callback);
89
- };
90
- follow(`https://github.com${urlPath}`);
91
- }
92
-
93
- function install() {
94
- if (!isInsideNodeModules()) return;
95
- const projectRoot = getProjectRoot();
96
- if (!projectRoot) return;
97
- const kiloDir = path.join(projectRoot, '.config', 'kilo');
98
- const sourceDir = path.dirname(__dirname);
99
-
100
- safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(kiloDir, 'agents'));
101
- safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(kiloDir, 'hooks'));
102
- safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(kiloDir, 'skills'));
103
- safeCopyFile(path.join(sourceDir, 'kilocode.json'), path.join(kiloDir, 'kilocode.json'));
104
- safeCopyFile(path.join(sourceDir, '.mcp.json'), path.join(kiloDir, '.mcp.json'));
105
- safeCopyFile(path.join(sourceDir, 'gm-kilo.mjs'), path.join(kiloDir, 'plugins', 'gm-kilo.mjs'));
106
- safeCopyFile(path.join(sourceDir, 'gm.json'), path.join(kiloDir, 'gm.json'));
107
- safeCopyFile(path.join(sourceDir, 'README.md'), path.join(kiloDir, 'README.md'));
108
- safeCopyFile(path.join(sourceDir, 'LICENSE'), path.join(kiloDir, 'LICENSE'));
109
- safeCopyFile(path.join(sourceDir, 'CONTRIBUTING.md'), path.join(kiloDir, 'CONTRIBUTING.md'));
110
- safeCopyFile(path.join(sourceDir, '.gitignore'), path.join(kiloDir, '.gitignore'));
111
- safeCopyFile(path.join(sourceDir, '.editorconfig'), path.join(kiloDir, '.editorconfig'));
112
-
113
- safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(kiloDir, 'skills'));
114
- safeCopyDirectory(path.join(sourceDir, 'lang'), path.join(kiloDir, 'lang'));
115
- safeCopyDirectory(path.join(sourceDir, 'bin'), path.join(kiloDir, 'bin'));
116
-
117
- updateGitignore(projectRoot);
118
-
119
- const IS_WIN = process.platform === 'win32';
120
- const binDest = path.join(kiloDir, 'hooks', 'bin', IS_WIN ? 'plugkit.exe' : 'plugkit');
121
- const requiredVersion = getRequiredVersion(sourceDir);
122
- const installedVersion = fs.existsSync(binDest) ? getInstalledVersion(binDest) : null;
123
- if (!installedVersion || (requiredVersion && installedVersion !== requiredVersion)) {
124
- downloadBin(requiredVersion, binDest, (err) => {
125
- if (err) process.stderr.write('plugkit download failed: ' + err.message + '\n');
126
- });
127
- }
128
- }
129
-
130
- install();
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const https = require('https');
6
-
7
- const PLUGKIT_REPO = 'AnEntrypoint/rs-plugkit';
8
-
9
- function isInsideNodeModules() {
10
- return __dirname.includes(path.sep + 'node_modules' + path.sep);
11
- }
12
-
13
- function getProjectRoot() {
14
- if (!isInsideNodeModules()) return null;
15
- let current = __dirname;
16
- while (current !== path.dirname(current)) {
17
- current = path.dirname(current);
18
- if (path.basename(current) === 'node_modules') return path.dirname(current);
19
- }
20
- return null;
21
- }
22
-
23
- function safeCopyFile(src, dst) {
24
- try {
25
- const dstDir = path.dirname(dst);
26
- if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
27
- fs.writeFileSync(dst, fs.readFileSync(src));
28
- return true;
29
- } catch { return false; }
30
- }
31
-
32
- function safeCopyDirectory(src, dst) {
33
- try {
34
- if (!fs.existsSync(src)) return false;
35
- fs.mkdirSync(dst, { recursive: true });
36
- fs.readdirSync(src, { withFileTypes: true }).forEach(entry => {
37
- const srcPath = path.join(src, entry.name);
38
- const dstPath = path.join(dst, entry.name);
39
- if (entry.isDirectory()) safeCopyDirectory(srcPath, dstPath);
40
- else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
41
- });
42
- return true;
43
- } catch { return false; }
44
- }
45
-
46
- function updateGitignore(projectRoot) {
47
- try {
48
- const gitignorePath = path.join(projectRoot, '.gitignore');
49
- const entry = '.gm/';
50
- let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
51
- if (content.includes(entry)) return;
52
- if (content && !content.endsWith('\n')) content += '\n';
53
- fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
54
- } catch {}
55
- }
56
-
57
- function getRequiredVersion(sourceDir) {
58
- try {
59
- const gm = JSON.parse(fs.readFileSync(path.join(sourceDir, 'gm.json'), 'utf-8'));
60
- return gm.plugkitVersion || null;
61
- } catch { return null; }
62
- }
63
-
64
- function getInstalledVersion(binPath) {
65
- try {
66
- const { spawnSync } = require('child_process');
67
- const r = spawnSync(binPath, ['--version'], { encoding: 'utf8', timeout: 5000 });
68
- const m = (r.stdout || '').trim().match(/(\d+\.\d+\.\d+)/);
69
- return m ? m[1] : null;
70
- } catch { return null; }
71
- }
72
-
73
- function downloadBin(version, dest, callback) {
74
- const IS_WIN = process.platform === 'win32';
75
- const asset = IS_WIN ? 'plugkit.exe' : 'plugkit';
76
- const urlPath = version
77
- ? `/AnEntrypoint/rs-plugkit/releases/download/v${version}/${asset}`
78
- : `/AnEntrypoint/rs-plugkit/releases/latest/download/${asset}`;
79
- const destDir = path.dirname(dest);
80
- if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
81
- const follow = (url) => {
82
- const mod = url.startsWith('https') ? https : require('http');
83
- const opts = { ...require('url').parse(url), headers: { 'User-Agent': 'gm-postinstall' } };
84
- mod.get(opts, res => {
85
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return follow(res.headers.location);
86
- if (res.statusCode !== 200) return callback(new Error(`HTTP ${res.statusCode}`));
87
- const chunks = [];
88
- res.on('data', c => chunks.push(c));
89
- res.on('end', () => { try { fs.writeFileSync(dest, Buffer.concat(chunks)); try { fs.chmodSync(dest, 0o755); } catch {} callback(null); } catch (e) { callback(e); } });
90
- }).on('error', callback);
91
- };
92
- follow(`https://github.com${urlPath}`);
93
- }
94
-
95
- function install() {
96
- if (!isInsideNodeModules()) return;
97
- const projectRoot = getProjectRoot();
98
- if (!projectRoot) return;
99
- const ocDir = path.join(projectRoot, '.config', 'opencode');
100
- const sourceDir = path.dirname(__dirname);
101
-
102
- safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(ocDir, 'agents'));
103
- safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(ocDir, 'hooks'));
104
- safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(ocDir, 'skills'));
105
- safeCopyFile(path.join(sourceDir, 'opencode.json'), path.join(ocDir, 'opencode.json'));
106
- safeCopyFile(path.join(sourceDir, '.mcp.json'), path.join(ocDir, '.mcp.json'));
107
- safeCopyFile(path.join(sourceDir, 'gm-oc.mjs'), path.join(ocDir, 'plugins', 'gm-oc.mjs'));
108
- safeCopyFile(path.join(sourceDir, 'gm.json'), path.join(ocDir, 'gm.json'));
109
- safeCopyFile(path.join(sourceDir, 'README.md'), path.join(ocDir, 'README.md'));
110
- safeCopyFile(path.join(sourceDir, 'LICENSE'), path.join(ocDir, 'LICENSE'));
111
- safeCopyFile(path.join(sourceDir, 'CONTRIBUTING.md'), path.join(ocDir, 'CONTRIBUTING.md'));
112
- safeCopyFile(path.join(sourceDir, '.gitignore'), path.join(ocDir, '.gitignore'));
113
- safeCopyFile(path.join(sourceDir, '.editorconfig'), path.join(ocDir, '.editorconfig'));
114
-
115
- safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(ocDir, 'skills'));
116
- safeCopyDirectory(path.join(sourceDir, 'lang'), path.join(ocDir, 'lang'));
117
- safeCopyDirectory(path.join(sourceDir, 'bin'), path.join(ocDir, 'bin'));
118
-
119
- updateGitignore(projectRoot);
120
-
121
- const IS_WIN = process.platform === 'win32';
122
- const binDest = path.join(ocDir, 'hooks', 'bin', IS_WIN ? 'plugkit.exe' : 'plugkit');
123
- const requiredVersion = getRequiredVersion(sourceDir);
124
- const installedVersion = fs.existsSync(binDest) ? getInstalledVersion(binDest) : null;
125
- if (!installedVersion || (requiredVersion && installedVersion !== requiredVersion)) {
126
- downloadBin(requiredVersion, binDest, (err) => {
127
- if (err) process.stderr.write('plugkit download failed: ' + err.message + '\n');
128
- });
129
- }
130
- }
131
-
132
- install();
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const https = require('https');
6
-
7
- const PLUGKIT_REPO = 'AnEntrypoint/rs-plugkit';
8
-
9
- function isInsideNodeModules() {
10
- return __dirname.includes(path.sep + 'node_modules' + path.sep);
11
- }
12
-
13
- function getProjectRoot() {
14
- if (!isInsideNodeModules()) return null;
15
- let current = __dirname;
16
- while (current !== path.dirname(current)) {
17
- current = path.dirname(current);
18
- if (path.basename(current) === 'node_modules') return path.dirname(current);
19
- }
20
- return null;
21
- }
22
-
23
- function safeCopyFile(src, dst) {
24
- try {
25
- const dstDir = path.dirname(dst);
26
- if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
27
- fs.writeFileSync(dst, fs.readFileSync(src));
28
- return true;
29
- } catch { return false; }
30
- }
31
-
32
- function safeCopyDirectory(src, dst) {
33
- try {
34
- if (!fs.existsSync(src)) return false;
35
- fs.mkdirSync(dst, { recursive: true });
36
- fs.readdirSync(src, { withFileTypes: true }).forEach(entry => {
37
- const srcPath = path.join(src, entry.name);
38
- const dstPath = path.join(dst, entry.name);
39
- if (entry.isDirectory()) safeCopyDirectory(srcPath, dstPath);
40
- else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
41
- });
42
- return true;
43
- } catch { return false; }
44
- }
45
-
46
- function updateGitignore(projectRoot) {
47
- try {
48
- const gitignorePath = path.join(projectRoot, '.gitignore');
49
- const entry = '.gm/';
50
- let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
51
- if (content.includes(entry)) return;
52
- if (content && !content.endsWith('\n')) content += '\n';
53
- fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
54
- } catch {}
55
- }
56
-
57
- function getRequiredVersion(sourceDir) {
58
- try {
59
- const gm = JSON.parse(fs.readFileSync(path.join(sourceDir, 'gm.json'), 'utf-8'));
60
- return gm.plugkitVersion || null;
61
- } catch { return null; }
62
- }
63
-
64
- function getInstalledVersion(binPath) {
65
- try {
66
- const { spawnSync } = require('child_process');
67
- const r = spawnSync(binPath, ['--version'], { encoding: 'utf8', timeout: 5000 });
68
- const out = (r.stdout || '').trim();
69
- const m = out.match(/(\d+\.\d+\.\d+)/);
70
- return m ? m[1] : null;
71
- } catch { return null; }
72
- }
73
-
74
- function downloadBin(version, dest, callback) {
75
- const IS_WIN = process.platform === 'win32';
76
- const asset = IS_WIN ? 'plugkit.exe' : 'plugkit';
77
- const tag = version ? `v${version}` : 'latest';
78
- const urlPath = version
79
- ? `/AnEntrypoint/rs-plugkit/releases/download/v${version}/${asset}`
80
- : `/AnEntrypoint/rs-plugkit/releases/latest/download/${asset}`;
81
-
82
- const destDir = path.dirname(dest);
83
- if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
84
-
85
- const follow = (url) => {
86
- const isHttps = url.startsWith('https');
87
- const mod = isHttps ? https : require('http');
88
- const options = typeof url === 'string'
89
- ? { ...require('url').parse(url), headers: { 'User-Agent': 'gm-postinstall' } }
90
- : url;
91
- mod.get(options, res => {
92
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
93
- return follow(res.headers.location);
94
- }
95
- if (res.statusCode !== 200) return callback(new Error(`HTTP ${res.statusCode}`));
96
- const chunks = [];
97
- res.on('data', c => chunks.push(c));
98
- res.on('end', () => {
99
- try {
100
- fs.writeFileSync(dest, Buffer.concat(chunks));
101
- try { fs.chmodSync(dest, 0o755); } catch {}
102
- callback(null);
103
- } catch (e) { callback(e); }
104
- });
105
- }).on('error', callback);
106
- };
107
-
108
- follow(`https://github.com${urlPath}`);
109
- }
110
-
111
- function install() {
112
- if (!isInsideNodeModules()) return;
113
- const projectRoot = getProjectRoot();
114
- if (!projectRoot) return;
115
-
116
- const claudeDir = path.join(projectRoot, '.claude');
117
- const sourceDir = path.dirname(__dirname);
118
-
119
- safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(claudeDir, 'agents'));
120
- safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(claudeDir, 'hooks'));
121
- safeCopyFile(path.join(sourceDir, '.mcp.json'), path.join(claudeDir, '.mcp.json'));
122
-
123
- updateGitignore(projectRoot);
124
-
125
- const IS_WIN = process.platform === 'win32';
126
- const binDest = path.join(claudeDir, 'bin', IS_WIN ? 'plugkit.exe' : 'plugkit');
127
- const requiredVersion = getRequiredVersion(sourceDir);
128
- const installedVersion = fs.existsSync(binDest) ? getInstalledVersion(binDest) : null;
129
-
130
- if (!installedVersion || (requiredVersion && installedVersion !== requiredVersion)) {
131
- downloadBin(requiredVersion, binDest, (err) => {
132
- if (err) process.stderr.write('plugkit download failed: ' + err.message + '\n');
133
- });
134
- }
135
- }
136
-
137
- install();