gm-skill 0.1.1 → 0.1.2
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/gm-complete.SKILL.md +106 -0
- package/gm-emit.SKILL.md +70 -0
- package/gm-execute.SKILL.md +88 -0
- package/gm.SKILL.md +63 -0
- package/index.js +1 -9
- package/lib/daemon-bootstrap.js +2 -2
- package/lib/git.js +332 -0
- package/lib/index.js +37 -0
- package/lib/loader.js +66 -0
- package/lib/manifest.js +16 -13
- package/lib/prepare.js +14 -0
- package/lib/spool.js +163 -0
- package/package.json +6 -4
- package/planning.SKILL.md +118 -0
- package/skills/gm/SKILL.md +63 -0
- package/skills/gm/index.js +113 -0
- package/skills/gm-complete/SKILL.md +106 -0
- package/skills/gm-complete/index.js +118 -0
- package/skills/gm-complete.SKILL.md +106 -0
- package/skills/gm-emit/SKILL.md +70 -0
- package/skills/gm-emit/index.js +90 -0
- package/skills/gm-emit.SKILL.md +70 -0
- package/skills/gm-execute/SKILL.md +88 -0
- package/skills/gm-execute/index.js +91 -0
- package/skills/gm-execute.SKILL.md +88 -0
- package/skills/gm.SKILL.md +63 -0
- package/skills/planning/SKILL.md +118 -0
- package/skills/planning/index.js +107 -0
- package/skills/planning.SKILL.md +118 -0
- package/skills/update-docs/SKILL.md +66 -0
- package/skills/update-docs/index.js +108 -0
- package/skills/update-docs.SKILL.md +66 -0
- package/test-build.js +29 -0
- package/test-e2e.js +117 -0
- package/test-unified.js +24 -0
- package/update-docs.SKILL.md +66 -0
package/test-e2e.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
console.log('=== GM-SKILL END-TO-END TEST ===\n');
|
|
5
|
+
|
|
6
|
+
const skillsDir = path.join(__dirname, 'skills');
|
|
7
|
+
const skills = ['gm', 'planning', 'gm-execute', 'gm-emit', 'gm-complete', 'update-docs'];
|
|
8
|
+
|
|
9
|
+
console.log('1. Checking skill structure...\n');
|
|
10
|
+
let structureOk = true;
|
|
11
|
+
|
|
12
|
+
skills.forEach(skill => {
|
|
13
|
+
const skillPath = path.join(skillsDir, skill);
|
|
14
|
+
const indexPath = path.join(skillPath, 'index.js');
|
|
15
|
+
const skillMdPath = path.join(skillPath, 'SKILL.md');
|
|
16
|
+
|
|
17
|
+
const hasIndex = fs.existsSync(indexPath);
|
|
18
|
+
const hasMd = fs.existsSync(skillMdPath);
|
|
19
|
+
|
|
20
|
+
const status = hasIndex && hasMd ? '✓' : '✗';
|
|
21
|
+
console.log(` ${status} ${skill}`);
|
|
22
|
+
console.log(` index.js: ${hasIndex ? '✓' : '✗'} SKILL.md: ${hasMd ? '✓' : '✗'}`);
|
|
23
|
+
|
|
24
|
+
if (!hasIndex || !hasMd) {
|
|
25
|
+
structureOk = false;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!structureOk) {
|
|
30
|
+
console.log('\n✗ FAILED: Some skills are missing index.js or SKILL.md');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log('\n2. Testing skill exports...\n');
|
|
35
|
+
|
|
36
|
+
let exportsOk = true;
|
|
37
|
+
skills.forEach(skill => {
|
|
38
|
+
try {
|
|
39
|
+
const skillPath = path.join(skillsDir, skill, 'index.js');
|
|
40
|
+
const skillModule = require(skillPath);
|
|
41
|
+
|
|
42
|
+
if (typeof skillModule !== 'function') {
|
|
43
|
+
console.log(` ✗ ${skill}: module.exports is not a function`);
|
|
44
|
+
exportsOk = false;
|
|
45
|
+
} else {
|
|
46
|
+
console.log(` ✓ ${skill}: exports async function`);
|
|
47
|
+
}
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.log(` ✗ ${skill}: failed to require - ${err.message}`);
|
|
50
|
+
exportsOk = false;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!exportsOk) {
|
|
55
|
+
console.log('\n✗ FAILED: Some skill modules are not properly exported');
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log('\n3. Testing orchestration chain (async)...\n');
|
|
60
|
+
|
|
61
|
+
async function testChain() {
|
|
62
|
+
try {
|
|
63
|
+
const gmModule = require(path.join(skillsDir, 'gm', 'index.js'));
|
|
64
|
+
|
|
65
|
+
const result = await gmModule({
|
|
66
|
+
request: 'test task for gm-skill implementation',
|
|
67
|
+
taskId: 'test-' + Date.now(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!result) {
|
|
71
|
+
console.log(' ✗ gm returned null');
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!result.phase) {
|
|
76
|
+
console.log(' ✗ result missing phase');
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!result.context) {
|
|
81
|
+
console.log(' ✗ result missing context');
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log(` ✓ gm returned valid JSON`);
|
|
86
|
+
console.log(` - phase: ${result.phase}`);
|
|
87
|
+
console.log(` - nextSkill: ${result.nextSkill || 'null'}`);
|
|
88
|
+
|
|
89
|
+
if (result.context.phases && result.context.phases.length > 0) {
|
|
90
|
+
console.log(` - chain: ${result.context.phases.map(p => p.skill).join(' → ')}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (result.error) {
|
|
94
|
+
console.log(` - error: ${result.error}`);
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return true;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.log(` ✗ Chain failed: ${err.message}`);
|
|
101
|
+
console.log(` ${err.stack.split('\n')[1]}`);
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
testChain().then(success => {
|
|
107
|
+
if (success) {
|
|
108
|
+
console.log('\n✓ ALL TESTS PASSED');
|
|
109
|
+
process.exit(0);
|
|
110
|
+
} else {
|
|
111
|
+
console.log('\n✗ TESTS FAILED');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
}).catch(err => {
|
|
115
|
+
console.error('\n✗ Fatal error:', err.message);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
package/test-unified.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { prepare } = require('./index.js');
|
|
2
|
+
|
|
3
|
+
async function test() {
|
|
4
|
+
console.log('Testing gm-skill prepare()...');
|
|
5
|
+
try {
|
|
6
|
+
const state = await prepare({ sessionId: 'test-session-' + Date.now() });
|
|
7
|
+
console.log('Prepare successful!');
|
|
8
|
+
console.log('Session ID:', state.sessionId);
|
|
9
|
+
console.log('CWD:', state.cwd);
|
|
10
|
+
console.log('Snapshot Git:', JSON.stringify(state.snapshot.git, null, 2));
|
|
11
|
+
console.log('Snapshot Tasks count:', state.snapshot.tasks.length);
|
|
12
|
+
|
|
13
|
+
if (state.snapshot.error) {
|
|
14
|
+
console.warn('Snapshot error:', state.snapshot.error);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
process.exit(0);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error('Prepare failed:', e);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test();
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: update-docs
|
|
3
|
+
description: UPDATE-DOCS phase. Refresh README.md, AGENTS.md, and docs/index.html to reflect changes made this session. Commits and pushes doc updates. Terminal phase — declares COMPLETE.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GM UPDATE-DOCS
|
|
7
|
+
|
|
8
|
+
Entry: feature verified, committed, pushed. Exit: docs match disk, committed, pushed → COMPLETE. Unknown architecture change → `planning`.
|
|
9
|
+
|
|
10
|
+
Every claim in docs is verifiable against disk. Phase names match frontmatter, platform names match `platforms/`, file paths exist, constraint counts are accurate. An unverifiable section is removed, not speculated.
|
|
11
|
+
|
|
12
|
+
## Sequence
|
|
13
|
+
|
|
14
|
+
What changed — run directly via Bash:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
git log -5 --oneline
|
|
18
|
+
git diff HEAD~1 --stat
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Read current docs via Read tool, or via a nodejs spool file (`in/nodejs/<N>.js`):
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
const fs = require('fs');
|
|
25
|
+
['README.md', 'AGENTS.md', 'docs/index.html', 'gm-starter/agents/gm.md'].forEach(f => {
|
|
26
|
+
try { console.log(`=== ${f} ===\n` + fs.readFileSync(f, 'utf8')); }
|
|
27
|
+
catch(e) { console.log(`MISSING: ${f}`); }
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Write changed sections only:
|
|
32
|
+
|
|
33
|
+
- **README.md** — platform count, skill tree diagram, quick-start commands
|
|
34
|
+
- **AGENTS.md** — via `Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<learnings>')`. Never inline-edit.
|
|
35
|
+
- **docs/index.html** — `PHASES` array, platform lists, state machine diagram
|
|
36
|
+
- **gm-starter/agents/gm.md** — skill chain line if new skills added
|
|
37
|
+
|
|
38
|
+
Verify from disk (Read tool, or a nodejs spool file):
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
const content = require('fs').readFileSync('/abs/path/file.md', 'utf8');
|
|
42
|
+
console.log(content.includes('expectedString'), content.length);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Commit and push directly via Bash:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
git add README.md docs/index.html gm-starter/agents/gm.md
|
|
49
|
+
git commit -m "docs: update documentation to reflect session changes"
|
|
50
|
+
git push -u origin HEAD
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Exit: browser cleanup
|
|
54
|
+
|
|
55
|
+
After docs push succeeds, close any browser sessions spawned during this or prior skill phases. Write a nodejs spool file calling rs-exec:
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
const sessionId = process.env.CLAUDE_SESSION_ID;
|
|
59
|
+
if (!sessionId) return;
|
|
60
|
+
const rs = require('rs-exec');
|
|
61
|
+
try {
|
|
62
|
+
rs.client().close_sessions_for(sessionId).catch(() => {});
|
|
63
|
+
} catch (e) {}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Best-effort: session context or rs-exec unavailable → skip gracefully. No error thrown.
|