instar 1.3.641 → 1.3.643

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.
Files changed (54) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +160 -6
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +29 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/InFlightSyncOpMarker.d.ts +29 -0
  8. package/dist/core/InFlightSyncOpMarker.d.ts.map +1 -0
  9. package/dist/core/InFlightSyncOpMarker.js +149 -0
  10. package/dist/core/InFlightSyncOpMarker.js.map +1 -0
  11. package/dist/core/PostUpdateMigrator.d.ts +16 -0
  12. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  13. package/dist/core/PostUpdateMigrator.js +91 -0
  14. package/dist/core/PostUpdateMigrator.js.map +1 -1
  15. package/dist/core/SessionManager.d.ts +146 -1
  16. package/dist/core/SessionManager.d.ts.map +1 -1
  17. package/dist/core/SessionManager.js +498 -144
  18. package/dist/core/SessionManager.js.map +1 -1
  19. package/dist/core/SleepWakeDetector.d.ts +33 -0
  20. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  21. package/dist/core/SleepWakeDetector.js +53 -0
  22. package/dist/core/SleepWakeDetector.js.map +1 -1
  23. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  24. package/dist/core/devGatedFeatures.js +23 -0
  25. package/dist/core/devGatedFeatures.js.map +1 -1
  26. package/dist/core/types.d.ts +52 -0
  27. package/dist/core/types.d.ts.map +1 -1
  28. package/dist/core/types.js.map +1 -1
  29. package/dist/lifeline/ServerSupervisor.d.ts +42 -0
  30. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  31. package/dist/lifeline/ServerSupervisor.js +79 -4
  32. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  33. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  34. package/dist/lifeline/TelegramLifeline.js +8 -0
  35. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  36. package/dist/monitoring/DegradedTmuxGuard.d.ts +161 -0
  37. package/dist/monitoring/DegradedTmuxGuard.d.ts.map +1 -0
  38. package/dist/monitoring/DegradedTmuxGuard.js +277 -0
  39. package/dist/monitoring/DegradedTmuxGuard.js.map +1 -0
  40. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  41. package/dist/monitoring/guardManifest.js +18 -0
  42. package/dist/monitoring/guardManifest.js.map +1 -1
  43. package/dist/server/routes.d.ts.map +1 -1
  44. package/dist/server/routes.js +13 -5
  45. package/dist/server/routes.js.map +1 -1
  46. package/package.json +2 -2
  47. package/scripts/lint-no-direct-destructive.js +14 -0
  48. package/scripts/lint-sync-subprocess-chokepoint.js +208 -0
  49. package/scripts/sync-subprocess-chokepoint-baseline.json +148 -0
  50. package/src/data/builtin-manifest.json +65 -65
  51. package/upgrades/1.3.642.md +46 -0
  52. package/upgrades/1.3.643.md +66 -0
  53. package/upgrades/side-effects/false-excuse-deferral-stop-guard.md +75 -0
  54. package/upgrades/side-effects/tmux-event-loop-resilience.md +86 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.641",
3
+ "version": "1.3.643",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "test:contract": "node scripts/run-contract-tests.js",
29
29
  "test:contract:raw": "vitest run --config vitest.contract.config.ts",
30
30
  "test:all": "vitest run && vitest run --config vitest.integration.config.ts && vitest run --config vitest.e2e.config.ts",
31
- "lint": "tsc --noEmit && node scripts/lint-no-direct-destructive.js && node scripts/lint-no-direct-llm-http.js && node scripts/lint-no-direct-url-log.js && node scripts/lint-no-unfunneled-topic-creation.js && node scripts/lint-no-unfunneled-headless-launch.js && node scripts/lint-no-unfunneled-credential-write.js && node scripts/lint-state-registry.js && node scripts/lint-store-retention-declared.js && node scripts/lint-no-wholefile-sync-read.js && node scripts/lint-cas-emit-placement.js && node scripts/lint-journal-actuation-ban.js && node scripts/lint-no-blocking-process-scans.js && node scripts/lint-dev-agent-dark-gate.js && node scripts/lint-guard-manifest.js && node scripts/lint-llm-attribution.js && node scripts/lint-no-mainthread-cartographer-walk.js && node scripts/lint-scrape-fixture-realness.js && node scripts/check-codex-rule1-drift.js",
31
+ "lint": "tsc --noEmit && node scripts/lint-no-direct-destructive.js && node scripts/lint-no-direct-llm-http.js && node scripts/lint-no-direct-url-log.js && node scripts/lint-no-unfunneled-topic-creation.js && node scripts/lint-no-unfunneled-headless-launch.js && node scripts/lint-no-unfunneled-credential-write.js && node scripts/lint-state-registry.js && node scripts/lint-store-retention-declared.js && node scripts/lint-no-wholefile-sync-read.js && node scripts/lint-cas-emit-placement.js && node scripts/lint-journal-actuation-ban.js && node scripts/lint-no-blocking-process-scans.js && node scripts/lint-sync-subprocess-chokepoint.js && node scripts/lint-dev-agent-dark-gate.js && node scripts/lint-guard-manifest.js && node scripts/lint-llm-attribution.js && node scripts/lint-no-mainthread-cartographer-walk.js && node scripts/lint-scrape-fixture-realness.js && node scripts/check-codex-rule1-drift.js",
32
32
  "lint:destructive": "node scripts/lint-no-direct-destructive.js",
33
33
  "lint:dev-agent-dark-gate": "node scripts/lint-dev-agent-dark-gate.js",
34
34
  "lint:guard-manifest": "node scripts/lint-guard-manifest.js",
@@ -61,6 +61,15 @@ const ALLOWLIST = new Set([
61
61
  'src/core/SafeFsExecutor.ts',
62
62
  'tests/unit/SafeGitExecutor.test.ts',
63
63
  'tests/unit/SafeFsExecutor.test.ts',
64
+ // tmux-event-loop-resilience Increment 1 tests: per-test cleanup of
65
+ // mkdtempSync dirs under os.tmpdir() (the cross-process marker round-trip
66
+ // needs a real on-disk mirror dir; the e2e needs a throwaway stateDir). The
67
+ // targets are os.tmpdir paths, never the source tree. Routing through
68
+ // SafeFsExecutor.safeRmSync would write an audit entry per teardown call —
69
+ // worse noise than a scoped allowlist entry for a test's own tmpdir cleanup.
70
+ // (Spec: docs/specs/tmux-event-loop-resilience.md, Step 8.)
71
+ 'tests/unit/InFlightSyncOpMarker.test.ts',
72
+ 'tests/e2e/tmux-resilience-lifecycle.test.ts',
64
73
  // The lint rule itself runs before SafeGitExecutor.ts is compiled, so it
65
74
  // needs direct execSync as a bootstrap escape. The single git call here is
66
75
  // a read-only `git diff --cached --name-only` for staged-file detection.
@@ -96,6 +105,11 @@ const ALLOWLIST = new Set([
96
105
  // instar#1069) — read-only `git diff --cached --name-only` for --staged.
97
106
  // Cannot depend on the TS funnel because TS is not compiled at pre-push.
98
107
  'scripts/lint-no-mainthread-cartographer-walk.js',
108
+ // Same bootstrap-escape pattern (tmux sync-subprocess chokepoint lint,
109
+ // docs/specs/tmux-event-loop-resilience.md) — a read-only `git ls-files` /
110
+ // `git diff --cached --name-only` for staged-file detection. Cannot depend on
111
+ // the TS funnel because TS is not compiled when the lint runs in pre-push.
112
+ 'scripts/lint-sync-subprocess-chokepoint.js',
99
113
  // Postinstall bootstrap script — runs before TypeScript is compiled and
100
114
  // before SafeFsExecutor is available. CommonJS, can't use ESM imports.
101
115
  'scripts/fix-better-sqlite3.cjs',
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lint-sync-subprocess-chokepoint.js — tmux Event-Loop Resilience, Increment 1.
4
+ *
5
+ * A SYNCHRONOUS subprocess spawn (`spawnSync` / `execSync` / `execFileSync`) blocks
6
+ * the single-threaded Node event loop for the FULL duration of the child process. A
7
+ * slow/wedged tmux (or any slow sync spawn) on the runtime hot path is exactly the
8
+ * ~0-CPU I/O-wait block this increment exists to make survivable: the marker module
9
+ * (src/core/InFlightSyncOpMarker.ts) is the SOLE funnel through which a sync blocking
10
+ * op may run — `withSyncOp(() => execFileSync(...))` records depth so SleepWakeDetector
11
+ * + ServerSupervisor can tell the block apart from a real sleep instead of mis-reaping
12
+ * the session or restarting a live-but-blocked server.
13
+ *
14
+ * Rule: in src/core/, src/monitoring/, and src/server/, no RAW synchronous child-process
15
+ * spawn (`spawnSync` / `execSync` / `execFileSync`) outside the chokepoint module. A
16
+ * raw sync spawn must EITHER funnel through `withSyncOp` (so the (B) marker sees it) OR,
17
+ * if it is a genuinely pre-runtime / CLI-boot call that can never run on a cadence,
18
+ * carry an inline justification comment on the same line or the line directly above:
19
+ * // lint-allow-sync-spawn: <why this never blocks the runtime event loop>
20
+ *
21
+ * This lint bans the RAW spawn outside the funnel — NOT sync-ness itself: the marker
22
+ * module legitimately WRAPS sync calls, and the D1-excluded injection-sequence callsites
23
+ * (send-keys + /bin/sleep, where synchronous timing IS the correctness mechanism) stay
24
+ * sync but funnel through `withSyncOp`. So this lint is satisfied when a sync spawn is
25
+ * funneled, allow-commented, or grandfathered in the FROZEN baseline.
26
+ *
27
+ * COVERAGE HONESTY (No Silent Degradation): a static line-regex, NOT complete — it cannot
28
+ * prove a flagged line is actually WRAPPED by withSyncOp at runtime (that is the (B) unit
29
+ * tests' job). It is the cheap FORWARD ratchet that stops a NEW raw sync spawn from being
30
+ * introduced outside the funnel. The 40+ existing SessionManager callsites are
31
+ * grandfathered by the baseline so this increment's conversion can land incrementally.
32
+ *
33
+ * Ships baseline-grandfathered: a FROZEN baseline records today's literal hits; a NEW hit
34
+ * (not in the baseline, not funneled, not allow-commented) FAILS. The baseline may only
35
+ * shrink. Exit codes: 0 — clean; 1 — at least one new violation.
36
+ *
37
+ * Usage:
38
+ * node scripts/lint-sync-subprocess-chokepoint.js # full scan dirs
39
+ * node scripts/lint-sync-subprocess-chokepoint.js --staged # staged files
40
+ * node scripts/lint-sync-subprocess-chokepoint.js path/to/file.ts # explicit files
41
+ * node scripts/lint-sync-subprocess-chokepoint.js --write-baseline # (re)generate baseline
42
+ * node scripts/lint-sync-subprocess-chokepoint.js --baseline <p> --root <p> # test overrides
43
+ */
44
+ import fs from 'node:fs';
45
+ import path from 'node:path';
46
+ import { execSync } from 'node:child_process';
47
+ import { fileURLToPath } from 'node:url';
48
+
49
+ const __filename = fileURLToPath(import.meta.url);
50
+ const ROOT = path.resolve(path.dirname(__filename), '..');
51
+
52
+ function argVal(flag) {
53
+ const i = process.argv.indexOf(flag);
54
+ return i >= 0 && process.argv[i + 1] ? process.argv[i + 1] : null;
55
+ }
56
+
57
+ const BASELINE = path.resolve(
58
+ argVal('--baseline') || path.join(ROOT, 'scripts', 'sync-subprocess-chokepoint-baseline.json'),
59
+ );
60
+ // --root overrides the repo root the SCAN_DIRS are resolved against (tests / alternate checkouts).
61
+ const SCAN_BASE = path.resolve(argVal('--root') || ROOT);
62
+ const SCAN_DIRS = ['src/core', 'src/monitoring', 'src/server'];
63
+ const EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.mjs', '.cjs']);
64
+
65
+ // The chokepoint module itself — the SOLE place a raw sync spawn may legitimately live
66
+ // (it WRAPS the call in withSyncOp; everything else must route through it).
67
+ const CHOKEPOINT = 'src/core/InFlightSyncOpMarker.ts';
68
+
69
+ // A BARE synchronous child-process spawn imported from node:child_process. The
70
+ // negative lookbehind `(?<![.\w])` rejects a member-access form (`SafeGitExecutor.execSync(`,
71
+ // `SafeFsExecutor.execFileSync(`) — those are the SAFE funnels, not a raw event-loop block —
72
+ // and a longer identifier (`myExecSync`). `\s*\(` so only an actual call matches, never an
73
+ // import name. The *Async variants (execFileAsync / execFile) never match (different verb).
74
+ const VIOLATION = /(?<![.\w])(spawnSync|execSync|execFileSync)\s*\(/;
75
+ const ALLOW = /lint-allow-sync-spawn:/;
76
+ // The FUNNEL: a sync spawn lexically wrapped by withSyncOp(...) on the same line is the
77
+ // REQUIRED pattern (the (B) marker sees it) — never a violation, regardless of baseline.
78
+ const FUNNELED = /\bwithSyncOp\s*\(/;
79
+
80
+ const inScanDir = (p) => SCAN_DIRS.some((d) => p === d || p.startsWith(d + '/'));
81
+ const normalize = (p) => p.split(path.sep).join('/');
82
+
83
+ function listFiles() {
84
+ if (process.argv.includes('--staged')) {
85
+ const out = execSync('git diff --cached --name-only', { cwd: ROOT, encoding: 'utf-8' });
86
+ return out
87
+ .split('\n')
88
+ .filter(Boolean)
89
+ .map(normalize)
90
+ .filter((p) => inScanDir(p));
91
+ }
92
+ // Explicit file args are checked as-given (targeted use / self-tests).
93
+ const explicit = process.argv
94
+ .slice(2)
95
+ .filter((a) => !a.startsWith('--'))
96
+ // Drop the values consumed by --baseline / --root.
97
+ .filter((a) => a !== argVal('--baseline') && a !== argVal('--root'));
98
+ if (explicit.length) return explicit;
99
+
100
+ const files = [];
101
+ const walk = (dir) => {
102
+ let entries;
103
+ try {
104
+ entries = fs.readdirSync(dir, { withFileTypes: true });
105
+ } catch {
106
+ return;
107
+ }
108
+ for (const e of entries) {
109
+ if (e.name === 'node_modules' || e.name === '.git' || e.name === 'dist') continue;
110
+ const full = path.join(dir, e.name);
111
+ if (e.isDirectory()) walk(full);
112
+ else if (EXTENSIONS.has(path.extname(e.name))) files.push(full);
113
+ }
114
+ };
115
+ for (const d of SCAN_DIRS) walk(path.join(SCAN_BASE, d));
116
+ return files;
117
+ }
118
+
119
+ // Collect every raw sync-spawn hit not allow-commented and not in the chokepoint module.
120
+ // Keyed on file + the trimmed call line + the occurrence index of that exact line text
121
+ // within the file (line-number-independent so the baseline survives edits above it).
122
+ function collectHits() {
123
+ const hits = [];
124
+ for (const fileArg of listFiles()) {
125
+ const abs = path.isAbsolute(fileArg) ? fileArg : path.join(ROOT, fileArg);
126
+ const rel = normalize(path.relative(ROOT, abs));
127
+ if (!EXTENSIONS.has(path.extname(rel))) continue;
128
+ if (rel === CHOKEPOINT) continue; // the funnel may wrap sync calls
129
+ let content;
130
+ try {
131
+ content = fs.readFileSync(abs, 'utf-8');
132
+ } catch {
133
+ continue;
134
+ }
135
+ const lines = content.split('\n');
136
+ const seenLineText = new Map(); // trimmed-line-text → occurrence count so far
137
+ for (let i = 0; i < lines.length; i++) {
138
+ const raw = lines[i];
139
+ const trimmed = raw.trimStart();
140
+ if (/^(\/\/|\*|\/\*)/.test(trimmed)) continue; // comment-only mention
141
+ if (!VIOLATION.test(raw)) continue;
142
+ // FUNNELED: a sync spawn wrapped by withSyncOp(...) on the same line is the required
143
+ // pattern (the marker sees it) — allowed unconditionally, never grandfathered/baselined.
144
+ if (FUNNELED.test(raw)) continue;
145
+ // Inline justification on this line or within the 6 lines directly above.
146
+ let allowed = false;
147
+ for (let j = i; j >= Math.max(0, i - 6); j--) {
148
+ if (ALLOW.test(lines[j])) {
149
+ allowed = true;
150
+ break;
151
+ }
152
+ }
153
+ if (allowed) continue;
154
+ const text = raw.trim();
155
+ const occ = seenLineText.get(text) ?? 0;
156
+ seenLineText.set(text, occ + 1);
157
+ hits.push({ file: rel, line: i + 1, text, key: `${rel}::${text}::${occ}` });
158
+ }
159
+ }
160
+ return hits;
161
+ }
162
+
163
+ const hits = collectHits();
164
+
165
+ // Generate-baseline mode: record current hits as grandfathered.
166
+ if (process.argv.includes('--write-baseline')) {
167
+ fs.writeFileSync(
168
+ BASELINE,
169
+ JSON.stringify(
170
+ {
171
+ note:
172
+ 'FROZEN baseline of RAW synchronous subprocess spawns (spawnSync/execSync/execFileSync) outside the InFlightSyncOpMarker funnel, at tmux Event-Loop Resilience Increment 1. These are grandfathered while the (A)/(B) conversion lands incrementally. May only SHRINK — a NEW raw sync spawn outside the funnel fails the lint. Funnel a call through withSyncOp(), or add an inline "// lint-allow-sync-spawn: <reason>" for a genuine pre-runtime/CLI-boot call.',
173
+ frozenAt: '2026-06-22',
174
+ keys: hits.map((h) => h.key).sort(),
175
+ },
176
+ null,
177
+ 2,
178
+ ) + '\n',
179
+ );
180
+ console.log(`lint-sync-subprocess-chokepoint: wrote baseline with ${hits.length} grandfathered hit(s).`);
181
+ process.exit(0);
182
+ }
183
+
184
+ let baseline = { keys: [] };
185
+ try {
186
+ baseline = JSON.parse(fs.readFileSync(BASELINE, 'utf8'));
187
+ } catch {
188
+ // No baseline yet → treat as empty (every current hit is a NEW violation).
189
+ }
190
+ const baselineSet = new Set(baseline.keys || []);
191
+
192
+ const newViolations = hits.filter((h) => !baselineSet.has(h.key));
193
+ if (newViolations.length) {
194
+ console.error('lint-sync-subprocess-chokepoint: FAIL — new RAW synchronous subprocess spawn(s) outside the InFlightSyncOpMarker funnel:');
195
+ for (const v of newViolations) {
196
+ console.error(
197
+ ` • ${v.file}:${v.line} — raw sync spawn (${v.text}). A sync blocking op must funnel through ` +
198
+ `withSyncOp() so the in-flight marker sees it (or add "// lint-allow-sync-spawn: <reason>" for a genuine ` +
199
+ `pre-runtime/CLI-boot call). See docs/specs/tmux-event-loop-resilience-spec.md.`,
200
+ );
201
+ }
202
+ console.error(`\nlint-sync-subprocess-chokepoint: ${newViolations.length} new violation(s).`);
203
+ process.exit(1);
204
+ }
205
+ console.log(
206
+ `lint-sync-subprocess-chokepoint: clean — ${hits.length} raw sync spawn(s), all grandfathered (${baselineSet.size} baselined).`,
207
+ );
208
+ process.exit(0);
@@ -0,0 +1,148 @@
1
+ {
2
+ "note": "FROZEN baseline of RAW synchronous subprocess spawns (spawnSync/execSync/execFileSync) outside the InFlightSyncOpMarker funnel, at tmux Event-Loop Resilience Increment 1. These are grandfathered while the (A)/(B) conversion lands incrementally. May only SHRINK — a NEW raw sync spawn outside the funnel fails the lint. Funnel a call through withSyncOp(), or add an inline \"// lint-allow-sync-spawn: <reason>\" for a genuine pre-runtime/CLI-boot call.",
3
+ "frozenAt": "2026-06-22",
4
+ "keys": [
5
+ "src/core/AgentRegistry.ts::execSync(`lsof -iTCP:${port} -sTCP:LISTEN -P -n`, { stdio: 'ignore' });::0",
6
+ "src/core/AgentWorktreeDetector.ts::output = execFileSync('git', ['-C', opts.instarRepo, 'worktree', 'list', '--porcelain'], {::0",
7
+ "src/core/BitwardenProvider.ts::const created = execFileSync(bw, [::0",
8
+ "src/core/BitwardenProvider.ts::const existingJson = execFileSync(bw, [::0",
9
+ "src/core/BitwardenProvider.ts::const output = execFileSync(bw, ['status', '--raw'], {::0",
10
+ "src/core/BitwardenProvider.ts::const output = execFileSync(bw, [::0",
11
+ "src/core/BitwardenProvider.ts::const output = execFileSync(bw, [::1",
12
+ "src/core/BitwardenProvider.ts::const output = execFileSync(bw, [::2",
13
+ "src/core/BitwardenProvider.ts::const output = execFileSync(bw, [::3",
14
+ "src/core/BitwardenProvider.ts::const result = execFileSync('which', ['bw'], {::0",
15
+ "src/core/BitwardenProvider.ts::const session = execFileSync(bw, ['login', email, masterPassword, '--raw'], {::0",
16
+ "src/core/BitwardenProvider.ts::const session = execFileSync(bw, ['unlock', masterPassword, '--raw'], {::0",
17
+ "src/core/BitwardenProvider.ts::execFileSync(bw, ['list', 'folders', '--raw'], {::0",
18
+ "src/core/BitwardenProvider.ts::execFileSync(bw, [::0",
19
+ "src/core/BitwardenProvider.ts::execFileSync(bw, [::1",
20
+ "src/core/BitwardenProvider.ts::execFileSync(bw, [::2",
21
+ "src/core/CaffeinateManager.ts::const result = spawnSync('pgrep', ['-x', 'caffeinate'], {::0",
22
+ "src/core/Config.ts::const asdfResult = execFileSync(asdfBin, ['which', name], {::0",
23
+ "src/core/Config.ts::const npmPrefix = execFileSync('npm', ['config', 'get', 'prefix'], {::0",
24
+ "src/core/Config.ts::const result = execFileSync('which', ['gh'], { encoding: 'utf-8', stdio: 'pipe' }).trim();::0",
25
+ "src/core/Config.ts::const result = execFileSync('which', ['git'], { encoding: 'utf-8', stdio: 'pipe' }).trim();::0",
26
+ "src/core/Config.ts::const result = execFileSync('which', ['tmux'], { encoding: 'utf-8', stdio: 'pipe' }).trim();::0",
27
+ "src/core/Config.ts::const result = execFileSync('which', [name], {::0",
28
+ "src/core/FileClassifier.ts::execFileSync(bin, args, {::0",
29
+ "src/core/GitSync.ts::execFileSync('sh', ['-c', validationConfig.buildCommand], {::0",
30
+ "src/core/GitSync.ts::execFileSync('sh', ['-c', validationConfig.testCommand], {::0",
31
+ "src/core/GlobalInstallCleanup.ts::execFileSync('asdf', ['reshim', 'nodejs'], {::0",
32
+ "src/core/InstarWorktreeManager.ts::execFileSync('npm', ['run', 'prepare'], {::0",
33
+ "src/core/OAuthRefresher.ts::const raw = execFileSync(::0",
34
+ "src/core/OAuthRefresher.ts::execFileSync(::0",
35
+ "src/core/PostUpdateMigrator.ts::execFileSync('plutil', ['-lint', plistPath], { stdio: 'pipe' });::0",
36
+ "src/core/PostUpdateMigrator.ts::try { execFileSync('launchctl', ['bootout', `gui/${uid}`, plistPath], { stdio: 'ignore' }); } catch { /* not loaded */ }::0",
37
+ "src/core/PostUpdateMigrator.ts::try { execFileSync('launchctl', ['bootstrap', `gui/${uid}`, plistPath], { stdio: 'ignore' }); } catch { /* non-fatal */ }::0",
38
+ "src/core/Prerequisites.ts::const output = execFileSync(claudePath, ['--version'], {::0",
39
+ "src/core/Prerequisites.ts::const output = execFileSync(tmuxPath, ['-V'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();::0",
40
+ "src/core/Prerequisites.ts::execFileSync('/bin/bash', [::0",
41
+ "src/core/Prerequisites.ts::execFileSync('which', ['brew'], { encoding: 'utf-8', stdio: 'pipe' });::0",
42
+ "src/core/Prerequisites.ts::execFileSync(cmd, args, {::0",
43
+ "src/core/SafeGitExecutor.ts::_cachedConfigIdentity.email = execFileSync('git', ['config', '--global', 'user.email'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim() || undefined;::0",
44
+ "src/core/SafeGitExecutor.ts::_cachedConfigIdentity.name = execFileSync('git', ['config', '--global', 'user.name'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim() || undefined;::0",
45
+ "src/core/SafeGitExecutor.ts::static execSync(args: readonly string[], opts: SafeGitOptions): string {::0",
46
+ "src/core/SafeGitExecutor.ts::stdout = execFileSync('git', args as string[], {::0",
47
+ "src/core/SafeGitExecutor.ts::stdout = execFileSync('git', args as string[], {::1",
48
+ "src/core/SecretStore.ts::const result = execFileSync('secret-tool', [::0",
49
+ "src/core/SecretStore.ts::const result = execFileSync('security', [::0",
50
+ "src/core/SecretStore.ts::execFileSync('secret-tool', [::0",
51
+ "src/core/SecretStore.ts::execFileSync('security', [::0",
52
+ "src/core/SecretStore.ts::execFileSync('security', [::1",
53
+ "src/core/SessionManager.ts::const out = execFileSync(::0",
54
+ "src/core/SessionManager.ts::const out = execFileSync(::1",
55
+ "src/core/SessionManager.ts::const paneInfo = execFileSync(::0",
56
+ "src/core/SessionManager.ts::const panePid = execFileSync(::0",
57
+ "src/core/SessionManager.ts::const panePid = execFileSync(::1",
58
+ "src/core/SessionManager.ts::const panePid = execFileSync(::2",
59
+ "src/core/SessionManager.ts::const psOutput = execFileSync(::0",
60
+ "src/core/SessionManager.ts::const psOutput = execFileSync(::1",
61
+ "src/core/SessionManager.ts::execFileSync('/bin/sleep', [postPasteDelaySec], { timeout: 4000 });::0",
62
+ "src/core/SessionManager.ts::execFileSync(::0",
63
+ "src/core/SessionManager.ts::execFileSync(::1",
64
+ "src/core/SessionManager.ts::execFileSync(::2",
65
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['has-session', '-t', `=${name}`], {::0",
66
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['kill-session', '-t', `=${session.tmuxSession}`], {::0",
67
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['kill-session', '-t', `=${session.tmuxSession}`], {::1",
68
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['kill-session', '-t', tmuxSession], { encoding: 'utf-8' });::0",
69
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', `=${tmuxSession}:`, 'Down'], {::0",
70
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', `=${tmuxSession}:`, 'Enter'], {::0",
71
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, '-l', text], {::0",
72
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, '-l', text], {::1",
73
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, 'Enter'], {::0",
74
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, 'Enter'], {::1",
75
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, '\\x1b[200~'], {::0",
76
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, ['send-keys', '-t', exactTarget, '\\x1b[201~'], {::0",
77
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::0",
78
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::1",
79
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::2",
80
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::3",
81
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::4",
82
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, [::5",
83
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, tmuxArgs, { encoding: 'utf-8' });::0",
84
+ "src/core/SessionManager.ts::execFileSync(this.config.tmuxPath, tmuxArgs, { encoding: 'utf-8' });::1",
85
+ "src/core/SessionManager.ts::execFileSync(tmuxPath, ['send-keys', '-t', target, 'C-m'], { encoding: 'utf-8', timeout: 5000 });::0",
86
+ "src/core/SessionManager.ts::execFileSync(tmuxPath, ['send-keys', '-t', target, 'Enter'], { encoding: 'utf-8', timeout: 5000 });::0",
87
+ "src/core/SessionManager.ts::execFileSync(tmuxPath, ['send-keys', '-t', target, 'Enter'], { encoding: 'utf-8', timeout: 5000 });::1",
88
+ "src/core/SessionManager.ts::execFileSync(tmuxPath, ['send-keys', '-t', target, 'Enter'], { encoding: 'utf-8', timeout: 5000 });::2",
89
+ "src/core/SessionManager.ts::return execFileSync(::0",
90
+ "src/core/SessionManager.ts::try { execFileSync('/bin/sleep', ['0.15'], { timeout: 1000 }); } catch { /* @silent-fallback-ok — sleep is best-effort */ }::0",
91
+ "src/core/SessionManager.ts::try { execFileSync('/bin/sleep', ['0.3'], { timeout: 2000 }); } catch { /* ignore */ }::0",
92
+ "src/core/SessionManager.ts::try { execFileSync('/bin/sleep', ['0.3'], { timeout: 2000 }); } catch { /* ignore */ }::1",
93
+ "src/core/SessionManager.ts::try { execFileSync('/bin/sleep', ['0.3'], { timeout: 2000 }); } catch { /* ignore */ }::2",
94
+ "src/core/TopicResumeMap.ts::const hasSession = spawnSync(this.tmuxPath, ['has-session', '-t', `=${info.sessionName}`]);::0",
95
+ "src/core/UpdateChecker.ts::execFileSync('xattr', ['-rd', attr, shadowDir], { stdio: 'ignore' });::0",
96
+ "src/core/UpdateChecker.ts::execFileSync(process.execPath, ['-e', `require(\"fs\").readFileSync(${JSON.stringify(newCliPath)})`], {::0",
97
+ "src/core/WorktreeKeyVault.ts::const raw = execFileSync('secret-tool', ['lookup', 'service', KEYCHAIN_SERVICE, 'account', account], {::0",
98
+ "src/core/WorktreeKeyVault.ts::const raw = execFileSync('security', [::0",
99
+ "src/core/WorktreeKeyVault.ts::execFileSync('secret-tool', ['--version'], { stdio: 'pipe', timeout: 2000 });::0",
100
+ "src/core/WorktreeKeyVault.ts::execFileSync('secret-tool', ['store', '--label', `instar:${account}`,::0",
101
+ "src/core/WorktreeKeyVault.ts::execFileSync('security', ['delete-generic-password', '-s', KEYCHAIN_SERVICE, '-a', account], {::0",
102
+ "src/core/WorktreeKeyVault.ts::execFileSync('security', ['list-keychains', '-d', 'user'], { stdio: 'pipe', timeout: 2000 });::0",
103
+ "src/core/WorktreeKeyVault.ts::execFileSync('security', [::0",
104
+ "src/core/WorktreeManager.ts::execFileSync('cp', ['-R', '--reflink=auto', mainNodeModules, wtNodeModules], { timeout: 60_000 });::0",
105
+ "src/core/WorktreeManager.ts::execFileSync('cp', ['-R', mainNodeModules, wtNodeModules], { timeout: 600_000 });::0",
106
+ "src/core/WorktreeManager.ts::execFileSync('cp', ['-c', '-R', mainNodeModules, wtNodeModules], { timeout: 60_000 });::0",
107
+ "src/core/WorktreeManager.ts::return execFileSync('sysctl', ['-n', 'kern.boottime'], { encoding: 'utf-8', timeout: 2000 }).trim();::0",
108
+ "src/core/WorktreeManager.ts::return execFileSync('wmic', ['os', 'get', 'lastbootuptime'], { encoding: 'utf-8', timeout: 2000 }).trim();::0",
109
+ "src/core/WorktreeManager.ts::try { execFileSync('zstd', ['--version'], { stdio: 'pipe' }); return true; }::0",
110
+ "src/core/accountFollowMeCooperativeWipe.ts::execFileSync('security', ['delete-generic-password', '-s', service], {::0",
111
+ "src/core/accountFollowMeCooperativeWipe.ts::execFileSync(spec.cmd, spec.args, {::0",
112
+ "src/core/codexCapabilities.ts::const help = execFileSync(binaryPath, ['--help'], {::0",
113
+ "src/core/codexHookArm.ts::const tmux = (args: string[]) => execFileSync(deps.tmuxPath, args, { encoding: 'utf-8', timeout: 10_000 });::0",
114
+ "src/core/codexHookArm.ts::execFileSync('sleep', ['1']);::0",
115
+ "src/core/codexHookArm.ts::execFileSync('sleep', ['2']);::0",
116
+ "src/core/codexHookArm.ts::execFileSync('sleep', ['2']);::1",
117
+ "src/core/codexHookArm.ts::execFileSync('sleep', ['3']);::0",
118
+ "src/monitoring/CiFailurePoller.ts::((args) => execFileSync('gh', args, { encoding: 'utf-8', timeout: 15000, stdio: ['pipe', 'pipe', 'pipe'] }));::0",
119
+ "src/monitoring/CredentialProvider.ts::const result = execFileSync(::0",
120
+ "src/monitoring/CredentialProvider.ts::const result = execFileSync(::1",
121
+ "src/monitoring/CredentialProvider.ts::execFileSync('security', ['-i'], {::0",
122
+ "src/monitoring/CredentialProvider.ts::execFileSync(::0",
123
+ "src/monitoring/HealthChecker.ts::execFileSync(this.config.sessions.tmuxPath, ['-V'], {::0",
124
+ "src/monitoring/HealthChecker.ts::execFileSync(this.config.sessions.tmuxPath, ['list-sessions'], {::0",
125
+ "src/monitoring/MemoryPressureMonitor.ts::const output = spawnSync('vm_stat', [], { encoding: 'utf-8', timeout: 5000 }).stdout ?? '';::0",
126
+ "src/monitoring/OrphanProcessReaper.ts::return spawnSync('/bin/sh', ['-c', cmd], { encoding: 'utf-8', timeout }).stdout ?? '';::0",
127
+ "src/monitoring/ResumeQueue.ts::out = execFileSync('df', ['-P', stateDir], { timeout: 3000, encoding: 'utf-8' });::0",
128
+ "src/monitoring/SessionRecovery.ts::const output = execFileSync('lsof', ['-p', String(pid), '-Fn'], {::0",
129
+ "src/monitoring/TelemetryHeartbeat.ts::const output = execFileSync('ioreg', ['-rd1', '-c', 'IOPlatformExpertDevice'], { encoding: 'utf-8' });::0",
130
+ "src/monitoring/WorktreeMonitor.ts::const result = spawnSync('/bin/sh', ['-c', `git ${args}`], {::0",
131
+ "src/monitoring/agentWorktreeGit.ts::out = execFileSync('lsof', ['-w', '-d', 'cwd', '-Fn'], { encoding: 'utf-8', timeout: 15_000, maxBuffer: 32 * 1024 * 1024 });::0",
132
+ "src/monitoring/mcpProcessReaperDeps.ts::return execFileSync(file, args, { encoding: 'utf8', timeout, stdio: ['ignore', 'pipe', 'ignore'] });::0",
133
+ "src/monitoring/probes/PlatformProbe.ts::execSync('sleep 0.2', { timeout: 1000 });::0",
134
+ "src/monitoring/probes/PlatformProbe.ts::execSync(::0",
135
+ "src/monitoring/probes/PlatformProbe.ts::execSync(`${tmuxPath} has-session -t ${testSessionName} 2>/dev/null`, { timeout: 1000 });::0",
136
+ "src/monitoring/probes/PlatformProbe.ts::execSync(`ls \"${testDir}\" > /dev/null 2>&1`, { timeout: 3000 });::0",
137
+ "src/monitoring/probes/PlatformProbe.ts::try { execSync(`${tmuxPath} kill-session -t ${testSessionName} 2>/dev/null`, { timeout: 3000 }); } catch { /* ok */ }::0",
138
+ "src/monitoring/probes/PlatformProbe.ts::try { execSync(`${tmuxPath} kill-session -t ${testSessionName} 2>/dev/null`, { timeout: 3000 }); } catch { /* ok */ }::1",
139
+ "src/monitoring/probes/SessionProbe.ts::execFileSync(deps.tmuxPath, ['-V'], { encoding: 'utf-8', timeout: 3000 });::0",
140
+ "src/monitoring/probes/SessionProbe.ts::execFileSync(deps.tmuxPath, ['has-session', '-t', session.tmuxSession], {::0",
141
+ "src/server/routes.ts::const ghRepo = execFileSync('gh', ['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner'], {::0",
142
+ "src/server/routes.ts::const out = execFileSync(::0",
143
+ "src/server/routes.ts::const output = execFileSync(tmuxPath, ['list-sessions', '-F', '#{session_name}'], {::0",
144
+ "src/server/routes.ts::const result = execFileSync('gh', [::0",
145
+ "src/server/routes.ts::execFileSync(tmuxPath, ['kill-session', '-t', `=${paneSession}`], { stdio: 'ignore' });::0",
146
+ "src/server/routes.ts::try { execFileSync(tmuxPath, ['clear-history', '-t', `=${paneSession}:`], { stdio: 'ignore' }); cleared = true; }::0"
147
+ ]
148
+ }