gm-oc 2.0.1061 → 2.0.1063
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 +61 -15
- package/package.json +1 -1
- package/skills/gm-cc/SKILL.md +1 -1
- package/skills/gm-codex/SKILL.md +1 -1
- package/skills/gm-copilot-cli/SKILL.md +1 -1
- package/skills/gm-cursor/SKILL.md +1 -1
- package/skills/gm-gc/SKILL.md +1 -1
- package/skills/gm-jetbrains/SKILL.md +1 -1
- package/skills/gm-kilo/SKILL.md +1 -1
- package/skills/gm-oc/SKILL.md +1 -1
- package/skills/gm-vscode/SKILL.md +1 -1
- package/skills/gm-zed/SKILL.md +1 -1
package/gm-oc.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import { readFileSync, existsSync, writeFileSync, unlinkSync } from 'fs';
|
|
|
2
2
|
import { join, dirname, extname, basename } from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { spawnSync } from 'child_process';
|
|
5
|
-
import { tmpdir } from 'os';
|
|
6
5
|
|
|
7
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
7
|
const LANG_ALIASES = { js:'nodejs',javascript:'nodejs',ts:'typescript',node:'nodejs',py:'python',sh:'bash',shell:'bash',zsh:'bash' };
|
|
@@ -29,18 +28,53 @@ function stripFooter(s) { return s ? s.replace(/\n\[Running tools\][\s\S]*$/, ''
|
|
|
29
28
|
function runExecSync(rawLang, code, cwd) {
|
|
30
29
|
const lang = LANG_ALIASES[rawLang] || rawLang || 'nodejs';
|
|
31
30
|
const projectDir = cwd || process.cwd();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
const spoolBase = join(projectDir, '.gm', 'exec-spool');
|
|
32
|
+
const taskId = Date.now() + '-' + Math.random().toString(16).slice(2, 8);
|
|
33
|
+
|
|
34
|
+
const isVerb = ['codesearch','recall','memorize','wait','sleep','status','close','browser','runner','type','kill-port','forget','feedback','discipline','pause','health'].includes(lang);
|
|
35
|
+
const langDir = lang.match(/^(nodejs|python|bash|typescript|go|rust|c|cpp|java|deno)$/) ? lang : 'nodejs';
|
|
36
|
+
const ext = {nodejs:'js',python:'py',bash:'sh',typescript:'ts',go:'go',rust:'rs',c:'c',cpp:'cpp',java:'java',deno:'ts'}[langDir] || 'js';
|
|
37
|
+
|
|
38
|
+
const inDir = join(spoolBase, 'in', isVerb ? lang : langDir);
|
|
39
|
+
const outDir = join(spoolBase, 'out');
|
|
40
|
+
const inFile = join(inDir, taskId + (isVerb ? '.txt' : '.' + ext));
|
|
41
|
+
const jsonFile = join(outDir, taskId + '.json');
|
|
42
|
+
|
|
43
|
+
try { fs.mkdirSync(inDir, { recursive: true }); fs.mkdirSync(outDir, { recursive: true }); } catch(e) {}
|
|
44
|
+
writeFileSync(inFile, code, 'utf-8');
|
|
45
|
+
|
|
46
|
+
const start = Date.now();
|
|
47
|
+
while (Date.now() - start < 28000) {
|
|
48
|
+
if (existsSync(jsonFile)) {
|
|
49
|
+
try {
|
|
50
|
+
const meta = JSON.parse(readFileSync(jsonFile, 'utf-8'));
|
|
51
|
+
const outFile = jsonFile.replace(/\.json$/, '.out');
|
|
52
|
+
const errFile = jsonFile.replace(/\.json$/, '.err');
|
|
53
|
+
const stdout = existsSync(outFile) ? readFileSync(outFile, 'utf-8') : '';
|
|
54
|
+
const stderr = existsSync(errFile) ? readFileSync(errFile, 'utf-8') : '';
|
|
55
|
+
const o = stdout.trimEnd(), e = stripFooter(stderr).trimEnd();
|
|
56
|
+
return o && e ? o + '\n[stderr]\n' + e : o || e || '(no output)';
|
|
57
|
+
} catch(e) {}
|
|
58
|
+
}
|
|
59
|
+
try { require('child_process').execSync('sleep 0.05', { stdio: 'ignore' }); } catch(e) { const s = Date.now(); while(Date.now()-s<50){} }
|
|
42
60
|
}
|
|
43
|
-
return
|
|
61
|
+
return '[spool dispatch timeout after 28s]';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ensureSpoolWatcher(dir) {
|
|
65
|
+
try {
|
|
66
|
+
const spoolBase = join(dir, '.gm', 'exec-spool');
|
|
67
|
+
const pidFile = join(spoolBase, '.watcher.pid');
|
|
68
|
+
try { fs.mkdirSync(spoolBase, { recursive: true }); } catch(e) {}
|
|
69
|
+
const alreadyRunning = existsSync(pidFile) && (() => { try { const p = parseInt(readFileSync(pidFile,'utf-8')); process.kill(p,0); return true; } catch(e) { return false; } })();
|
|
70
|
+
if (!alreadyRunning) {
|
|
71
|
+
const r = spawnSync('node', [join(__dirname, '..', 'bin', 'plugkit.js'), 'spool'], {
|
|
72
|
+
detached: true, stdio: 'ignore', windowsHide: true,
|
|
73
|
+
env: { ...process.env, GM_SPOOL_DIR: spoolBase }
|
|
74
|
+
});
|
|
75
|
+
if (r.pid) { try { writeFileSync(pidFile, String(r.pid), 'utf-8'); } catch(e) {} }
|
|
76
|
+
}
|
|
77
|
+
} catch(e) {}
|
|
44
78
|
}
|
|
45
79
|
|
|
46
80
|
const BANNED_BASH = ['grep','rg','find','glob','awk','sed','cat','head','tail'];
|
|
@@ -61,7 +95,19 @@ export async function GmPlugin({ directory }) {
|
|
|
61
95
|
if (!sessionStarted) {
|
|
62
96
|
sessionStarted = true;
|
|
63
97
|
try { runPlugkit(['hook', 'session-start']); } catch(e) {}
|
|
64
|
-
try {
|
|
98
|
+
try {
|
|
99
|
+
const spoolBase = join(directory, '.gm', 'exec-spool');
|
|
100
|
+
const pidFile = join(spoolBase, '.watcher.pid');
|
|
101
|
+
try { fs.mkdirSync(spoolBase, { recursive: true }); } catch(e) {}
|
|
102
|
+
const alreadyRunning = existsSync(pidFile) && (() => { try { const p = parseInt(readFileSync(pidFile,'utf-8')); process.kill(p,0); return true; } catch(e) { return false; } })();
|
|
103
|
+
if (!alreadyRunning) {
|
|
104
|
+
const r = spawnSync('node', [join(__dirname, '..', 'bin', 'plugkit.js'), 'spool'], {
|
|
105
|
+
detached: true, stdio: 'ignore', windowsHide: true,
|
|
106
|
+
env: { ...process.env, GM_SPOOL_DIR: spoolBase }
|
|
107
|
+
});
|
|
108
|
+
if (r.pid) { try { writeFileSync(pidFile, String(r.pid), 'utf-8'); } catch(e) {} }
|
|
109
|
+
}
|
|
110
|
+
} catch(e) {}
|
|
65
111
|
}
|
|
66
112
|
},
|
|
67
113
|
|
|
@@ -81,7 +127,7 @@ export async function GmPlugin({ directory }) {
|
|
|
81
127
|
if (!sessionStarted) {
|
|
82
128
|
sessionStarted = true;
|
|
83
129
|
try { runPlugkit(['hook', 'session-start']); } catch(e) {}
|
|
84
|
-
try {
|
|
130
|
+
try { ensureSpoolWatcher(directory); } catch(e) {}
|
|
85
131
|
}
|
|
86
132
|
try { const rules = readFileSync(agentMd,'utf-8'); if (rules) output.system.unshift(rules); } catch(e) {}
|
|
87
133
|
try {
|
|
@@ -132,7 +178,7 @@ export async function GmPlugin({ directory }) {
|
|
|
132
178
|
if (!sessionStarted) {
|
|
133
179
|
sessionStarted = true;
|
|
134
180
|
try { runPlugkit(['hook', 'session-start']); } catch(e) {}
|
|
135
|
-
try {
|
|
181
|
+
try { ensureSpoolWatcher(directory); } catch(e) {}
|
|
136
182
|
}
|
|
137
183
|
const skillName = (args.skill || args.name || '').toString();
|
|
138
184
|
if (FORBIDDEN_TOOLS.has(input.tool)) {
|
package/package.json
CHANGED
package/skills/gm-cc/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
package/skills/gm-codex/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
package/skills/gm-gc/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
package/skills/gm-kilo/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
package/skills/gm-oc/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|
package/skills/gm-zed/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ allowed-tools: Skill
|
|
|
8
8
|
|
|
9
9
|
AI-native software engineering orchestrated via skill chain: PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS.
|
|
10
10
|
|
|
11
|
-
**Bootstrap pattern**:
|
|
11
|
+
**Bootstrap pattern**: `bun x gm-plugkit@latest --daemon` downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Call once at session start; idempotent on subsequent calls. All execution routes through the file-spool: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`, poll `out/<N>.json` for results.
|
|
12
12
|
|
|
13
13
|
**Session-ID threading (no session-start hook)**: At skill invoke time, generate or detect SESSION_ID (env var `SESSION_ID` or `uuid()`). Pass `sessionId: "<id>"` in every rs-exec RPC body (spawn, tail, watch, etc.) and every spool-written task body. All task-scoped cleanup (deleteTask, getTask, appendOutput, killSessionTasks) requires matching sessionId. Absence is forbidden — hard reject by rs-exec handler.
|
|
14
14
|
|