gm-cc 2.0.352 → 2.0.354
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.
|
|
7
|
+
"version": "2.0.354",
|
|
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); });
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-search
|
|
3
|
+
description: Mandatory codebase search workflow. Use whenever you need to find anything in the codebase. Start with two words, iterate by changing or adding words until found.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CODEBASE SEARCH — Mandatory Workflow
|
|
7
|
+
|
|
8
|
+
`exec:codesearch` is the only way to search the codebase. Glob, Grep, Find, Explore are hook-blocked.
|
|
9
|
+
|
|
10
|
+
## Syntax
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
exec:codesearch
|
|
14
|
+
<natural language query>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Mandatory Search Protocol
|
|
18
|
+
|
|
19
|
+
**Start with exactly two words.** Never start broader. Never start with one word.
|
|
20
|
+
|
|
21
|
+
**Iterate by changing or adding words** — do not switch approach or give up until the content is found:
|
|
22
|
+
|
|
23
|
+
1. Start: two-word query most likely to match
|
|
24
|
+
2. No results → change one word (synonym, related term)
|
|
25
|
+
3. Still no results → add a third word (narrow scope)
|
|
26
|
+
4. Still no results → swap the changed word again
|
|
27
|
+
5. Keep iterating — changing or adding words each pass — until content is found
|
|
28
|
+
|
|
29
|
+
**Never**: start with one word | start with a sentence | give up after one miss | switch to a different tool | declare content missing after fewer than 4 search attempts
|
|
30
|
+
|
|
31
|
+
**Each search is one `exec:codesearch` call.** Run them sequentially — use each result to inform the next query.
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
Finding where a function is defined:
|
|
36
|
+
```
|
|
37
|
+
exec:codesearch
|
|
38
|
+
session cleanup idle
|
|
39
|
+
```
|
|
40
|
+
→ no results →
|
|
41
|
+
```
|
|
42
|
+
exec:codesearch
|
|
43
|
+
cleanup sessions timeout
|
|
44
|
+
```
|
|
45
|
+
→ found.
|
|
46
|
+
|
|
47
|
+
Finding config format:
|
|
48
|
+
```
|
|
49
|
+
exec:codesearch
|
|
50
|
+
plugin registration format
|
|
51
|
+
```
|
|
52
|
+
→ no results →
|
|
53
|
+
```
|
|
54
|
+
exec:codesearch
|
|
55
|
+
plugin config array
|
|
56
|
+
```
|
|
57
|
+
→ found.
|
package/skills/gm/SKILL.md
CHANGED
|
@@ -86,12 +86,19 @@ start|stop|status
|
|
|
86
86
|
|
|
87
87
|
## CODEBASE EXPLORATION
|
|
88
88
|
|
|
89
|
+
`exec:codesearch` is the only way to search. **Glob, Grep, Read, Explore, WebSearch are hook-blocked.**
|
|
90
|
+
|
|
89
91
|
```
|
|
90
92
|
exec:codesearch
|
|
91
|
-
<
|
|
93
|
+
<two-word query to start>
|
|
92
94
|
```
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
**Mandatory search protocol** (from `code-search` skill):
|
|
97
|
+
1. Start with exactly **two words** — never one, never a sentence
|
|
98
|
+
2. No results → change one word (synonym or related term)
|
|
99
|
+
3. Still no results → add a third word to narrow scope
|
|
100
|
+
4. Keep changing or adding words each pass until content is found
|
|
101
|
+
5. Minimum 4 attempts before concluding content is absent
|
|
95
102
|
|
|
96
103
|
## BROWSER AUTOMATION
|
|
97
104
|
|
|
@@ -61,12 +61,19 @@ start|stop|status
|
|
|
61
61
|
|
|
62
62
|
## CODEBASE EXPLORATION
|
|
63
63
|
|
|
64
|
+
`exec:codesearch` is the only way to search. **Glob, Grep, Read, Explore, WebSearch are hook-blocked.**
|
|
65
|
+
|
|
64
66
|
```
|
|
65
67
|
exec:codesearch
|
|
66
|
-
<
|
|
68
|
+
<two-word query to start>
|
|
67
69
|
```
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
**Mandatory search protocol** (from `code-search` skill):
|
|
72
|
+
1. Start with exactly **two words** — never one, never a sentence
|
|
73
|
+
2. No results → change one word (synonym or related term)
|
|
74
|
+
3. Still no results → add a third word to narrow scope
|
|
75
|
+
4. Keep changing or adding words each pass until content is found
|
|
76
|
+
5. Minimum 4 attempts before concluding content is absent
|
|
70
77
|
|
|
71
78
|
## IMPORT-BASED DEBUGGING
|
|
72
79
|
|