gm-kilo 2.0.1059 → 2.0.1061
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/README.md +32 -70
- package/agents/gm.md +1 -1
- package/cli.js +16 -10
- package/gm-kilo.mjs +33 -50
- package/install.js +5 -1
- package/package.json +1 -4
- package/skills/gm/SKILL.md +0 -11
- package/skills/gm-cc/SKILL.md +0 -2
- package/skills/gm-codex/SKILL.md +0 -2
- package/skills/gm-copilot-cli/SKILL.md +0 -2
- package/skills/gm-cursor/SKILL.md +0 -2
- package/skills/gm-gc/SKILL.md +0 -2
- package/skills/gm-jetbrains/SKILL.md +0 -2
- package/skills/gm-kilo/SKILL.md +0 -2
- package/skills/gm-oc/SKILL.md +0 -2
- package/skills/gm-vscode/SKILL.md +0 -2
- package/skills/gm-zed/SKILL.md +0 -2
package/README.md
CHANGED
|
@@ -4,97 +4,59 @@
|
|
|
4
4
|
|
|
5
5
|
### One-liner (recommended)
|
|
6
6
|
|
|
7
|
-
Install directly from npm
|
|
7
|
+
Install directly from npm:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
bun x gm-kilo@latest
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
This
|
|
13
|
+
This copies the plugin to `~/.config/kilo/` and registers it in your config. Restart Kilo to activate.
|
|
14
14
|
|
|
15
|
-
###
|
|
15
|
+
### Via npm install
|
|
16
16
|
|
|
17
|
-
**Windows and Unix:**
|
|
18
17
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
**Windows PowerShell:**
|
|
23
|
-
```powershell
|
|
24
|
-
git clone https://github.com/AnEntrypoint/gm-kilo "\$env:APPDATA\kilo\plugin" && cd "\$env:APPDATA\kilo\plugin" && bun install
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Step 2: Configure MCP Servers
|
|
28
|
-
|
|
29
|
-
Kilo uses the OpenCode configuration format. Create or update `~/.config/kilo/opencode.json`:
|
|
30
|
-
|
|
31
|
-
```json
|
|
32
|
-
{
|
|
33
|
-
"\$schema": "https://opencode.ai/config.json",
|
|
34
|
-
"mcp": {
|
|
35
|
-
"dev": {
|
|
36
|
-
"type": "local",
|
|
37
|
-
"command": ["bun x", "mcp-gm"],
|
|
38
|
-
"timeout": 360000,
|
|
39
|
-
"enabled": true
|
|
40
|
-
},
|
|
41
|
-
"code-search": {
|
|
42
|
-
"type": "local",
|
|
43
|
-
"command": ["bun x", "codebasesearch"],
|
|
44
|
-
"timeout": 360000,
|
|
45
|
-
"enabled": true
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Step 3: Update Kilo Configuration
|
|
52
|
-
|
|
53
|
-
Update `~/.config/kilo/kilocode.json` to reference the plugin:
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"\$schema": "https://kilo.ai/config.json",
|
|
58
|
-
"default_agent": "gm",
|
|
59
|
-
"plugin": ["/home/user/.config/kilo/plugin"]
|
|
60
|
-
}
|
|
18
|
+
npm install -g gm-kilo
|
|
19
|
+
gm-kilo
|
|
61
20
|
```
|
|
62
21
|
|
|
63
|
-
|
|
22
|
+
### Manual installation
|
|
64
23
|
|
|
65
|
-
|
|
24
|
+
Clone to the global plugin directory:
|
|
66
25
|
|
|
67
|
-
Start Kilo and verify the tools appear:
|
|
68
26
|
```bash
|
|
69
|
-
kilo
|
|
27
|
+
git clone https://github.com/AnEntrypoint/gm-kilo ~/.config/kilo/plugin
|
|
70
28
|
```
|
|
71
29
|
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
kilo mcp list
|
|
75
|
-
```
|
|
30
|
+
## Features
|
|
76
31
|
|
|
77
|
-
|
|
32
|
+
- **State machine agent** — PLAN→EXECUTE→EMIT→VERIFY→COMPLETE orchestration
|
|
33
|
+
- **Skill chain** — gm, planning, gm-execute, gm-emit, gm-complete, update-docs
|
|
34
|
+
- **exec: dispatch** — code execution via spool watcher (nodejs, python, bash, typescript, go, rust)
|
|
35
|
+
- **Code search** — semantic codebase exploration via exec:codesearch
|
|
36
|
+
- **Git enforcement** — blocks session end with uncommitted changes or unpushed commits
|
|
37
|
+
- **Memory** — rs-learn integration for cross-session knowledge retention
|
|
78
38
|
|
|
79
|
-
##
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
The plugin installs:
|
|
42
|
+
- **Agent** (`agents/gm.md`) — primary orchestrator with skill-chain instructions
|
|
43
|
+
- **Skills** (`skills/`) — PLAN, EXECUTE, EMIT, VERIFY, UPDATE-DOCS skill definitions
|
|
44
|
+
- **Plugin** (`plugins/gm-kilo.mjs`) — hooks for session lifecycle, tool gating, exec: dispatch
|
|
45
|
+
- **Lang runners** (`lang/`) — language-specific execution plugins
|
|
80
46
|
|
|
81
|
-
|
|
82
|
-
- **State machine agent** - Complete `gm` behavioral rule system
|
|
83
|
-
- **Git enforcement** - Blocks uncommitted changes and unpushed commits on session idle
|
|
84
|
-
- **AST analysis** - Automatic codebase analysis via mcp-thorns on session start
|
|
85
|
-
- **.prd enforcement** - Blocks exit if work items remain in .prd file
|
|
47
|
+
All exec: commands route through the spool watcher at `.gm/exec-spool/` for session-isolated task execution.
|
|
86
48
|
|
|
87
49
|
## Troubleshooting
|
|
88
50
|
|
|
89
|
-
**
|
|
90
|
-
- Verify `~/.config/kilo/
|
|
91
|
-
- Check
|
|
92
|
-
- Run `kilo mcp list` to verify servers are connected
|
|
51
|
+
**Plugin not loading:**
|
|
52
|
+
- Verify `~/.config/kilo/plugins/gm-kilo.mjs` exists
|
|
53
|
+
- Check `kilocode.json` has the plugin path in the `plugin` array
|
|
93
54
|
- Restart Kilo CLI completely
|
|
94
55
|
|
|
95
|
-
**
|
|
96
|
-
- Verify
|
|
97
|
-
-
|
|
98
|
-
- Run `bun install` in the plugin directory to ensure dependencies are installed
|
|
56
|
+
**Skills not appearing:**
|
|
57
|
+
- Verify `~/.config/kilo/skills/` contains skill directories with SKILL.md files
|
|
58
|
+
- Skill names must be lowercase with hyphens (e.g., `gm`, `gm-execute`)
|
|
99
59
|
|
|
100
|
-
|
|
60
|
+
**exec: commands failing:**
|
|
61
|
+
- Check `.gm/exec-spool/` directory exists in your project
|
|
62
|
+
- Verify plugkit binary is present at `~/.config/kilo/bin/`
|
package/agents/gm.md
CHANGED
package/cli.js
CHANGED
|
@@ -33,21 +33,27 @@ try {
|
|
|
33
33
|
copyRecursive(path.join(srcDir, 'lang'), path.join(kiloConfigDir, 'lang'));
|
|
34
34
|
copyRecursive(path.join(srcDir, 'bin'), path.join(kiloConfigDir, 'bin'));
|
|
35
35
|
copyRecursive(path.join(srcDir, 'hooks'), path.join(kiloConfigDir, 'hooks'));
|
|
36
|
+
copyRecursive(path.join(srcDir, 'scripts'), path.join(kiloConfigDir, 'scripts'));
|
|
36
37
|
|
|
37
38
|
const kiloJsonPath = path.join(kiloConfigDir, 'kilocode.json');
|
|
39
|
+
const configExisted = fs.existsSync(kiloJsonPath);
|
|
38
40
|
let kiloConfig = {};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
if (configExisted) {
|
|
42
|
+
try {
|
|
43
|
+
const raw = fs.readFileSync(kiloJsonPath, 'utf-8');
|
|
44
|
+
kiloConfig = JSON.parse(raw);
|
|
45
|
+
if (kiloConfig['']) { delete kiloConfig['']; }
|
|
46
|
+
} catch (e) {}
|
|
47
|
+
}
|
|
48
|
+
if (!configExisted) {
|
|
49
|
+
kiloConfig['$schema'] = 'https://kilo.ai/config.json';
|
|
50
|
+
kiloConfig.default_agent = 'gm';
|
|
51
|
+
}
|
|
47
52
|
const kiloPluginPath = path.join(kiloConfigDir, 'plugins', 'gm-kilo.mjs');
|
|
48
53
|
if (!Array.isArray(kiloConfig.plugin)) kiloConfig.plugin = [];
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
if (!kiloConfig.plugin.some(p => typeof p === 'string' && p.includes('gm-kilo'))) {
|
|
55
|
+
kiloConfig.plugin.push(kiloPluginPath);
|
|
56
|
+
}
|
|
51
57
|
fs.writeFileSync(kiloJsonPath, JSON.stringify(kiloConfig, null, 2) + '\n');
|
|
52
58
|
|
|
53
59
|
const oldDir = process.platform === 'win32'
|
package/gm-kilo.mjs
CHANGED
|
@@ -15,64 +15,32 @@ function runPlugkit(args) {
|
|
|
15
15
|
const bin = join(__dirname, '..', 'bin', 'plugkit.js');
|
|
16
16
|
if (!existsSync(bin)) return '';
|
|
17
17
|
try {
|
|
18
|
-
const r = spawnSync('node', [bin, ...args], { encoding: 'utf-8', timeout:
|
|
18
|
+
const r = spawnSync('node', [bin, ...args], { encoding: 'utf-8', timeout: 300000, windowsHide: true });
|
|
19
19
|
return (r.stdout || '').trim() || (r.stderr || '').trim();
|
|
20
20
|
} catch(e) { return ''; }
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function safePrintf(s) {
|
|
24
|
-
return "printf '%s' '" + String(s).replace(
|
|
24
|
+
return "printf '%s' '" + String(s).replace(/'/g,"'\\\\''")+"'";
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function stripFooter(s) { return s ? s.replace(/\n\[Running tools\][\s\S]*$/, '').trimEnd() : ''; }
|
|
28
28
|
|
|
29
|
-
function tryLangPlugin(lang, code, cwd) {
|
|
30
|
-
const projectDir = cwd || process.cwd();
|
|
31
|
-
const candidates = [join(projectDir, 'lang', lang+'.js'), join(__dirname, '..', 'lang', lang+'.js')];
|
|
32
|
-
for (const langPluginFile of candidates) {
|
|
33
|
-
if (!existsSync(langPluginFile)) continue;
|
|
34
|
-
try {
|
|
35
|
-
const plugin = require(langPluginFile);
|
|
36
|
-
if (plugin && plugin.exec && plugin.exec.run) {
|
|
37
|
-
const result = plugin.exec.run(code, projectDir);
|
|
38
|
-
if (result && typeof result.then === 'function') continue;
|
|
39
|
-
return String(result === undefined ? '' : result);
|
|
40
|
-
}
|
|
41
|
-
} catch(e) {}
|
|
42
|
-
}
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
29
|
function runExecSync(rawLang, code, cwd) {
|
|
47
30
|
const lang = LANG_ALIASES[rawLang] || rawLang || 'nodejs';
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (lang === '
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (lang === 'python') return out(spawnSync('python3',['-c',code],opts));
|
|
60
|
-
if (lang === 'bash' || lang === 'sh') {
|
|
61
|
-
const tmp = join(tmpdir(),'gm-exec-'+Date.now()+'.sh');
|
|
62
|
-
writeFileSync(tmp,code,'utf-8');
|
|
63
|
-
const r = spawnSync('bash',[tmp],opts);
|
|
64
|
-
try { unlinkSync(tmp); } catch(e) {}
|
|
65
|
-
return out(r);
|
|
31
|
+
const projectDir = cwd || process.cwd();
|
|
32
|
+
if (lang === 'codesearch' || lang === 'search') return runPlugkit(['search', '--path', projectDir, code.trim()]);
|
|
33
|
+
if (['runner','status','sleep','close'].includes(lang)) return runPlugkit([lang, code.trim()]);
|
|
34
|
+
if (['browser','tail','watch','wait','type','kill-port','health','recall','memorize','forget','feedback','discipline','pause'].includes(lang)) {
|
|
35
|
+
return runPlugkit(['exec', '--lang', lang, '--code', code.trim(), '--cwd', projectDir]);
|
|
36
|
+
}
|
|
37
|
+
if (lang === 'cmd') {
|
|
38
|
+
const opts = { encoding: 'utf-8', timeout: 30000, windowsHide: true, cwd: projectDir };
|
|
39
|
+
const r = spawnSync('cmd', ['/c', code], opts);
|
|
40
|
+
const o = (r.stdout || '').trimEnd(), e = stripFooter(r.stderr || '').trimEnd();
|
|
41
|
+
return o && e ? o + '\n[stderr]\n' + e : o || e || '(no output)';
|
|
66
42
|
}
|
|
67
|
-
|
|
68
|
-
const tmp = join(tmpdir(),'gm-exec-'+Date.now()+'.'+ext);
|
|
69
|
-
const src = lang === 'typescript' ? code : 'const __r=await(async()=>{\n'+code+'\n})();if(__r!==undefined){if(typeof __r==="object"){console.log(JSON.stringify(__r,null,2));}else{console.log(__r);}}';
|
|
70
|
-
writeFileSync(tmp,src,'utf-8');
|
|
71
|
-
const r = spawnSync('bun',['run',tmp],opts);
|
|
72
|
-
try { unlinkSync(tmp); } catch(e) {}
|
|
73
|
-
let result = out(r);
|
|
74
|
-
if (result) result = result.split(tmp).join('<script>');
|
|
75
|
-
return result;
|
|
43
|
+
return runPlugkit(['exec', '--lang', lang, '--code', code.trim(), '--cwd', projectDir]);
|
|
76
44
|
}
|
|
77
45
|
|
|
78
46
|
const BANNED_BASH = ['grep','rg','find','glob','awk','sed','cat','head','tail'];
|
|
@@ -89,7 +57,16 @@ export async function GmPlugin({ directory }) {
|
|
|
89
57
|
const injectedSessions = new Set();
|
|
90
58
|
|
|
91
59
|
return {
|
|
60
|
+
'session.created': async () => {
|
|
61
|
+
if (!sessionStarted) {
|
|
62
|
+
sessionStarted = true;
|
|
63
|
+
try { runPlugkit(['hook', 'session-start']); } catch(e) {}
|
|
64
|
+
try { runPlugkit(['bootstrap', directory]); } catch(e) {}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
|
|
92
68
|
'experimental.chat.system.transform': async (input, output) => {
|
|
69
|
+
const gmDir = join(directory, '.gm');
|
|
93
70
|
try {
|
|
94
71
|
const giPath = join(directory, '.gitignore');
|
|
95
72
|
const entry = '.gm-stop-verified';
|
|
@@ -113,6 +90,12 @@ export async function GmPlugin({ directory }) {
|
|
|
113
90
|
if (prd) output.system.push('\nPENDING WORK (.prd):\n'+prd);
|
|
114
91
|
}
|
|
115
92
|
} catch(e) {}
|
|
93
|
+
try {
|
|
94
|
+
const needsGmPath = join(gmDir, 'needs-gm');
|
|
95
|
+
if (existsSync(needsGmPath)) {
|
|
96
|
+
output.system.push('\nCRITICAL: You MUST invoke the `gm` skill before any other tool. Your current state is BLOCKED by a safety gate until gm runs.');
|
|
97
|
+
}
|
|
98
|
+
} catch(e) {}
|
|
116
99
|
},
|
|
117
100
|
|
|
118
101
|
'experimental.chat.messages.transform': async (input, output) => {
|
|
@@ -207,10 +190,10 @@ export async function GmPlugin({ directory }) {
|
|
|
207
190
|
if (input.tool !== 'bash' && input.tool !== 'Bash' && input.tool !== 'shell' && input.tool !== 'Shell' && input.tool !== 'spawn/exec') return;
|
|
208
191
|
const cmd = (output.args && output.args.command) || '';
|
|
209
192
|
if (!cmd) return;
|
|
210
|
-
if (/^\s*git(?:\s|$)/.test(cmd)) return;
|
|
211
|
-
const m = cmd.match(/^exec(?::(\S+))?\n([\s\S]+)$/);
|
|
193
|
+
if (/^\s*(git|gh)(?:\s|$)/.test(cmd)) return;
|
|
194
|
+
const m = cmd.match(/^exec(?::(\S+))?\s*\n([\s\S]+)$/);
|
|
212
195
|
if (!m) {
|
|
213
|
-
throw new Error('Use exec: prefix for Bash. The command must start with `exec` or `exec:<lang>` on its own line, then the body on the next line. Examples
|
|
196
|
+
throw new Error('Use exec: prefix for Bash. The command must start with `exec` or `exec:<lang>` on its own line, then the body on the next line. Examples:\\n\\nexec\\nls -la\\n\\nexec:nodejs\\nconsole.log("hello")\\n\\nexec:bash\\ngit status\\n\\nLanguages: nodejs (default), bash, python, typescript, go, rust, deno, cmd. File I/O via exec:nodejs + require("fs"). Raw JIT execution can also bypass Bash entirely: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` (e.g. in/nodejs/42.js) and the spool watcher executes it and writes `.gm/exec-spool/out/<N>.json`. Codebase search: exec:codesearch on its own line, then a two-word query.');
|
|
214
197
|
}
|
|
215
198
|
const rawLang = (m[1]||'').toLowerCase();
|
|
216
199
|
if (rawLang === 'bash' || rawLang === 'sh' || rawLang === '') {
|
|
@@ -218,7 +201,7 @@ export async function GmPlugin({ directory }) {
|
|
|
218
201
|
if (banned) throw new Error('`'+banned+'` is blocked in exec:bash. Use exec:codesearch instead. For raw JIT execution, write code to `.gm/exec-spool/in/<lang>/<N>.<ext>` (e.g. in/nodejs/42.js); the spool watcher executes it and writes out/<N>.json.');
|
|
219
202
|
}
|
|
220
203
|
const result = runExecSync(m[1]||'', m[2], output.args.workdir || directory);
|
|
221
|
-
|
|
204
|
+
throw new Error('exec:'+(m[1]||'nodejs')+' output:\n\n'+result);
|
|
222
205
|
},
|
|
223
206
|
'message.updated': async (input, output) => {
|
|
224
207
|
try {
|
package/install.js
CHANGED
|
@@ -33,10 +33,14 @@ function install() {
|
|
|
33
33
|
if (!isInsideNodeModules()) return;
|
|
34
34
|
const projectRoot = getProjectRoot();
|
|
35
35
|
if (!projectRoot) return;
|
|
36
|
-
const kiloDir = path.join(projectRoot, '.
|
|
36
|
+
const kiloDir = path.join(projectRoot, '.kilo', 'plugins', 'gm-kilo');
|
|
37
37
|
const sourceDir = __dirname;
|
|
38
38
|
safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(kiloDir, 'agents'));
|
|
39
39
|
safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(kiloDir, 'hooks'));
|
|
40
|
+
safeCopyDirectory(path.join(sourceDir, 'bin'), path.join(kiloDir, 'bin'));
|
|
41
|
+
safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(kiloDir, 'skills'));
|
|
42
|
+
safeCopyDirectory(path.join(sourceDir, 'lang'), path.join(kiloDir, 'lang'));
|
|
43
|
+
safeCopyDirectory(path.join(sourceDir, 'scripts'), path.join(kiloDir, 'scripts'));
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
install();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-kilo",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1061",
|
|
4
4
|
"description": "State machine agent with hooks, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,9 +30,6 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"postinstall": "node scripts/postinstall-kilo.js"
|
|
35
|
-
},
|
|
36
33
|
"files": [
|
|
37
34
|
"agents/",
|
|
38
35
|
"bin/",
|
package/skills/gm/SKILL.md
CHANGED
|
@@ -2,17 +2,6 @@
|
|
|
2
2
|
name: gm
|
|
3
3
|
description: Orchestrator dispatching PLAN→EXECUTE→EMIT→VERIFY→UPDATE-DOCS skill chain; spool-driven task execution with session isolation
|
|
4
4
|
allowed-tools: Skill
|
|
5
|
-
compatible-platforms:
|
|
6
|
-
- gm-cc
|
|
7
|
-
- gm-gc
|
|
8
|
-
- gm-oc
|
|
9
|
-
- gm-kilo
|
|
10
|
-
- gm-codex
|
|
11
|
-
- gm-copilot-cli
|
|
12
|
-
- gm-vscode
|
|
13
|
-
- gm-cursor
|
|
14
|
-
- gm-zed
|
|
15
|
-
- gm-jetbrains
|
|
16
5
|
end-to-end: true
|
|
17
6
|
---
|
|
18
7
|
|
package/skills/gm-cc/SKILL.md
CHANGED
package/skills/gm-codex/SKILL.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
name: gm-copilot-cli
|
|
3
3
|
description: AI-native software engineering via skill-driven orchestration on copilot-cli; bootstraps plugkit for task execution and session isolation
|
|
4
4
|
allowed-tools: Skill
|
|
5
|
-
compatible-platforms:
|
|
6
|
-
- gm-copilot-cli
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# GM — copilot-cli Platform
|
package/skills/gm-gc/SKILL.md
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
name: gm-jetbrains
|
|
3
3
|
description: AI-native software engineering via skill-driven orchestration on jetbrains; bootstraps plugkit for task execution and session isolation
|
|
4
4
|
allowed-tools: Skill
|
|
5
|
-
compatible-platforms:
|
|
6
|
-
- gm-jetbrains
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
# GM — jetbrains Platform
|
package/skills/gm-kilo/SKILL.md
CHANGED
package/skills/gm-oc/SKILL.md
CHANGED
package/skills/gm-zed/SKILL.md
CHANGED