gm-cc 2.0.247 → 2.0.250
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/.claude-plugin/marketplace.json +1 -1
- package/hooks/hooks.json +12 -7
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/bootstrap.js +45 -0
- package/scripts/postinstall-kilo.js +55 -42
- package/scripts/postinstall-oc.js +57 -42
- package/scripts/postinstall.js +137 -101
- package/hooks/pre-tool-use-hook.js +0 -504
- package/hooks/prompt-submit-hook.js +0 -177
- package/hooks/session-start-hook.js +0 -187
- package/hooks/stop-hook-git.js +0 -190
- package/hooks/stop-hook.js +0 -57
|
@@ -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.
|
|
7
|
+
"version": "2.0.250",
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "State machine agent with hooks, skills, and automated git enforcement"
|
|
10
10
|
},
|
package/hooks/hooks.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"hooks": [
|
|
8
8
|
{
|
|
9
9
|
"type": "command",
|
|
10
|
-
"command": "
|
|
10
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/plugkit hook pre-tool-use",
|
|
11
11
|
"timeout": 3600
|
|
12
12
|
}
|
|
13
13
|
]
|
|
@@ -19,8 +19,13 @@
|
|
|
19
19
|
"hooks": [
|
|
20
20
|
{
|
|
21
21
|
"type": "command",
|
|
22
|
-
"command": "
|
|
23
|
-
"timeout":
|
|
22
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/bootstrap.js",
|
|
23
|
+
"timeout": 60000
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "command",
|
|
27
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/plugkit hook session-start",
|
|
28
|
+
"timeout": 180000
|
|
24
29
|
}
|
|
25
30
|
]
|
|
26
31
|
}
|
|
@@ -31,8 +36,8 @@
|
|
|
31
36
|
"hooks": [
|
|
32
37
|
{
|
|
33
38
|
"type": "command",
|
|
34
|
-
"command": "
|
|
35
|
-
"timeout":
|
|
39
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/plugkit hook prompt-submit",
|
|
40
|
+
"timeout": 60000
|
|
36
41
|
}
|
|
37
42
|
]
|
|
38
43
|
}
|
|
@@ -43,12 +48,12 @@
|
|
|
43
48
|
"hooks": [
|
|
44
49
|
{
|
|
45
50
|
"type": "command",
|
|
46
|
-
"command": "
|
|
51
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/plugkit hook stop",
|
|
47
52
|
"timeout": 300000
|
|
48
53
|
},
|
|
49
54
|
{
|
|
50
55
|
"type": "command",
|
|
51
|
-
"command": "
|
|
56
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/bin/plugkit hook stop-git",
|
|
52
57
|
"timeout": 60000
|
|
53
58
|
}
|
|
54
59
|
]
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const https = require('https');
|
|
6
|
+
|
|
7
|
+
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
|
|
8
|
+
if (!pluginRoot) process.exit(0);
|
|
9
|
+
|
|
10
|
+
const IS_WIN = process.platform === 'win32';
|
|
11
|
+
const binPath = path.join(pluginRoot, 'bin', IS_WIN ? 'plugkit.exe' : 'plugkit');
|
|
12
|
+
|
|
13
|
+
if (fs.existsSync(binPath)) process.exit(0);
|
|
14
|
+
|
|
15
|
+
function getVersion() {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(fs.readFileSync(path.join(pluginRoot, 'gm.json'), 'utf8')).plugkitVersion || null;
|
|
18
|
+
} catch { return null; }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function download(version, dest, cb) {
|
|
22
|
+
const asset = IS_WIN ? 'plugkit.exe' : 'plugkit';
|
|
23
|
+
const urlPath = version
|
|
24
|
+
? `/AnEntrypoint/rs-plugkit/releases/download/v${version}/${asset}`
|
|
25
|
+
: `/AnEntrypoint/rs-plugkit/releases/latest/download/${asset}`;
|
|
26
|
+
const destDir = path.dirname(dest);
|
|
27
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
28
|
+
const follow = (url) => {
|
|
29
|
+
const mod = url.startsWith('https') ? https : require('http');
|
|
30
|
+
const opts = { ...require('url').parse(url), headers: { 'User-Agent': 'gm-bootstrap' } };
|
|
31
|
+
mod.get(opts, res => {
|
|
32
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return follow(res.headers.location);
|
|
33
|
+
if (res.statusCode !== 200) return cb(new Error(`HTTP ${res.statusCode}`));
|
|
34
|
+
const chunks = [];
|
|
35
|
+
res.on('data', c => chunks.push(c));
|
|
36
|
+
res.on('end', () => { try { fs.writeFileSync(dest, Buffer.concat(chunks)); try { fs.chmodSync(dest, 0o755); } catch {} cb(null); } catch (e) { cb(e); } });
|
|
37
|
+
}).on('error', cb);
|
|
38
|
+
};
|
|
39
|
+
follow(`https://github.com${urlPath}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
download(getVersion(), binPath, (err) => {
|
|
43
|
+
if (err) { process.stderr.write(`bootstrap: ${err.message}\n`); process.exit(1); }
|
|
44
|
+
process.exit(0);
|
|
45
|
+
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const
|
|
5
|
+
const https = require('https');
|
|
6
6
|
|
|
7
7
|
function isInsideNodeModules() {
|
|
8
8
|
return __dirname.includes(path.sep + 'node_modules' + path.sep);
|
|
@@ -13,23 +13,18 @@ function getProjectRoot() {
|
|
|
13
13
|
let current = __dirname;
|
|
14
14
|
while (current !== path.dirname(current)) {
|
|
15
15
|
current = path.dirname(current);
|
|
16
|
-
if (path.basename(current) === 'node_modules')
|
|
17
|
-
return path.dirname(current);
|
|
18
|
-
}
|
|
16
|
+
if (path.basename(current) === 'node_modules') return path.dirname(current);
|
|
19
17
|
}
|
|
20
18
|
return null;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
function safeCopyFile(src, dst) {
|
|
24
22
|
try {
|
|
25
|
-
const content = fs.readFileSync(src, 'utf-8');
|
|
26
23
|
const dstDir = path.dirname(dst);
|
|
27
24
|
if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
|
|
28
|
-
fs.writeFileSync(dst,
|
|
25
|
+
fs.writeFileSync(dst, fs.readFileSync(src));
|
|
29
26
|
return true;
|
|
30
|
-
} catch
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
27
|
+
} catch { return false; }
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
function safeCopyDirectory(src, dst) {
|
|
@@ -43,9 +38,7 @@ function safeCopyDirectory(src, dst) {
|
|
|
43
38
|
else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
|
|
44
39
|
});
|
|
45
40
|
return true;
|
|
46
|
-
} catch
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
41
|
+
} catch { return false; }
|
|
49
42
|
}
|
|
50
43
|
|
|
51
44
|
function updateGitignore(projectRoot) {
|
|
@@ -53,13 +46,48 @@ function updateGitignore(projectRoot) {
|
|
|
53
46
|
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
54
47
|
const entry = '.gm-stop-verified';
|
|
55
48
|
let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
56
|
-
if (content.includes(entry)) return
|
|
49
|
+
if (content.includes(entry)) return;
|
|
57
50
|
if (content && !content.endsWith('\n')) content += '\n';
|
|
58
51
|
fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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}`);
|
|
63
91
|
}
|
|
64
92
|
|
|
65
93
|
function install() {
|
|
@@ -67,9 +95,8 @@ function install() {
|
|
|
67
95
|
const projectRoot = getProjectRoot();
|
|
68
96
|
if (!projectRoot) return;
|
|
69
97
|
const kiloDir = path.join(projectRoot, '.config', 'kilo');
|
|
70
|
-
const sourceDir =
|
|
98
|
+
const sourceDir = path.dirname(__dirname);
|
|
71
99
|
|
|
72
|
-
// Copy files
|
|
73
100
|
safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(kiloDir, 'agents'));
|
|
74
101
|
safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(kiloDir, 'hooks'));
|
|
75
102
|
safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(kiloDir, 'skills'));
|
|
@@ -83,36 +110,22 @@ function install() {
|
|
|
83
110
|
safeCopyFile(path.join(sourceDir, '.gitignore'), path.join(kiloDir, '.gitignore'));
|
|
84
111
|
safeCopyFile(path.join(sourceDir, '.editorconfig'), path.join(kiloDir, '.editorconfig'));
|
|
85
112
|
|
|
86
|
-
// Also write plugin/ directory - Kilo loads from ~/.config/kilo/plugin/ as a local file plugin
|
|
87
113
|
const pluginDir = path.join(kiloDir, 'plugin');
|
|
88
114
|
if (!fs.existsSync(pluginDir)) fs.mkdirSync(pluginDir, { recursive: true });
|
|
89
115
|
const gmMjsSrc = path.join(sourceDir, 'gm.mjs');
|
|
90
|
-
if (fs.existsSync(gmMjsSrc))
|
|
91
|
-
safeCopyFile(gmMjsSrc, path.join(pluginDir, 'gm.mjs'));
|
|
92
|
-
}
|
|
116
|
+
if (fs.existsSync(gmMjsSrc)) safeCopyFile(gmMjsSrc, path.join(pluginDir, 'gm.mjs'));
|
|
93
117
|
fs.writeFileSync(path.join(pluginDir, 'index.js'), "export { default } from './gm.mjs';\n", 'utf-8');
|
|
94
118
|
|
|
95
|
-
// Update .gitignore
|
|
96
119
|
updateGitignore(projectRoot);
|
|
97
120
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
for (const pkg of packages) {
|
|
107
|
-
try {
|
|
108
|
-
execSync(`bun x ${pkg} --version`, {
|
|
109
|
-
encoding: 'utf-8',
|
|
110
|
-
stdio: 'pipe',
|
|
111
|
-
timeout: 60000
|
|
112
|
-
});
|
|
113
|
-
} catch (e) {
|
|
114
|
-
// Silent - cache warming is best-effort
|
|
115
|
-
}
|
|
121
|
+
const IS_WIN = process.platform === 'win32';
|
|
122
|
+
const binDest = path.join(kiloDir, '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
|
+
});
|
|
116
129
|
}
|
|
117
130
|
}
|
|
118
131
|
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const
|
|
5
|
+
const https = require('https');
|
|
6
|
+
|
|
7
|
+
const PLUGKIT_REPO = 'AnEntrypoint/rs-plugkit';
|
|
6
8
|
|
|
7
9
|
function isInsideNodeModules() {
|
|
8
10
|
return __dirname.includes(path.sep + 'node_modules' + path.sep);
|
|
@@ -13,23 +15,18 @@ function getProjectRoot() {
|
|
|
13
15
|
let current = __dirname;
|
|
14
16
|
while (current !== path.dirname(current)) {
|
|
15
17
|
current = path.dirname(current);
|
|
16
|
-
if (path.basename(current) === 'node_modules')
|
|
17
|
-
return path.dirname(current);
|
|
18
|
-
}
|
|
18
|
+
if (path.basename(current) === 'node_modules') return path.dirname(current);
|
|
19
19
|
}
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function safeCopyFile(src, dst) {
|
|
24
24
|
try {
|
|
25
|
-
const content = fs.readFileSync(src, 'utf-8');
|
|
26
25
|
const dstDir = path.dirname(dst);
|
|
27
26
|
if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
|
|
28
|
-
fs.writeFileSync(dst,
|
|
27
|
+
fs.writeFileSync(dst, fs.readFileSync(src));
|
|
29
28
|
return true;
|
|
30
|
-
} catch
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
29
|
+
} catch { return false; }
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
function safeCopyDirectory(src, dst) {
|
|
@@ -43,9 +40,7 @@ function safeCopyDirectory(src, dst) {
|
|
|
43
40
|
else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
|
|
44
41
|
});
|
|
45
42
|
return true;
|
|
46
|
-
} catch
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
43
|
+
} catch { return false; }
|
|
49
44
|
}
|
|
50
45
|
|
|
51
46
|
function updateGitignore(projectRoot) {
|
|
@@ -53,13 +48,48 @@ function updateGitignore(projectRoot) {
|
|
|
53
48
|
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
54
49
|
const entry = '.gm-stop-verified';
|
|
55
50
|
let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
56
|
-
if (content.includes(entry)) return
|
|
51
|
+
if (content.includes(entry)) return;
|
|
57
52
|
if (content && !content.endsWith('\n')) content += '\n';
|
|
58
53
|
fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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}`);
|
|
63
93
|
}
|
|
64
94
|
|
|
65
95
|
function install() {
|
|
@@ -67,9 +97,8 @@ function install() {
|
|
|
67
97
|
const projectRoot = getProjectRoot();
|
|
68
98
|
if (!projectRoot) return;
|
|
69
99
|
const ocDir = path.join(projectRoot, '.config', 'opencode');
|
|
70
|
-
const sourceDir =
|
|
100
|
+
const sourceDir = path.dirname(__dirname);
|
|
71
101
|
|
|
72
|
-
// Copy files
|
|
73
102
|
safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(ocDir, 'agents'));
|
|
74
103
|
safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(ocDir, 'hooks'));
|
|
75
104
|
safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(ocDir, 'skills'));
|
|
@@ -83,35 +112,21 @@ function install() {
|
|
|
83
112
|
safeCopyFile(path.join(sourceDir, '.gitignore'), path.join(ocDir, '.gitignore'));
|
|
84
113
|
safeCopyFile(path.join(sourceDir, '.editorconfig'), path.join(ocDir, '.editorconfig'));
|
|
85
114
|
|
|
86
|
-
// Also write to plugins/gm-oc.mjs - the actual file OpenCode loads
|
|
87
115
|
const pluginsDir = path.join(ocDir, 'plugins');
|
|
88
116
|
if (!fs.existsSync(pluginsDir)) fs.mkdirSync(pluginsDir, { recursive: true });
|
|
89
117
|
const gmMjsSrc = path.join(sourceDir, 'gm.mjs');
|
|
90
|
-
if (fs.existsSync(gmMjsSrc))
|
|
91
|
-
safeCopyFile(gmMjsSrc, path.join(pluginsDir, 'gm-oc.mjs'));
|
|
92
|
-
}
|
|
118
|
+
if (fs.existsSync(gmMjsSrc)) safeCopyFile(gmMjsSrc, path.join(pluginsDir, 'gm-oc.mjs'));
|
|
93
119
|
|
|
94
|
-
// Update .gitignore
|
|
95
120
|
updateGitignore(projectRoot);
|
|
96
121
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
for (const pkg of packages) {
|
|
106
|
-
try {
|
|
107
|
-
execSync(`bun x ${pkg} --version`, {
|
|
108
|
-
encoding: 'utf-8',
|
|
109
|
-
stdio: 'pipe',
|
|
110
|
-
timeout: 60000
|
|
111
|
-
});
|
|
112
|
-
} catch (e) {
|
|
113
|
-
// Silent - cache warming is best-effort
|
|
114
|
-
}
|
|
122
|
+
const IS_WIN = process.platform === 'win32';
|
|
123
|
+
const binDest = path.join(ocDir, 'hooks', 'bin', IS_WIN ? 'plugkit.exe' : 'plugkit');
|
|
124
|
+
const requiredVersion = getRequiredVersion(sourceDir);
|
|
125
|
+
const installedVersion = fs.existsSync(binDest) ? getInstalledVersion(binDest) : null;
|
|
126
|
+
if (!installedVersion || (requiredVersion && installedVersion !== requiredVersion)) {
|
|
127
|
+
downloadBin(requiredVersion, binDest, (err) => {
|
|
128
|
+
if (err) process.stderr.write('plugkit download failed: ' + err.message + '\n');
|
|
129
|
+
});
|
|
115
130
|
}
|
|
116
131
|
}
|
|
117
132
|
|