@askexenow/exe-os 0.9.197 → 0.9.199

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 (156) hide show
  1. package/deploy/compose/cloudflared/config.yml.example +3 -0
  2. package/deploy/compose/docker-compose.yml +2 -2
  3. package/deploy/compose/init-db.sql +4 -0
  4. package/deploy/stack-manifests/v0.9.json +10 -5
  5. package/dist/{backfill-metadata-KYCN4I7C.js → backfill-metadata-RL7T4XGY.js} +1 -1
  6. package/dist/bin/agentic-ontology-backfill.js +1 -1
  7. package/dist/bin/agentic-reflection-backfill.js +1 -1
  8. package/dist/bin/agentic-semantic-label.js +1 -1
  9. package/dist/bin/backfill-conversations.js +1 -1
  10. package/dist/bin/backfill-responses.js +1 -1
  11. package/dist/bin/backfill-vectors.js +2 -2
  12. package/dist/bin/bulk-sync-postgres.js +1 -1
  13. package/dist/bin/cleanup-stale-review-tasks.js +2 -2
  14. package/dist/bin/cli.js +10 -10
  15. package/dist/bin/exe-agent.js +8 -8
  16. package/dist/bin/exe-assign.js +1 -1
  17. package/dist/bin/exe-boot.js +4 -4
  18. package/dist/bin/exe-call.js +1 -1
  19. package/dist/bin/exe-dispatch.js +2 -2
  20. package/dist/bin/exe-doctor.js +1 -1
  21. package/dist/bin/exe-export-behaviors.js +2 -2
  22. package/dist/bin/exe-forget.js +3 -3
  23. package/dist/bin/exe-gateway.js +4 -4
  24. package/dist/bin/exe-heartbeat.js +2 -2
  25. package/dist/bin/exe-kill.js +3 -3
  26. package/dist/bin/exe-launch-agent.js +3 -9
  27. package/dist/bin/exe-new-employee.js +2 -2
  28. package/dist/bin/exe-pending-messages.js +3 -3
  29. package/dist/bin/exe-pending-notifications.js +2 -2
  30. package/dist/bin/exe-pending-reviews.js +2 -2
  31. package/dist/bin/exe-rename.js +1 -1
  32. package/dist/bin/exe-review.js +3 -3
  33. package/dist/bin/exe-search.js +2 -2
  34. package/dist/bin/exe-session-cleanup.js +5 -5
  35. package/dist/bin/exe-start-codex.js +2 -2
  36. package/dist/bin/exe-start-opencode.js +2 -2
  37. package/dist/bin/exe-status.js +3 -3
  38. package/dist/bin/exe-team.js +1 -1
  39. package/dist/bin/generate-hook-manifest.js +30 -0
  40. package/dist/bin/git-sweep.js +2 -2
  41. package/dist/bin/graph-backfill.js +1 -1
  42. package/dist/bin/graph-export.js +2 -2
  43. package/dist/bin/import-history.js +1 -1
  44. package/dist/bin/install.js +3 -3
  45. package/dist/bin/intercom-check.js +3 -3
  46. package/dist/bin/scan-tasks.js +2 -2
  47. package/dist/bin/setup.js +1 -1
  48. package/dist/bin/shard-migrate.js +1 -1
  49. package/dist/bin/stack-update.js +1 -1
  50. package/dist/bin/vps-health-gate.js +1 -1
  51. package/dist/browser-sanitizer-Q3GWRYKI.js +229 -0
  52. package/dist/browser-session-store-TSD4PCY7.js +232 -0
  53. package/dist/{capacity-monitor-H7D43IUQ.js → capacity-monitor-2TRPP3AX.js} +2 -2
  54. package/dist/{catchup-brief-PTVQRBQK.js → catchup-brief-74ORL525.js} +3 -3
  55. package/dist/{chunk-BM4X3WHU.js → chunk-2DWKMJPE.js} +1 -1
  56. package/dist/{chunk-EMUQSTJL.js → chunk-2HEXCZGP.js} +1 -1
  57. package/dist/{chunk-HX4ULQ3E.js → chunk-5YVGHP2B.js} +11 -11
  58. package/dist/{chunk-5RT7IBY4.js → chunk-6BJ5GZD4.js} +3 -3
  59. package/dist/{chunk-BUN6JIDP.js → chunk-ACOQS4ZL.js} +1 -1
  60. package/dist/{chunk-HH4UGDJH.js → chunk-CGAYSKQF.js} +2 -2
  61. package/dist/{chunk-ADI4Z63O.js → chunk-DNEOEKWA.js} +2 -2
  62. package/dist/{chunk-7JCK6TXX.js → chunk-FDD7KX7Q.js} +39 -3
  63. package/dist/{chunk-7AJST6LP.js → chunk-FXVTLBBA.js} +1 -1
  64. package/dist/{chunk-CGDA6NJI.js → chunk-IFFVONU6.js} +1 -1
  65. package/dist/{chunk-VGBQKQHJ.js → chunk-JDGCEOT4.js} +1 -1
  66. package/dist/{chunk-2EVDBTCZ.js → chunk-JDHB6I4O.js} +1 -1
  67. package/dist/{chunk-FL4PEEWL.js → chunk-JQLWMZZJ.js} +1 -1
  68. package/dist/{chunk-4F4SOCKN.js → chunk-JRLSQFIE.js} +44 -44
  69. package/dist/{chunk-34ENR4JM.js → chunk-KRYEHI4V.js} +2 -2
  70. package/dist/{chunk-T5U27Y4H.js → chunk-M7NGABPF.js} +5 -5
  71. package/dist/{chunk-WP6P3LSI.js → chunk-MABQMUCQ.js} +9 -26
  72. package/dist/chunk-MNNWWEVJ.js +58 -0
  73. package/dist/{chunk-LLEB3QLI.js → chunk-MWGAC2ER.js} +1 -1
  74. package/dist/{chunk-UTDZUTRN.js → chunk-OF6TXNOC.js} +1 -1
  75. package/dist/{chunk-HH2QED73.js → chunk-OYU7TCBG.js} +1 -1
  76. package/dist/{chunk-UTUYZCQA.js → chunk-PHIQW2IU.js} +3 -3
  77. package/dist/{chunk-FXYOH3NG.js → chunk-RUKOGGQG.js} +1 -1
  78. package/dist/{chunk-FC3U23FN.js → chunk-WSYFZZCP.js} +2 -2
  79. package/dist/{chunk-QCNSCSCH.js → chunk-YZIUQ77U.js} +2 -2
  80. package/dist/{chunk-IUC2332K.js → chunk-ZAF4GJTD.js} +4 -4
  81. package/dist/{chunk-Q4WJJBOP.js → chunk-ZLP5TNRU.js} +1 -1
  82. package/dist/{crm-webhook-LRLN55LB.js → crm-webhook-OFWPEK33.js} +2 -2
  83. package/dist/{cto-delegation-gate-2FZN5SUY.js → cto-delegation-gate-7PGS5IN4.js} +1 -1
  84. package/dist/{daemon-orchestration-N5GPEP4F.js → daemon-orchestration-MP3PPX7Q.js} +3 -3
  85. package/dist/{exe-export-4ZJTQRRE.js → exe-export-QMGWH3PL.js} +1 -1
  86. package/dist/{exe-import-JI3FTSWZ.js → exe-import-7NNKSCKI.js} +1 -1
  87. package/dist/{fast-db-init-URP3KJAE.js → fast-db-init-DAZZ7ZUP.js} +1 -1
  88. package/dist/gateway/index.js +5 -5
  89. package/dist/{git-task-sweep-GPPNL2DK.js → git-task-sweep-SLANXCSW.js} +2 -2
  90. package/dist/hooks/bug-report-worker.js +3 -3
  91. package/dist/hooks/codex-stop-task-finalizer.js +3 -3
  92. package/dist/hooks/commit-complete.js +4 -4
  93. package/dist/hooks/error-recall.js +2 -2
  94. package/dist/hooks/ingest.js +2 -2
  95. package/dist/hooks/instructions-loaded.js +1 -1
  96. package/dist/hooks/manifest.json +25 -0
  97. package/dist/hooks/notification.js +1 -1
  98. package/dist/hooks/post-compact.js +2 -2
  99. package/dist/hooks/post-tool-combined.js +2 -2
  100. package/dist/hooks/pre-compact.js +3 -3
  101. package/dist/hooks/pre-tool-use.js +6 -6
  102. package/dist/hooks/prompt-submit.js +8 -8
  103. package/dist/hooks/session-end.js +18 -10
  104. package/dist/hooks/session-start.js +17 -4
  105. package/dist/hooks/stop.js +5 -5
  106. package/dist/hooks/subagent-stop.js +2 -2
  107. package/dist/hooks/summary-worker.js +5 -5
  108. package/dist/index.js +10 -10
  109. package/dist/{installer-4SH2HTIU.js → installer-CWKEI7SE.js} +2 -2
  110. package/dist/{installer-BTOQSNZI.js → installer-DWVZFKAH.js} +4 -4
  111. package/dist/{installer-MWOEIXKV.js → installer-GSA2KOSE.js} +2 -2
  112. package/dist/lib/consolidation.js +2 -2
  113. package/dist/lib/embed-worker.js +81 -14
  114. package/dist/lib/employee-templates.js +1 -1
  115. package/dist/lib/exe-daemon.js +121 -69
  116. package/dist/lib/hybrid-search.js +2 -2
  117. package/dist/lib/messaging.js +2 -2
  118. package/dist/lib/schedules.js +2 -2
  119. package/dist/lib/store.js +1 -1
  120. package/dist/lib/tasks.js +2 -2
  121. package/dist/lib/tmux-routing.js +1 -1
  122. package/dist/mcp/register-tools.js +26 -26
  123. package/dist/mcp/server.js +29 -29
  124. package/dist/mcp/tools/create-task.js +3 -3
  125. package/dist/mcp/tools/list-tasks.js +3 -3
  126. package/dist/mcp/tools/send-message.js +3 -3
  127. package/dist/mcp/tools/update-task.js +3 -3
  128. package/dist/{notifications-GENT3AWZ.js → notifications-WYNI5OG6.js} +1 -1
  129. package/dist/{orchestrator-A72IFTWK.js → orchestrator-FRFCMLW3.js} +2 -2
  130. package/dist/{reranker-JJRY3V3V.js → reranker-2ZWUZRUF.js} +1 -1
  131. package/dist/{review-polling-UJ4P3BIG.js → review-polling-ADP5YFHW.js} +2 -2
  132. package/dist/runtime/index.js +11 -11
  133. package/dist/{session-events-GWEVYXPJ.js → session-events-JA3MCMZK.js} +2 -2
  134. package/dist/{session-scope-DKE6OPV5.js → session-scope-LXQKQDIS.js} +1 -1
  135. package/dist/{setup-wizard-B4WDA4KT.js → setup-wizard-GRR4F4TX.js} +1 -1
  136. package/dist/{stack-update-PI2TWEGS.js → stack-update-C4BAPLXJ.js} +1 -1
  137. package/dist/{task-enforcement-QYS2QEEO.js → task-enforcement-KSLBFILH.js} +1 -1
  138. package/dist/{task-scope-OS66ZD7O.js → task-scope-AI62AIPT.js} +1 -1
  139. package/dist/{tasks-crud-DJH4NZC2.js → tasks-crud-IEOK55IV.js} +1 -1
  140. package/dist/{tasks-review-Z6PA4AF5.js → tasks-review-ID7V6RSR.js} +1 -1
  141. package/dist/tui/App.js +8 -8
  142. package/dist/{tui-data-JI4URSHX.js → tui-data-HIFVW2PE.js} +1 -1
  143. package/dist/{worker-gate-DIILYSRZ.js → worker-gate-F3L7XDMJ.js} +1 -1
  144. package/dist/{workflow-engine-PJ5YSMRL.js → workflow-engine-H5KTDDJG.js} +2 -2
  145. package/package.json +3 -3
  146. package/release-notes.json +201 -207
  147. package/dist/chunk-WZTQUBIE.js +0 -125
  148. package/dist/{chunk-42QSXHKN.js → chunk-4X7CMJDN.js} +0 -0
  149. package/dist/{chunk-ZGPURQ4J.js → chunk-54MZI4PK.js} +0 -0
  150. package/dist/{chunk-TF2BZTXF.js → chunk-7WUBXLK2.js} +3 -3
  151. /package/dist/{chunk-SSRRHKIO.js → chunk-MQLMIY6U.js} +0 -0
  152. /package/dist/{chunk-M4UP7VWO.js → chunk-NF4AEKQK.js} +0 -0
  153. /package/dist/{chunk-LZU4HY4C.js → chunk-XNXTN5XZ.js} +0 -0
  154. /package/dist/{core-memory-UHWYIN2A.js → core-memory-VQKCHGFX.js} +0 -0
  155. /package/dist/{exe-key-4EUOGKBN.js → exe-key-QZ5GWV6D.js} +0 -0
  156. /package/dist/{skill-refinement-2U2UCV2H.js → skill-refinement-3UVLBCZD.js} +0 -0
@@ -0,0 +1,232 @@
1
+ import {
2
+ enforcePrivateFileSync,
3
+ ensurePrivateDirSync
4
+ } from "./chunk-LYH5HE24.js";
5
+ import "./chunk-MLKGABMK.js";
6
+
7
+ // src/lib/browser-session-store.ts
8
+ import crypto from "crypto";
9
+ import path from "path";
10
+ import os from "os";
11
+ import {
12
+ existsSync,
13
+ readFileSync,
14
+ writeFileSync,
15
+ unlinkSync,
16
+ readdirSync,
17
+ statSync
18
+ } from "fs";
19
+ var ALGORITHM = "aes-256-gcm";
20
+ var IV_LENGTH = 12;
21
+ var TAG_LENGTH = 16;
22
+ var HKDF_INFO = "exe-browser-cookies-v1";
23
+ var DEFAULT_TTL_MS = 30 * 60 * 1e3;
24
+ var _jarCache = /* @__PURE__ */ new Map();
25
+ var _cookieKey = null;
26
+ function initCookieCrypto(masterKey) {
27
+ if (masterKey.length !== 32) {
28
+ throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
29
+ }
30
+ _cookieKey = Buffer.from(
31
+ crypto.hkdfSync("sha256", masterKey, "", HKDF_INFO, 32)
32
+ );
33
+ }
34
+ function isCookieCryptoInitialized() {
35
+ return _cookieKey !== null;
36
+ }
37
+ function encrypt(data) {
38
+ if (!_cookieKey) {
39
+ return "plain:" + Buffer.from(data, "utf-8").toString("base64");
40
+ }
41
+ const iv = crypto.randomBytes(IV_LENGTH);
42
+ const cipher = crypto.createCipheriv(ALGORITHM, _cookieKey, iv);
43
+ const encrypted = Buffer.concat([
44
+ cipher.update(Buffer.from(data, "utf-8")),
45
+ cipher.final()
46
+ ]);
47
+ const tag = cipher.getAuthTag();
48
+ return "enc:" + Buffer.concat([iv, encrypted, tag]).toString("base64");
49
+ }
50
+ function decrypt(ciphertext) {
51
+ if (ciphertext.startsWith("plain:")) {
52
+ return Buffer.from(ciphertext.slice(6), "base64").toString("utf-8");
53
+ }
54
+ if (!ciphertext.startsWith("enc:")) {
55
+ throw new Error("Unknown cookie store format");
56
+ }
57
+ if (!_cookieKey) {
58
+ throw new Error("Cookie crypto not initialized but encrypted data found");
59
+ }
60
+ const combined = Buffer.from(ciphertext.slice(4), "base64");
61
+ if (combined.length < IV_LENGTH + TAG_LENGTH) {
62
+ throw new Error("Cookie data too short");
63
+ }
64
+ const iv = combined.subarray(0, IV_LENGTH);
65
+ const tag = combined.subarray(combined.length - TAG_LENGTH);
66
+ const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
67
+ const decipher = crypto.createDecipheriv(ALGORITHM, _cookieKey, iv);
68
+ decipher.setAuthTag(tag);
69
+ return Buffer.concat([
70
+ decipher.update(encrypted),
71
+ decipher.final()
72
+ ]).toString("utf-8");
73
+ }
74
+ function getStoreDir() {
75
+ const base = process.env.EXE_OS_DIR ?? path.join(os.homedir(), ".exe-os");
76
+ return path.join(base, "browser-sessions");
77
+ }
78
+ function getJarPath(agentId, sessionKey) {
79
+ const safe = (s) => s.replace(/[^a-zA-Z0-9_-]/g, "_");
80
+ return path.join(getStoreDir(), `${safe(agentId)}-${safe(sessionKey)}.cookies.enc`);
81
+ }
82
+ function jarCacheKey(agentId, sessionKey) {
83
+ return `${agentId}:${sessionKey}`;
84
+ }
85
+ function getTtlMs() {
86
+ const envTtl = process.env.EXE_BROWSER_SESSION_TTL;
87
+ if (envTtl) {
88
+ const parsed = parseInt(envTtl, 10);
89
+ if (!isNaN(parsed) && parsed > 0) return parsed * 1e3;
90
+ }
91
+ return DEFAULT_TTL_MS;
92
+ }
93
+ function loadCookieJar(agentId, sessionKey) {
94
+ const cacheKey = jarCacheKey(agentId, sessionKey);
95
+ const cached = _jarCache.get(cacheKey);
96
+ if (cached) {
97
+ const ttl = getTtlMs();
98
+ if (Date.now() - cached.lastAccessed > ttl) {
99
+ clearCookieJar(agentId, sessionKey);
100
+ return null;
101
+ }
102
+ return cached;
103
+ }
104
+ const jarPath = getJarPath(agentId, sessionKey);
105
+ if (!existsSync(jarPath)) return null;
106
+ try {
107
+ const raw = readFileSync(jarPath, "utf-8");
108
+ const jar = JSON.parse(decrypt(raw));
109
+ const ttl = getTtlMs();
110
+ if (Date.now() - jar.lastAccessed > ttl) {
111
+ clearCookieJar(agentId, sessionKey);
112
+ return null;
113
+ }
114
+ const now = Math.floor(Date.now() / 1e3);
115
+ jar.cookies = jar.cookies.filter((c) => !c.expires || c.expires > now);
116
+ _jarCache.set(cacheKey, jar);
117
+ return jar;
118
+ } catch {
119
+ try {
120
+ unlinkSync(jarPath);
121
+ } catch {
122
+ }
123
+ return null;
124
+ }
125
+ }
126
+ function saveCookieJar(agentId, sessionKey, cookies) {
127
+ const cacheKey = jarCacheKey(agentId, sessionKey);
128
+ const existing = loadCookieJar(agentId, sessionKey);
129
+ const now = Date.now();
130
+ const cookieMap = /* @__PURE__ */ new Map();
131
+ if (existing) {
132
+ for (const c of existing.cookies) {
133
+ cookieMap.set(`${c.domain}:${c.path}:${c.name}`, c);
134
+ }
135
+ }
136
+ for (const c of cookies) {
137
+ cookieMap.set(`${c.domain}:${c.path}:${c.name}`, c);
138
+ }
139
+ const nowSec = Math.floor(now / 1e3);
140
+ const merged = [...cookieMap.values()].filter(
141
+ (c) => !c.expires || c.expires > nowSec
142
+ );
143
+ const jar = {
144
+ agentId,
145
+ sessionKey,
146
+ cookies: merged,
147
+ lastAccessed: now,
148
+ createdAt: existing?.createdAt ?? now
149
+ };
150
+ const storeDir = getStoreDir();
151
+ ensurePrivateDirSync(storeDir);
152
+ const jarPath = getJarPath(agentId, sessionKey);
153
+ const encrypted = encrypt(JSON.stringify(jar));
154
+ writeFileSync(jarPath, encrypted, "utf-8");
155
+ enforcePrivateFileSync(jarPath);
156
+ _jarCache.set(cacheKey, jar);
157
+ }
158
+ function getCookiesForUrl(agentId, sessionKey, url) {
159
+ const jar = loadCookieJar(agentId, sessionKey);
160
+ if (!jar || jar.cookies.length === 0) return [];
161
+ let hostname;
162
+ try {
163
+ hostname = new URL(url).hostname;
164
+ } catch {
165
+ return [];
166
+ }
167
+ const now = Math.floor(Date.now() / 1e3);
168
+ return jar.cookies.filter((c) => {
169
+ if (c.expires && c.expires <= now) return false;
170
+ const cookieDomain = c.domain.startsWith(".") ? c.domain.slice(1) : c.domain;
171
+ return hostname === cookieDomain || hostname.endsWith("." + cookieDomain);
172
+ });
173
+ }
174
+ function clearCookieJar(agentId, sessionKey) {
175
+ const cacheKey = jarCacheKey(agentId, sessionKey);
176
+ _jarCache.delete(cacheKey);
177
+ const jarPath = getJarPath(agentId, sessionKey);
178
+ try {
179
+ if (existsSync(jarPath)) unlinkSync(jarPath);
180
+ } catch {
181
+ }
182
+ }
183
+ function cleanupExpiredJars() {
184
+ const storeDir = getStoreDir();
185
+ if (!existsSync(storeDir)) return 0;
186
+ const ttl = getTtlMs();
187
+ const now = Date.now();
188
+ let cleaned = 0;
189
+ try {
190
+ const files = readdirSync(storeDir).filter((f) => f.endsWith(".cookies.enc"));
191
+ for (const file of files) {
192
+ const filePath = path.join(storeDir, file);
193
+ try {
194
+ const stat = statSync(filePath);
195
+ if (now - stat.mtimeMs > ttl) {
196
+ unlinkSync(filePath);
197
+ cleaned++;
198
+ }
199
+ } catch {
200
+ }
201
+ }
202
+ } catch {
203
+ }
204
+ return cleaned;
205
+ }
206
+ function touchCookieJar(agentId, sessionKey) {
207
+ const cacheKey = jarCacheKey(agentId, sessionKey);
208
+ const cached = _jarCache.get(cacheKey);
209
+ if (cached) {
210
+ cached.lastAccessed = Date.now();
211
+ const jarPath = getJarPath(agentId, sessionKey);
212
+ try {
213
+ if (existsSync(jarPath)) {
214
+ const raw = readFileSync(jarPath, "utf-8");
215
+ const jar = JSON.parse(decrypt(raw));
216
+ jar.lastAccessed = Date.now();
217
+ writeFileSync(jarPath, encrypt(JSON.stringify(jar)), "utf-8");
218
+ }
219
+ } catch {
220
+ }
221
+ }
222
+ }
223
+ export {
224
+ cleanupExpiredJars,
225
+ clearCookieJar,
226
+ getCookiesForUrl,
227
+ initCookieCrypto,
228
+ isCookieCryptoInitialized,
229
+ loadCookieJar,
230
+ saveCookieJar,
231
+ touchCookieJar
232
+ };
@@ -8,9 +8,9 @@ import {
8
8
  isAtCapacity,
9
9
  isWithinRelaunchCooldown,
10
10
  pollCapacityDead
11
- } from "./chunk-Q4WJJBOP.js";
11
+ } from "./chunk-ZLP5TNRU.js";
12
12
  import "./chunk-WRCETUYE.js";
13
- import "./chunk-WP6P3LSI.js";
13
+ import "./chunk-MABQMUCQ.js";
14
14
  import "./chunk-RN6XYY7U.js";
15
15
  import "./chunk-QI4IXJN7.js";
16
16
  import "./chunk-64WZEXXA.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  lightweightSearch
3
- } from "./chunk-IUC2332K.js";
4
- import "./chunk-42QSXHKN.js";
3
+ } from "./chunk-ZAF4GJTD.js";
4
+ import "./chunk-4X7CMJDN.js";
5
5
  import "./chunk-CHCA3ZM2.js";
6
6
  import "./chunk-OO5CPMT3.js";
7
7
  import {
8
8
  sessionScopeFilter,
9
9
  strictSessionScopeFilter
10
- } from "./chunk-WP6P3LSI.js";
10
+ } from "./chunk-MABQMUCQ.js";
11
11
  import "./chunk-RN6XYY7U.js";
12
12
  import "./chunk-QI4IXJN7.js";
13
13
  import "./chunk-64WZEXXA.js";
@@ -2,7 +2,7 @@ import {
2
2
  listWorkflowDefinitions,
3
3
  runWorkflow,
4
4
  startWorkflow
5
- } from "./chunk-UTDZUTRN.js";
5
+ } from "./chunk-OF6TXNOC.js";
6
6
  import {
7
7
  initCRMBridge
8
8
  } from "./chunk-ONKIWA3R.js";
@@ -102,7 +102,7 @@ DO NOT keep working degraded. Instead:
102
102
  2. Send intercom to the COO session to trigger kill + relaunch:
103
103
  MY_SESSION=$(tmux display-message -p '#{session_name}' 2>/dev/null)
104
104
  EXE_SESSION="\${MY_SESSION#\${AGENT_ID}-}"
105
- tmux send-keys -t "$EXE_SESSION" "/exe-intercom context-full: \${AGENT_ID} hit capacity. Checkpoint saved. Resume task <task-id>." Enter
105
+ tmux send-keys -t "$EXE_SESSION" "context-full: \${AGENT_ID} hit capacity. Checkpoint saved. Resume task <task-id>." Enter
106
106
 
107
107
  3. Stop working immediately. Do not attempt to continue with degraded context.
108
108
 
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  MultiAgentOrchestrator
3
- } from "./chunk-7AJST6LP.js";
3
+ } from "./chunk-FXVTLBBA.js";
4
4
  import {
5
5
  createQuietRenderer,
6
6
  createTerminalRenderer,
7
7
  renderAgentEvents
8
8
  } from "./chunk-YZFZDJWZ.js";
9
- import {
10
- checkDangerousPatterns,
11
- hasCriticalPattern
12
- } from "./chunk-AVE2B4DQ.js";
13
9
  import {
14
10
  checkPathSafety,
15
11
  checkReadPathSafety,
16
12
  containsPathTraversal
17
13
  } from "./chunk-NGVOA6ZQ.js";
14
+ import {
15
+ checkDangerousPatterns,
16
+ hasCriticalPattern
17
+ } from "./chunk-AVE2B4DQ.js";
18
18
  import {
19
19
  ContextManager,
20
20
  agentLoop,
@@ -33,16 +33,16 @@ import {
33
33
  partitionTools,
34
34
  zodToJsonSchema
35
35
  } from "./chunk-JQ6TLNIV.js";
36
- import {
37
- composeHooks,
38
- createDefaultHooks
39
- } from "./chunk-O377P7GM.js";
40
36
  import {
41
37
  EMPLOYEE_PERMISSIONS,
42
38
  checkPermission,
43
39
  createPermissionsFromPreset,
44
40
  createRestrictedPermissions
45
41
  } from "./chunk-PRKVT4KN.js";
42
+ import {
43
+ composeHooks,
44
+ createDefaultHooks
45
+ } from "./chunk-O377P7GM.js";
46
46
  import {
47
47
  PERMISSION_PRESETS,
48
48
  evaluatePermission,
@@ -327,7 +327,7 @@ function createExeOSHooks(config) {
327
327
  async onSubagentStop(_reason) {
328
328
  try {
329
329
  const { getClient } = await import("./lib/database.js");
330
- const { sessionScopeFilter } = await import("./task-scope-OS66ZD7O.js");
330
+ const { sessionScopeFilter } = await import("./task-scope-AI62AIPT.js");
331
331
  const client = getClient();
332
332
  const ehScope = sessionScopeFilter();
333
333
  const tasks = await client.execute({
@@ -419,7 +419,7 @@ function createExeOSHooks(config) {
419
419
  try {
420
420
  const { writeMemory, flushBatch } = await import("./lib/store.js");
421
421
  const { getClient } = await import("./lib/database.js");
422
- const { sessionScopeFilter: cpScopeFilter } = await import("./task-scope-OS66ZD7O.js");
422
+ const { sessionScopeFilter: cpScopeFilter } = await import("./task-scope-AI62AIPT.js");
423
423
  const client = getClient();
424
424
  const cpScope = cpScopeFilter();
425
425
  const tasks = await client.execute({
@@ -11,7 +11,7 @@ import {
11
11
  sessionScopeFilter,
12
12
  updateTaskStatus,
13
13
  writeNotification
14
- } from "./chunk-WP6P3LSI.js";
14
+ } from "./chunk-MABQMUCQ.js";
15
15
  import {
16
16
  getTransport
17
17
  } from "./chunk-TXWQPL2U.js";
@@ -136,7 +136,7 @@ async function dispatchTaskToEmployee(input) {
136
136
  let crossProject = false;
137
137
  if (input.projectName) {
138
138
  try {
139
- const { assertSessionScope } = await import("./session-scope-DKE6OPV5.js");
139
+ const { assertSessionScope } = await import("./session-scope-LXQKQDIS.js");
140
140
  const check = assertSessionScope("dispatch_task", input.projectName);
141
141
  if (check.reason === "cross_session_denied") {
142
142
  crossProject = true;
@@ -396,7 +396,7 @@ async function updateTask(input) {
396
396
  await markTaskNotificationsRead(taskFile);
397
397
  if (input.status === "needs_review" && !isCoordinator) {
398
398
  try {
399
- const { writeNotification: writeNotification2 } = await import("./notifications-GENT3AWZ.js");
399
+ const { writeNotification: writeNotification2 } = await import("./notifications-WYNI5OG6.js");
400
400
  await writeNotification2({
401
401
  agentId: String(row.assigned_to),
402
402
  agentRole: String(row.assigned_to),
@@ -4,7 +4,7 @@ import {
4
4
  resolveExeSession,
5
5
  sendIntercom,
6
6
  strictSessionScopeFilter
7
- } from "./chunk-WP6P3LSI.js";
7
+ } from "./chunk-MABQMUCQ.js";
8
8
  import {
9
9
  getClient
10
10
  } from "./chunk-TGOJR5SS.js";
@@ -19,7 +19,7 @@ import {
19
19
  import {
20
20
  createCRMWebhookHandler,
21
21
  parseTwentyWebhook
22
- } from "./chunk-HH2QED73.js";
22
+ } from "./chunk-OYU7TCBG.js";
23
23
  import {
24
24
  BotRegistry,
25
25
  BotRuntime,
@@ -42,7 +42,7 @@ import {
42
42
  retryWithBackoff,
43
43
  routeMessage,
44
44
  validateGatewayConfig
45
- } from "./chunk-BM4X3WHU.js";
45
+ } from "./chunk-2DWKMJPE.js";
46
46
  import {
47
47
  OllamaProvider
48
48
  } from "./chunk-FWFFZGSC.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionScopeFilter
3
- } from "./chunk-WP6P3LSI.js";
3
+ } from "./chunk-MABQMUCQ.js";
4
4
 
5
5
  // src/lib/git-task-sweep.ts
6
6
  import { execSync } from "child_process";
@@ -178,7 +178,7 @@ async function sweepTasks(projectName, options = {}) {
178
178
  }
179
179
  if (!dryRun) {
180
180
  try {
181
- const { updateTaskStatus } = await import("./tasks-crud-DJH4NZC2.js");
181
+ const { updateTaskStatus } = await import("./tasks-crud-IEOK55IV.js");
182
182
  await updateTaskStatus({
183
183
  taskId: task.id,
184
184
  status: "needs_review",
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-WRCETUYE.js";
4
4
  import {
5
5
  updateTask
6
- } from "./chunk-5RT7IBY4.js";
6
+ } from "./chunk-6BJ5GZD4.js";
7
7
  import {
8
8
  ensureEmployee,
9
9
  extractRootExe,
@@ -14,7 +14,7 @@ import {
14
14
  sessionScopeFilter,
15
15
  strictSessionScopeFilter,
16
16
  writeNotification
17
- } from "./chunk-WP6P3LSI.js";
17
+ } from "./chunk-MABQMUCQ.js";
18
18
  import {
19
19
  queueIntercom
20
20
  } from "./chunk-QI4IXJN7.js";
@@ -331,7 +331,7 @@ async function pollIdleKill(deps, idleTickCounts, opts) {
331
331
  try {
332
332
  const { execFileSync: warnExec } = await import("child_process");
333
333
  const shutdownMsg = [
334
- "/exe-intercom SHUTDOWN WARNING: Your session will be terminated in ~90 seconds due to inactivity.",
334
+ "SHUTDOWN WARNING: Your session will be terminated in ~90 seconds due to inactivity.",
335
335
  "All your tasks are complete. Before shutdown:",
336
336
  "1. store_memory() any important decisions, discoveries, or context from this session",
337
337
  "2. If you learned anything non-obvious, commit it to memory for future sessions",
@@ -1313,6 +1313,42 @@ function reapZombieAgentProcesses(deps) {
1313
1313
  }
1314
1314
  }
1315
1315
  if (hasLiveSession) continue;
1316
+ const coordinatorSessions = [...liveSessions].filter(
1317
+ (s) => isCoordinatorName(s.replace(/^\w+-/, "")) || isExeSession(s)
1318
+ );
1319
+ if (coordinatorSessions.length > 0) {
1320
+ let belongsToCoordinator = false;
1321
+ for (const cs of coordinatorSessions) {
1322
+ try {
1323
+ const panePids = execSync(
1324
+ `tmux list-panes -t ${JSON.stringify(cs)} -F '#{pane_pid}' 2>/dev/null`,
1325
+ { encoding: "utf8", timeout: 3e3 }
1326
+ ).trim().split("\n").map(Number).filter(Boolean);
1327
+ for (const panePid of panePids) {
1328
+ let walk = pid;
1329
+ for (let d = 0; d < 10; d++) {
1330
+ if (walk === panePid) {
1331
+ belongsToCoordinator = true;
1332
+ break;
1333
+ }
1334
+ const p = procMap.get(walk);
1335
+ if (!p || p.ppid <= 1) break;
1336
+ walk = p.ppid;
1337
+ }
1338
+ if (belongsToCoordinator) break;
1339
+ }
1340
+ } catch {
1341
+ }
1342
+ if (belongsToCoordinator) break;
1343
+ }
1344
+ if (belongsToCoordinator) {
1345
+ process.stderr.write(
1346
+ `[zombie-agent-reaper] SKIPPING PID ${pid} \u2014 belongs to coordinator session (${info.args.slice(0, 60)})
1347
+ `
1348
+ );
1349
+ continue;
1350
+ }
1351
+ }
1316
1352
  const rssKb = getRssKb(pid);
1317
1353
  const rssMb = rssKb ? Math.round(rssKb / 1024) : "?";
1318
1354
  const desc = `PID ${pid} (age=${ageSecs}s, RSS=${rssMb}MB, ${info.args.slice(0, 80)})`;
@@ -9,7 +9,7 @@ import {
9
9
  isEmployeeAlive,
10
10
  sessionScopeFilter,
11
11
  updateTaskStatus
12
- } from "./chunk-WP6P3LSI.js";
12
+ } from "./chunk-MABQMUCQ.js";
13
13
  import {
14
14
  DEFAULT_COORDINATOR_TEMPLATE_NAME,
15
15
  getCoordinatorName
@@ -111,7 +111,7 @@ function releaseBackfillLock() {
111
111
  }
112
112
  async function getTaskAwareCapacity() {
113
113
  const { getClient } = await import("./lib/database.js");
114
- const { sessionScopeFilter } = await import("./task-scope-OS66ZD7O.js");
114
+ const { sessionScopeFilter } = await import("./task-scope-AI62AIPT.js");
115
115
  const client = getClient();
116
116
  const scope = sessionScopeFilter();
117
117
  const result = await client.execute({
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-BDYUENC7.js";
4
4
  import {
5
5
  listTasks
6
- } from "./chunk-WP6P3LSI.js";
6
+ } from "./chunk-MABQMUCQ.js";
7
7
 
8
8
  // src/mcp/tools/list-tasks.ts
9
9
  import { z } from "zod";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  vectorToBlob
3
- } from "./chunk-42QSXHKN.js";
3
+ } from "./chunk-4X7CMJDN.js";
4
4
  import {
5
5
  extractKeywords,
6
6
  keywordsToString
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getCurrentSessionScope,
3
3
  strictSessionScopeFilter
4
- } from "./chunk-WP6P3LSI.js";
4
+ } from "./chunk-MABQMUCQ.js";
5
5
  import {
6
6
  getProjectName
7
7
  } from "./chunk-OPU3NYOO.js";