gm-kilo 2.0.47 → 2.0.48
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 +28 -3
- package/.gitignore +3 -0
- package/hooks/pre-tool-use-hook.js +24 -1
- package/package.json +2 -2
- package/skills/dev/SKILL.md +35 -29
- package/skills/process-management/SKILL.md +21 -0
|
@@ -11,27 +11,52 @@ 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 }}
|
|
14
16
|
|
|
15
17
|
- uses: actions/setup-node@v4
|
|
16
18
|
with:
|
|
17
19
|
node-version: '22'
|
|
18
20
|
registry-url: 'https://registry.npmjs.org'
|
|
19
21
|
|
|
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
|
+
|
|
20
46
|
- name: Publish to npm
|
|
21
47
|
run: |
|
|
22
48
|
PACKAGE=$(jq -r '.name' package.json)
|
|
23
49
|
VERSION=$(jq -r '.version' package.json)
|
|
24
50
|
echo "Package: $PACKAGE@$VERSION"
|
|
25
51
|
|
|
26
|
-
# Skip if this exact version is already on npm
|
|
27
52
|
PUBLISHED=$(npm view "$PACKAGE@$VERSION" version 2>/dev/null || echo "")
|
|
28
53
|
if [ "$PUBLISHED" = "$VERSION" ]; then
|
|
29
|
-
echo "
|
|
54
|
+
echo "$PACKAGE@$VERSION already published - skipping"
|
|
30
55
|
exit 0
|
|
31
56
|
fi
|
|
32
57
|
|
|
33
58
|
echo "Publishing $PACKAGE@$VERSION..."
|
|
34
59
|
npm publish --access public
|
|
35
|
-
echo "
|
|
60
|
+
echo "Published $PACKAGE@$VERSION"
|
|
36
61
|
env:
|
|
37
62
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.gitignore
CHANGED
|
@@ -55,6 +55,29 @@ const run = () => {
|
|
|
55
55
|
return { block: true, reason: 'Plan mode is disabled. Use GM agent planning (PLAN→EXECUTE→EMIT→VERIFY→COMPLETE state machine) via gm:gm subagent instead.' };
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
if (tool_name === 'Bash') {
|
|
59
|
+
const command = (tool_input?.command || '').trim();
|
|
60
|
+
const allowed = /^(git |npm publish|npm pack|docker |sudo systemctl|systemctl )/.test(command);
|
|
61
|
+
if (!allowed) {
|
|
62
|
+
return { block: true, reason: 'Bash is blocked. Use the code_execution tool with Python instead. The hook intercepts code_execution, runs python3, and returns stdout/stderr/exit_code. Example: use code_execution with code "import subprocess; r=subprocess.run([\'node\',\'--version\'],capture_output=True,text=True); print(r.stdout)"' };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (tool_name === 'code_execution') {
|
|
67
|
+
const code = tool_input?.code || '';
|
|
68
|
+
const { spawnSync } = require('child_process');
|
|
69
|
+
const proc = spawnSync('python3', ['-'], {
|
|
70
|
+
input: code,
|
|
71
|
+
encoding: 'utf-8',
|
|
72
|
+
timeout: 30000
|
|
73
|
+
});
|
|
74
|
+
const stdout = proc.stdout || '';
|
|
75
|
+
const stderr = proc.stderr || '';
|
|
76
|
+
const exitCode = proc.status !== null ? proc.status : 1;
|
|
77
|
+
const result = `[CODE EXECUTION RESULT]\nstdout: ${stdout}\nstderr: ${stderr}\nexit_code: ${exitCode}`;
|
|
78
|
+
return { block: true, reason: result };
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
return { allow: true };
|
|
59
82
|
} catch (error) {
|
|
60
83
|
return { allow: true };
|
|
@@ -70,7 +93,7 @@ try {
|
|
|
70
93
|
} else {
|
|
71
94
|
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: result.reason } }));
|
|
72
95
|
}
|
|
73
|
-
process.exit(
|
|
96
|
+
process.exit(0);
|
|
74
97
|
}
|
|
75
98
|
|
|
76
99
|
if (isGemini) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-kilo",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.48",
|
|
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/skills/dev/SKILL.md
CHANGED
|
@@ -1,48 +1,54 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dev
|
|
3
|
-
description: Execute code
|
|
4
|
-
allowed-tools: Bash
|
|
3
|
+
description: Execute code by calling the code_execution tool with Python code. The PreToolUse hook intercepts code_execution calls, runs the Python via python3, and returns stdout/stderr/exit_code as the result. Use for all code execution, file operations, running scripts, and hypothesis testing.
|
|
4
|
+
allowed-tools: Bash,code_execution
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Code Execution with dev
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Use the `code_execution` tool with Python code. The hook intercepts the call, executes the Python locally, and returns the result as a deny reason formatted as:
|
|
10
10
|
|
|
11
|
-
## Run code inline
|
|
12
|
-
|
|
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
11
|
```
|
|
12
|
+
[CODE EXECUTION RESULT]
|
|
13
|
+
stdout: <output>
|
|
14
|
+
stderr: <errors>
|
|
15
|
+
exit_code: <N>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Run code inline
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
```python
|
|
21
|
+
# File operations
|
|
22
|
+
import os, json
|
|
23
|
+
print(json.dumps(os.listdir('.')))
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
# Read a file
|
|
26
|
+
with open('package.json') as f:
|
|
27
|
+
print(f.read())
|
|
34
28
|
|
|
35
|
-
# Write
|
|
36
|
-
|
|
29
|
+
# Write a file
|
|
30
|
+
with open('out.json', 'w') as f:
|
|
31
|
+
import json
|
|
32
|
+
json.dump({'ok': True}, f, indent=2)
|
|
37
33
|
|
|
38
34
|
# Stat / exists
|
|
39
|
-
|
|
35
|
+
import os
|
|
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)
|
|
40
47
|
```
|
|
41
48
|
|
|
42
49
|
## Rules
|
|
43
50
|
|
|
44
51
|
- Each run under 15 seconds
|
|
45
52
|
- Pack every related hypothesis into one run — never one idea per run
|
|
46
|
-
- No persistent temp files; if a temp file is needed, delete it in the same
|
|
47
|
-
-
|
|
48
|
-
- Use `bun` over `node` when available
|
|
53
|
+
- No persistent temp files; if a temp file is needed, delete it in the same code
|
|
54
|
+
- Use `code_execution` tool for all execution; Bash only for git/npm publish/docker
|
|
@@ -12,6 +12,27 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
All applications MUST run through PM2. Direct invocations (node, bun, python) are forbidden for any process that produces output or has a lifecycle.
|
|
14
14
|
|
|
15
|
+
## Installation (First Time Only)
|
|
16
|
+
|
|
17
|
+
Check if PM2 is installed:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pm2 --version
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If command not found, install globally:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g pm2
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Verify installation:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pm2 --version # should print version number
|
|
33
|
+
pm2 ping # should respond "pong"
|
|
34
|
+
```
|
|
35
|
+
|
|
15
36
|
## Pre-Start Check (MANDATORY)
|
|
16
37
|
|
|
17
38
|
Before starting any process, check what is already running:
|