gm-plugkit 2.0.1217 → 2.0.1219
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/package.json +1 -1
- package/plugkit-wasm-wrapper.js +75 -10
- package/plugkit.sha256 +1 -1
- package/plugkit.version +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-plugkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1219",
|
|
4
4
|
"description": "Bootstrap and daemon-spawn tool for gm plugkit binary. Downloads the correct platform binary, verifies SHA256, and starts the spool watcher daemon. Includes plugkit-wasm-wrapper for WASM-based spool watching.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/plugkit-wasm-wrapper.js
CHANGED
|
@@ -70,6 +70,32 @@ function isSpoolPollCommand(command) {
|
|
|
70
70
|
return null;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
function isBrowserRunningFileLocal(rel) {
|
|
74
|
+
if (!rel) return false;
|
|
75
|
+
const norm = String(rel).replace(/\\\\/g, '/');
|
|
76
|
+
if (/\\.(html?|tsx|jsx|vue|svelte)$/i.test(norm)) return true;
|
|
77
|
+
if (/\\.(mjs|cjs|js|ts|css|scss|sass)$/i.test(norm) && /^(src|public|site|app|pages|components|client|web)\\//i.test(norm)) return true;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function recordBrowserEditLocal(cwd, filePath) {
|
|
82
|
+
try {
|
|
83
|
+
const fs = require('fs');
|
|
84
|
+
const path = require('path');
|
|
85
|
+
let rel = filePath;
|
|
86
|
+
try { rel = path.relative(cwd, filePath); } catch (_) {}
|
|
87
|
+
if (!isBrowserRunningFileLocal(rel)) return false;
|
|
88
|
+
const editsFile = path.join(cwd, '.gm', 'exec-spool', '.turn-browser-edits.json');
|
|
89
|
+
fs.mkdirSync(path.dirname(editsFile), { recursive: true });
|
|
90
|
+
let list = [];
|
|
91
|
+
try { list = JSON.parse(fs.readFileSync(editsFile, 'utf8')); if (!Array.isArray(list)) list = []; } catch (_) {}
|
|
92
|
+
const entry = { file: rel.replace(/\\\\/g, '/'), ts: Date.now() };
|
|
93
|
+
if (!list.some(e => e && e.file === entry.file)) list.push(entry);
|
|
94
|
+
fs.writeFileSync(editsFile, JSON.stringify(list));
|
|
95
|
+
return true;
|
|
96
|
+
} catch (_) { return false; }
|
|
97
|
+
}
|
|
98
|
+
|
|
73
99
|
let raw = '';
|
|
74
100
|
process.stdin.setEncoding('utf8');
|
|
75
101
|
process.stdin.on('data', (chunk) => { raw += chunk; });
|
|
@@ -78,6 +104,17 @@ process.stdin.on('end', () => {
|
|
|
78
104
|
try { event = JSON.parse(raw || '{}'); } catch (_) { event = {}; }
|
|
79
105
|
const tool = event.tool_name || event.tool || '';
|
|
80
106
|
const input = event.tool_input || event.input || {};
|
|
107
|
+
const cwd = event.cwd || process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
108
|
+
|
|
109
|
+
if (tool === 'Write' || tool === 'Edit' || tool === 'MultiEdit') {
|
|
110
|
+
const fp = input.file_path || input.filePath || input.path || '';
|
|
111
|
+
if (fp) {
|
|
112
|
+
try { recordBrowserEditLocal(cwd, fp); } catch (_) {}
|
|
113
|
+
}
|
|
114
|
+
process.stdout.write(JSON.stringify({ continue: true }));
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
|
|
81
118
|
if (tool !== 'Bash') {
|
|
82
119
|
process.stdout.write(JSON.stringify({ continue: true }));
|
|
83
120
|
process.exit(0);
|
|
@@ -165,15 +202,17 @@ function ensureSpoolPollGate(cwd) {
|
|
|
165
202
|
if (!settings.hooks || typeof settings.hooks !== 'object') settings.hooks = {};
|
|
166
203
|
if (!Array.isArray(settings.hooks.PreToolUse)) settings.hooks.PreToolUse = [];
|
|
167
204
|
const wantCommand = `node "\${CLAUDE_PROJECT_DIR}/.gm/hooks/spool-poll-gate.js"`;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
205
|
+
for (const matcher of ['Bash', 'Write', 'Edit', 'MultiEdit']) {
|
|
206
|
+
let entry = settings.hooks.PreToolUse.find(e => e && e.matcher === matcher);
|
|
207
|
+
if (!entry) {
|
|
208
|
+
entry = { matcher, hooks: [] };
|
|
209
|
+
settings.hooks.PreToolUse.push(entry);
|
|
210
|
+
}
|
|
211
|
+
if (!Array.isArray(entry.hooks)) entry.hooks = [];
|
|
212
|
+
const already = entry.hooks.some(h => h && typeof h.command === 'string' && h.command.includes('spool-poll-gate.js'));
|
|
213
|
+
if (!already) {
|
|
214
|
+
entry.hooks.push({ type: 'command', command: wantCommand });
|
|
215
|
+
}
|
|
177
216
|
}
|
|
178
217
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
179
218
|
} catch (_) {}
|
|
@@ -1184,7 +1223,17 @@ function makeHostFunctions(instanceRef) {
|
|
|
1184
1223
|
const opts = optsStr ? JSON.parse(optsStr) : {};
|
|
1185
1224
|
const lang = opts.lang || 'nodejs';
|
|
1186
1225
|
const cwd = opts.cwd || process.cwd();
|
|
1187
|
-
const
|
|
1226
|
+
const rawTimeout = opts.timeoutMs;
|
|
1227
|
+
if (rawTimeout === undefined || rawTimeout === null || typeof rawTimeout !== 'number' || !Number.isFinite(rawTimeout) || rawTimeout <= 0 || !Number.isInteger(rawTimeout)) {
|
|
1228
|
+
return writeWasmJson(instanceRef.value, {
|
|
1229
|
+
ok: false,
|
|
1230
|
+
error: 'missing timeoutMs',
|
|
1231
|
+
required: 'positive integer milliseconds',
|
|
1232
|
+
paper_ref: '§20',
|
|
1233
|
+
received: rawTimeout === undefined ? null : rawTimeout,
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
const timeoutMs = rawTimeout;
|
|
1188
1237
|
let cmd, args;
|
|
1189
1238
|
if (lang === 'nodejs' || lang === 'js') { cmd = process.execPath; args = ['-e', code]; }
|
|
1190
1239
|
else if (lang === 'python') { cmd = 'python'; args = ['-c', code]; }
|
|
@@ -1716,6 +1765,13 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
1716
1765
|
const sessForRecall = readCurrentSess();
|
|
1717
1766
|
if (isInstructionTurnStart(sessForRecall)) {
|
|
1718
1767
|
autoRecallPayload = tryAutoRecallForTurnEntry(instance, sessForRecall, process.cwd());
|
|
1768
|
+
try {
|
|
1769
|
+
const _spoolDir = path.join(process.cwd(), '.gm', 'exec-spool');
|
|
1770
|
+
for (const _f of ['.turn-browser-edits.json', '.turn-browser-witnessed']) {
|
|
1771
|
+
const _p = path.join(_spoolDir, _f);
|
|
1772
|
+
if (fs.existsSync(_p)) fs.unlinkSync(_p);
|
|
1773
|
+
}
|
|
1774
|
+
} catch (_) {}
|
|
1719
1775
|
}
|
|
1720
1776
|
}
|
|
1721
1777
|
|
|
@@ -1742,6 +1798,15 @@ async function runSpoolWatcher(instance, spoolDir) {
|
|
|
1742
1798
|
logEvent('plugkit', 'dispatch.end', { verb, task: taskBase, dur_ms, out_bytes: resultStr.length });
|
|
1743
1799
|
emitOrchestratorEvents(verb, taskBase, resultStr);
|
|
1744
1800
|
|
|
1801
|
+
if (verb === 'browser') {
|
|
1802
|
+
try {
|
|
1803
|
+
const witnessFile = path.join(process.cwd(), '.gm', 'exec-spool', '.turn-browser-witnessed');
|
|
1804
|
+
fs.mkdirSync(path.dirname(witnessFile), { recursive: true });
|
|
1805
|
+
fs.writeFileSync(witnessFile, JSON.stringify({ ts: Date.now(), task: taskBase, dur_ms }));
|
|
1806
|
+
logEvent('plugkit', 'browser.witness-marked', { task: taskBase });
|
|
1807
|
+
} catch (_) {}
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1745
1810
|
try { instance.exports.plugkit_free(verbPtr, verbBytes.length); } catch (_) {}
|
|
1746
1811
|
try { instance.exports.plugkit_free(bodyPtr, bodyBytes.length); } catch (_) {}
|
|
1747
1812
|
try { instance.exports.plugkit_free(ptr, len); } catch (_) {}
|
package/plugkit.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"plugkit.wasm":"
|
|
1
|
+
{"plugkit.wasm":"0ce920f00138b9524a0a1ad062dab691e4959497853644a7d06403c2b77ed480"}
|
package/plugkit.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.447
|