gm-oc 2.0.366 → 2.0.367
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/gm-oc.mjs +49 -8
- package/package.json +1 -1
package/gm-oc.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { spawnSync } from 'child_process';
|
|
|
5
5
|
import { tmpdir } from 'os';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const LANG_ALIASES = { js:'nodejs',javascript:'nodejs',ts:'typescript',node:'nodejs',py:'python',sh:'bash',shell:'bash',zsh:'bash' };
|
|
8
9
|
const FORBIDDEN_TOOLS = new Set(['glob','Glob','grep','Grep','search_file_content','Find','find']);
|
|
9
10
|
const FORBIDDEN_FILE_RE = [/\.(test|spec)\.(js|ts|jsx|tsx|mjs|cjs)$/, /^(jest|vitest|mocha|ava|jasmine|tap)\.(config|setup)/, /\.(snap|stub|mock|fixture)\.(js|ts|json)$/];
|
|
10
11
|
const FORBIDDEN_PATH_RE = ['/__tests__/','/test/','/tests/','/fixtures/','/test-data/',"/__mocks__/"];
|
|
@@ -19,6 +20,52 @@ function runPlugkit(args) {
|
|
|
19
20
|
} catch(e) { return ''; }
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
function safePrintf(s) {
|
|
24
|
+
return "printf '%s' '" + String(s).replace(/\\\\/g,'\\\\\\\\').replace(/'/g,"'\\\\''")+"'";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function stripFooter(s) { return s ? s.replace(/\n\[Running tools\][\s\S]*$/, '').trimEnd() : ''; }
|
|
28
|
+
|
|
29
|
+
function tryLangPlugin(lang, code, cwd) {
|
|
30
|
+
const langPluginDir = join(__dirname, '..', 'lang');
|
|
31
|
+
const langPluginFile = join(langPluginDir, lang+'.js');
|
|
32
|
+
if (!existsSync(langPluginFile)) return null;
|
|
33
|
+
try {
|
|
34
|
+
const plugin = require(langPluginFile);
|
|
35
|
+
if (plugin && plugin.exec && plugin.exec.run) {
|
|
36
|
+
const result = plugin.exec.run(code, cwd || process.cwd());
|
|
37
|
+
if (result && typeof result.then === 'function') return null;
|
|
38
|
+
return String(result === undefined ? '' : result);
|
|
39
|
+
}
|
|
40
|
+
} catch(e) {}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function runExecSync(rawLang, code, cwd) {
|
|
45
|
+
const lang = LANG_ALIASES[rawLang] || rawLang || 'nodejs';
|
|
46
|
+
const opts = { encoding: 'utf-8', timeout: 30000, ...(cwd && { cwd }) };
|
|
47
|
+
const out = (r) => { const o = (r.stdout||'').trimEnd(), e = stripFooter(r.stderr||'').trimEnd(); return o && e ? o+'\n[stderr]\n'+e : o||e||'(no output)'; };
|
|
48
|
+
const pluginResult = tryLangPlugin(lang, code, cwd);
|
|
49
|
+
if (pluginResult !== null) return pluginResult;
|
|
50
|
+
if (lang === 'python') return out(spawnSync('python3',['-c',code],opts));
|
|
51
|
+
if (lang === 'bash' || lang === 'sh') {
|
|
52
|
+
const tmp = join(tmpdir(),'gm-exec-'+Date.now()+'.sh');
|
|
53
|
+
writeFileSync(tmp,code,'utf-8');
|
|
54
|
+
const r = spawnSync('bash',[tmp],opts);
|
|
55
|
+
try { unlinkSync(tmp); } catch(e) {}
|
|
56
|
+
return out(r);
|
|
57
|
+
}
|
|
58
|
+
const ext = lang === 'typescript' ? 'ts' : 'mjs';
|
|
59
|
+
const tmp = join(tmpdir(),'gm-exec-'+Date.now()+'.'+ext);
|
|
60
|
+
const src = lang === 'typescript' ? code : 'const __r=await(async()=>{\n'+code+'\n})();if(__r!==undefined){if(typeof __r==="object"){console.log(JSON.stringify(__r,null,2));}else{console.log(__r);}}';
|
|
61
|
+
writeFileSync(tmp,src,'utf-8');
|
|
62
|
+
const r = spawnSync('bun',['run',tmp],opts);
|
|
63
|
+
try { unlinkSync(tmp); } catch(e) {}
|
|
64
|
+
let result = out(r);
|
|
65
|
+
if (result) result = result.split(tmp).join('<script>');
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
22
69
|
export async function GmPlugin({ directory }) {
|
|
23
70
|
const agentMd = join(__dirname, '..', 'agents', 'gm.md');
|
|
24
71
|
const prdFile = join(directory, '.prd');
|
|
@@ -98,14 +145,8 @@ export async function GmPlugin({ directory }) {
|
|
|
98
145
|
output.args.command = "echo 'Bash tool can only be used with exec syntax:\n\nexec[:lang]\n<command>\n\nExamples:\nexec\nls -la\n\nexec:nodejs\nconsole.log(\"hello\")' 1>&2 && false";
|
|
99
146
|
return;
|
|
100
147
|
}
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const ext = lang === 'python' ? 'py' : lang === 'bash' || lang === 'sh' ? 'sh' : 'mjs';
|
|
104
|
-
const ts = Date.now();
|
|
105
|
-
const tmp = join(tmpdir(), 'plugkit-exec-' + ts + '.' + ext);
|
|
106
|
-
writeFileSync(tmp, code, 'utf-8');
|
|
107
|
-
const binJs = join(__dirname, '..', 'bin', 'plugkit.js');
|
|
108
|
-
output.args.command = 'node ' + binJs + ' exec --lang=' + lang + ' --file=' + tmp + ' --cwd=' + (output.args.workdir || directory);
|
|
148
|
+
const result = runExecSync(m[1]||'', m[2], output.args.workdir || directory);
|
|
149
|
+
output.args = { ...output.args, command: safePrintf('exec:'+(m[1]||'nodejs')+' output:\n\n'+result) };
|
|
109
150
|
}
|
|
110
151
|
};
|
|
111
152
|
}
|