@askexenow/exe-os 0.9.300 → 0.9.301

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 (244) hide show
  1. package/deploy/compose/erp-nginx/nginx.conf +6 -3
  2. package/dist/active-agent-UNJO6AJ2.js +27 -0
  3. package/dist/active-agent-Y5LSIMVC.js +28 -0
  4. package/dist/agentic-ontology-QEV7GI3T.js +25 -0
  5. package/dist/backfill-metadata-RQZ4BN7G.js +600 -0
  6. package/dist/behaviors-A3L5CWMK.js +46 -0
  7. package/dist/bin/agentic-ontology-backfill.js +5 -5
  8. package/dist/bin/agentic-reflection-backfill.js +6 -6
  9. package/dist/bin/agentic-semantic-label.js +5 -5
  10. package/dist/bin/backfill-conversations.js +4 -4
  11. package/dist/bin/backfill-responses.js +4 -4
  12. package/dist/bin/backfill-vectors.js +5 -5
  13. package/dist/bin/bulk-sync-postgres.js +7 -7
  14. package/dist/bin/cc-doctor.js +4 -4
  15. package/dist/bin/cleanup-stale-review-tasks.js +9 -9
  16. package/dist/bin/cli.js +15 -15
  17. package/dist/bin/exe-agent-config.js +2 -2
  18. package/dist/bin/exe-agent.js +4 -4
  19. package/dist/bin/exe-assign.js +5 -5
  20. package/dist/bin/exe-boot.js +23 -18
  21. package/dist/bin/exe-call.js +4 -4
  22. package/dist/bin/exe-cloud.js +7 -7
  23. package/dist/bin/exe-dispatch.js +9 -9
  24. package/dist/bin/exe-doctor.js +2 -2
  25. package/dist/bin/exe-export-behaviors.js +7 -7
  26. package/dist/bin/exe-forget.js +6 -6
  27. package/dist/bin/exe-gateway.js +7 -7
  28. package/dist/bin/exe-healthcheck.js +4 -4
  29. package/dist/bin/exe-heartbeat.js +9 -9
  30. package/dist/bin/exe-kill.js +12 -12
  31. package/dist/bin/exe-launch-agent.js +16 -16
  32. package/dist/bin/exe-new-employee.js +6 -6
  33. package/dist/bin/exe-pending-messages.js +10 -10
  34. package/dist/bin/exe-pending-notifications.js +9 -9
  35. package/dist/bin/exe-pending-reviews.js +9 -9
  36. package/dist/bin/exe-rename.js +4 -4
  37. package/dist/bin/exe-review.js +11 -11
  38. package/dist/bin/exe-search.js +5 -5
  39. package/dist/bin/exe-session-cleanup.js +14 -14
  40. package/dist/bin/exe-settings.js +7 -7
  41. package/dist/bin/exe-start-codex.js +11 -11
  42. package/dist/bin/exe-start-opencode.js +8 -8
  43. package/dist/bin/exe-status.js +10 -10
  44. package/dist/bin/exe-team.js +3 -3
  45. package/dist/bin/exe-watchdog.js +3 -3
  46. package/dist/bin/git-sweep.js +10 -10
  47. package/dist/bin/graph-backfill.js +4 -4
  48. package/dist/bin/graph-export.js +5 -5
  49. package/dist/bin/import-history.js +7 -7
  50. package/dist/bin/install.js +6 -6
  51. package/dist/bin/intercom-check.js +4 -4
  52. package/dist/bin/mcp-sessions.js +2 -2
  53. package/dist/bin/orchestration-metrics.js +4 -4
  54. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  55. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  56. package/dist/bin/scan-tasks.js +9 -9
  57. package/dist/bin/setup.js +1 -1
  58. package/dist/bin/shard-migrate.js +4 -4
  59. package/dist/capability-cards-VTGDTOZ4.js +89 -0
  60. package/dist/capacity-monitor-G2MAJPRP.js +51 -0
  61. package/dist/catchup-brief-VBGEJQRS.js +175 -0
  62. package/dist/chunk-24JVDLQJ.js +345 -0
  63. package/dist/chunk-2T3OYZMR.js +1158 -0
  64. package/dist/chunk-3ABY3QDX.js +199 -0
  65. package/dist/chunk-3G3ECFB5.js +668 -0
  66. package/dist/chunk-3LHOFGHT.js +280 -0
  67. package/dist/chunk-3RA62PNQ.js +58 -0
  68. package/dist/chunk-3XRS5AVV.js +567 -0
  69. package/dist/chunk-3YK7X5FD.js +1186 -0
  70. package/dist/chunk-4L6PVYFE.js +54 -0
  71. package/dist/chunk-4O67LBMK.js +377 -0
  72. package/dist/chunk-4OIU3N6U.js +167 -0
  73. package/dist/chunk-5SYYMNPE.js +30 -0
  74. package/dist/chunk-5TO5PH7O.js +304 -0
  75. package/dist/chunk-5XD2Y463.js +402 -0
  76. package/dist/chunk-63AENHJC.js +123 -0
  77. package/dist/chunk-673IFJYB.js +731 -0
  78. package/dist/chunk-7AWH47AR.js +448 -0
  79. package/dist/chunk-7P4B6AEP.js +227 -0
  80. package/dist/chunk-7VHOALNC.js +244 -0
  81. package/dist/chunk-ASJHCAVL.js +38 -0
  82. package/dist/chunk-DICIFTCS.js +150 -0
  83. package/dist/chunk-DIFI5JDC.js +76 -0
  84. package/dist/chunk-DPOIJ5SM.js +284 -0
  85. package/dist/chunk-FAZNXNA5.js +33 -0
  86. package/dist/chunk-FCHG5RC4.js +197 -0
  87. package/dist/chunk-FFKSPZO2.js +157 -0
  88. package/dist/chunk-FNHYH5U6.js +331 -0
  89. package/dist/chunk-FWPDAQ6Q.js +1350 -0
  90. package/dist/chunk-FZB73QOI.js +210 -0
  91. package/dist/chunk-GJBR6QLD.js +630 -0
  92. package/dist/chunk-GRSYAHKI.js +535 -0
  93. package/dist/chunk-J5HFRVNW.js +362 -0
  94. package/dist/chunk-J6SD7LT2.js +171 -0
  95. package/dist/chunk-JURL2S27.js +128 -0
  96. package/dist/chunk-KPUYYOFS.js +122 -0
  97. package/dist/chunk-LAFARYU5.js +456 -0
  98. package/dist/chunk-LSDXEHKL.js +381 -0
  99. package/dist/chunk-MS2EOZJQ.js +290 -0
  100. package/dist/chunk-MUIMJGSQ.js +128 -0
  101. package/dist/chunk-NJMPNYBS.js +427 -0
  102. package/dist/chunk-OJACH2JF.js +128 -0
  103. package/dist/chunk-OO4IFABD.js +382 -0
  104. package/dist/chunk-Q65NCNL4.js +1352 -0
  105. package/dist/chunk-QIGS2LRT.js +735 -0
  106. package/dist/chunk-S73ZAJ2S.js +262 -0
  107. package/dist/chunk-SJ4UF7YK.js +1094 -0
  108. package/dist/chunk-SOZ7D77I.js +204 -0
  109. package/dist/chunk-TDX2LK2M.js +240 -0
  110. package/dist/chunk-U5RKGLV6.js +50 -0
  111. package/dist/chunk-UFGTHBHP.js +127 -0
  112. package/dist/chunk-ULCYWCPI.js +1079 -0
  113. package/dist/chunk-V6LOEOXG.js +3372 -0
  114. package/dist/chunk-VAZOVAW4.js +2162 -0
  115. package/dist/chunk-VEUQVKKT.js +185 -0
  116. package/dist/chunk-VIDDJ5RF.js +214 -0
  117. package/dist/chunk-VNB4ROYG.js +348 -0
  118. package/dist/chunk-VWUQFZFB.js +395 -0
  119. package/dist/chunk-W77GRCNA.js +85 -0
  120. package/dist/chunk-WVMG4ZRH.js +14597 -0
  121. package/dist/chunk-WYVOTRRZ.js +129 -0
  122. package/dist/chunk-XQQ7D4I4.js +85 -0
  123. package/dist/chunk-YHJPTIPR.js +836 -0
  124. package/dist/chunk-YLKS7KKC.js +2145 -0
  125. package/dist/chunk-YU3KEVCO.js +333 -0
  126. package/dist/chunk-ZDPU3JTF.js +221 -0
  127. package/dist/chunk-ZDY4LYAJ.js +81 -0
  128. package/dist/chunk-ZG33AACD.js +70 -0
  129. package/dist/chunk-ZKHPZ6KN.js +181 -0
  130. package/dist/chunk-ZO2TM5N5.js +97 -0
  131. package/dist/chunk-ZSUACDQC.js +4388 -0
  132. package/dist/co-activation-XM25BLZM.js +74 -0
  133. package/dist/co-occurrence-CKEMDPWO.js +95 -0
  134. package/dist/core-memory-ZDA76EU3.js +110 -0
  135. package/dist/crdt-sync-BJKZB6T6.js +33 -0
  136. package/dist/crm-webhook-E5PAFAUN.js +10 -0
  137. package/dist/cto-delegation-gate-EMY6ZZ2F.js +280 -0
  138. package/dist/daemon-orchestration-Y5Y6YNE3.js +143 -0
  139. package/dist/db-backup-HFJ53IBU.js +43 -0
  140. package/dist/doc-graph-extractor-ID45AQ2P.js +133 -0
  141. package/dist/dreaming-N6B7KBIE.js +34 -0
  142. package/dist/exe-drift-CPUEAPIU.js +70 -0
  143. package/dist/exe-export-4RTGDV53.js +77 -0
  144. package/dist/exe-import-AZMIF34Z.js +80 -0
  145. package/dist/exe-key-LJV23AJI.js +673 -0
  146. package/dist/exe-snapshot-ZOZBW7V6.js +338 -0
  147. package/dist/fast-db-init-ATRZGHOL.js +7 -0
  148. package/dist/gateway/index.js +8 -8
  149. package/dist/git-staleness-XNOKI4D3.js +112 -0
  150. package/dist/git-task-sweep-3MO4OVND.js +42 -0
  151. package/dist/global-procedures-EBAPPWGZ.js +22 -0
  152. package/dist/graph-auto-extract-VJOUQBPK.js +183 -0
  153. package/dist/hooks/bug-report-worker.js +11 -11
  154. package/dist/hooks/codex-stop-task-finalizer.js +11 -11
  155. package/dist/hooks/commit-complete.js +11 -11
  156. package/dist/hooks/error-recall.js +6 -6
  157. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  158. package/dist/hooks/ingest.js +6 -6
  159. package/dist/hooks/instructions-loaded.js +4 -4
  160. package/dist/hooks/manifest.json +19 -19
  161. package/dist/hooks/notification.js +4 -4
  162. package/dist/hooks/post-compact.js +11 -11
  163. package/dist/hooks/post-tool-combined.js +5 -5
  164. package/dist/hooks/pre-compact.js +12 -12
  165. package/dist/hooks/pre-tool-use.js +14 -14
  166. package/dist/hooks/prompt-submit.js +26 -24
  167. package/dist/hooks/session-end.js +15 -15
  168. package/dist/hooks/session-start.js +12 -12
  169. package/dist/hooks/stop.js +14 -14
  170. package/dist/hooks/subagent-stop.js +10 -10
  171. package/dist/hooks/summary-worker.js +14 -14
  172. package/dist/index.js +17 -17
  173. package/dist/installer-37KFNAWE.js +344 -0
  174. package/dist/installer-F55NR4E2.js +298 -0
  175. package/dist/installer-KOYBUS4J.js +40 -0
  176. package/dist/lib/cloud-sync.js +7 -7
  177. package/dist/lib/consolidation.js +5 -5
  178. package/dist/lib/database.js +2 -2
  179. package/dist/lib/db.js +2 -2
  180. package/dist/lib/employee-templates.js +4 -4
  181. package/dist/lib/employees.js +2 -2
  182. package/dist/lib/exe-daemon.js +40 -40
  183. package/dist/lib/hybrid-search.js +5 -5
  184. package/dist/lib/identity.js +2 -2
  185. package/dist/lib/messaging.js +9 -9
  186. package/dist/lib/reminders.js +3 -3
  187. package/dist/lib/schedules.js +5 -5
  188. package/dist/lib/session-registry.js +4 -4
  189. package/dist/lib/skill-learning.js +6 -6
  190. package/dist/lib/store.js +4 -4
  191. package/dist/lib/task-router.js +3 -3
  192. package/dist/lib/tasks.js +10 -10
  193. package/dist/lib/tmux-routing.js +8 -8
  194. package/dist/lib/token-spend.js +3 -3
  195. package/dist/mcp/register-tools.js +54 -54
  196. package/dist/mcp/server.js +55 -55
  197. package/dist/mcp/tools/complete-reminder.js +4 -4
  198. package/dist/mcp/tools/create-reminder.js +4 -4
  199. package/dist/mcp/tools/create-task.js +12 -12
  200. package/dist/mcp/tools/deactivate-behavior.js +7 -7
  201. package/dist/mcp/tools/list-reminders.js +4 -4
  202. package/dist/mcp/tools/list-tasks.js +12 -12
  203. package/dist/mcp/tools/send-message.js +11 -11
  204. package/dist/mcp/tools/update-task.js +11 -11
  205. package/dist/mcp-http-config-7KJZI7UD.js +31 -0
  206. package/dist/memory-cards-ZIT7ZKL5.js +180 -0
  207. package/dist/memory-graph-extractor-LY2VORZT.js +22 -0
  208. package/dist/memory-poisoning-defense-SEM25TY5.js +224 -0
  209. package/dist/memory-reflection-J2W7CJ7C.js +244 -0
  210. package/dist/notifications-RLMSI4YE.js +47 -0
  211. package/dist/orchestration-events-TGQYA72K.js +27 -0
  212. package/dist/orchestrator-JQD5G3CW.js +35 -0
  213. package/dist/pipeline-router-3Q3YBYSM.js +15 -0
  214. package/dist/plan-limits-YGXTYCW4.js +28 -0
  215. package/dist/project-boot-TDOZKKDR.js +299 -0
  216. package/dist/projection-worker-TMKUSVGD.js +1084 -0
  217. package/dist/prospective-memory-CNJDBNWF.js +232 -0
  218. package/dist/reranker-YQIRNGDM.js +19 -0
  219. package/dist/retrieval-health-M5BVB7EV.js +12 -0
  220. package/dist/review-polling-ZMB3OBPC.js +126 -0
  221. package/dist/runtime/index.js +11 -11
  222. package/dist/session-events-UTMCKDIN.js +38 -0
  223. package/dist/session-kill-telemetry-FRQA5MVD.js +31 -0
  224. package/dist/session-scope-2BD6QLNI.js +88 -0
  225. package/dist/setup-wizard-W64I6SHC.js +12 -0
  226. package/dist/skill-refinement-FXCXTUS2.js +159 -0
  227. package/dist/steward-gate-JDR3SLH3.js +15 -0
  228. package/dist/task-enforcement-WCEA4FZI.js +506 -0
  229. package/dist/task-scope-L5GDL2AV.js +37 -0
  230. package/dist/tasks-crud-S36AFYYM.js +79 -0
  231. package/dist/tasks-notify-W2W2BJRB.js +40 -0
  232. package/dist/tasks-review-34WV7BX2.js +49 -0
  233. package/dist/telemetry-upload-3CSVO3J7.js +741 -0
  234. package/dist/token-budget-ZG2MQ5GD.js +86 -0
  235. package/dist/tool-telemetry-ODL4F2CW.js +17 -0
  236. package/dist/tui/App.js +16 -16
  237. package/dist/tui-data-Z5UF7KEI.js +260 -0
  238. package/dist/wiki-acl-SZFHCEC4.js +111 -0
  239. package/dist/worker-gate-OOO6BWZ6.js +21 -0
  240. package/dist/workflow-engine-QY3IFFR2.js +28 -0
  241. package/dist/worktree-CNOQZBNT.js +28 -0
  242. package/dist/worktree-sweep-SE7ITXC4.js +21 -0
  243. package/package.json +1 -1
  244. package/release-notes.json +88 -88
@@ -0,0 +1,244 @@
1
+ import {
2
+ employeeSessionName,
3
+ ensureEmployee,
4
+ markAsReadByTaskFile,
5
+ notifyParentExe,
6
+ resolveExeSession,
7
+ sendIntercom
8
+ } from "./chunk-ZSUACDQC.js";
9
+ import {
10
+ getTransport
11
+ } from "./chunk-KOO3J5PV.js";
12
+ import {
13
+ recordOrchestrationEventBestEffort
14
+ } from "./chunk-GJBR6QLD.js";
15
+ import {
16
+ getAgentRuntime
17
+ } from "./chunk-QRTJNSKU.js";
18
+ import {
19
+ getSessionKey
20
+ } from "./chunk-CVYC6DUW.js";
21
+ import {
22
+ isCoordinatorName,
23
+ isMultiInstance,
24
+ shouldAutoInstance
25
+ } from "./chunk-V6LOEOXG.js";
26
+
27
+ // src/lib/tasks-notify.ts
28
+ var VERIFY_DELAY_MS = 1e4;
29
+ var ACK_PATTERNS = [
30
+ /New task assigned/,
31
+ /START WORKING NOW/,
32
+ /marked in_progress/,
33
+ /Reading.*\.md/
34
+ ];
35
+ function resolveDispatchRuntime(agentId, override) {
36
+ if (override) return override;
37
+ try {
38
+ return getAgentRuntime(agentId).runtime ?? null;
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+ async function verifyDispatch(sessionName, delayMs = VERIFY_DELAY_MS) {
44
+ const transport = getTransport();
45
+ await new Promise((r) => setTimeout(r, delayMs));
46
+ if (!transport.isAlive(sessionName)) {
47
+ return "session_dead";
48
+ }
49
+ try {
50
+ const output = transport.capturePane(sessionName, 20);
51
+ const acked = ACK_PATTERNS.some((p) => p.test(output));
52
+ return acked ? "verified" : "sent_unverified";
53
+ } catch {
54
+ return "sent_unverified";
55
+ }
56
+ }
57
+ async function dispatchTaskToEmployee(input) {
58
+ if (isCoordinatorName(input.assignedTo)) return { dispatched: "skipped" };
59
+ const dispatchRuntime = resolveDispatchRuntime(input.assignedTo, input.spawnRuntime);
60
+ recordOrchestrationEventBestEffort({
61
+ eventType: "dispatch.attempted",
62
+ source: "tasks-notify.dispatchTaskToEmployee",
63
+ taskId: input.taskId ?? null,
64
+ agentId: input.assignedTo,
65
+ runtime: dispatchRuntime,
66
+ payload: { priority: input.priority, projectName: input.projectName }
67
+ });
68
+ let crossProject = false;
69
+ if (input.projectName) {
70
+ try {
71
+ const { assertSessionScope } = await import("./session-scope-2BD6QLNI.js");
72
+ const check = assertSessionScope("dispatch_task", input.projectName);
73
+ if (check.reason === "cross_session_denied") {
74
+ crossProject = true;
75
+ recordOrchestrationEventBestEffort({
76
+ eventType: "dispatch.failed",
77
+ source: "tasks-notify.dispatchTaskToEmployee",
78
+ taskId: input.taskId ?? null,
79
+ agentId: input.assignedTo,
80
+ runtime: dispatchRuntime,
81
+ errorCode: "cross_session_denied",
82
+ payload: { projectName: input.projectName }
83
+ });
84
+ return { dispatched: "skipped", crossProject: true };
85
+ }
86
+ } catch {
87
+ }
88
+ }
89
+ try {
90
+ const transport = getTransport();
91
+ const exeSession = resolveExeSession();
92
+ if (!exeSession) {
93
+ recordOrchestrationEventBestEffort({
94
+ eventType: "dispatch.failed",
95
+ source: "tasks-notify.dispatchTaskToEmployee",
96
+ taskId: input.taskId ?? null,
97
+ agentId: input.assignedTo,
98
+ runtime: dispatchRuntime,
99
+ errorCode: "no_exe_session"
100
+ });
101
+ return { dispatched: "session_missing" };
102
+ }
103
+ const multiInstance = isMultiInstance(input.assignedTo);
104
+ if (multiInstance) {
105
+ const projectDir = input.projectDir ?? process.cwd();
106
+ const autoOpts = shouldAutoInstance(input.assignedTo);
107
+ const result = ensureEmployee(input.assignedTo, exeSession, projectDir, {
108
+ ...autoOpts,
109
+ runtimeOverride: input.spawnRuntime,
110
+ modelOverride: input.spawnModel
111
+ });
112
+ if (result.status === "failed") {
113
+ process.stderr.write(
114
+ `[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${result.error}
115
+ `
116
+ );
117
+ recordOrchestrationEventBestEffort({
118
+ eventType: "dispatch.failed",
119
+ source: "tasks-notify.dispatchTaskToEmployee",
120
+ taskId: input.taskId ?? null,
121
+ agentId: input.assignedTo,
122
+ sessionScope: exeSession,
123
+ runtime: dispatchRuntime,
124
+ errorCode: "spawn_failed",
125
+ payload: { path: "multi_instance", error: result.error }
126
+ });
127
+ return { dispatched: "session_missing" };
128
+ }
129
+ const dispatched = result.status === "intercom_sent" || result.status === "intercom_unprocessed" ? "sent_unverified" : "spawned";
130
+ process.stderr.write(
131
+ `[dispatch-audit] ${dispatched === "spawned" ? "SPAWNED" : "INTERCOM"} \u2192 ${result.sessionName} | task="${input.title}" [${input.priority}]
132
+ `
133
+ );
134
+ recordOrchestrationEventBestEffort({
135
+ eventType: "dispatch.completed",
136
+ source: "tasks-notify.dispatchTaskToEmployee",
137
+ taskId: input.taskId ?? null,
138
+ agentId: input.assignedTo,
139
+ sessionScope: exeSession,
140
+ tmuxSession: result.sessionName,
141
+ runtime: dispatchRuntime,
142
+ result: dispatched,
143
+ payload: { path: "multi_instance", priority: input.priority }
144
+ });
145
+ return { dispatched, session: result.sessionName, crossProject };
146
+ }
147
+ const sessionName = employeeSessionName(input.assignedTo, exeSession);
148
+ if (transport.isAlive(sessionName)) {
149
+ const result = sendIntercom(sessionName, { force: true });
150
+ const dispatched = result === "acknowledged" || result === "debounced" || result === "queued" ? "verified" : result === "delivered" ? "sent_unverified" : "session_dead";
151
+ process.stderr.write(
152
+ `[dispatch-audit] intercom \u2192 ${sessionName} | task="${input.title}" [${input.priority}] | result=${dispatched} (sendIntercom=${result})
153
+ `
154
+ );
155
+ recordOrchestrationEventBestEffort({
156
+ eventType: "dispatch.completed",
157
+ source: "tasks-notify.dispatchTaskToEmployee",
158
+ taskId: input.taskId ?? null,
159
+ agentId: input.assignedTo,
160
+ sessionScope: exeSession,
161
+ tmuxSession: sessionName,
162
+ runtime: dispatchRuntime,
163
+ result: dispatched,
164
+ payload: { path: "single_instance_intercom", priority: input.priority }
165
+ });
166
+ return { dispatched, session: sessionName, crossProject };
167
+ } else {
168
+ const projectDir = input.projectDir ?? process.cwd();
169
+ const result = ensureEmployee(input.assignedTo, exeSession, projectDir, {
170
+ runtimeOverride: input.spawnRuntime,
171
+ modelOverride: input.spawnModel
172
+ });
173
+ if (result.status === "failed") {
174
+ process.stderr.write(
175
+ `[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${result.error}
176
+ `
177
+ );
178
+ recordOrchestrationEventBestEffort({
179
+ eventType: "dispatch.failed",
180
+ source: "tasks-notify.dispatchTaskToEmployee",
181
+ taskId: input.taskId ?? null,
182
+ agentId: input.assignedTo,
183
+ sessionScope: exeSession,
184
+ runtime: dispatchRuntime,
185
+ errorCode: "spawn_failed",
186
+ payload: { path: "single_instance_spawn", error: result.error }
187
+ });
188
+ return { dispatched: "session_missing" };
189
+ }
190
+ process.stderr.write(
191
+ `[dispatch-audit] SPAWNED \u2192 ${result.sessionName} | task="${input.title}" [${input.priority}]
192
+ `
193
+ );
194
+ recordOrchestrationEventBestEffort({
195
+ eventType: "dispatch.completed",
196
+ source: "tasks-notify.dispatchTaskToEmployee",
197
+ taskId: input.taskId ?? null,
198
+ agentId: input.assignedTo,
199
+ sessionScope: exeSession,
200
+ tmuxSession: result.sessionName,
201
+ runtime: dispatchRuntime,
202
+ result: "spawned",
203
+ payload: { path: "single_instance_spawn", priority: input.priority }
204
+ });
205
+ return { dispatched: "spawned", session: result.sessionName, crossProject };
206
+ }
207
+ } catch {
208
+ recordOrchestrationEventBestEffort({
209
+ eventType: "dispatch.failed",
210
+ source: "tasks-notify.dispatchTaskToEmployee",
211
+ taskId: input.taskId ?? null,
212
+ agentId: input.assignedTo,
213
+ runtime: dispatchRuntime,
214
+ errorCode: "exception"
215
+ });
216
+ return { dispatched: "session_missing" };
217
+ }
218
+ }
219
+ function notifyTaskDone() {
220
+ try {
221
+ const key = getSessionKey();
222
+ if (key && !process.env.VITEST) {
223
+ notifyParentExe(key);
224
+ process.stderr.write(
225
+ `[dispatch-audit] notifyTaskDone \u2192 parent coordinator (session=${key})
226
+ `
227
+ );
228
+ }
229
+ } catch {
230
+ }
231
+ }
232
+ async function markTaskNotificationsRead(taskFile) {
233
+ try {
234
+ await markAsReadByTaskFile(taskFile);
235
+ } catch {
236
+ }
237
+ }
238
+
239
+ export {
240
+ verifyDispatch,
241
+ dispatchTaskToEmployee,
242
+ notifyTaskDone,
243
+ markTaskNotificationsRead
244
+ };
@@ -0,0 +1,38 @@
1
+ import {
2
+ listReminders
3
+ } from "./chunk-ZKHPZ6KN.js";
4
+
5
+ // src/mcp/tools/list-reminders.ts
6
+ import { z } from "zod";
7
+ function registerListReminders(server) {
8
+ server.registerTool(
9
+ "list_reminders",
10
+ {
11
+ title: "List Reminders",
12
+ description: "List active reminders. Pass include_completed=true to see all.",
13
+ inputSchema: {
14
+ include_completed: z.boolean().optional().default(false).describe("Include completed reminders")
15
+ }
16
+ },
17
+ async ({ include_completed }) => {
18
+ const reminders = await listReminders(include_completed);
19
+ if (reminders.length === 0) {
20
+ return {
21
+ content: [{ type: "text", text: "No active reminders." }]
22
+ };
23
+ }
24
+ const lines = reminders.map((r) => {
25
+ const due = r.dueDate ? ` (due: ${r.dueDate})` : "";
26
+ const done = r.completedAt ? " [DONE]" : "";
27
+ return `\u2022 ${r.text}${due}${done} [id: ${r.id.slice(0, 8)}]`;
28
+ });
29
+ return {
30
+ content: [{ type: "text", text: lines.join("\n") }]
31
+ };
32
+ }
33
+ );
34
+ }
35
+
36
+ export {
37
+ registerListReminders
38
+ };
@@ -0,0 +1,150 @@
1
+ import {
2
+ isCoordinatorRole
3
+ } from "./chunk-V6LOEOXG.js";
4
+
5
+ // src/lib/task-router.ts
6
+ import { randomUUID } from "crypto";
7
+ var DEFAULT_BLOOM_CONFIG = {
8
+ complexityToTier: {
9
+ routine: "junior",
10
+ standard: "standard",
11
+ complex: "senior",
12
+ critical: "specialist"
13
+ },
14
+ tierRules: {
15
+ junior: {
16
+ eligible: [],
17
+ // resolved dynamically from roster (Principal Engineer role)
18
+ reviewRequired: false,
19
+ manualOnly: false
20
+ },
21
+ standard: {
22
+ eligible: [],
23
+ // resolved dynamically from roster (Principal Engineer role)
24
+ reviewRequired: false,
25
+ manualOnly: false
26
+ },
27
+ senior: {
28
+ eligible: [],
29
+ // any specialist, but review required
30
+ reviewRequired: true,
31
+ manualOnly: false
32
+ },
33
+ specialist: {
34
+ eligible: [],
35
+ reviewRequired: true,
36
+ manualOnly: true
37
+ }
38
+ }
39
+ };
40
+ function resolveBloomRouting(complexity, config = DEFAULT_BLOOM_CONFIG) {
41
+ const tier = config.complexityToTier[complexity];
42
+ const rule = config.tierRules[tier];
43
+ return {
44
+ tier,
45
+ reviewRequired: rule.reviewRequired,
46
+ manualOnly: rule.manualOnly,
47
+ eligible: rule.eligible
48
+ };
49
+ }
50
+ async function scoreEmployee(taskVector, agentId, searchFn) {
51
+ const results = await searchFn(taskVector, agentId, { limit: 5 });
52
+ if (results.length === 0) {
53
+ return { agentId, score: 0 };
54
+ }
55
+ const distances = results.map((r) => r["_distance"]).filter((d) => typeof d === "number");
56
+ if (distances.length > 0) {
57
+ const avgDistance = distances.reduce((sum, d) => sum + d, 0) / distances.length;
58
+ return { agentId, score: 1 / (1 + avgDistance) };
59
+ }
60
+ return { agentId, score: results.length / 5 };
61
+ }
62
+ function keywordScoreTask(taskDescription, employee) {
63
+ const task = taskDescription.toLowerCase();
64
+ const terms = `${employee.name} ${employee.role}`.toLowerCase().split(/[^a-z0-9]+/).filter((term) => term.length >= 3);
65
+ if (terms.length === 0) return 0;
66
+ const matches = terms.filter((term) => task.includes(term)).length;
67
+ return matches / terms.length;
68
+ }
69
+ async function routeTask(taskDescription, employees, embedFn, searchFn, options) {
70
+ let specialists = employees.filter((e) => !isCoordinatorRole(e.role));
71
+ if (specialists.length === 0) {
72
+ throw new Error(
73
+ "No specialist employees available. Create one with /exe-new-employee."
74
+ );
75
+ }
76
+ let bloomRouting;
77
+ if (options?.complexity) {
78
+ bloomRouting = resolveBloomRouting(options.complexity, options.bloomConfig);
79
+ if (bloomRouting.manualOnly) {
80
+ throw new Error(
81
+ `Task complexity "${options.complexity}" requires manual assignment (tier: ${bloomRouting.tier}).`
82
+ );
83
+ }
84
+ if (bloomRouting.eligible.length > 0) {
85
+ const eligible = new Set(bloomRouting.eligible);
86
+ const filtered = specialists.filter((e) => eligible.has(e.name));
87
+ if (filtered.length > 0) {
88
+ specialists = filtered;
89
+ }
90
+ }
91
+ }
92
+ let taskVector = null;
93
+ try {
94
+ taskVector = await embedFn(taskDescription);
95
+ } catch {
96
+ taskVector = null;
97
+ }
98
+ const scored = taskVector ? await Promise.all(
99
+ specialists.map(async (emp) => {
100
+ const { score } = await scoreEmployee(taskVector, emp.name, searchFn);
101
+ return { employee: emp, score };
102
+ })
103
+ ) : specialists.map((emp) => ({
104
+ employee: emp,
105
+ score: keywordScoreTask(taskDescription, emp)
106
+ }));
107
+ scored.sort((a, b) => b.score - a.score);
108
+ return { ...scored[0], bloomRouting };
109
+ }
110
+ function createAssignmentMemory(taskDescription, assignedTo, assignedBy) {
111
+ return {
112
+ id: randomUUID(),
113
+ agent_id: assignedTo.name,
114
+ agent_role: assignedTo.role,
115
+ session_id: `assign-${Date.now()}`,
116
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
117
+ tool_name: "assignment",
118
+ project_name: "",
119
+ has_error: false,
120
+ raw_text: `Task assigned by ${assignedBy}: ${taskDescription}`,
121
+ vector: null
122
+ // Will be backfilled
123
+ };
124
+ }
125
+ function formatAssignmentOutput(employee, task, score, mode, bloomRouting) {
126
+ const modeLabel = mode === "auto" ? "auto-routed" : "direct";
127
+ const percent = Math.round(score * 100);
128
+ const lines = [
129
+ `Assigned to ${employee.name} (${employee.role})`,
130
+ `Mode: ${modeLabel}`,
131
+ `Relevance: ${percent}%`,
132
+ `Task: ${task}`
133
+ ];
134
+ if (bloomRouting) {
135
+ lines.push(`Complexity tier: ${bloomRouting.tier}`);
136
+ if (bloomRouting.reviewRequired) {
137
+ lines.push(`Review: required`);
138
+ }
139
+ }
140
+ return lines.join("\n");
141
+ }
142
+
143
+ export {
144
+ DEFAULT_BLOOM_CONFIG,
145
+ resolveBloomRouting,
146
+ scoreEmployee,
147
+ routeTask,
148
+ createAssignmentMemory,
149
+ formatAssignmentOutput
150
+ };
@@ -0,0 +1,76 @@
1
+ import {
2
+ fastDbInit
3
+ } from "./chunk-ZDY4LYAJ.js";
4
+ import {
5
+ sessionScopeFilter
6
+ } from "./chunk-ZSUACDQC.js";
7
+ import {
8
+ formatStatusAll,
9
+ formatStatusDeep,
10
+ getEmployeeStatuses,
11
+ inTmux
12
+ } from "./chunk-SSTLTIF3.js";
13
+ import {
14
+ getClient,
15
+ isCoordinatorRole,
16
+ loadEmployees
17
+ } from "./chunk-V6LOEOXG.js";
18
+ import {
19
+ isMainModule
20
+ } from "./chunk-6Y4B3QF6.js";
21
+
22
+ // src/bin/exe-status.ts
23
+ async function status(targetEmployee) {
24
+ if (!inTmux()) {
25
+ return "Not in a tmux session. Start tmux first: tmux new-session -s work";
26
+ }
27
+ const employees = await loadEmployees();
28
+ const names = employees.filter((e) => !isCoordinatorRole(e.role)).map((e) => e.name);
29
+ const roles = new Map(employees.map((e) => [e.name, e.role ?? ""]));
30
+ await fastDbInit();
31
+ const client = getClient();
32
+ const taskMap = /* @__PURE__ */ new Map();
33
+ try {
34
+ const esScope = sessionScopeFilter();
35
+ const result = await client.execute({
36
+ sql: `SELECT assigned_to, title, priority FROM tasks
37
+ WHERE status = 'in_progress'${esScope.sql}
38
+ ORDER BY priority ASC, created_at ASC`,
39
+ args: [...esScope.args]
40
+ });
41
+ for (const row of result.rows) {
42
+ const assignee = String(row.assigned_to);
43
+ if (!taskMap.has(assignee)) {
44
+ taskMap.set(assignee, {
45
+ title: String(row.title),
46
+ priority: String(row.priority)
47
+ });
48
+ }
49
+ }
50
+ } catch {
51
+ }
52
+ if (targetEmployee) {
53
+ if (!names.includes(targetEmployee)) {
54
+ return `Employee "${targetEmployee}" not found. Available: ${names.join(", ")}`;
55
+ }
56
+ const statuses2 = getEmployeeStatuses([targetEmployee]);
57
+ const s = statuses2[0];
58
+ return formatStatusDeep(s, taskMap.get(targetEmployee), roles.get(targetEmployee) ?? "");
59
+ }
60
+ const statuses = getEmployeeStatuses(names);
61
+ return formatStatusAll(statuses, taskMap, roles);
62
+ }
63
+ if (isMainModule(import.meta.url)) {
64
+ const target = process.argv[2];
65
+ status(target).then((output) => {
66
+ process.stdout.write(output + "\n");
67
+ }).catch((err) => {
68
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
69
+ `);
70
+ process.exit(1);
71
+ });
72
+ }
73
+
74
+ export {
75
+ status
76
+ };