gm-gc 2.0.145 → 2.0.147
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/gemini-extension.json +1 -1
- package/hooks/prompt-submit-hook.js +23 -116
- package/package.json +1 -1
package/gemini-extension.json
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
if (process.env.AGENTGUI_SUBPROCESS === '1') {
|
|
4
|
+
console.log(JSON.stringify({ additionalContext: '' }));
|
|
5
|
+
process.exit(0);
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
const fs = require('fs');
|
|
4
9
|
const path = require('path');
|
|
5
10
|
const { execSync } = require('child_process');
|
|
@@ -7,8 +12,8 @@ const { execSync } = require('child_process');
|
|
|
7
12
|
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || process.env.GEMINI_PROJECT_DIR || process.env.OC_PLUGIN_ROOT || process.env.KILO_PLUGIN_ROOT || path.join(__dirname, '..');
|
|
8
13
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.GEMINI_PROJECT_DIR || process.env.OC_PROJECT_DIR || process.env.KILO_PROJECT_DIR;
|
|
9
14
|
|
|
10
|
-
const COMPACT_CONTEXT = 'use gm agent | ref: TOOL_INVARIANTS | codesearch for exploration |
|
|
11
|
-
const PLAN_MODE_BLOCK = 'DO NOT use EnterPlanMode
|
|
15
|
+
const COMPACT_CONTEXT = 'use gm agent | ref: TOOL_INVARIANTS | codesearch for exploration | bun x gm-exec for execution';
|
|
16
|
+
const PLAN_MODE_BLOCK = 'DO NOT use EnterPlanMode. Use GM agent planning (PLAN→EXECUTE→EMIT→VERIFY→COMPLETE state machine) instead. Plan mode is blocked.';
|
|
12
17
|
|
|
13
18
|
const ensureGitignore = () => {
|
|
14
19
|
if (!projectDir) return;
|
|
@@ -25,102 +30,23 @@ const ensureGitignore = () => {
|
|
|
25
30
|
: content + '\n' + entry + '\n';
|
|
26
31
|
fs.writeFileSync(gitignorePath, newContent);
|
|
27
32
|
}
|
|
28
|
-
} catch (e) {
|
|
29
|
-
// Silently fail - not critical
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const getBaseContext = (resetMsg = '') => {
|
|
34
|
-
let ctx = 'use gm agent';
|
|
35
|
-
if (resetMsg) ctx += ' - ' + resetMsg;
|
|
36
|
-
return ctx;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const readStdinPrompt = () => {
|
|
40
|
-
try {
|
|
41
|
-
const raw = fs.readFileSync(0, 'utf-8');
|
|
42
|
-
const data = JSON.parse(raw);
|
|
43
|
-
return data.prompt || '';
|
|
44
|
-
} catch (e) {
|
|
45
|
-
return '';
|
|
46
|
-
}
|
|
33
|
+
} catch (e) {}
|
|
47
34
|
};
|
|
48
35
|
|
|
49
|
-
const
|
|
50
|
-
if (!pluginRoot) return '';
|
|
51
|
-
try {
|
|
52
|
-
return fs.readFileSync(path.join(pluginRoot, 'agents/gm.md'), 'utf-8');
|
|
53
|
-
} catch (e) {
|
|
54
|
-
return '';
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const runMcpThorns = () => {
|
|
36
|
+
const runThorns = () => {
|
|
59
37
|
if (!projectDir || !fs.existsSync(projectDir)) return '';
|
|
38
|
+
const localThorns = path.join(process.env.HOME || '/root', 'mcp-thorns', 'index.js');
|
|
39
|
+
const thornsBin = fs.existsSync(localThorns) ? `node ${localThorns}` : 'bun x mcp-thorns@latest';
|
|
60
40
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
killSignal: 'SIGTERM'
|
|
69
|
-
});
|
|
70
|
-
} catch (bunErr) {
|
|
71
|
-
if (bunErr.killed && bunErr.signal === 'SIGTERM') {
|
|
72
|
-
thornOutput = '=== mcp-thorns ===\nSkipped (3min timeout)';
|
|
73
|
-
} else {
|
|
74
|
-
try {
|
|
75
|
-
thornOutput = execSync('npx -y mcp-thorns', {
|
|
76
|
-
encoding: 'utf-8',
|
|
77
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
78
|
-
cwd: projectDir,
|
|
79
|
-
timeout: 180000,
|
|
80
|
-
killSignal: 'SIGTERM'
|
|
81
|
-
});
|
|
82
|
-
} catch (npxErr) {
|
|
83
|
-
if (npxErr.killed && npxErr.signal === 'SIGTERM') {
|
|
84
|
-
thornOutput = '=== mcp-thorns ===\nSkipped (3min timeout)';
|
|
85
|
-
} else {
|
|
86
|
-
thornOutput = `=== mcp-thorns ===\nSkipped (error: ${bunErr.message.split('\n')[0]})`;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return `=== Repository analysis ===\n${thornOutput}`;
|
|
92
|
-
} catch (e) {
|
|
93
|
-
return `=== mcp-thorns ===\nSkipped (error: ${e.message.split('\n')[0]})`;
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const runCodeSearch = (query, cwd) => {
|
|
98
|
-
if (!query || !cwd || !fs.existsSync(cwd)) return '';
|
|
99
|
-
try {
|
|
100
|
-
const escaped = query.replace(/"/g, '\\"').substring(0, 200);
|
|
101
|
-
let out;
|
|
102
|
-
try {
|
|
103
|
-
out = execSync(`bun x codebasesearch "${escaped}"`, {
|
|
104
|
-
encoding: 'utf-8',
|
|
105
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
106
|
-
cwd,
|
|
107
|
-
timeout: 55000,
|
|
108
|
-
killSignal: 'SIGTERM'
|
|
109
|
-
});
|
|
110
|
-
} catch (bunErr) {
|
|
111
|
-
if (bunErr.killed) return '';
|
|
112
|
-
out = execSync(`npx -y codebasesearch "${escaped}"`, {
|
|
113
|
-
encoding: 'utf-8',
|
|
114
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
115
|
-
cwd,
|
|
116
|
-
timeout: 55000,
|
|
117
|
-
killSignal: 'SIGTERM'
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
const lines = out.split('\n');
|
|
121
|
-
const resultStart = lines.findIndex(l => l.includes('Searching for:'));
|
|
122
|
-
return resultStart >= 0 ? lines.slice(resultStart).join('\n').trim() : out.trim();
|
|
41
|
+
const out = execSync(`${thornsBin} ${projectDir}`, {
|
|
42
|
+
encoding: 'utf-8',
|
|
43
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
|
+
timeout: 15000,
|
|
45
|
+
killSignal: 'SIGTERM'
|
|
46
|
+
});
|
|
47
|
+
return `=== mcp-thorns ===\n${out.trim()}`;
|
|
123
48
|
} catch (e) {
|
|
49
|
+
if (e.killed) return '=== mcp-thorns ===\nSkipped (timeout)';
|
|
124
50
|
return '';
|
|
125
51
|
}
|
|
126
52
|
};
|
|
@@ -141,31 +67,12 @@ const emit = (additionalContext) => {
|
|
|
141
67
|
|
|
142
68
|
try {
|
|
143
69
|
ensureGitignore();
|
|
144
|
-
|
|
145
|
-
const prompt = readStdinPrompt();
|
|
146
70
|
const parts = [];
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (gmContent) {
|
|
151
|
-
parts.push(gmContent);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const thornOutput = runMcpThorns();
|
|
155
|
-
parts.push(thornOutput);
|
|
156
|
-
|
|
157
|
-
// Always: base context and codebasesearch
|
|
158
|
-
parts.push(getBaseContext() + ' | ' + COMPACT_CONTEXT + ' | ' + PLAN_MODE_BLOCK);
|
|
159
|
-
|
|
160
|
-
if (prompt && projectDir) {
|
|
161
|
-
const searchResults = runCodeSearch(prompt, projectDir);
|
|
162
|
-
if (searchResults) {
|
|
163
|
-
parts.push(`=== Semantic code search results ===\n${searchResults}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
71
|
+
const thorns = runThorns();
|
|
72
|
+
if (thorns) parts.push(thorns);
|
|
73
|
+
parts.push('use gm agent | ' + COMPACT_CONTEXT + ' | ' + PLAN_MODE_BLOCK);
|
|
167
74
|
emit(parts.join('\n\n'));
|
|
168
75
|
} catch (error) {
|
|
169
|
-
emit(
|
|
76
|
+
emit('use gm agent | hook error: ' + error.message);
|
|
170
77
|
process.exit(0);
|
|
171
78
|
}
|