gm-cc 2.0.246 → 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.
@@ -1,101 +1,137 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { execSync } = require('child_process');
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') {
17
- return path.dirname(current);
18
- }
19
- }
20
- return null;
21
- }
22
-
23
- function safeCopyFile(src, dst) {
24
- try {
25
- const content = fs.readFileSync(src, 'utf-8');
26
- const dstDir = path.dirname(dst);
27
- if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
28
- fs.writeFileSync(dst, content, 'utf-8');
29
- return true;
30
- } catch (err) {
31
- return false;
32
- }
33
- }
34
-
35
- function safeCopyDirectory(src, dst) {
36
- try {
37
- if (!fs.existsSync(src)) return false;
38
- fs.mkdirSync(dst, { recursive: true });
39
- fs.readdirSync(src, { withFileTypes: true }).forEach(entry => {
40
- const srcPath = path.join(src, entry.name);
41
- const dstPath = path.join(dst, entry.name);
42
- if (entry.isDirectory()) safeCopyDirectory(srcPath, dstPath);
43
- else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
44
- });
45
- return true;
46
- } catch (err) {
47
- return false;
48
- }
49
- }
50
-
51
- function updateGitignore(projectRoot) {
52
- try {
53
- const gitignorePath = path.join(projectRoot, '.gitignore');
54
- const entry = '.gm-stop-verified';
55
- let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
56
- if (content.includes(entry)) return true;
57
- if (content && !content.endsWith('\n')) content += '\n';
58
- fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
59
- return true;
60
- } catch (err) {
61
- return false;
62
- }
63
- }
64
-
65
- function warmBunCache() {
66
- const packages = [];
67
- for (const pkg of packages) {
68
- try {
69
- execSync(`bun x ${pkg} --version`, {
70
- encoding: 'utf-8',
71
- stdio: 'pipe',
72
- timeout: 60000
73
- });
74
- } catch (e) {
75
- // Silent - cache warming is best-effort
76
- }
77
- }
78
- }
79
-
80
- function install() {
81
- if (!isInsideNodeModules()) return;
82
- const projectRoot = getProjectRoot();
83
- if (!projectRoot) return;
84
- const claudeDir = path.join(projectRoot, '.claude');
85
- const sourceDir = __dirname.replace(/[/\\]scripts$/, '');
86
-
87
- // Copy files
88
- safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(claudeDir, 'agents'));
89
- safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(claudeDir, 'hooks'));
90
- safeCopyFile(path.join(sourceDir, '.mcp.json'), path.join(claudeDir, '.mcp.json'));
91
-
92
- // Update .gitignore
93
- updateGitignore(projectRoot);
94
-
95
- // Warm bun x cache for packages used by hooks
96
- warmBunCache();
97
-
98
- // Silent success
99
- }
100
-
101
- install();
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-stop-verified';
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();