@askexenow/exe-os 0.9.150 → 0.9.153

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 (153) hide show
  1. package/dist/{backfill-metadata-7IANPCAL.js → backfill-metadata-PPI5QFYW.js} +1 -1
  2. package/dist/bin/agentic-ontology-backfill.js +1 -1
  3. package/dist/bin/agentic-reflection-backfill.js +1 -1
  4. package/dist/bin/agentic-semantic-label.js +1 -1
  5. package/dist/bin/backfill-conversations.js +1 -1
  6. package/dist/bin/backfill-responses.js +1 -1
  7. package/dist/bin/backfill-vectors.js +2 -2
  8. package/dist/bin/bulk-sync-postgres.js +5 -4
  9. package/dist/bin/cleanup-stale-review-tasks.js +2 -2
  10. package/dist/bin/cli.js +10 -10
  11. package/dist/bin/exe-agent.js +3 -3
  12. package/dist/bin/exe-assign.js +1 -1
  13. package/dist/bin/exe-boot.js +6 -6
  14. package/dist/bin/exe-call.js +3 -3
  15. package/dist/bin/exe-cloud.js +1 -1
  16. package/dist/bin/exe-dispatch.js +2 -2
  17. package/dist/bin/exe-doctor.js +1 -1
  18. package/dist/bin/exe-export-behaviors.js +2 -2
  19. package/dist/bin/exe-forget.js +3 -3
  20. package/dist/bin/exe-gateway.js +4 -4
  21. package/dist/bin/exe-heartbeat.js +2 -2
  22. package/dist/bin/exe-kill.js +3 -3
  23. package/dist/bin/exe-launch-agent.js +5 -5
  24. package/dist/bin/exe-new-employee.js +4 -4
  25. package/dist/bin/exe-pending-messages.js +3 -3
  26. package/dist/bin/exe-pending-notifications.js +2 -2
  27. package/dist/bin/exe-pending-reviews.js +2 -2
  28. package/dist/bin/exe-rename.js +3 -3
  29. package/dist/bin/exe-review.js +3 -3
  30. package/dist/bin/exe-search.js +2 -2
  31. package/dist/bin/exe-session-cleanup.js +11 -10
  32. package/dist/bin/exe-settings.js +1 -1
  33. package/dist/bin/exe-start-codex.js +5 -5
  34. package/dist/bin/exe-start-opencode.js +2 -2
  35. package/dist/bin/exe-status.js +3 -3
  36. package/dist/bin/exe-team.js +1 -1
  37. package/dist/bin/git-sweep.js +2 -2
  38. package/dist/bin/graph-backfill.js +1 -1
  39. package/dist/bin/graph-export.js +2 -2
  40. package/dist/bin/install.js +3 -3
  41. package/dist/bin/intercom-check.js +3 -3
  42. package/dist/bin/pre-publish.js +1 -1
  43. package/dist/bin/scan-tasks.js +2 -2
  44. package/dist/bin/setup.js +1 -1
  45. package/dist/bin/shard-migrate.js +1 -1
  46. package/dist/{capacity-monitor-J3SVO7LJ.js → capacity-monitor-5IVGAQ34.js} +2 -2
  47. package/dist/{catchup-brief-AIFZT456.js → catchup-brief-HFJR32Q3.js} +3 -3
  48. package/dist/{chunk-72XIEBYJ.js → chunk-25NSQUZ3.js} +1 -1
  49. package/dist/{chunk-Z43CJQ7T.js → chunk-3ZU7RTMF.js} +33 -7
  50. package/dist/{chunk-26VUCVSE.js → chunk-4IEQIUBZ.js} +1 -1
  51. package/dist/{chunk-EYTMNAU7.js → chunk-4PDXCEXT.js} +5 -5
  52. package/dist/{chunk-7JTZNHA4.js → chunk-4RKL53PD.js} +3 -2
  53. package/dist/{chunk-DJVXUJIR.js → chunk-5U5MI4VH.js} +29 -29
  54. package/dist/{chunk-GIAAHYMW.js → chunk-7WEVNBV2.js} +1 -1
  55. package/dist/{chunk-JM4A2E5A.js → chunk-AFMQR776.js} +1 -1
  56. package/dist/{chunk-3JR37K7C.js → chunk-AMVDQ7HH.js} +9 -5
  57. package/dist/{chunk-O2Y4WJYW.js → chunk-BPBUSSYF.js} +192 -5
  58. package/dist/{chunk-BQ3KXWA7.js → chunk-CBLNQNWT.js} +1 -1
  59. package/dist/{chunk-XQSGAG2G.js → chunk-CF4DZKKE.js} +1 -1
  60. package/dist/{chunk-DMBFPZOP.js → chunk-EYQ3DHHI.js} +3 -3
  61. package/dist/{chunk-X2XE65WV.js → chunk-H5STRY47.js} +9 -4
  62. package/dist/{chunk-7HONLLJ2.js → chunk-HZNQYDAN.js} +2 -2
  63. package/dist/{chunk-4K7HJL37.js → chunk-IWGGTD5D.js} +1 -1
  64. package/dist/{chunk-WR45FP7O.js → chunk-JJA6F6NA.js} +1 -1
  65. package/dist/{chunk-LJX5SV6L.js → chunk-JUM3EUB2.js} +2 -2
  66. package/dist/{chunk-IGYF67K3.js → chunk-L5WTOR3T.js} +2 -2
  67. package/dist/{chunk-3VHX5XFJ.js → chunk-LIJC4CRF.js} +1 -1
  68. package/dist/{chunk-FSH4VWSL.js → chunk-M37FGM3X.js} +2 -2
  69. package/dist/{chunk-XWQKCCCO.js → chunk-MWRHXGAB.js} +7 -0
  70. package/dist/{chunk-5NQKE3X4.js → chunk-OQYZQR24.js} +1 -1
  71. package/dist/{chunk-LLDY5HPV.js → chunk-PC6Y4ATU.js} +1 -1
  72. package/dist/{chunk-4WIWYUU2.js → chunk-PMCXWAVQ.js} +2 -2
  73. package/dist/{chunk-TCKZYGC5.js → chunk-SGLVCPZP.js} +1 -1
  74. package/dist/{chunk-XEH3USTI.js → chunk-SJKOILTX.js} +1 -1
  75. package/dist/{chunk-DSKUPORS.js → chunk-UQE5R5PM.js} +1 -1
  76. package/dist/{chunk-EEXG4ZJS.js → chunk-VJW3E5KW.js} +7 -7
  77. package/dist/{chunk-CRS6YTBM.js → chunk-WPNWFI4A.js} +1 -1
  78. package/dist/{chunk-GPHURFBS.js → chunk-WZMS6X56.js} +1 -1
  79. package/dist/{chunk-IT2JDL5L.js → chunk-XQC5BNCJ.js} +14 -9
  80. package/dist/{chunk-LBX2VQCC.js → chunk-YOH3ABTS.js} +1 -1
  81. package/dist/{crm-webhook-AJYXEFZD.js → crm-webhook-SOUYMO3X.js} +2 -2
  82. package/dist/{cto-delegation-gate-7OIN66NU.js → cto-delegation-gate-UGCMXYAO.js} +1 -1
  83. package/dist/{daemon-orchestration-EHONVEHN.js → daemon-orchestration-MD34RKQZ.js} +3 -3
  84. package/dist/{exe-export-IVFME5VN.js → exe-export-UDQU7MMM.js} +3 -3
  85. package/dist/{exe-import-O76AYBUE.js → exe-import-OY42LQL4.js} +3 -3
  86. package/dist/{fast-db-init-NCOIEAM6.js → fast-db-init-TLOT2K43.js} +1 -1
  87. package/dist/gateway/index.js +5 -5
  88. package/dist/{git-task-sweep-NOXCELFQ.js → git-task-sweep-D4IKRGCV.js} +2 -2
  89. package/dist/{global-procedures-FXWQ35RU.js → global-procedures-ISPSC4B5.js} +2 -2
  90. package/dist/{hook-integrity-PR4BPZBT.js → hook-integrity-SA7S2SNI.js} +1 -1
  91. package/dist/hooks/bug-report-worker.js +3 -3
  92. package/dist/hooks/codex-stop-task-finalizer.js +3 -3
  93. package/dist/hooks/commit-complete.js +4 -4
  94. package/dist/hooks/error-recall.js +2 -2
  95. package/dist/hooks/ingest.js +6 -6
  96. package/dist/hooks/instructions-loaded.js +1 -1
  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 +102 -38
  103. package/dist/hooks/session-end.js +6 -6
  104. package/dist/hooks/session-start.js +5 -5
  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 +8 -8
  109. package/dist/{installer-5NAISFMT.js → installer-3YHQ5DJZ.js} +2 -2
  110. package/dist/{installer-FTGXXYRA.js → installer-4YIOBAFV.js} +2 -2
  111. package/dist/{installer-Q4IWV2GB.js → installer-SPQDAGPW.js} +2 -2
  112. package/dist/lib/cloud-sync.js +1 -1
  113. package/dist/lib/consolidation.js +2 -2
  114. package/dist/lib/employee-templates.js +3 -3
  115. package/dist/lib/exe-daemon.js +51 -34
  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 +25 -25
  123. package/dist/mcp/server.js +26 -26
  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/{mcp-http-config-PSQCITKG.js → mcp-http-config-JBNX3DAR.js} +1 -1
  129. package/dist/{notifications-LD563XOM.js → notifications-76XXO4Q7.js} +1 -1
  130. package/dist/{orchestrator-WQGPXMLN.js → orchestrator-XAT2JSBT.js} +2 -2
  131. package/dist/{push-notifications-KDYFOJRI.js → push-notifications-NSYLKFXR.js} +1 -1
  132. package/dist/{review-polling-J3R7MLT4.js → review-polling-E24XBNSI.js} +2 -2
  133. package/dist/runtime/index.js +3 -3
  134. package/dist/{session-events-XDDQ3M4A.js → session-events-CCXFQRFW.js} +2 -2
  135. package/dist/{session-scope-6MAGVHBA.js → session-scope-7QCZF3MJ.js} +1 -1
  136. package/dist/{setup-wizard-WJ73A2FY.js → setup-wizard-FA6YEYER.js} +1 -1
  137. package/dist/signal-paths-4GOIRLGH.js +19 -0
  138. package/dist/{task-enforcement-3RV64YVR.js → task-enforcement-NITY7TBM.js} +1 -1
  139. package/dist/{task-scope-2T3WIQQY.js → task-scope-YZDSPORL.js} +1 -1
  140. package/dist/{tasks-crud-B2BGA44L.js → tasks-crud-W5BFKNUS.js} +1 -1
  141. package/dist/{tasks-review-ZO3QDMT7.js → tasks-review-VXMELVLA.js} +1 -1
  142. package/dist/tui/App.js +10 -10
  143. package/dist/{tui-data-UAPARPDX.js → tui-data-FQYUPCYX.js} +1 -1
  144. package/dist/{worker-gate-TG6PR2S5.js → worker-gate-OZCNSASA.js} +1 -1
  145. package/dist/{workflow-engine-VIFLD5IV.js → workflow-engine-DA3AWD45.js} +2 -2
  146. package/package.json +1 -1
  147. package/release-notes.json +104 -104
  148. /package/dist/{chunk-II3NQJGV.js → chunk-U3B3TVLQ.js} +0 -0
  149. /package/dist/{chunk-34XNU32S.js → chunk-UIOTTKLS.js} +0 -0
  150. /package/dist/{chunk-OLVZBBVO.js → chunk-YABPRFBT.js} +0 -0
  151. /package/dist/{chunk-BF4W2VDS.js → chunk-YH7VB655.js} +0 -0
  152. /package/dist/{core-memory-MT7P34HU.js → core-memory-ONZIJYGR.js} +0 -0
  153. /package/dist/{exe-key-6HV5GYHH.js → exe-key-FC67RNXI.js} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-MLXJ5EZG.js";
4
4
  import {
5
5
  createTask
6
- } from "./chunk-EEXG4ZJS.js";
6
+ } from "./chunk-VJW3E5KW.js";
7
7
  import {
8
8
  getActiveAgent
9
9
  } from "./chunk-UHL4QL5E.js";
@@ -11,7 +11,7 @@ import {
11
11
  ensureEmployee,
12
12
  logTaskDispatch,
13
13
  resolveExeSession
14
- } from "./chunk-EYTMNAU7.js";
14
+ } from "./chunk-4PDXCEXT.js";
15
15
  import {
16
16
  getLicenseSync
17
17
  } from "./chunk-5NSTNICM.js";
@@ -149,14 +149,18 @@ function registerCreateTask(server) {
149
149
  } catch {
150
150
  }
151
151
  try {
152
- const signalDir = join(homedir(), ".exe-os", "task-signals");
152
+ const sessionScope = task.sessionScope || callerRoot || "default";
153
+ const { taskSignalPath: getSignalPath } = await import("./signal-paths-4GOIRLGH.js");
154
+ const { taskSignalDir } = await import("./signal-paths-4GOIRLGH.js");
155
+ const signalDir = taskSignalDir(sessionScope);
153
156
  mkdirSync(signalDir, { recursive: true });
154
- const signalPath = join(signalDir, `${assigned_to}.${task.id}.pending`);
157
+ const signalPath = getSignalPath(sessionScope, assigned_to, task.id);
155
158
  writeFileSync(signalPath, JSON.stringify({
156
159
  task_id: task.id,
157
160
  title,
158
161
  priority,
159
162
  assigned_by: assignedBy,
163
+ session_scope: sessionScope,
160
164
  created_at: (/* @__PURE__ */ new Date()).toISOString()
161
165
  }), "utf-8");
162
166
  } catch {
@@ -181,7 +185,7 @@ function registerCreateTask(server) {
181
185
  let projectConflictOpts = {};
182
186
  try {
183
187
  const { getClient } = await import("./lib/database.js");
184
- const { sessionScopeFilter } = await import("./task-scope-2T3WIQQY.js");
188
+ const { sessionScopeFilter } = await import("./task-scope-YZDSPORL.js");
185
189
  const client = getClient();
186
190
  const scope = sessionScopeFilter();
187
191
  const existing = await client.execute({
@@ -3,13 +3,17 @@ import {
3
3
  buildRawVisibilityFilter,
4
4
  buildWikiScopeFilter,
5
5
  searchMemories
6
- } from "./chunk-72XIEBYJ.js";
6
+ } from "./chunk-25NSQUZ3.js";
7
7
  import {
8
8
  getClient
9
9
  } from "./chunk-MBYJEE3B.js";
10
10
 
11
11
  // src/lib/hybrid-search.ts
12
12
  var RRF_K = 60;
13
+ var ABSTENTION_THRESHOLD = parseFloat(
14
+ process.env.EXE_ABSTENTION_THRESHOLD ?? "0.015"
15
+ );
16
+ var CONTRADICTION_TEMPORAL_BOOST = 1.5;
13
17
  function buildTemporalFilter(options, columnPrefix) {
14
18
  const asOf = options?.asOf;
15
19
  if (asOf) {
@@ -34,6 +38,76 @@ function appendMemoryTypeFilter(sql, args, column, options) {
34
38
  }
35
39
  return sql;
36
40
  }
41
+ function extractEntitySubqueries(query) {
42
+ const subqueries = [];
43
+ const quoted = query.match(/"([^"]+)"/g);
44
+ if (quoted) {
45
+ for (const q of quoted) {
46
+ subqueries.push(q.replace(/"/g, ""));
47
+ }
48
+ }
49
+ const words = query.split(/\s+/);
50
+ const properNouns = [];
51
+ for (let i = 1; i < words.length; i++) {
52
+ const word = words[i].replace(/[^a-zA-Z]/g, "");
53
+ if (word.length >= 2 && /^[A-Z]/.test(word) && !/^(What|When|Where|Who|How|Why|Which|Does|Did|Is|Are|Was|Were|Has|Have|Had|Can|Could|Would|Should|Do|The|And|But|For|Not|You|Your|His|Her|Its|Our|Their|This|That|These|Those)$/.test(word)) {
54
+ properNouns.push(word);
55
+ }
56
+ }
57
+ if (properNouns.length > 0) {
58
+ subqueries.push(properNouns.join(" "));
59
+ }
60
+ const prepPatterns = /(?:about|regarding|concerning|towards?|with|for|against)\s+(.+?)(?:\?|$|,|\band\b)/gi;
61
+ let match;
62
+ while ((match = prepPatterns.exec(query)) !== null) {
63
+ const phrase = match[1].trim();
64
+ if (phrase.length >= 3 && phrase.split(/\s+/).length <= 5) {
65
+ subqueries.push(phrase);
66
+ }
67
+ }
68
+ return [...new Set(subqueries)].slice(0, 3);
69
+ }
70
+ function resolveContradictions(results) {
71
+ if (results.length < 2) return results;
72
+ const entityGroups = /* @__PURE__ */ new Map();
73
+ for (const r of results) {
74
+ const words = (r.raw_text ?? "").toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length >= 4).slice(0, 3);
75
+ if (words.length < 2) continue;
76
+ const key = words.join("|");
77
+ for (const [existingKey, group] of entityGroups) {
78
+ const existingWords = new Set(existingKey.split("|"));
79
+ const overlapCount = words.filter((w) => existingWords.has(w)).length;
80
+ if (overlapCount >= 2) {
81
+ group.push(r);
82
+ entityGroups.set(existingKey, group);
83
+ break;
84
+ }
85
+ }
86
+ const existing = entityGroups.get(key) ?? [];
87
+ existing.push(r);
88
+ entityGroups.set(key, existing);
89
+ }
90
+ const temporalBoosts = /* @__PURE__ */ new Map();
91
+ for (const [, group] of entityGroups) {
92
+ if (group.length < 2) continue;
93
+ const sorted = [...group].sort(
94
+ (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
95
+ );
96
+ for (let i = 0; i < sorted.length; i++) {
97
+ const id = sorted[i].id;
98
+ const boost = i === 0 ? CONTRADICTION_TEMPORAL_BOOST : 1 / (1 + i * 0.3);
99
+ temporalBoosts.set(id, Math.max(temporalBoosts.get(id) ?? 0, boost));
100
+ }
101
+ }
102
+ if (temporalBoosts.size === 0) return results;
103
+ const scored = results.map((r, i) => {
104
+ const baseScore = 1 / (1 + i * 0.1);
105
+ const contradiction = temporalBoosts.get(r.id) ?? 1;
106
+ return { record: r, score: baseScore * contradiction };
107
+ });
108
+ scored.sort((a, b) => b.score - a.score);
109
+ return scored.map((s) => s.record);
110
+ }
37
111
  async function hybridSearch(queryText, agentId, options) {
38
112
  const { loadConfig } = await import("./lib/config.js");
39
113
  const config = await loadConfig();
@@ -112,8 +186,12 @@ async function hybridSearch(queryText, agentId, options) {
112
186
  } catch {
113
187
  }
114
188
  }
189
+ const entitySubqueries = extractEntitySubqueries(effectiveQuery);
190
+ const subqueryPromises = entitySubqueries.map(
191
+ (sq) => lightweightSearch(sq, agentId, { ...fetchOptions, limit: Math.min(fetchLimit, 20) }).catch(() => [])
192
+ );
115
193
  const includeStructuredCards = effectiveIsBroad || effectiveOptions.includeStructuredCards === true;
116
- const [ftsResults, vectorResults, cardResults, reflectionResults, grepResults] = await Promise.all([
194
+ const [ftsResults, vectorResults, cardResults, reflectionResults, grepResults, ...subqueryResults] = await Promise.all([
117
195
  lightweightSearch(effectiveQuery, agentId, fetchOptions),
118
196
  queryVector ? searchMemories(queryVector, agentId, fetchOptions) : Promise.resolve([]),
119
197
  includeStructuredCards ? (async () => {
@@ -142,7 +220,8 @@ async function hybridSearch(queryText, agentId, options) {
142
220
  return [];
143
221
  }
144
222
  })() : Promise.resolve([]),
145
- grepPromise
223
+ grepPromise,
224
+ ...subqueryPromises
146
225
  ]);
147
226
  const lists = [];
148
227
  const weights = [];
@@ -166,6 +245,12 @@ async function hybridSearch(queryText, agentId, options) {
166
245
  lists.push(grepResults);
167
246
  weights.push(0.5);
168
247
  }
248
+ for (const sqResult of subqueryResults) {
249
+ if (sqResult.length > 0) {
250
+ lists.push(sqResult);
251
+ weights.push(0.7);
252
+ }
253
+ }
169
254
  if (lists.length === 0) return [];
170
255
  if (lists.length === 1 && !effectiveIsBroad) return lists[0].slice(0, limit);
171
256
  const rrfLimit = effectiveIsBroad ? Math.max(limit * 5, broadFetchTopK) : limit;
@@ -182,6 +267,9 @@ async function hybridSearch(queryText, agentId, options) {
182
267
  } catch {
183
268
  }
184
269
  }
270
+ if (merged.length >= 2) {
271
+ merged = resolveContradictions(merged);
272
+ }
185
273
  const auto = config.scalingRoadmap?.rerankerAutoTrigger ?? {
186
274
  enabled: config.rerankerEnabled ?? true,
187
275
  broadQueryMinCardinality: 5e4,
@@ -217,6 +305,18 @@ async function hybridSearch(queryText, agentId, options) {
217
305
  }
218
306
  }
219
307
  const finalResults = (rerankedAndBlended ?? merged).slice(0, limit);
308
+ if (finalResults.length > 0) {
309
+ const topResult = finalResults[0];
310
+ const signalCount = lists.length;
311
+ const resultRatio = Math.min(1, finalResults.length / limit);
312
+ const retrievalConfidence = resultRatio * (signalCount >= 2 ? 1 : 0.7);
313
+ topResult._retrievalConfidence = retrievalConfidence;
314
+ if (retrievalConfidence < ABSTENTION_THRESHOLD) {
315
+ for (const r of finalResults) {
316
+ r._lowConfidence = true;
317
+ }
318
+ }
319
+ }
220
320
  if (options?.includeSource && finalResults.length > 0) {
221
321
  await attachDocumentMetadata(finalResults);
222
322
  }
@@ -231,9 +331,12 @@ async function hybridSearch(queryText, agentId, options) {
231
331
  cards: cardResults.length,
232
332
  reflections: reflectionResults.length,
233
333
  grep: grepResults.length,
334
+ entitySubqueries: subqueryResults.filter((r) => r.length > 0).length,
234
335
  entityBoost: entityBoostRan,
336
+ contradictionResolution: merged.length >= 2,
235
337
  reranker: rerankedAndBlended !== null,
236
- selfQueryRouter: effectiveQuery !== queryText
338
+ selfQueryRouter: effectiveQuery !== queryText,
339
+ lowConfidence: finalResults[0]?._lowConfidence ?? false
237
340
  },
238
341
  topResults: finalResults.slice(0, 10).map((r, i) => {
239
342
  const scored = r;
@@ -370,7 +473,91 @@ function rrfMergeMulti(lists, limit, k = RRF_K, weights) {
370
473
  async function lightweightSearch(queryText, agentId, options) {
371
474
  const client = getClient();
372
475
  const limit = options?.limit ?? 5;
373
- const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3);
476
+ const FTS_STOP_WORDS = /* @__PURE__ */ new Set([
477
+ "the",
478
+ "and",
479
+ "but",
480
+ "for",
481
+ "not",
482
+ "you",
483
+ "your",
484
+ "his",
485
+ "her",
486
+ "its",
487
+ "our",
488
+ "their",
489
+ "this",
490
+ "that",
491
+ "these",
492
+ "those",
493
+ "what",
494
+ "when",
495
+ "where",
496
+ "who",
497
+ "how",
498
+ "why",
499
+ "which",
500
+ "does",
501
+ "did",
502
+ "was",
503
+ "were",
504
+ "has",
505
+ "have",
506
+ "had",
507
+ "can",
508
+ "could",
509
+ "would",
510
+ "should",
511
+ "are",
512
+ "with",
513
+ "from",
514
+ "about",
515
+ "into",
516
+ "through",
517
+ "during",
518
+ "before",
519
+ "after",
520
+ "above",
521
+ "below",
522
+ "between",
523
+ "same",
524
+ "each",
525
+ "every",
526
+ "both",
527
+ "more",
528
+ "most",
529
+ "other",
530
+ "some",
531
+ "such",
532
+ "than",
533
+ "too",
534
+ "very",
535
+ "just",
536
+ "also",
537
+ "any",
538
+ "all",
539
+ "own",
540
+ "being",
541
+ "been",
542
+ "they",
543
+ "them",
544
+ "will",
545
+ "may",
546
+ "might",
547
+ "shall",
548
+ "must",
549
+ "need",
550
+ "like",
551
+ "only",
552
+ "then",
553
+ "here",
554
+ "there",
555
+ "once",
556
+ "over",
557
+ "much",
558
+ "many"
559
+ ]);
560
+ const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3 && !FTS_STOP_WORDS.has(t));
374
561
  if (terms.length === 0) {
375
562
  return recentRecords(agentId, options, limit);
376
563
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeAction,
3
3
  substituteTemplate
4
- } from "./chunk-BF4W2VDS.js";
4
+ } from "./chunk-YH7VB655.js";
5
5
 
6
6
  // src/automation/workflow-engine.ts
7
7
  import { randomUUID } from "crypto";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-UHL4QL5E.js";
4
4
  import {
5
5
  listTasks
6
- } from "./chunk-EYTMNAU7.js";
6
+ } from "./chunk-4PDXCEXT.js";
7
7
  import {
8
8
  getProjectName
9
9
  } from "./chunk-OPU3NYOO.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MultiAgentOrchestrator
3
- } from "./chunk-4K7HJL37.js";
3
+ } from "./chunk-IWGGTD5D.js";
4
4
  import {
5
5
  createQuietRenderer,
6
6
  createTerminalRenderer,
@@ -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-2T3WIQQY.js");
330
+ const { sessionScopeFilter } = await import("./task-scope-YZDSPORL.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-2T3WIQQY.js");
422
+ const { sessionScopeFilter: cpScopeFilter } = await import("./task-scope-YZDSPORL.js");
423
423
  const client = getClient();
424
424
  const cpScope = cpScopeFilter();
425
425
  const tasks = await client.execute({
@@ -26,14 +26,19 @@ function _resetPushConfig() {
26
26
  _cachedConfig = null;
27
27
  _notifyOn = null;
28
28
  }
29
- function sendDesktopNotification(title, body) {
29
+ function sendDesktopNotification(title, body, sessionScope) {
30
30
  try {
31
31
  const safeTitle = title.replace(/["\\\n]/g, " ").slice(0, 100);
32
32
  const safeBody = body.replace(/["\\\n]/g, " ").slice(0, 200);
33
33
  try {
34
34
  const osc9 = `\x1B]9;${safeTitle}: ${safeBody}\x07`;
35
- const sessions = execSync("tmux list-sessions -F '#{session_name}' 2>/dev/null", { encoding: "utf8", timeout: 2e3 }).trim().split("\n");
36
- const coordinatorSession = sessions.find((s) => /^exe\d*$/.test(s));
35
+ let coordinatorSession;
36
+ if (sessionScope) {
37
+ coordinatorSession = sessionScope;
38
+ } else {
39
+ const sessions = execSync("tmux list-sessions -F '#{session_name}' 2>/dev/null", { encoding: "utf8", timeout: 2e3 }).trim().split("\n");
40
+ coordinatorSession = sessions.find((s) => /^exe\d*$/.test(s));
41
+ }
37
42
  if (coordinatorSession) {
38
43
  execSync(`printf '${osc9.replace(/'/g, "'\\''")}' > /dev/tty 2>/dev/null || tmux display-message -p -t ${coordinatorSession} '' 2>/dev/null`, { timeout: 2e3, stdio: "ignore" });
39
44
  return true;
@@ -111,7 +116,7 @@ async function pushNotify(msg) {
111
116
  if (!notifyOn.has(msg.event)) return result;
112
117
  const formatted = formatMessage(msg);
113
118
  if (config.desktop !== false) {
114
- result.desktop = sendDesktopNotification(msg.title, msg.body);
119
+ result.desktop = sendDesktopNotification(msg.title, msg.body, msg.sessionScope);
115
120
  }
116
121
  if (config.telegram?.bot_token && config.telegram?.chat_id) {
117
122
  result.telegram = await sendTelegram(
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  updateTask
3
- } from "./chunk-EEXG4ZJS.js";
3
+ } from "./chunk-VJW3E5KW.js";
4
4
  import {
5
5
  TASK_ALREADY_CLAIMED_PREFIX
6
- } from "./chunk-EYTMNAU7.js";
6
+ } from "./chunk-4PDXCEXT.js";
7
7
 
8
8
  // src/mcp/tools/update-task.ts
9
9
  import { z } from "zod";
@@ -9,7 +9,7 @@ import {
9
9
  isEmployeeAlive,
10
10
  sessionScopeFilter,
11
11
  updateTaskStatus
12
- } from "./chunk-EYTMNAU7.js";
12
+ } from "./chunk-4PDXCEXT.js";
13
13
  import {
14
14
  DEFAULT_COORDINATOR_TEMPLATE_NAME,
15
15
  getCoordinatorName
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PLATFORM_PROCEDURE_TITLES
3
- } from "./chunk-XWQKCCCO.js";
3
+ } from "./chunk-MWRHXGAB.js";
4
4
  import {
5
5
  getClient,
6
6
  getIdentity,
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createCRMWebhookHandler,
6
6
  parseTwentyWebhook
7
- } from "./chunk-JM4A2E5A.js";
7
+ } from "./chunk-AFMQR776.js";
8
8
  import {
9
9
  WhatsAppAdapter
10
10
  } from "./chunk-ECSNSHZ7.js";
@@ -42,7 +42,7 @@ import {
42
42
  retryWithBackoff,
43
43
  routeMessage,
44
44
  validateGatewayConfig
45
- } from "./chunk-DSKUPORS.js";
45
+ } from "./chunk-UQE5R5PM.js";
46
46
  import {
47
47
  OllamaProvider
48
48
  } from "./chunk-FWFFZGSC.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  fastDbInit
3
- } from "./chunk-34XNU32S.js";
3
+ } from "./chunk-UIOTTKLS.js";
4
4
  import {
5
5
  sessionScopeFilter
6
- } from "./chunk-EYTMNAU7.js";
6
+ } from "./chunk-4PDXCEXT.js";
7
7
  import {
8
8
  formatStatusAll,
9
9
  formatStatusDeep,
@@ -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-2T3WIQQY.js");
114
+ const { sessionScopeFilter } = await import("./task-scope-YZDSPORL.js");
115
115
  const client = getClient();
116
116
  const scope = sessionScopeFilter();
117
117
  const result = await client.execute({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionScopeFilter
3
- } from "./chunk-EYTMNAU7.js";
3
+ } from "./chunk-4PDXCEXT.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-B2BGA44L.js");
181
+ const { updateTaskStatus } = await import("./tasks-crud-W5BFKNUS.js");
182
182
  await updateTaskStatus({
183
183
  taskId: task.id,
184
184
  status: "needs_review",
@@ -161,6 +161,13 @@ var PLATFORM_PROCEDURES = [
161
161
  priority: "p0",
162
162
  content: "Behaviors (Layer 2) are corrections \u2014 'don't do X again.' They are NOT a dumping ground for rules. Best practice per agent per project: max 10-15 active p0 behaviors. Beyond that, noise drowns signal \u2014 agents can't follow 50 rules injected every session. Before storing a new behavior, check behavior(action='list') for duplicates \u2014 supersede, don't stack. If an agent follows a behavior consistently for 2+ weeks, promote it to identity (exe.md) and deactivate the behavior. If the agent keeps violating it, the behavior isn't working \u2014 enforce it in code (hook, gate, or system check) instead. One clear sentence per behavior, not paragraphs. Periodic cleanup: COO should audit each agent's behaviors monthly \u2014 deduplicate, remove test junk, merge overlapping entries. Priority tiers: p0 = always injected (limit 10), p1 = standard (injected when relevant), p2 = nice-to-have."
163
163
  },
164
+ // --- Skills ---
165
+ {
166
+ title: "Skills \u2014 reusable procedures from proven work patterns",
167
+ domain: "operations",
168
+ priority: "p1",
169
+ content: "Skills are stored as behaviors with domain='skill'. They capture multi-step procedures that worked. WHEN TO CAPTURE: after completing a complex task (5+ tool calls) that involved non-obvious steps, error recovery, or a workflow that would help future sessions. SKIP for simple one-offs. FORMAT: 'SKILL: [name] \u2014 Step 1: ... Step 2: ... Pitfalls: ...' HOW TO FIND SKILLS: behavior(action='list', domain='skill') shows all captured skills. Before starting complex work, check if a relevant skill exists. HOW TO USE: Load the skill, follow its steps. If you deviate and find a better path, update the skill via behavior(action='store') with the improved version and supersede the old one. SKILL LIFECYCLE: capture \u2192 track (use_count, success_count) \u2192 refine (merge corrections after 3+ uses) \u2192 promote (move to identity after 10+ successful uses) \u2192 deactivate old behavior. Skills are per-agent per-project. Shared skills use domain='skill' with no project filter. Goal: procedural memory \u2014 not just corrections, but proven approaches that get better over time."
170
+ },
164
171
  // --- Updates ---
165
172
  {
166
173
  title: "How to update exe-os \u2014 CLI first, then stack",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  initStore
3
- } from "./chunk-72XIEBYJ.js";
3
+ } from "./chunk-25NSQUZ3.js";
4
4
  import {
5
5
  getClient,
6
6
  isInitialized
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getGlobalProceduresBlock
3
- } from "./chunk-LBX2VQCC.js";
3
+ } from "./chunk-YOH3ABTS.js";
4
4
 
5
5
  // src/lib/employee-templates.ts
6
6
  var BASE_OPERATING_PROCEDURES = `
@@ -830,7 +830,7 @@ function formatReport(report, flags) {
830
830
  return lines.join("\n");
831
831
  }
832
832
  async function fixNullVectors() {
833
- const { tryAcquireWorkerSlot, registerWorkerPid } = await import("./worker-gate-TG6PR2S5.js");
833
+ const { tryAcquireWorkerSlot, registerWorkerPid } = await import("./worker-gate-OZCNSASA.js");
834
834
  if (!tryAcquireWorkerSlot()) {
835
835
  process.stderr.write("[exe-doctor] Worker gate full \u2014 waiting for existing backfill workers to finish\n");
836
836
  await new Promise((r) => setTimeout(r, 5e3));
@@ -951,7 +951,7 @@ function splitAtSentences(text, maxChunkSize) {
951
951
  }
952
952
  async function main(argv = process.argv.slice(2)) {
953
953
  const flags = parseFlags(argv);
954
- const { fastDbInit } = await import("./fast-db-init-NCOIEAM6.js");
954
+ const { fastDbInit } = await import("./fast-db-init-TLOT2K43.js");
955
955
  const client = await fastDbInit();
956
956
  const report = await runAudit(client, flags);
957
957
  console.log(formatReport(report, flags));
@@ -48,7 +48,7 @@ function readOrCreateDaemonToken(homeDir = os.homedir()) {
48
48
  function buildMcpHttpHeaders(homeDir = os.homedir(), opts = {}) {
49
49
  const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
50
50
  const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
51
- const sessionName = opts.useShellPlaceholders ? "" : process.env.EXE_SESSION_NAME ?? "";
51
+ const sessionName = process.env.EXE_SESSION_NAME ?? "";
52
52
  const headers = {
53
53
  Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
54
54
  "X-Agent-Id": agentId,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getCurrentSessionScope,
3
3
  strictSessionScopeFilter
4
- } from "./chunk-EYTMNAU7.js";
4
+ } from "./chunk-4PDXCEXT.js";
5
5
  import {
6
6
  getProjectName
7
7
  } from "./chunk-OPU3NYOO.js";
@@ -2,7 +2,7 @@ import {
2
2
  listWorkflowDefinitions,
3
3
  runWorkflow,
4
4
  startWorkflow
5
- } from "./chunk-BQ3KXWA7.js";
5
+ } from "./chunk-CBLNQNWT.js";
6
6
  import {
7
7
  initCRMBridge
8
8
  } from "./chunk-GCNWCYJI.js";
@@ -11,7 +11,7 @@ import {
11
11
  sessionScopeFilter,
12
12
  updateTaskStatus,
13
13
  writeNotification
14
- } from "./chunk-EYTMNAU7.js";
14
+ } from "./chunk-4PDXCEXT.js";
15
15
  import {
16
16
  getTransport
17
17
  } from "./chunk-3TXOH3SJ.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-6MAGVHBA.js");
139
+ const { assertSessionScope } = await import("./session-scope-7QCZF3MJ.js");
140
140
  const check = assertSessionScope("dispatch_task", input.projectName);
141
141
  if (check.reason === "cross_session_denied") {
142
142
  crossProject = true;
@@ -331,7 +331,7 @@ async function updateTask(input) {
331
331
  let delivered = false;
332
332
  try {
333
333
  const { sendIntercom: sendIntercom2, resolveExeSession: resolveExeSession2 } = await import("./lib/tmux-routing.js");
334
- const exeSession = resolveExeSession2();
334
+ const exeSession = row.session_scope ? String(row.session_scope) : resolveExeSession2();
335
335
  if (exeSession) {
336
336
  const reviewerSession = `${reviewer}-${exeSession}`;
337
337
  const result = sendIntercom2(reviewerSession);
@@ -358,7 +358,7 @@ async function updateTask(input) {
358
358
  `);
359
359
  const { queueIntercom } = await import("./intercom-queue-K3DVKSPJ.js");
360
360
  const { resolveExeSession: resolveExeSession2 } = await import("./lib/tmux-routing.js");
361
- const exeSession = resolveExeSession2();
361
+ const exeSession = row.session_scope ? String(row.session_scope) : resolveExeSession2();
362
362
  if (exeSession) {
363
363
  const reviewerSession = isCoordinatorName(reviewer) ? exeSession : `${reviewer}-${exeSession}`;
364
364
  queueIntercom(reviewerSession, `Review ready: "${taskTitle}" by ${String(row.assigned_to)}. Run /exe-review.`);
@@ -369,7 +369,7 @@ async function updateTask(input) {
369
369
  }
370
370
  }
371
371
  try {
372
- const { pushNotifyAsync } = await import("./push-notifications-KDYFOJRI.js");
372
+ const { pushNotifyAsync } = await import("./push-notifications-NSYLKFXR.js");
373
373
  pushNotifyAsync({
374
374
  event: "review_ready",
375
375
  title: `Review ready: ${taskTitle.slice(0, 50)}`,
@@ -381,7 +381,7 @@ async function updateTask(input) {
381
381
  }
382
382
  if (!isCoordinator) {
383
383
  try {
384
- const { pushNotifyAsync } = await import("./push-notifications-KDYFOJRI.js");
384
+ const { pushNotifyAsync } = await import("./push-notifications-NSYLKFXR.js");
385
385
  const event = input.status === "needs_review" ? "review_ready" : "task_complete";
386
386
  pushNotifyAsync({
387
387
  event,
@@ -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-LD563XOM.js");
399
+ const { writeNotification: writeNotification2 } = await import("./notifications-76XXO4Q7.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-EYTMNAU7.js";
7
+ } from "./chunk-4PDXCEXT.js";
8
8
  import {
9
9
  getClient
10
10
  } from "./chunk-MBYJEE3B.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sendMessage
3
- } from "./chunk-CRS6YTBM.js";
3
+ } from "./chunk-WPNWFI4A.js";
4
4
  import {
5
5
  getActiveAgent
6
6
  } from "./chunk-UHL4QL5E.js";