gm-gc 2.0.152 → 2.0.154
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/agents/gm.md +8 -4
- package/gemini-extension.json +1 -1
- package/hooks/session-start-hook.js +23 -71
- package/hooks/stop-hook-git.js +3 -3
- package/hooks/stop-hook.js +1 -8
- package/package.json +1 -1
package/agents/gm.md
CHANGED
|
@@ -185,7 +185,7 @@ Server + client split:
|
|
|
185
185
|
- `git` — version control only
|
|
186
186
|
- `bun x gm-exec` — all other shell/code execution:
|
|
187
187
|
- `bun x gm-exec bash [--cwd=<dir>] <cmd>` — run shell commands
|
|
188
|
-
- `bun x gm-exec exec [--lang=<lang>] [--cwd=<dir>] [--file=<path>] <code>` — execute code (nodejs default; langs: nodejs, python, go, rust, c, cpp, java, deno, bash)
|
|
188
|
+
- `bun x gm-exec exec [--lang=<lang>] [--cwd=<dir>] [--file=<path>] <code>` — execute code (nodejs default; langs: nodejs, python, go, rust, c, cpp, java, deno, bash, cmd)
|
|
189
189
|
- `bun x gm-exec status <task_id>` — poll status + drain output of background task
|
|
190
190
|
- `bun x gm-exec sleep <task_id> [seconds]` — wait for task completion (default 30s timeout)
|
|
191
191
|
- `bun x gm-exec close <task_id>` — delete background task
|
|
@@ -194,8 +194,8 @@ Server + client split:
|
|
|
194
194
|
- Everything else is blocked
|
|
195
195
|
|
|
196
196
|
**gm-exec EXEC SAFETY RULES** — prevent stray files and working directory pollution:
|
|
197
|
-
- NEVER run `bun x gm-exec exec` without `--cwd` pointing to a safe scratch directory, not the project root. Use
|
|
198
|
-
- For any code longer than a single expression, use `--file=<path>` instead of inline `<code>`. Write the code to a temp file first via `bun x gm-exec exec "require('fs').writeFileSync('/
|
|
197
|
+
- NEVER run `bun x gm-exec exec` without `--cwd` pointing to a safe scratch directory, not the project root. Use the system temp directory (`os.tmpdir()` — `/tmp` on Unix, `C:\Users\<user>\AppData\Local\Temp` on Windows) for throwaway runs. Only use `--cwd=<project>` when the code explicitly needs to import from that project.
|
|
198
|
+
- For any code longer than a single expression, use `--file=<path>` instead of inline `<code>`. Write the code to a temp file first via `bun x gm-exec exec "require('fs').writeFileSync(require('os').tmpdir()+'/run.mjs', \`...\`)"` then run `bun x gm-exec exec --file=<tmpdir>/run.mjs`. This prevents shell quoting failures from leaking code fragments as filenames in the working directory.
|
|
199
199
|
- Single-line inline code is safe only when it contains no shell metacharacters (backticks, quotes, parens, brackets). If in doubt, use `--file`.
|
|
200
200
|
- After any exec session, verify no stray files were created: `bun x gm-exec bash --cwd=<project> "git status --porcelain"` must be empty. If stray files appear, delete them before proceeding.
|
|
201
201
|
|
|
@@ -293,6 +293,10 @@ Verification means executed system with witnessed working output. These are NOT
|
|
|
293
293
|
|
|
294
294
|
Completion requires all of: witnessed execution AND every possible scenario tested AND goal achieved AND real output AND gate conditions passed AND no remaining steps for user. Last 1% of work requires 99% of effort. Partial/ready/prepared states mean nothing. No handoffs ("here is how", "now you can"). Ignore context/token budget constraints entirely. Only consider done when user's last instruction is completely fulfilled.
|
|
295
295
|
|
|
296
|
+
**NO PREMATURE STOPPING**: Do not stop when you think it works. Do not stop when the main path succeeds. Do not stop after the first green output. Keep going until every item in the .prd is removed, every edge case is witnessed, every platform is rebuilt, every push is confirmed, and `git status --porcelain` is empty. "Looks good" is not done. "Should work" is not done. "I believe it's complete" is not done. Done means: zero remaining .prd items, zero unwitnessed claims, zero uncommitted changes, zero unpushed commits. Anything short of that is mid-execution, not completion.
|
|
297
|
+
|
|
298
|
+
**CONTINUING AFTER SUCCESS**: When one part succeeds, immediately enumerate what still remains. Never treat a partial success as a reason to report completion. After each witnessed success, ask: what other items in the .prd are still open? What edge cases haven't been executed yet? What downstream effects haven't been verified? Execute all of them before claiming COMPLETE state.
|
|
299
|
+
|
|
296
300
|
Incomplete execution rule: if a required step cannot be fully completed due to genuine constraints, explicitly state what was incomplete and why. Never pretend incomplete work was fully executed. Never silently skip steps.
|
|
297
301
|
|
|
298
302
|
After achieving goal: execute real system end to end via `bun x gm-exec`, witness it working, run actual integration tests in `agent-browser` skill for user-facing features, observe actual behavior. Ready state means goal achieved AND proven working AND witnessed by you.
|
|
@@ -462,7 +466,7 @@ When constraints conflict:
|
|
|
462
466
|
|
|
463
467
|
No policy conflict is preserved. Every conflict is resolved at the moment it is spotted.
|
|
464
468
|
|
|
465
|
-
**Never**: crash | exit | terminate | use fake data | leave remaining steps for user | spawn/exec/fork in code | write test files | approach context limits as reason to stop | summarize before done | end early due to context | create marker files as completion | use pkill (risks killing agent process) | treat ready state as done without execution | write .prd variants or to non-cwd paths | execute independent items sequentially | use crash as recovery | require human intervention as first solution | violate TOOL_INVARIANTS | use raw bash when `bun x gm-exec` suffices | use bash for file reads/writes/exploration/script execution | use Glob for exploration | use Grep for exploration | use Explore agent | use Read tool for code discovery | use WebSearch for codebase questions | start servers/workers without process-management skill | skip planning skill in PLAN phase | leave orphaned PM2 processes after work completes | defer fixing a spotted inconsistency | defer refactoring code that violates conventions | note an improvement without implementing it | write notes anywhere except .prd (temporary) or CLAUDE.md (permanent) | leave docs out of sync with code | silently pick one rule when two conflict | preserve a policy conflict without resolving it | enforce a policy only at end of session instead of at point of violation
|
|
469
|
+
**Never**: crash | exit | terminate | use fake data | leave remaining steps for user | spawn/exec/fork in code | write test files | approach context limits as reason to stop | summarize before done | end early due to context | create marker files as completion | use pkill (risks killing agent process) | treat ready state as done without execution | write .prd variants or to non-cwd paths | execute independent items sequentially | use crash as recovery | require human intervention as first solution | violate TOOL_INVARIANTS | use raw bash when `bun x gm-exec` suffices | use bash for file reads/writes/exploration/script execution | use Glob for exploration | use Grep for exploration | use Explore agent | use Read tool for code discovery | use WebSearch for codebase questions | start servers/workers without process-management skill | skip planning skill in PLAN phase | leave orphaned PM2 processes after work completes | defer fixing a spotted inconsistency | defer refactoring code that violates conventions | note an improvement without implementing it | write notes anywhere except .prd (temporary) or CLAUDE.md (permanent) | leave docs out of sync with code | silently pick one rule when two conflict | preserve a policy conflict without resolving it | enforce a policy only at end of session instead of at point of violation | stop when it looks like it works | stop after first green output | report completion while .prd items remain | treat partial success as completion | skip edge cases after main path succeeds | leave any item unwitnessed and claim it complete
|
|
466
470
|
|
|
467
471
|
**Always**: execute via `bun x gm-exec` or `agent-browser` skill | delete mocks on discovery | expose debug hooks | keep files under 200 lines | use ground truth | verify by witnessed execution | complete fully with real data | recover from failures | systems survive forever by design | checkpoint state continuously | contain all promises | maintain supervisors for all components | fix inconsistencies immediately when spotted | restructure code immediately when convention violation found | implement logical improvements immediately when identified | reconcile docs and code before emitting | resolve policy conflicts at the moment they are spotted
|
|
468
472
|
|
package/gemini-extension.json
CHANGED
|
@@ -4,8 +4,8 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
6
|
|
|
7
|
-
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || process.env.GEMINI_PROJECT_DIR || process.env.OC_PLUGIN_ROOT;
|
|
8
|
-
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.GEMINI_PROJECT_DIR || process.env.OC_PROJECT_DIR;
|
|
7
|
+
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || process.env.GEMINI_PROJECT_DIR || process.env.OC_PLUGIN_ROOT || process.env.KILO_PLUGIN_ROOT;
|
|
8
|
+
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.GEMINI_PROJECT_DIR || process.env.OC_PROJECT_DIR || process.env.KILO_PROJECT_DIR;
|
|
9
9
|
|
|
10
10
|
const ensureGitignore = () => {
|
|
11
11
|
if (!projectDir) return;
|
|
@@ -22,9 +22,7 @@ const ensureGitignore = () => {
|
|
|
22
22
|
: content + '\n' + entry + '\n';
|
|
23
23
|
fs.writeFileSync(gitignorePath, newContent);
|
|
24
24
|
}
|
|
25
|
-
} catch (e) {
|
|
26
|
-
// Silently fail - not critical
|
|
27
|
-
}
|
|
25
|
+
} catch (e) {}
|
|
28
26
|
};
|
|
29
27
|
|
|
30
28
|
ensureGitignore();
|
|
@@ -32,41 +30,24 @@ ensureGitignore();
|
|
|
32
30
|
try {
|
|
33
31
|
let outputs = [];
|
|
34
32
|
|
|
35
|
-
// 1. Read ./start.md
|
|
36
33
|
if (pluginRoot) {
|
|
37
|
-
const
|
|
34
|
+
const gmMdPath = path.join(pluginRoot, '/agents/gm.md');
|
|
38
35
|
try {
|
|
39
|
-
const
|
|
40
|
-
outputs.push(
|
|
41
|
-
} catch (e) {
|
|
42
|
-
// File may not exist in this context
|
|
43
|
-
}
|
|
36
|
+
const gmMdContent = fs.readFileSync(gmMdPath, 'utf-8');
|
|
37
|
+
outputs.push(gmMdContent);
|
|
38
|
+
} catch (e) {}
|
|
44
39
|
}
|
|
45
40
|
|
|
46
|
-
|
|
47
|
-
const codeSearchContext = `## 🔍 Semantic Code Search Now Available
|
|
48
|
-
|
|
49
|
-
Your prompts will trigger **semantic code search** - intelligent, intent-based exploration of your codebase.
|
|
41
|
+
const codeSearchContext = `## Semantic Code Search Available
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- "
|
|
54
|
-
- "
|
|
55
|
-
- "Show error handling patterns" → discovers try/catch patterns, error boundaries
|
|
43
|
+
Describe what you need in plain language to search the codebase:
|
|
44
|
+
- "Find authentication validation" locates auth checks, guards, permission logic
|
|
45
|
+
- "Where is database initialization?" finds connection setup, migrations, schemas
|
|
46
|
+
- "Show error handling patterns" discovers try/catch patterns, error boundaries
|
|
56
47
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
### Example
|
|
60
|
-
Instead of regex patterns, simply describe your intent:
|
|
61
|
-
"Find where API authorization is checked"
|
|
62
|
-
|
|
63
|
-
The search will find permission validations, role checks, authentication guards - however they're implemented.
|
|
64
|
-
|
|
65
|
-
### When to Use Code Search
|
|
66
|
-
When exploring unfamiliar code, finding similar patterns, understanding integrations, or locating feature implementations across your codebase.`;
|
|
48
|
+
Use the code-search skill for all codebase exploration.`;
|
|
67
49
|
outputs.push(codeSearchContext);
|
|
68
50
|
|
|
69
|
-
// 3. Run mcp-thorns (bun x with npx fallback)
|
|
70
51
|
if (projectDir && fs.existsSync(projectDir)) {
|
|
71
52
|
try {
|
|
72
53
|
let thornOutput;
|
|
@@ -97,55 +78,26 @@ When exploring unfamiliar code, finding similar patterns, understanding integrat
|
|
|
97
78
|
|
|
98
79
|
const isGemini = process.env.GEMINI_PROJECT_DIR !== undefined;
|
|
99
80
|
const isOpenCode = process.env.OC_PLUGIN_ROOT !== undefined;
|
|
81
|
+
const isKilo = process.env.KILO_PLUGIN_ROOT !== undefined;
|
|
100
82
|
|
|
101
83
|
if (isGemini) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
};
|
|
105
|
-
console.log(JSON.stringify(result, null, 2));
|
|
106
|
-
} else if (isOpenCode) {
|
|
107
|
-
const result = {
|
|
108
|
-
hookSpecificOutput: {
|
|
109
|
-
hookEventName: 'session.created',
|
|
110
|
-
additionalContext
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
console.log(JSON.stringify(result, null, 2));
|
|
84
|
+
console.log(JSON.stringify({ systemMessage: additionalContext }, null, 2));
|
|
85
|
+
} else if (isOpenCode || isKilo) {
|
|
86
|
+
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'session.created', additionalContext } }, null, 2));
|
|
114
87
|
} else {
|
|
115
|
-
|
|
116
|
-
hookSpecificOutput: {
|
|
117
|
-
hookEventName: 'SessionStart',
|
|
118
|
-
additionalContext
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
console.log(JSON.stringify(result, null, 2));
|
|
88
|
+
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext } }, null, 2));
|
|
122
89
|
}
|
|
123
90
|
} catch (error) {
|
|
124
91
|
const isGemini = process.env.GEMINI_PROJECT_DIR !== undefined;
|
|
125
92
|
const isOpenCode = process.env.OC_PLUGIN_ROOT !== undefined;
|
|
93
|
+
const isKilo = process.env.KILO_PLUGIN_ROOT !== undefined;
|
|
126
94
|
|
|
127
95
|
if (isGemini) {
|
|
128
|
-
console.log(JSON.stringify({
|
|
129
|
-
|
|
130
|
-
}, null, 2));
|
|
131
|
-
} else if (isOpenCode) {
|
|
132
|
-
console.log(JSON.stringify({
|
|
133
|
-
hookSpecificOutput: {
|
|
134
|
-
hookEventName: 'session.created',
|
|
135
|
-
additionalContext: `Error executing hook: ${error.message}`
|
|
136
|
-
}
|
|
137
|
-
}, null, 2));
|
|
96
|
+
console.log(JSON.stringify({ systemMessage: `Error executing hook: ${error.message}` }, null, 2));
|
|
97
|
+
} else if (isOpenCode || isKilo) {
|
|
98
|
+
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'session.created', additionalContext: `Error executing hook: ${error.message}` } }, null, 2));
|
|
138
99
|
} else {
|
|
139
|
-
console.log(JSON.stringify({
|
|
140
|
-
hookSpecificOutput: {
|
|
141
|
-
hookEventName: 'SessionStart',
|
|
142
|
-
additionalContext: `Error executing hook: ${error.message}`
|
|
143
|
-
}
|
|
144
|
-
}, null, 2));
|
|
100
|
+
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext: `Error executing hook: ${error.message}` } }, null, 2));
|
|
145
101
|
}
|
|
146
102
|
process.exit(0);
|
|
147
103
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
package/hooks/stop-hook-git.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
// Skip hooks when running inside agentgui subprocess to prevent spurious injections
|
|
4
3
|
if (process.env.AGENTGUI_SUBPROCESS === '1') {
|
|
5
4
|
console.log(JSON.stringify({ decision: 'approve' }));
|
|
6
5
|
process.exit(0);
|
|
@@ -9,13 +8,14 @@ if (process.env.AGENTGUI_SUBPROCESS === '1') {
|
|
|
9
8
|
const { execSync } = require('child_process');
|
|
10
9
|
const fs = require('fs');
|
|
11
10
|
const path = require('path');
|
|
11
|
+
const os = require('os');
|
|
12
12
|
const crypto = require('crypto');
|
|
13
13
|
|
|
14
14
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
15
15
|
|
|
16
16
|
const getCounterPath = () => {
|
|
17
17
|
const hash = crypto.createHash('md5').update(projectDir).digest('hex');
|
|
18
|
-
return path.join(
|
|
18
|
+
return path.join(os.tmpdir(), `gm-git-block-counter-${hash}.json`);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const readCounter = () => {
|
package/hooks/stop-hook.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
// Skip hooks when running inside agentgui subprocess to prevent spurious injections
|
|
4
3
|
if (process.env.AGENTGUI_SUBPROCESS === '1') {
|
|
5
4
|
console.log(JSON.stringify({ decision: 'approve' }));
|
|
6
5
|
process.exit(0);
|
|
@@ -9,8 +8,6 @@ if (process.env.AGENTGUI_SUBPROCESS === '1') {
|
|
|
9
8
|
const fs = require('fs');
|
|
10
9
|
const path = require('path');
|
|
11
10
|
|
|
12
|
-
// Always use current working directory for .prd location
|
|
13
|
-
// Explicitly resolve to ./.prd in the current folder
|
|
14
11
|
const projectDir = process.cwd();
|
|
15
12
|
const prdFile = path.resolve(projectDir, '.prd');
|
|
16
13
|
|
|
@@ -22,19 +19,15 @@ const run = () => {
|
|
|
22
19
|
if (aborted) return { ok: true };
|
|
23
20
|
|
|
24
21
|
try {
|
|
25
|
-
// Check if .prd file exists and has content
|
|
26
22
|
if (fs.existsSync(prdFile)) {
|
|
27
23
|
const prdContent = fs.readFileSync(prdFile, 'utf-8').trim();
|
|
28
24
|
if (prdContent.length > 0) {
|
|
29
|
-
// .prd has content, block stopping
|
|
30
25
|
return {
|
|
31
26
|
ok: false,
|
|
32
27
|
reason: `Work items remain in ${prdFile}. Remove completed items as they finish. Current items:\n\n${prdContent}`
|
|
33
28
|
};
|
|
34
29
|
}
|
|
35
30
|
}
|
|
36
|
-
|
|
37
|
-
// .prd doesn't exist or is empty, allow stop
|
|
38
31
|
return { ok: true };
|
|
39
32
|
} catch (error) {
|
|
40
33
|
return { ok: true };
|