gm-skill 2.0.1867 → 2.0.1869
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/README.md +11 -10
- package/bin/plugkit.version +1 -1
- package/bin/plugkit.wasm.sha256 +1 -1
- package/gm-plugkit/instructions/entry.md +1 -1
- package/gm-plugkit/package.json +1 -2
- package/gm-plugkit/plugkit-wasm-wrapper.js +34 -31
- package/gm-plugkit/plugkit.version +1 -1
- package/gm.json +2 -2
- package/package.json +1 -7
- package/skills/gm/SKILL.md +1 -1
- package/agents/gm.md +0 -22
- package/agents/memorize.md +0 -100
- package/agents/research-worker.md +0 -36
- package/agents/textprocessing.md +0 -47
- package/bin/gm-shell-validate.js +0 -143
- package/bin/gm-validate.js +0 -343
- package/gm-plugkit/lang-host-runner.js +0 -48
- package/lang/ssh.js +0 -187
- package/lib/skill-bootstrap.js +0 -935
- package/lib/spool.js +0 -170
- package/scripts/run-hook.sh +0 -6
package/lib/spool.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
function getSpoolBaseDir() {
|
|
5
|
-
const cwd = process.cwd();
|
|
6
|
-
return path.join(cwd, '.gm', 'exec-spool');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let taskIdSeq = 0;
|
|
10
|
-
function generateTaskId() {
|
|
11
|
-
return `${process.pid}-${Date.now()}-${(taskIdSeq++).toString(36)}`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function validateLang(lang) {
|
|
15
|
-
const valid = ['nodejs', 'python', 'bash', 'typescript', 'go', 'rust', 'c', 'cpp', 'java', 'deno'];
|
|
16
|
-
if (!valid.includes(lang)) {
|
|
17
|
-
throw new Error(`unknown lang '${lang}'; valid: ${valid.join(', ')}`);
|
|
18
|
-
}
|
|
19
|
-
return lang;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function getExtForLang(lang) {
|
|
23
|
-
const langExt = {
|
|
24
|
-
nodejs: 'js',
|
|
25
|
-
python: 'py',
|
|
26
|
-
bash: 'sh',
|
|
27
|
-
typescript: 'ts',
|
|
28
|
-
go: 'go',
|
|
29
|
-
rust: 'rs',
|
|
30
|
-
c: 'c',
|
|
31
|
-
cpp: 'cpp',
|
|
32
|
-
java: 'java',
|
|
33
|
-
deno: 'ts'
|
|
34
|
-
};
|
|
35
|
-
return langExt[lang] || 'js';
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function validateVerb(verb) {
|
|
39
|
-
if (typeof verb !== 'string' || !/^[a-z][a-z0-9_-]*$/.test(verb)) {
|
|
40
|
-
throw new Error(`invalid verb '${verb}'; expected a kebab/snake-case identifier`);
|
|
41
|
-
}
|
|
42
|
-
return verb;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function writeSpool(body, lang = 'nodejs', options = {}) {
|
|
46
|
-
const validLang = validateLang(lang);
|
|
47
|
-
const ext = getExtForLang(validLang);
|
|
48
|
-
const taskId = options.taskId || generateTaskId();
|
|
49
|
-
|
|
50
|
-
const baseDir = getSpoolBaseDir();
|
|
51
|
-
const inDir = path.join(baseDir, 'in', validLang);
|
|
52
|
-
const inFile = path.join(inDir, `${taskId}.${ext}`);
|
|
53
|
-
|
|
54
|
-
fs.mkdirSync(inDir, { recursive: true });
|
|
55
|
-
|
|
56
|
-
const sessionId = options.sessionId || process.env.CLAUDE_SESSION_ID;
|
|
57
|
-
let code = body;
|
|
58
|
-
if (sessionId) {
|
|
59
|
-
const prelude = validLang === 'bash'
|
|
60
|
-
? `SESSION_ID=${JSON.stringify(String(sessionId))}\n`
|
|
61
|
-
: `const SESSION_ID = ${JSON.stringify(sessionId)};\n`;
|
|
62
|
-
code = prelude + body;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const fd = fs.openSync(inFile, 'wx');
|
|
66
|
-
try { fs.writeSync(fd, code, null, 'utf8'); } finally { fs.closeSync(fd); }
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
id: taskId,
|
|
70
|
-
path: inFile,
|
|
71
|
-
lang: validLang,
|
|
72
|
-
ext
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function writeSpoolVerb(body, verb, options = {}) {
|
|
77
|
-
const validVerb = validateVerb(verb);
|
|
78
|
-
const taskId = options.taskId || generateTaskId();
|
|
79
|
-
const baseDir = getSpoolBaseDir();
|
|
80
|
-
const inDir = path.join(baseDir, 'in', validVerb);
|
|
81
|
-
const inFile = path.join(inDir, `${taskId}.txt`);
|
|
82
|
-
fs.mkdirSync(inDir, { recursive: true });
|
|
83
|
-
const fd = fs.openSync(inFile, 'wx');
|
|
84
|
-
try { fs.writeSync(fd, body, null, 'utf8'); } finally { fs.closeSync(fd); }
|
|
85
|
-
return { id: taskId, path: inFile, verb: validVerb };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function readSpoolOutput(id) {
|
|
89
|
-
const baseDir = getSpoolBaseDir();
|
|
90
|
-
const outDir = path.join(baseDir, 'out');
|
|
91
|
-
|
|
92
|
-
const outFile = path.join(outDir, `${id}.out`);
|
|
93
|
-
const errFile = path.join(outDir, `${id}.err`);
|
|
94
|
-
const jsonFile = path.join(outDir, `${id}.json`);
|
|
95
|
-
|
|
96
|
-
const stdout = fs.existsSync(outFile) ? fs.readFileSync(outFile, 'utf8') : '';
|
|
97
|
-
const stderr = fs.existsSync(errFile) ? fs.readFileSync(errFile, 'utf8') : '';
|
|
98
|
-
|
|
99
|
-
let metadata = {};
|
|
100
|
-
if (fs.existsSync(jsonFile)) {
|
|
101
|
-
try {
|
|
102
|
-
metadata = JSON.parse(fs.readFileSync(jsonFile, 'utf8'));
|
|
103
|
-
} catch (e) {
|
|
104
|
-
metadata = { error: 'Failed to parse metadata' };
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return {
|
|
109
|
-
id,
|
|
110
|
-
stdout,
|
|
111
|
-
stderr,
|
|
112
|
-
metadata,
|
|
113
|
-
exitCode: metadata.exitCode,
|
|
114
|
-
durationMs: metadata.durationMs,
|
|
115
|
-
timedOut: metadata.timedOut || false
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async function waitForCompletion(id, timeoutMs = 30000) {
|
|
120
|
-
const baseDir = getSpoolBaseDir();
|
|
121
|
-
const outDir = path.join(baseDir, 'out');
|
|
122
|
-
const jsonFile = path.join(outDir, `${id}.json`);
|
|
123
|
-
|
|
124
|
-
const start = Date.now();
|
|
125
|
-
const interval = 50;
|
|
126
|
-
|
|
127
|
-
while (Date.now() - start < timeoutMs) {
|
|
128
|
-
if (fs.existsSync(jsonFile)) {
|
|
129
|
-
try {
|
|
130
|
-
const metadata = JSON.parse(fs.readFileSync(jsonFile, 'utf8'));
|
|
131
|
-
const output = readSpoolOutput(id);
|
|
132
|
-
return {
|
|
133
|
-
ok: metadata.exitCode === 0 && !metadata.timedOut,
|
|
134
|
-
...output
|
|
135
|
-
};
|
|
136
|
-
} catch (e) {
|
|
137
|
-
await new Promise(r => setTimeout(r, interval));
|
|
138
|
-
}
|
|
139
|
-
} else {
|
|
140
|
-
await new Promise(r => setTimeout(r, interval));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const output = readSpoolOutput(id);
|
|
145
|
-
return {
|
|
146
|
-
ok: false,
|
|
147
|
-
...output,
|
|
148
|
-
timedOut: true,
|
|
149
|
-
stderr: output.stderr + `\n[spool timeout after ${timeoutMs}ms]`
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async function execSpool(body, lang, options = {}) {
|
|
154
|
-
const timeoutMs = options.timeoutMs || 30000;
|
|
155
|
-
const sessionId = options.sessionId || process.env.CLAUDE_SESSION_ID;
|
|
156
|
-
const task = lang === 'nodejs' || lang === 'bash' ? writeSpool(body, lang, { sessionId }) : writeSpoolVerb(body, lang, {});
|
|
157
|
-
const result = await waitForCompletion(task.id, timeoutMs);
|
|
158
|
-
if (options.cleanup !== false) {
|
|
159
|
-
try { fs.unlinkSync(task.path); } catch (e) {}
|
|
160
|
-
}
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
module.exports = {
|
|
165
|
-
writeSpool,
|
|
166
|
-
writeSpoolVerb,
|
|
167
|
-
readSpoolOutput,
|
|
168
|
-
waitForCompletion,
|
|
169
|
-
execSpool
|
|
170
|
-
};
|