gm-qwen 2.0.796 → 2.0.798

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/bin/bootstrap.js CHANGED
@@ -32,6 +32,11 @@ function binaryName() {
32
32
  return key.startsWith('win32') ? `plugkit-${key}.exe` : `plugkit-${key}`;
33
33
  }
34
34
 
35
+ function rtkBinaryName() {
36
+ const key = platformKey();
37
+ return key.startsWith('win32') ? `rtk-${key}.exe` : `rtk-${key}`;
38
+ }
39
+
35
40
  function cacheRoot() {
36
41
  const home = os.homedir();
37
42
  if (process.env.PLUGKIT_CACHE_DIR) return process.env.PLUGKIT_CACHE_DIR;
@@ -58,8 +63,8 @@ function readVersionFile(wrapperDir) {
58
63
  return fs.readFileSync(p, 'utf8').trim();
59
64
  }
60
65
 
61
- function readShaManifest(wrapperDir) {
62
- const p = path.join(wrapperDir, 'plugkit.sha256');
66
+ function readShaManifest(wrapperDir, manifestName) {
67
+ const p = path.join(wrapperDir, manifestName || 'plugkit.sha256');
63
68
  if (!fs.existsSync(p)) return null;
64
69
  const out = {};
65
70
  for (const line of fs.readFileSync(p, 'utf8').split(/\r?\n/)) {
@@ -275,12 +280,63 @@ async function bootstrap(opts) {
275
280
  fs.writeFileSync(okSentinel, new Date().toISOString());
276
281
  log(`installed ${finalPath}`);
277
282
  pruneOldVersions(root, version);
283
+ // Best-effort rtk fetch: failures here never block plugkit usage
284
+ try { await bootstrapRtk(verDir, version, wrapperDir, opts.silent); }
285
+ catch (err) { log(`rtk fetch skipped: ${err.message}`); }
278
286
  return finalPath;
279
287
  } finally {
280
288
  releaseLock(lockPath);
281
289
  }
282
290
  }
283
291
 
292
+ async function bootstrapRtk(verDir, version, wrapperDir, silent) {
293
+ const rtkName = rtkBinaryName();
294
+ const rtkPath = path.join(verDir, rtkName);
295
+ const rtkOk = path.join(verDir, '.rtk-ok');
296
+ if (fs.existsSync(rtkPath) && fs.existsSync(rtkOk)) {
297
+ if (!silent) log(`rtk cache hit: ${rtkPath}`);
298
+ return rtkPath;
299
+ }
300
+ const rtkSha = readShaManifest(wrapperDir, 'rtk.sha256');
301
+ const expected = rtkSha ? rtkSha[rtkName] : null;
302
+ const tmp = `${rtkPath}.partial`;
303
+ const url = `https://github.com/${RELEASE_REPO}/releases/download/v${version}/${rtkName}`;
304
+ await downloadWithRetry(url, tmp);
305
+ if (expected) {
306
+ const got = await sha256OfFile(tmp);
307
+ if (got !== expected) {
308
+ try { fs.unlinkSync(tmp); } catch (_) {}
309
+ throw new Error(`rtk sha256 mismatch: expected ${expected}, got ${got}`);
310
+ }
311
+ }
312
+ try { fs.renameSync(tmp, rtkPath); }
313
+ catch (err) {
314
+ if (err.code === 'EEXIST' || err.code === 'EPERM') {
315
+ try { fs.unlinkSync(rtkPath); } catch (_) {}
316
+ fs.renameSync(tmp, rtkPath);
317
+ } else throw err;
318
+ }
319
+ if (os.platform() !== 'win32') { try { fs.chmodSync(rtkPath, 0o755); } catch (_) {} }
320
+ fs.writeFileSync(rtkOk, new Date().toISOString());
321
+ log(`installed ${rtkPath}`);
322
+ return rtkPath;
323
+ }
324
+
325
+ function resolveCachedRtk(opts) {
326
+ opts = opts || {};
327
+ const wrapperDir = opts.wrapperDir || __dirname;
328
+ const version = opts.version || readVersionFile(wrapperDir);
329
+ const root = (() => {
330
+ try { const r = cacheRoot(); ensureDir(r); return r; }
331
+ catch (_) { const r = fallbackCacheRoot(); ensureDir(r); return r; }
332
+ })();
333
+ const verDir = path.join(root, `v${version}`);
334
+ const rtkPath = path.join(verDir, rtkBinaryName());
335
+ const rtkOk = path.join(verDir, '.rtk-ok');
336
+ if (fs.existsSync(rtkPath) && fs.existsSync(rtkOk)) return rtkPath;
337
+ return null;
338
+ }
339
+
284
340
  function resolveCachedBinary(opts) {
285
341
  opts = opts || {};
286
342
  const wrapperDir = opts.wrapperDir || __dirname;
@@ -296,7 +352,7 @@ function resolveCachedBinary(opts) {
296
352
  return null;
297
353
  }
298
354
 
299
- module.exports = { bootstrap, resolveCachedBinary, platformKey, binaryName, cacheRoot };
355
+ module.exports = { bootstrap, resolveCachedBinary, resolveCachedRtk, platformKey, binaryName, rtkBinaryName, cacheRoot };
300
356
 
301
357
  if (require.main === module) {
302
358
  bootstrap({ silent: false })
package/bin/plugkit.js CHANGED
@@ -3,10 +3,18 @@
3
3
  const { spawn, spawnSync } = require('child_process');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
- const { bootstrap, resolveCachedBinary } = require('./bootstrap');
6
+ const { bootstrap, resolveCachedBinary, resolveCachedRtk } = require('./bootstrap');
7
7
 
8
8
  const dir = __dirname;
9
9
 
10
+ function envWithRtkOnPath() {
11
+ const rtkPath = resolveCachedRtk({ wrapperDir: dir });
12
+ if (!rtkPath) return process.env;
13
+ const rtkDir = path.dirname(rtkPath);
14
+ const sep = process.platform === 'win32' ? ';' : ':';
15
+ return { ...process.env, PATH: `${rtkDir}${sep}${process.env.PATH || ''}` };
16
+ }
17
+
10
18
  async function resolveBinary() {
11
19
  const cached = resolveCachedBinary({ wrapperDir: dir });
12
20
  if (cached) return cached;
@@ -27,18 +35,20 @@ async function main() {
27
35
  else process.exit(1);
28
36
  }
29
37
 
38
+ const env = envWithRtkOnPath();
39
+
30
40
  if (isHook && !process.stdin.isTTY) {
31
41
  const chunks = [];
32
42
  process.stdin.on('data', c => chunks.push(c));
33
43
  process.stdin.on('end', () => {
34
- const child = spawn(bin, args, { stdio: ['pipe', 'inherit', 'inherit'], windowsHide: true });
44
+ const child = spawn(bin, args, { stdio: ['pipe', 'inherit', 'inherit'], windowsHide: true, env });
35
45
  child.stdin.end(Buffer.concat(chunks));
36
46
  child.on('close', code => process.exit(code ?? 1));
37
47
  child.on('error', () => process.exit(1));
38
48
  });
39
49
  process.stdin.on('error', () => process.exit(1));
40
50
  } else {
41
- const result = spawnSync(bin, args, { stdio: 'inherit', windowsHide: true });
51
+ const result = spawnSync(bin, args, { stdio: 'inherit', windowsHide: true, env });
42
52
  process.exit(result.status ?? 1);
43
53
  }
44
54
  }
@@ -1,6 +1,6 @@
1
- 603038716d558efcac3b24e68400b4a2486a2c78e4ced414194c9fbbbbd547da plugkit-win32-x64.exe
2
- cca898364d36c545a2d1f0f26b6cc3dd2a6e31b9618637861268ec849c14ca32 plugkit-win32-arm64.exe
3
- d5c71d0db807d4ce8c1f9e90ff7eb83dbb7660302772e4c7e6c66852ceb80291 plugkit-darwin-x64
4
- afa78bbe82ee25e1c623f047a89428d3c5b6e6b8791b9f8cf938e155181accce plugkit-darwin-arm64
5
- 778e584a8eaeedf48c68aa5bbc0b44686a2932375d372d40711ec2436bb3cebe plugkit-linux-x64
6
- fde889403b76ec6a4b4672dfc77693a63253b2547a8ecec8b06b278887ceb5b0 plugkit-linux-arm64
1
+ 94dbf530ce616160fce13770fc8e6ba139895634a1787a984531f288f1e3359a plugkit-win32-x64.exe
2
+ 5ff80e5f5209e56f7b0483b7491351e620b110530fa6c091b67ad68e0c8aff62 plugkit-win32-arm64.exe
3
+ 12feecb6a02413d48862d8ce3cdf8d42249d7980e3b9037051aabcf879628e74 plugkit-darwin-x64
4
+ 7ef0cbc8dbb199c0964bc59662d8321251ea402a46417ca024e23f9df9b750a0 plugkit-darwin-arm64
5
+ 10e0e1f83e20252bc201dd681437f8b6248689e1238f3187e7cd9d6807a7a52b plugkit-linux-x64
6
+ bdd907fb31b011297e5f0658cd0746683c55469619c0c31e9730cee6ed86d50f plugkit-linux-arm64
@@ -1 +1 @@
1
- 0.1.257
1
+ 0.1.258
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.796",
3
+ "version": "2.0.798",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -23,5 +23,5 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
26
- "plugkitVersion": "0.1.257"
26
+ "plugkitVersion": "0.1.258"
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-qwen",
3
- "version": "2.0.796",
3
+ "version": "2.0.798",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -41,6 +41,8 @@ Multiple facts → parallel Agent calls in ONE message. End-of-turn: scan for un
41
41
 
42
42
  ## AUTONOMY — HARD RULE
43
43
 
44
+ **USER REQUEST = AUTHORIZATION — HARD RULE.** The user's first message asking for X *is* the approval to do X. Re-asking "want me to do X?", "should I proceed with X?", "which shape of X do you want?" after the user already said "do X" is forced closure dressed as deference — the user already authorized the work and waits while the agent stalls. The PRD is *how* the agent records the authorization, not a second permission gate; the agent writes it and proceeds. Surfacing tradeoffs is allowed *inside* the same chain (one sentence: "going with shape A because Y") so the user can interrupt — never as a stop-and-wait. The bar to legitimately ask before starting is the same bar that applies mid-chain: destructive-irreversible AND not covered by the request, OR genuinely ambiguous *intent* (not "which of two viable approaches"). Defaulting to the deeper / more thorough / cross-repo shape when the user said "deeply integrate" is the obvious read of the request — pick it and execute. Multi-repo scope, build cost, and CI duration are never grounds to re-confirm.
45
+
44
46
  A written PRD is the user's authorization. Once it exists, EXECUTE owns the work to COMPLETE. Resolve every doubt that arises during execution by witnessed probe, by recall, or by re-reading the PRD — never by asking the user. Any question whose answer the agent could obtain itself is a question the agent owes itself, not the user.
45
47
 
46
48
  **FINISH ALL REMAINING STEPS — HARD RULE**: when a request enumerates or implies multiple work items ("all", "any", "everything", "the rest", "remaining"), or after a covering family is constructed under MAXIMAL COVER, the agent finishes every witnessable item in the same turn. Stopping after one item to ask "which next?" is forbidden — the answer is *all of them*, in one chain, until `.gm/prd.yml` is empty and git is clean and pushed. Mid-chain "should I…", "want me to…", "which would you like…" prompts are forced closure; replace them with the next skill invocation.
@@ -43,6 +43,8 @@ Runs until: .gm/prd.yml empty AND git clean AND all pushes confirmed AND CI gree
43
43
 
44
44
  ## AUTONOMY — HARD RULE
45
45
 
46
+ **USER REQUEST = AUTHORIZATION.** The user's message asking for X is the green light. PLAN's job is to translate that ask into a PRD and start — not to re-confirm. "Want me to do X?", "should I take shape A or B?", "this is multi-repo work, OK to proceed?" after the user said "do X" are all forced closure. When the user surfaces a tradeoff (deep vs light, single-file vs cross-repo), pick the read that matches the obvious meaning of the request — "deeply integrate" means deep, "all platforms" means all — declare the choice in one line ("going with A because Y") and execute. Multi-repo scope, build cost, CI duration, binary-size impact, and "this will take a while" are never grounds to re-confirm. The user already knows; that's why they asked.
47
+
46
48
  PRD written → execute to COMPLETE without asking the user. Doubts that arise during execution are resolved by witnessed probe, by recall, or by re-reading the PRD — never by asking. Any question whose answer is reachable from the agent's tools belongs to the agent, not the user.
47
49
 
48
50
  Asking is last-resort: destructive-irreversible without PRD coverage, OR user intent irrecoverable from PRD/memory/code/web. Channel: `exec:pause` (renames `prd.yml` → `prd.paused.yml`; question in header). In-conversation asking is last-resort beneath last-resort.