gm-skill 2.0.1519 → 2.0.1520

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-plugkit",
3
- "version": "2.0.1519",
3
+ "version": "2.0.1520",
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": {
@@ -807,6 +807,49 @@ function cleanDeadProfileFragments(cwd) {
807
807
  }
808
808
  }
809
809
 
810
+ function parsePlaywriterSessionList(stdout) {
811
+ const rows = [];
812
+ if (!stdout) return rows;
813
+ const lines = stdout.split(/\r?\n/);
814
+ for (const line of lines) {
815
+ const m = line.match(/^\s*(\d+)\s+\S+\s+\S+\s+\S+\s+(\S+)/);
816
+ if (!m) continue;
817
+ const id = m[1];
818
+ let cwd = m[2];
819
+ if (cwd === '-') cwd = '';
820
+ rows.push({ id, cwd });
821
+ }
822
+ return rows;
823
+ }
824
+
825
+ function reapOrphanBrowserSessions(pw, cwd, claudeSessionId, reason) {
826
+ try {
827
+ const ports = readJsonFile(browserPortsFile(cwd), {});
828
+ const activeIds = new Set();
829
+ for (const ent of Object.values(ports)) {
830
+ if (ent && ent.pwSessionId) activeIds.add(String(ent.pwSessionId));
831
+ }
832
+ const r = runBrowserRunner(pw, ['session', 'list'], 15000, cwd, claudeSessionId);
833
+ if (!r || r.status !== 0) return { reaped: 0 };
834
+ const rows = parsePlaywriterSessionList(r.stdout || '');
835
+ const norm = (p) => String(p || '').replace(/[\\/]+$/, '').toLowerCase();
836
+ const wantCwd = norm(cwd);
837
+ let reaped = 0;
838
+ for (const { id, cwd: rowCwd } of rows) {
839
+ if (rowCwd && norm(rowCwd) !== wantCwd) continue;
840
+ if (activeIds.has(String(id))) continue;
841
+ const d = runBrowserRunner(pw, ['session', 'delete', id], 15000, cwd, claudeSessionId);
842
+ if (d && d.status === 0) {
843
+ reaped++;
844
+ try { logEvent('plugkit', 'browser.orphan-session-reaped', { session_id: id, reason: reason || 'boot', cwd }); } catch (_) {}
845
+ }
846
+ }
847
+ return { reaped };
848
+ } catch (_) {
849
+ return { reaped: 0 };
850
+ }
851
+ }
852
+
810
853
  function resolveWindowsExeLocal(cmd) {
811
854
  if (process.platform !== 'win32') return cmd;
812
855
  try {
@@ -1137,6 +1180,7 @@ function getOrCreateBrowserSession(cwd, claudeSessionId, pw) {
1137
1180
  }
1138
1181
  }
1139
1182
  cleanDeadProfileFragments(cwd);
1183
+ reapOrphanBrowserSessions(pw, cwd, claudeSessionId, 'pre-spawn');
1140
1184
  const profileDir = acquireProfileDir(cwd, claudeSessionId);
1141
1185
  const aliveCdpForProfile = (() => {
1142
1186
  for (const key of Object.keys(ports)) {
@@ -2085,6 +2129,8 @@ async function runSpoolWatcher(instance, spoolDir) {
2085
2129
  fs.writeFileSync(path.join(gmDir, 'long-gap-retry-state'), '');
2086
2130
  } catch (_) {}
2087
2131
 
2132
+ try { reapOrphanBrowserSessions(findBrowserRunner(), process.cwd(), process.env.CLAUDE_SESSION_ID || 'claude-loop-iter', 'watcher-boot'); } catch (_) {}
2133
+
2088
2134
 
2089
2135
  const LOCK_PATH = path.join(spoolDir, '.watcher.lock');
2090
2136
  try {
@@ -2722,6 +2768,7 @@ async function runSpoolWatcher(instance, spoolDir) {
2722
2768
  try { writeJsonFile(portsFile, ports); } catch (_) {}
2723
2769
  try { writeJsonFile(sessionsFile, sessions); } catch (_) {}
2724
2770
  }
2771
+ try { reapOrphanBrowserSessions(findBrowserRunner(), process.cwd(), process.env.CLAUDE_SESSION_ID || 'claude-loop-iter', 'idle-sweep'); } catch (_) {}
2725
2772
  } catch (e) {
2726
2773
  console.error(`[browser-idle] error: ${e.message}`);
2727
2774
  }
package/gm.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm",
3
- "version": "2.0.1519",
3
+ "version": "2.0.1520",
4
4
  "description": "Spool-dispatch orchestration engine with unified state machine, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-skill",
3
- "version": "2.0.1519",
3
+ "version": "2.0.1520",
4
4
  "description": "Canonical universal harness — AI-native software engineering via skill-driven orchestration; bootstraps plugkit for task execution and session isolation. Install in any AI coding agent host.",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",