gm-cc 2.0.352 → 2.0.353
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/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/watch-cascade.js +166 -0
|
@@ -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.353",
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "State machine agent with hooks, skills, and automated git enforcement"
|
|
10
10
|
},
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { execSync, spawnSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
const REPOS = {
|
|
7
|
+
'rs-exec': 'AnEntrypoint/rs-exec',
|
|
8
|
+
'rs-codeinsight':'AnEntrypoint/rs-codeinsight',
|
|
9
|
+
'rs-search': 'AnEntrypoint/rs-search',
|
|
10
|
+
'rs-plugkit': 'AnEntrypoint/rs-plugkit',
|
|
11
|
+
'plugforge': 'AnEntrypoint/plugforge',
|
|
12
|
+
'gm-cc': 'AnEntrypoint/gm-cc',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const POLL_MS = 20000;
|
|
16
|
+
const TIMEOUT_MS = 30 * 60 * 1000;
|
|
17
|
+
|
|
18
|
+
function gh(args) {
|
|
19
|
+
const r = spawnSync('gh', args, { encoding: 'utf8' });
|
|
20
|
+
if (r.status !== 0) throw new Error(r.stderr.trim() || `gh ${args.join(' ')} failed`);
|
|
21
|
+
return r.stdout.trim();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function latestRun(repo) {
|
|
25
|
+
const out = gh(['run', 'list', '--repo', repo, '--limit', '1', '--json', 'databaseId,status,conclusion,name,headBranch,createdAt']);
|
|
26
|
+
const rows = JSON.parse(out);
|
|
27
|
+
return rows[0] || null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getGmCcSha() {
|
|
31
|
+
return gh(['api', 'repos/AnEntrypoint/gm-cc/git/refs/heads/main', '--jq', '.object.sha']);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getInstalledSha() {
|
|
35
|
+
const os = require('os');
|
|
36
|
+
const path = require('path');
|
|
37
|
+
const fs = require('fs');
|
|
38
|
+
const base = path.join(os.homedir(), '.claude/plugins/cache/gm-cc/gm');
|
|
39
|
+
if (!fs.existsSync(base)) return null;
|
|
40
|
+
const dirs = fs.readdirSync(base).filter(d => /^[0-9a-f]{12,}$/.test(d));
|
|
41
|
+
dirs.sort((a, b) => {
|
|
42
|
+
try {
|
|
43
|
+
const av = JSON.parse(fs.readFileSync(path.join(base, a, 'gm.json'), 'utf8')).version || '0';
|
|
44
|
+
const bv = JSON.parse(fs.readFileSync(path.join(base, b, 'gm.json'), 'utf8')).version || '0';
|
|
45
|
+
return bv.localeCompare(av, undefined, { numeric: true });
|
|
46
|
+
} catch { return 0; }
|
|
47
|
+
});
|
|
48
|
+
if (!dirs[0]) return null;
|
|
49
|
+
const gm = JSON.parse(fs.readFileSync(path.join(base, dirs[0], 'gm.json'), 'utf8'));
|
|
50
|
+
return { hash: dirs[0], version: gm.version, plugkitVersion: gm.plugkitVersion };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getPlugkitVersion() {
|
|
54
|
+
const fs = require('fs');
|
|
55
|
+
const cargo = 'C:/dev/rs-plugkit/Cargo.toml';
|
|
56
|
+
if (!fs.existsSync(cargo)) return null;
|
|
57
|
+
const m = fs.readFileSync(cargo, 'utf8').match(/^version\s*=\s*"([^"]+)"/m);
|
|
58
|
+
return m ? m[1] : null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function validate(label, fn) {
|
|
62
|
+
try {
|
|
63
|
+
const result = fn();
|
|
64
|
+
console.log(` ✓ ${label}: ${result}`);
|
|
65
|
+
return true;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.log(` ✗ ${label}: ${e.message}`);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function watchRun(repo, runId, label) {
|
|
73
|
+
const start = Date.now();
|
|
74
|
+
while (Date.now() - start < TIMEOUT_MS) {
|
|
75
|
+
const out = gh(['run', 'view', String(runId), '--repo', repo, '--json', 'status,conclusion']);
|
|
76
|
+
const { status, conclusion } = JSON.parse(out);
|
|
77
|
+
process.stdout.write(`\r ${label}: ${status} ${conclusion || ''} `);
|
|
78
|
+
if (status === 'completed') {
|
|
79
|
+
process.stdout.write('\n');
|
|
80
|
+
if (conclusion !== 'success') throw new Error(`${label} concluded: ${conclusion}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await sleep(POLL_MS);
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`${label} timed out after ${TIMEOUT_MS / 60000}min`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
89
|
+
|
|
90
|
+
async function waitForNewRun(repo, label, afterTime, maxWaitMs = 5 * 60 * 1000) {
|
|
91
|
+
const start = Date.now();
|
|
92
|
+
while (Date.now() - start < maxWaitMs) {
|
|
93
|
+
const run = latestRun(repo);
|
|
94
|
+
if (run && new Date(run.createdAt).getTime() > afterTime) return run;
|
|
95
|
+
process.stdout.write(`\r Waiting for ${label} run to appear... `);
|
|
96
|
+
await sleep(POLL_MS);
|
|
97
|
+
}
|
|
98
|
+
process.stdout.write('\n');
|
|
99
|
+
throw new Error(`No new run appeared in ${repo} within ${maxWaitMs / 60000}min`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function main() {
|
|
103
|
+
const triggerTime = Date.now();
|
|
104
|
+
|
|
105
|
+
console.log('\n=== Cascade Watcher ===');
|
|
106
|
+
console.log('Monitoring full pipeline: rs-{exec,codeinsight,search} → rs-plugkit → plugforge → gm-cc\n');
|
|
107
|
+
|
|
108
|
+
console.log('[1] Baseline');
|
|
109
|
+
const baseGmCcSha = getGmCcSha();
|
|
110
|
+
const baseInstalled = getInstalledSha();
|
|
111
|
+
const basePlugkitVersion = getPlugkitVersion();
|
|
112
|
+
console.log(` gm-cc HEAD: ${baseGmCcSha}`);
|
|
113
|
+
console.log(` installed hash: ${baseInstalled ? baseInstalled.hash : 'unknown'} (gm v${baseInstalled?.version}, plugkit v${baseInstalled?.plugkitVersion})`);
|
|
114
|
+
console.log(` local plugkit: v${basePlugkitVersion}`);
|
|
115
|
+
|
|
116
|
+
console.log('\n[2] rs-plugkit Release run');
|
|
117
|
+
const plugkitRun = await waitForNewRun('AnEntrypoint/rs-plugkit', 'rs-plugkit Release', triggerTime - 10 * 60 * 1000);
|
|
118
|
+
console.log(` Run #${plugkitRun.databaseId} "${plugkitRun.name}" on ${plugkitRun.headBranch}`);
|
|
119
|
+
await watchRun('AnEntrypoint/rs-plugkit', plugkitRun.databaseId, 'rs-plugkit Release');
|
|
120
|
+
|
|
121
|
+
console.log('\n[3] Validate rs-plugkit version bumped');
|
|
122
|
+
validate('rs-plugkit Cargo.toml version', () => {
|
|
123
|
+
const v = getPlugkitVersion();
|
|
124
|
+
if (!v) throw new Error('Could not read');
|
|
125
|
+
return `v${v}`;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
validate('plugforge-starter/gm.json plugkitVersion', () => {
|
|
129
|
+
const fs = require('fs');
|
|
130
|
+
const p = 'C:/dev/plugforge/plugforge-starter/gm.json';
|
|
131
|
+
if (!fs.existsSync(p)) throw new Error('file not found');
|
|
132
|
+
const j = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
133
|
+
return `v${j.plugkitVersion}`;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
console.log('\n[4] plugforge Build & Publish run');
|
|
137
|
+
const afterPlugkit = Date.now();
|
|
138
|
+
const pfRun = await waitForNewRun('AnEntrypoint/plugforge', 'plugforge Build & Publish', afterPlugkit - 3 * 60 * 1000);
|
|
139
|
+
console.log(` Run #${pfRun.databaseId} "${pfRun.name}" on ${pfRun.headBranch}`);
|
|
140
|
+
await watchRun('AnEntrypoint/plugforge', pfRun.databaseId, 'plugforge Build & Publish');
|
|
141
|
+
|
|
142
|
+
console.log('\n[5] Validate gm-cc updated');
|
|
143
|
+
const newGmCcSha = getGmCcSha();
|
|
144
|
+
validate('gm-cc HEAD changed', () => {
|
|
145
|
+
if (newGmCcSha === baseGmCcSha) throw new Error(`still ${baseGmCcSha}`);
|
|
146
|
+
return newGmCcSha;
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
console.log('\n[6] Validate local installed plugin (requires /plugin + /reload-plugins)');
|
|
150
|
+
const installed = getInstalledSha();
|
|
151
|
+
validate('installed hash matches gm-cc HEAD prefix', () => {
|
|
152
|
+
if (!installed) throw new Error('no installed plugin found');
|
|
153
|
+
if (!newGmCcSha.startsWith(installed.hash)) throw new Error(`installed ${installed.hash} != gm-cc ${newGmCcSha.slice(0, 12)}`);
|
|
154
|
+
return `${installed.hash} (gm v${installed.version}, plugkit v${installed.plugkitVersion})`;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
console.log('\n=== Cascade complete ===');
|
|
158
|
+
console.log(` gm-cc: ${baseGmCcSha.slice(0, 12)} → ${newGmCcSha.slice(0, 12)}`);
|
|
159
|
+
if (installed && newGmCcSha.startsWith(installed.hash)) {
|
|
160
|
+
console.log(' Local plugin is up to date.');
|
|
161
|
+
} else {
|
|
162
|
+
console.log(' ⚠ Run /plugin then /reload-plugins to update local cache.');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
main().catch(e => { console.error('\nFATAL:', e.message); process.exit(1); });
|