gm-kilo 2.0.1058 → 2.0.1060
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/cli.js +1 -0
- package/gm-kilo.mjs +25 -50
- package/install.js +5 -1
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -33,6 +33,7 @@ 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');
|
|
38
39
|
let kiloConfig = {};
|
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
|
-
if (lang === 'sleep') return runPlugkit(['sleep', code.trim()]);
|
|
54
|
-
if (lang === 'close') return runPlugkit(['close', code.trim()]);
|
|
55
|
-
if (lang === 'browser') return runPlugkit(['exec', '--lang', 'browser', '--code', code.trim(), '--cwd', cwd || process.cwd()]);
|
|
56
|
-
if (lang === 'cmd') return out(spawnSync('cmd',['/c',code],opts));
|
|
57
|
-
const pluginResult = tryLangPlugin(lang, code, cwd);
|
|
58
|
-
if (pluginResult !== null) return pluginResult;
|
|
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]);
|
|
66
36
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (result) result = result.split(tmp).join('<script>');
|
|
75
|
-
return result;
|
|
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)';
|
|
42
|
+
}
|
|
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'];
|
|
@@ -90,6 +58,7 @@ export async function GmPlugin({ directory }) {
|
|
|
90
58
|
|
|
91
59
|
return {
|
|
92
60
|
'experimental.chat.system.transform': async (input, output) => {
|
|
61
|
+
const gmDir = join(directory, '.gm');
|
|
93
62
|
try {
|
|
94
63
|
const giPath = join(directory, '.gitignore');
|
|
95
64
|
const entry = '.gm-stop-verified';
|
|
@@ -113,6 +82,12 @@ export async function GmPlugin({ directory }) {
|
|
|
113
82
|
if (prd) output.system.push('\nPENDING WORK (.prd):\n'+prd);
|
|
114
83
|
}
|
|
115
84
|
} catch(e) {}
|
|
85
|
+
try {
|
|
86
|
+
const needsGmPath = join(gmDir, 'needs-gm');
|
|
87
|
+
if (existsSync(needsGmPath)) {
|
|
88
|
+
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.');
|
|
89
|
+
}
|
|
90
|
+
} catch(e) {}
|
|
116
91
|
},
|
|
117
92
|
|
|
118
93
|
'experimental.chat.messages.transform': async (input, output) => {
|
|
@@ -207,10 +182,10 @@ export async function GmPlugin({ directory }) {
|
|
|
207
182
|
if (input.tool !== 'bash' && input.tool !== 'Bash' && input.tool !== 'shell' && input.tool !== 'Shell' && input.tool !== 'spawn/exec') return;
|
|
208
183
|
const cmd = (output.args && output.args.command) || '';
|
|
209
184
|
if (!cmd) return;
|
|
210
|
-
if (/^\s*git(?:\s|$)/.test(cmd)) return;
|
|
211
|
-
const m = cmd.match(/^exec(?::(\S+))?\n([\s\S]+)$/);
|
|
185
|
+
if (/^\s*(git|gh)(?:\s|$)/.test(cmd)) return;
|
|
186
|
+
const m = cmd.match(/^exec(?::(\S+))?\s*\n([\s\S]+)$/);
|
|
212
187
|
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
|
|
188
|
+
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
189
|
}
|
|
215
190
|
const rawLang = (m[1]||'').toLowerCase();
|
|
216
191
|
if (rawLang === 'bash' || rawLang === 'sh' || rawLang === '') {
|
|
@@ -218,7 +193,7 @@ export async function GmPlugin({ directory }) {
|
|
|
218
193
|
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
194
|
}
|
|
220
195
|
const result = runExecSync(m[1]||'', m[2], output.args.workdir || directory);
|
|
221
|
-
|
|
196
|
+
throw new Error('exec:'+(m[1]||'nodejs')+' output:\n\n'+result);
|
|
222
197
|
},
|
|
223
198
|
'message.updated': async (input, output) => {
|
|
224
199
|
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();
|