gm-kilo 2.0.50 → 2.0.52
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/.github/workflows/publish-npm.yml +3 -28
- package/.gitignore +0 -3
- package/.mcp.json +1 -7
- package/agents/gm.md +5 -5
- package/hooks/pre-tool-use-hook.js +2 -2
- package/package.json +2 -2
- package/scripts/postinstall.js +2 -22
- package/skills/dev/SKILL.md +29 -35
|
@@ -11,52 +11,27 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
13
|
- uses: actions/checkout@v4
|
|
14
|
-
with:
|
|
15
|
-
token: ${{ secrets.GH_PAT || github.token }}
|
|
16
14
|
|
|
17
15
|
- uses: actions/setup-node@v4
|
|
18
16
|
with:
|
|
19
17
|
node-version: '22'
|
|
20
18
|
registry-url: 'https://registry.npmjs.org'
|
|
21
19
|
|
|
22
|
-
- name: Configure git
|
|
23
|
-
run: |
|
|
24
|
-
git config user.name "github-actions[bot]"
|
|
25
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
26
|
-
|
|
27
|
-
- name: Bump patch version
|
|
28
|
-
run: |
|
|
29
|
-
PACKAGE=$(jq -r '.name' package.json)
|
|
30
|
-
OLD_VERSION=$(jq -r '.version' package.json)
|
|
31
|
-
|
|
32
|
-
# Skip bump if last commit was already a version bump
|
|
33
|
-
LAST_MSG=$(git log -1 --pretty=%s)
|
|
34
|
-
if echo "$LAST_MSG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
35
|
-
echo "Last commit was a version bump, skipping"
|
|
36
|
-
echo "SKIP_BUMP=true" >> $GITHUB_ENV
|
|
37
|
-
else
|
|
38
|
-
npm version patch --no-git-tag-version
|
|
39
|
-
NEW_VERSION=$(jq -r '.version' package.json)
|
|
40
|
-
git add package.json
|
|
41
|
-
git commit -m "v$NEW_VERSION"
|
|
42
|
-
git push
|
|
43
|
-
echo "Bumped $PACKAGE from $OLD_VERSION to $NEW_VERSION"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
20
|
- name: Publish to npm
|
|
47
21
|
run: |
|
|
48
22
|
PACKAGE=$(jq -r '.name' package.json)
|
|
49
23
|
VERSION=$(jq -r '.version' package.json)
|
|
50
24
|
echo "Package: $PACKAGE@$VERSION"
|
|
51
25
|
|
|
26
|
+
# Skip if this exact version is already on npm
|
|
52
27
|
PUBLISHED=$(npm view "$PACKAGE@$VERSION" version 2>/dev/null || echo "")
|
|
53
28
|
if [ "$PUBLISHED" = "$VERSION" ]; then
|
|
54
|
-
echo "$PACKAGE@$VERSION already published - skipping"
|
|
29
|
+
echo "✅ $PACKAGE@$VERSION already published - skipping"
|
|
55
30
|
exit 0
|
|
56
31
|
fi
|
|
57
32
|
|
|
58
33
|
echo "Publishing $PACKAGE@$VERSION..."
|
|
59
34
|
npm publish --access public
|
|
60
|
-
echo "Published $PACKAGE@$VERSION"
|
|
35
|
+
echo "✅ Published $PACKAGE@$VERSION"
|
|
61
36
|
env:
|
|
62
37
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.gitignore
CHANGED
package/.mcp.json
CHANGED
package/agents/gm.md
CHANGED
|
@@ -54,11 +54,11 @@ The .prd path must resolve to exactly ./.prd in current working directory. No va
|
|
|
54
54
|
|
|
55
55
|
Scope: Where and how code runs. Governs tool selection and execution context.
|
|
56
56
|
|
|
57
|
-
All execution via `
|
|
57
|
+
All execution via `dev` skill or `agent-browser` skill. Every hypothesis proven by execution before changing files. Know nothing until execution proves it.
|
|
58
58
|
|
|
59
|
-
**CODE YOUR HYPOTHESES**: Test every possible hypothesis using the `
|
|
59
|
+
**CODE YOUR HYPOTHESES**: Test every possible hypothesis using the `dev` skill or `agent-browser` skill. Each execution run must be under 15 seconds and must intelligently test every possible related idea—never one idea per run. Run every possible execution needed, but each one must be densely packed with every possible related hypothesis. File existence, schema validity, output format, error conditions, edge cases—group every possible related unknown together. The goal is every possible hypothesis per run. Use `agent-browser` skill for cross-client UI testing and browser-based hypothesis validation.
|
|
60
60
|
|
|
61
|
-
**DEFAULT IS
|
|
61
|
+
**DEFAULT IS CODE, NOT BASH**: `dev` skill is the primary execution tool. Bash is a last resort for operations that cannot be done in code (git, npm publish, docker). If you find yourself writing a bash command, stop and ask: can this be done in the `dev` skill? The answer is almost always yes.
|
|
62
62
|
|
|
63
63
|
**TOOL POLICY**: All code execution via `dev` skill. Use `code-search` skill for exploration. Reference TOOL_INVARIANTS for enforcement.
|
|
64
64
|
|
|
@@ -74,8 +74,8 @@ All execution via `code_execution` tool (Python) or `agent-browser` skill. Every
|
|
|
74
74
|
|
|
75
75
|
**REQUIRED TOOL MAPPING**:
|
|
76
76
|
- Code exploration: `code-search` skill — THE ONLY exploration tool. Semantic search 102 file types. Natural language queries with line numbers. No glob, no grep, no find, no explore agent, no Read for discovery.
|
|
77
|
-
- Code execution:
|
|
78
|
-
- File operations: `
|
|
77
|
+
- Code execution: `dev` skill — run JS/TS/Python/Go/Rust/etc via Bash
|
|
78
|
+
- File operations: `dev` skill with bun/node fs inline — read, write, stat files
|
|
79
79
|
- Bash: ONLY git, npm publish/pack, docker, system daemons
|
|
80
80
|
- Browser: Use **`agent-browser` skill** instead of puppeteer/playwright - same power, cleaner syntax, built for AI agents
|
|
81
81
|
|
|
@@ -57,9 +57,9 @@ const run = () => {
|
|
|
57
57
|
|
|
58
58
|
if (tool_name === 'Bash') {
|
|
59
59
|
const command = (tool_input?.command || '').trim();
|
|
60
|
-
const allowed = /^(git |npm publish|npm pack|docker |sudo systemctl|systemctl )/.test(command);
|
|
60
|
+
const allowed = /^(git |gh |npm publish|npm pack|docker |sudo systemctl|systemctl )/.test(command);
|
|
61
61
|
if (!allowed) {
|
|
62
|
-
return { block: true, reason: 'Bash is blocked. Use the code_execution MCP tool instead. It supports Python, JS/TS, Go, Rust, C/C++ and bash via the language parameter.
|
|
62
|
+
return { block: true, reason: 'Bash is blocked. Use the code_execution MCP tool instead. It supports Python, JS/TS, Go, Rust, C/C++ and bash via the language parameter.' };
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-kilo",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.52",
|
|
4
4
|
"description": "State machine agent with hooks, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,4 +54,4 @@
|
|
|
54
54
|
".gitignore",
|
|
55
55
|
".editorconfig"
|
|
56
56
|
]
|
|
57
|
-
}
|
|
57
|
+
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -127,31 +127,11 @@ function install() {
|
|
|
127
127
|
// Copy files
|
|
128
128
|
safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(claudeDir, 'agents'));
|
|
129
129
|
safeCopyDirectory(path.join(sourceDir, 'hooks'), path.join(claudeDir, 'hooks'));
|
|
130
|
-
safeCopyDirectory(path.join(sourceDir, 'skills'), path.join(claudeDir, 'skills'));
|
|
131
130
|
safeCopyFile(path.join(sourceDir, '.mcp.json'), path.join(claudeDir, '.mcp.json'));
|
|
132
|
-
|
|
133
|
-
// Write settings.json with autoUpdates and hooks wired up
|
|
134
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
135
|
-
let settings = {};
|
|
136
|
-
if (fs.existsSync(settingsPath)) {
|
|
137
|
-
try { settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8')); } catch (e) {}
|
|
138
|
-
}
|
|
139
|
-
settings.autoUpdates = true;
|
|
140
|
-
settings.hooks = settings.hooks || {};
|
|
141
|
-
const hookCmd = `node ${path.join(claudeDir, 'hooks', 'pre-tool-use-hook.js')}`;
|
|
142
|
-
settings.hooks.PreToolUse = settings.hooks.PreToolUse || [{ matcher: '*', hooks: [{ type: 'command', command: hookCmd }] }];
|
|
143
|
-
const sessionHookCmd = `node ${path.join(claudeDir, 'hooks', 'session-start-hook.js')}`;
|
|
144
|
-
settings.hooks.SessionStart = settings.hooks.SessionStart || [{ hooks: [{ type: 'command', command: sessionHookCmd }] }];
|
|
145
|
-
const stopHookCmd = `node ${path.join(claudeDir, 'hooks', 'stop-hook.js')}`;
|
|
146
|
-
const stopGitCmd = `node ${path.join(claudeDir, 'hooks', 'stop-hook-git.js')}`;
|
|
147
|
-
settings.hooks.Stop = settings.hooks.Stop || [{ hooks: [{ type: 'command', command: stopHookCmd }, { type: 'command', command: stopGitCmd }] }];
|
|
148
|
-
const promptHookCmd = `node ${path.join(claudeDir, 'hooks', 'prompt-submit-hook.js')}`;
|
|
149
|
-
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit || [{ hooks: [{ type: 'command', command: promptHookCmd }] }];
|
|
150
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
151
|
-
|
|
131
|
+
|
|
152
132
|
// Update .gitignore
|
|
153
133
|
updateGitignore(projectRoot);
|
|
154
|
-
|
|
134
|
+
|
|
155
135
|
// Silent success
|
|
156
136
|
}
|
|
157
137
|
|
package/skills/dev/SKILL.md
CHANGED
|
@@ -1,54 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dev
|
|
3
|
-
description: Execute code
|
|
4
|
-
allowed-tools: Bash
|
|
3
|
+
description: Execute code and shell commands. Use for all code execution, file operations, running scripts, testing hypotheses, and any task that requires running code. Replaces plugin:gm:dev and mcp-glootie.
|
|
4
|
+
allowed-tools: Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Code Execution with dev
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
[CODE EXECUTION RESULT]
|
|
13
|
-
stdout: <output>
|
|
14
|
-
stderr: <errors>
|
|
15
|
-
exit_code: <N>
|
|
16
|
-
```
|
|
9
|
+
Execute code directly using the Bash tool. No wrapper, no persistent files, no cleanup needed beyond what the code itself creates.
|
|
17
10
|
|
|
18
11
|
## Run code inline
|
|
19
12
|
|
|
20
|
-
```
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
```bash
|
|
14
|
+
# JavaScript / TypeScript
|
|
15
|
+
bun -e "const fs = require('fs'); console.log(fs.readdirSync('.'))"
|
|
16
|
+
bun -e "import { readFileSync } from 'fs'; console.log(readFileSync('package.json', 'utf-8'))"
|
|
17
|
+
|
|
18
|
+
# Run a file
|
|
19
|
+
bun run script.ts
|
|
20
|
+
node script.js
|
|
21
|
+
|
|
22
|
+
# Python
|
|
23
|
+
python -c "import json; print(json.dumps({'ok': True}))"
|
|
24
|
+
|
|
25
|
+
# Shell
|
|
26
|
+
bash -c "ls -la && cat package.json"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## File operations (inline, no temp files)
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
```bash
|
|
32
|
+
# Read
|
|
33
|
+
bun -e "console.log(require('fs').readFileSync('path/to/file', 'utf-8'))"
|
|
28
34
|
|
|
29
|
-
# Write
|
|
30
|
-
|
|
31
|
-
import json
|
|
32
|
-
json.dump({'ok': True}, f, indent=2)
|
|
35
|
+
# Write
|
|
36
|
+
bun -e "require('fs').writeFileSync('out.json', JSON.stringify({x:1}, null, 2))"
|
|
33
37
|
|
|
34
38
|
# Stat / exists
|
|
35
|
-
|
|
36
|
-
print(os.path.exists('file.txt'), os.path.getsize('.'))
|
|
37
|
-
|
|
38
|
-
# HTTP requests
|
|
39
|
-
import urllib.request
|
|
40
|
-
resp = urllib.request.urlopen('https://example.com')
|
|
41
|
-
print(resp.read()[:200])
|
|
42
|
-
|
|
43
|
-
# Run subprocess
|
|
44
|
-
import subprocess
|
|
45
|
-
r = subprocess.run(['node', '--version'], capture_output=True, text=True)
|
|
46
|
-
print(r.stdout)
|
|
39
|
+
bun -e "const fs=require('fs'); console.log(fs.existsSync('file.txt'), fs.statSync?.('.')?.size)"
|
|
47
40
|
```
|
|
48
41
|
|
|
49
42
|
## Rules
|
|
50
43
|
|
|
51
44
|
- Each run under 15 seconds
|
|
52
45
|
- Pack every related hypothesis into one run — never one idea per run
|
|
53
|
-
- No persistent temp files; if a temp file is needed, delete it in the same
|
|
54
|
-
-
|
|
46
|
+
- No persistent temp files; if a temp file is needed, delete it in the same command
|
|
47
|
+
- No spawn/exec/fork inside executed code
|
|
48
|
+
- Use `bun` over `node` when available
|