@askexenow/exe-os 0.9.207 → 0.9.209

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 (138) hide show
  1. package/dist/{backfill-metadata-4N22ZA6N.js → backfill-metadata-32SPFWL5.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 +1 -1
  9. package/dist/bin/cleanup-stale-review-tasks.js +2 -2
  10. package/dist/bin/cli.js +5 -5
  11. package/dist/bin/exe-agent.js +10 -10
  12. package/dist/bin/exe-assign.js +1 -1
  13. package/dist/bin/exe-boot.js +3 -3
  14. package/dist/bin/exe-dispatch.js +2 -2
  15. package/dist/bin/exe-doctor.js +1 -1
  16. package/dist/bin/exe-export-behaviors.js +2 -2
  17. package/dist/bin/exe-forget.js +3 -3
  18. package/dist/bin/exe-gateway.js +4 -4
  19. package/dist/bin/exe-heartbeat.js +2 -2
  20. package/dist/bin/exe-kill.js +3 -3
  21. package/dist/bin/exe-launch-agent.js +2 -2
  22. package/dist/bin/exe-pending-messages.js +3 -3
  23. package/dist/bin/exe-pending-notifications.js +2 -2
  24. package/dist/bin/exe-pending-reviews.js +2 -2
  25. package/dist/bin/exe-review.js +3 -3
  26. package/dist/bin/exe-search.js +2 -2
  27. package/dist/bin/exe-session-cleanup.js +5 -5
  28. package/dist/bin/exe-start-codex.js +1 -1
  29. package/dist/bin/exe-start-opencode.js +1 -1
  30. package/dist/bin/exe-status.js +3 -3
  31. package/dist/bin/exe-team.js +1 -1
  32. package/dist/bin/git-sweep.js +2 -2
  33. package/dist/bin/graph-backfill.js +1 -1
  34. package/dist/bin/graph-export.js +2 -2
  35. package/dist/bin/import-history.js +1 -1
  36. package/dist/bin/intercom-check.js +3 -3
  37. package/dist/bin/mcp-sessions.js +194 -0
  38. package/dist/bin/orchestration-metrics.js +1 -1
  39. package/dist/bin/scan-tasks.js +2 -2
  40. package/dist/bin/setup.js +1 -1
  41. package/dist/bin/shard-migrate.js +1 -1
  42. package/dist/{capacity-monitor-EHXIFEE2.js → capacity-monitor-PQ7EZ5ES.js} +2 -2
  43. package/dist/{catchup-brief-AYLBTVRM.js → catchup-brief-FJM4C6R6.js} +3 -3
  44. package/dist/{chunk-EAHUS6WU.js → chunk-3GFXV46R.js} +1 -1
  45. package/dist/{chunk-MGPVDQIM.js → chunk-5452FPV5.js} +1 -1
  46. package/dist/{chunk-TV7ZTQ7L.js → chunk-6XAXYBCI.js} +7 -7
  47. package/dist/{chunk-4EOXPKWA.js → chunk-A3K7V6SW.js} +128 -4
  48. package/dist/{chunk-7VDMUMHM.js → chunk-AOBTVA7I.js} +3 -3
  49. package/dist/{chunk-QOAPYITU.js → chunk-BO6HP63V.js} +2 -2
  50. package/dist/{chunk-RRMPIH6C.js → chunk-DYY6DEA4.js} +3 -3
  51. package/dist/{chunk-SQK3Q6VY.js → chunk-EXRMA2QK.js} +16 -16
  52. package/dist/{chunk-YQKFNXGL.js → chunk-EYXCCLFI.js} +2 -2
  53. package/dist/{chunk-3BV34EJB.js → chunk-GD5AQDZL.js} +1 -1
  54. package/dist/{chunk-MMLE3M4J.js → chunk-IZPPTNXR.js} +1 -1
  55. package/dist/{chunk-FLCWUX6G.js → chunk-K5EXLDQD.js} +1 -1
  56. package/dist/{chunk-QOTQZAAE.js → chunk-K5O5UAO3.js} +1 -1
  57. package/dist/{chunk-T4TMVXF5.js → chunk-LEVLIEBX.js} +4 -4
  58. package/dist/{chunk-OBVXTLRM.js → chunk-MTZZHS73.js} +2 -2
  59. package/dist/{chunk-DBSMRM52.js → chunk-PQU74C7J.js} +2 -2
  60. package/dist/{chunk-WGOVSJNR.js → chunk-PZCC4YWO.js} +1 -1
  61. package/dist/{chunk-434A3L6O.js → chunk-Q72H4NTD.js} +99 -32
  62. package/dist/{chunk-T4BKQ3CX.js → chunk-RVT5AV3R.js} +48 -48
  63. package/dist/{chunk-PNQ74YDS.js → chunk-SNEP3JX2.js} +2 -2
  64. package/dist/{chunk-BS6YQM5R.js → chunk-UK5GYNHU.js} +1 -1
  65. package/dist/{chunk-MB7PRC5E.js → chunk-VBPNKKOP.js} +1 -1
  66. package/dist/{chunk-3M2CCVXM.js → chunk-VUJHFM4F.js} +1 -1
  67. package/dist/{chunk-4EKVVGVV.js → chunk-YDXCENQ5.js} +1 -1
  68. package/dist/{chunk-RS5JCKEP.js → chunk-ZCA2WOY3.js} +1 -1
  69. package/dist/{crm-webhook-VSPYINPL.js → crm-webhook-NGKBEDCE.js} +2 -2
  70. package/dist/{cto-delegation-gate-W7ESM5IQ.js → cto-delegation-gate-6YC3E5RL.js} +1 -1
  71. package/dist/{daemon-orchestration-TC3JWVDC.js → daemon-orchestration-QVJ26DDN.js} +3 -3
  72. package/dist/{exe-export-6NC4TNCZ.js → exe-export-3KLM55BC.js} +1 -1
  73. package/dist/{exe-import-GQRGZKW3.js → exe-import-SFRVKEGL.js} +1 -1
  74. package/dist/{fast-db-init-4ETTWASA.js → fast-db-init-WSVNCMIA.js} +1 -1
  75. package/dist/gateway/index.js +19 -19
  76. package/dist/{git-task-sweep-HMSTHZ6X.js → git-task-sweep-KBCSNNWI.js} +2 -2
  77. package/dist/hooks/bug-report-worker.js +3 -3
  78. package/dist/hooks/codex-stop-task-finalizer.js +3 -3
  79. package/dist/hooks/commit-complete.js +4 -4
  80. package/dist/hooks/error-recall.js +2 -2
  81. package/dist/hooks/ingest.js +2 -2
  82. package/dist/hooks/instructions-loaded.js +1 -1
  83. package/dist/hooks/manifest.json +18 -18
  84. package/dist/hooks/notification.js +1 -1
  85. package/dist/hooks/post-compact.js +2 -2
  86. package/dist/hooks/post-tool-combined.js +2 -2
  87. package/dist/hooks/pre-compact.js +3 -3
  88. package/dist/hooks/pre-tool-use.js +6 -6
  89. package/dist/hooks/prompt-submit.js +8 -8
  90. package/dist/hooks/session-end.js +4 -4
  91. package/dist/hooks/session-start.js +4 -4
  92. package/dist/hooks/stop.js +5 -5
  93. package/dist/hooks/subagent-stop.js +2 -2
  94. package/dist/hooks/summary-worker.js +5 -5
  95. package/dist/index.js +12 -12
  96. package/dist/lib/consolidation.js +2 -2
  97. package/dist/lib/exe-daemon.js +31 -14
  98. package/dist/lib/hybrid-search.js +2 -2
  99. package/dist/lib/messaging.js +2 -2
  100. package/dist/lib/schedules.js +2 -2
  101. package/dist/lib/store.js +1 -1
  102. package/dist/lib/tasks.js +2 -2
  103. package/dist/lib/tmux-routing.js +1 -1
  104. package/dist/lib/token-spend.js +1 -1
  105. package/dist/mcp/register-tools.js +28 -28
  106. package/dist/mcp/server.js +31 -31
  107. package/dist/mcp/tools/create-task.js +3 -3
  108. package/dist/mcp/tools/list-tasks.js +3 -3
  109. package/dist/mcp/tools/send-message.js +3 -3
  110. package/dist/mcp/tools/update-task.js +3 -3
  111. package/dist/{notifications-25FGAXTC.js → notifications-YF7ANNPB.js} +1 -1
  112. package/dist/{orchestrator-ZWPDXMW4.js → orchestrator-3G7MW4XO.js} +2 -2
  113. package/dist/{reranker-TRLLNJHH.js → reranker-KKGT2QH5.js} +1 -1
  114. package/dist/{review-polling-QQMFB3Q4.js → review-polling-E2ZTZAR7.js} +2 -2
  115. package/dist/runtime/index.js +7 -7
  116. package/dist/{session-events-OWSPMDJV.js → session-events-RNEA3WRN.js} +2 -2
  117. package/dist/{session-scope-PKBCQOLO.js → session-scope-RGIEAQRR.js} +1 -1
  118. package/dist/{setup-wizard-2INM4CSL.js → setup-wizard-AZOKR4PP.js} +1 -1
  119. package/dist/{task-enforcement-M2NU3OVK.js → task-enforcement-OSPCFH5T.js} +1 -1
  120. package/dist/{task-scope-LQRP3MQ2.js → task-scope-4CBJ3QI2.js} +1 -1
  121. package/dist/{tasks-crud-TMYB245Z.js → tasks-crud-PQ23SS5C.js} +5 -1
  122. package/dist/{tasks-review-GJWB2BPT.js → tasks-review-XZSYVGRL.js} +1 -1
  123. package/dist/{telemetry-upload-Y3CPHI7M.js → telemetry-upload-DPF4WUMT.js} +21 -7
  124. package/dist/tui/App.js +7 -7
  125. package/dist/{tui-data-ZVRIZAIF.js → tui-data-SKVPBPBV.js} +1 -1
  126. package/dist/{worker-gate-VZLM2AU3.js → worker-gate-XHZWIMDA.js} +1 -1
  127. package/dist/{workflow-engine-ESXHBY55.js → workflow-engine-RN3ADPEN.js} +2 -2
  128. package/package.json +1 -1
  129. package/release-notes.json +71 -71
  130. /package/dist/{chunk-KJVFW5C7.js → chunk-E3Q4R3K6.js} +0 -0
  131. /package/dist/{chunk-MTR5SMNA.js → chunk-GMQKS5JD.js} +0 -0
  132. /package/dist/{chunk-P5J37OSU.js → chunk-MBF42HXN.js} +0 -0
  133. /package/dist/{chunk-ATKMIQXP.js → chunk-RUTQMSNJ.js} +0 -0
  134. /package/dist/{chunk-SEPXWHA3.js → chunk-UDSY3K33.js} +0 -0
  135. /package/dist/{chunk-5YFC6HQX.js → chunk-Z2HB2SXL.js} +0 -0
  136. /package/dist/{core-memory-6JX6V4QR.js → core-memory-U6ZYHCFK.js} +0 -0
  137. /package/dist/{exe-key-K7FHMOVL.js → exe-key-FLTUNYFH.js} +0 -0
  138. /package/dist/{skill-refinement-KL2INB5E.js → skill-refinement-BGWMSERG.js} +0 -0
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isMainModule
4
+ } from "../chunk-6Y4B3QF6.js";
5
+ import "../chunk-MLKGABMK.js";
6
+
7
+ // src/bin/mcp-sessions.ts
8
+ function boxTable(headers, rows) {
9
+ const colWidths = headers.map(
10
+ (h, i) => Math.max(h.length, ...rows.map((r) => stripAnsi(r[i] ?? "").length))
11
+ );
12
+ const top = "\u250C" + colWidths.map((w) => "\u2500".repeat(w + 2)).join("\u252C") + "\u2510";
13
+ const mid = "\u251C" + colWidths.map((w) => "\u2500".repeat(w + 2)).join("\u253C") + "\u2524";
14
+ const bot = "\u2514" + colWidths.map((w) => "\u2500".repeat(w + 2)).join("\u2534") + "\u2518";
15
+ const formatRow = (cells) => "\u2502" + cells.map((c, i) => " " + padRight(c, colWidths[i]) + " ").join("\u2502") + "\u2502";
16
+ const lines = [top, formatRow(headers), mid];
17
+ for (const row of rows) {
18
+ lines.push(formatRow(row));
19
+ }
20
+ lines.push(bot);
21
+ return lines.join("\n");
22
+ }
23
+ function padRight(str, width) {
24
+ const visible = stripAnsi(str).length;
25
+ return str + " ".repeat(Math.max(0, width - visible));
26
+ }
27
+ function stripAnsi(str) {
28
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
29
+ }
30
+ function formatAge(ms) {
31
+ if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
32
+ if (ms < 36e5) return `${Math.round(ms / 6e4)}m`;
33
+ const h = Math.floor(ms / 36e5);
34
+ const m = Math.round(ms % 36e5 / 6e4);
35
+ return m > 0 ? `${h}h ${m}m` : `${h}h`;
36
+ }
37
+ async function collectSessions() {
38
+ const { listTmuxSessions } = await import("../lib/tmux-status.js");
39
+ const { loadEmployeesSync } = await import("../lib/employees.js");
40
+ const { listSessions: listRegistered } = await import("../lib/session-registry.js");
41
+ const tmuxSessions = listTmuxSessions();
42
+ const employees = loadEmployeesSync();
43
+ const roleMap = new Map(employees.map((e) => [e.name, e.role ?? "employee"]));
44
+ const registry = listRegistered();
45
+ const registryMap = new Map(registry.map((r) => [r.windowName, r]));
46
+ const taskMap = /* @__PURE__ */ new Map();
47
+ try {
48
+ const { fastDbInit } = await import("../fast-db-init-WSVNCMIA.js");
49
+ await fastDbInit();
50
+ const { getClient } = await import("../lib/database.js");
51
+ const { sessionScopeFilter } = await import("../task-scope-4CBJ3QI2.js");
52
+ const client = getClient();
53
+ const scope = sessionScopeFilter();
54
+ const result = await client.execute({
55
+ sql: `SELECT assigned_to, title, priority, status FROM tasks
56
+ WHERE status IN ('open', 'in_progress', 'needs_review', 'blocked')${scope.sql}
57
+ ORDER BY CASE status WHEN 'in_progress' THEN 0 WHEN 'open' THEN 1 WHEN 'needs_review' THEN 2 ELSE 3 END,
58
+ priority ASC, created_at DESC`,
59
+ args: [...scope.args]
60
+ });
61
+ for (const row of result.rows) {
62
+ const agent = String(row.assigned_to);
63
+ if (!taskMap.has(agent)) {
64
+ taskMap.set(agent, {
65
+ title: String(row.title).slice(0, 40),
66
+ priority: String(row.priority),
67
+ status: String(row.status)
68
+ });
69
+ }
70
+ }
71
+ } catch {
72
+ }
73
+ const rows = [];
74
+ for (const sess of tmuxSessions) {
75
+ const isEmployee = sess.includes("-");
76
+ const agentPart = isEmployee ? sess.split("-")[0] : sess;
77
+ const agentName = agentPart.replace(/\d+$/, "");
78
+ const role = roleMap.get(agentName) ?? (isEmployee ? "employee" : "coordinator");
79
+ const regEntry = registryMap.get(sess);
80
+ const age = regEntry?.registeredAt ? formatAge(Date.now() - new Date(regEntry.registeredAt).getTime()) : "?";
81
+ const task = taskMap.get(agentName);
82
+ let status = "idle";
83
+ let taskTitle = "\u2014";
84
+ let priority = "";
85
+ if (task) {
86
+ status = task.status === "in_progress" ? "working" : task.status;
87
+ taskTitle = task.title;
88
+ priority = task.priority.toUpperCase();
89
+ }
90
+ const statusDisplay = status === "working" ? "\u{1F7E2} working" : status === "needs_review" ? "\u{1F7E0} review" : status === "blocked" ? "\u{1F534} blocked" : status === "open" ? "\u{1F7E1} has task" : "\u26AA idle";
91
+ rows.push({
92
+ session: sess,
93
+ agent: agentName,
94
+ role,
95
+ status: statusDisplay,
96
+ task: taskTitle,
97
+ priority,
98
+ age,
99
+ contextPct: "\u2014"
100
+ // Would need pane capture — skip for speed
101
+ });
102
+ }
103
+ rows.sort((a, b) => {
104
+ const aCoord = !a.session.includes("-") ? 0 : 1;
105
+ const bCoord = !b.session.includes("-") ? 0 : 1;
106
+ if (aCoord !== bCoord) return aCoord - bCoord;
107
+ return a.session.localeCompare(b.session);
108
+ });
109
+ return rows;
110
+ }
111
+ async function getDaemonHealth() {
112
+ try {
113
+ const { readFileSync } = await import("fs");
114
+ const { homedir } = await import("os");
115
+ const { join } = await import("path");
116
+ const healthLog = join(homedir(), ".exe-os", "logs", "daemon-health.log");
117
+ const lines = readFileSync(healthLog, "utf-8").trim().split("\n");
118
+ let bootTs = "";
119
+ let lastHeartbeat = {};
120
+ let blockCount = 0;
121
+ let selfHealCount = 0;
122
+ let pid = 0;
123
+ for (let i = lines.length - 1; i >= Math.max(0, lines.length - 200); i--) {
124
+ try {
125
+ const entry = JSON.parse(lines[i]);
126
+ if (!pid && entry.event === "mcp_bind") pid = Number(entry.pid);
127
+ if (pid && Number(entry.pid) !== pid) continue;
128
+ if (entry.event === "boot") {
129
+ bootTs = String(entry.ts);
130
+ break;
131
+ }
132
+ if (entry.event === "heartbeat" && !lastHeartbeat.ts) lastHeartbeat = entry;
133
+ if (entry.event === "event_loop_blocked") blockCount++;
134
+ if (entry.event === "self_heal_restart") selfHealCount++;
135
+ } catch {
136
+ continue;
137
+ }
138
+ }
139
+ const uptime = bootTs ? formatAge(Date.now() - new Date(bootTs).getTime()) : "?";
140
+ const data = lastHeartbeat.data ?? {};
141
+ const rss = data.daemonRssMb ? `${Math.round(Number(data.daemonRssMb))} MB` : "?";
142
+ const cpu = data.daemonCpu !== void 0 ? `${Number(data.daemonCpu).toFixed(1)}%` : "?";
143
+ return [
144
+ ["Uptime", uptime],
145
+ ["PID", String(pid || "?")],
146
+ ["RSS", rss],
147
+ ["CPU", cpu],
148
+ ["Event loop blocks", String(blockCount)],
149
+ ["Self-heal restarts", String(selfHealCount)]
150
+ ];
151
+ } catch {
152
+ return [["Daemon", "unreachable"]];
153
+ }
154
+ }
155
+ async function main() {
156
+ const args = process.argv.slice(2);
157
+ const jsonMode = args.includes("--json");
158
+ const showDaemon = args.includes("--daemon");
159
+ const sessions = await collectSessions();
160
+ if (jsonMode) {
161
+ process.stdout.write(JSON.stringify(sessions, null, 2) + "\n");
162
+ return;
163
+ }
164
+ if (sessions.length === 0) {
165
+ process.stdout.write("No active sessions.\n");
166
+ return;
167
+ }
168
+ const headers = ["Session", "Agent", "Role", "Status", "Task", "Pri", "Age"];
169
+ const rows = sessions.map((s) => [s.session, s.agent, s.role, s.status, s.task, s.priority, s.age]);
170
+ process.stdout.write("\n" + boxTable(headers, rows) + "\n");
171
+ const working = sessions.filter((s) => s.status.includes("working")).length;
172
+ const idle = sessions.filter((s) => s.status.includes("idle")).length;
173
+ const review = sessions.filter((s) => s.status.includes("review")).length;
174
+ process.stdout.write(`
175
+ ${sessions.length} sessions: ${working} working, ${review} in review, ${idle} idle
176
+ `);
177
+ if (showDaemon) {
178
+ const health = await getDaemonHealth();
179
+ process.stdout.write("\n" + boxTable(["Daemon", "Value"], health) + "\n");
180
+ }
181
+ process.stdout.write("\n");
182
+ }
183
+ if (isMainModule(import.meta.url)) {
184
+ main().catch((err) => {
185
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
186
+ `);
187
+ process.exit(1);
188
+ });
189
+ }
190
+ export {
191
+ boxTable,
192
+ collectSessions,
193
+ getDaemonHealth
194
+ };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-MTR5SMNA.js";
4
+ } from "../chunk-GMQKS5JD.js";
5
5
  import {
6
6
  formatOrchestrationMetrics,
7
7
  getOrchestrationMetrics
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  queryTaskRows
4
- } from "../chunk-4EOXPKWA.js";
4
+ } from "../chunk-A3K7V6SW.js";
5
5
  import "../chunk-FYJCMGTD.js";
6
6
  import "../chunk-QI4IXJN7.js";
7
7
  import "../chunk-IR4L6K5L.js";
@@ -73,7 +73,7 @@ function checkMcpHealth() {
73
73
  }
74
74
  }
75
75
  async function scanFromDb(agentId, tmuxSession, projectName) {
76
- const { fastDbInit } = await import("../fast-db-init-4ETTWASA.js");
76
+ const { fastDbInit } = await import("../fast-db-init-WSVNCMIA.js");
77
77
  try {
78
78
  await fastDbInit();
79
79
  } catch (err) {
package/dist/bin/setup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSetupWizard
4
- } from "../chunk-ATKMIQXP.js";
4
+ } from "../chunk-RUTQMSNJ.js";
5
5
  import "../chunk-6D23UNXU.js";
6
6
  import "../chunk-WXW3XGWX.js";
7
7
  import "../chunk-LYH5HE24.js";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  disposeStore,
10
10
  initStore
11
- } from "../chunk-KJVFW5C7.js";
11
+ } from "../chunk-E3Q4R3K6.js";
12
12
  import "../chunk-CHCA3ZM2.js";
13
13
  import "../chunk-XJQASQPO.js";
14
14
  import "../chunk-MP2AFCGL.js";
@@ -8,9 +8,9 @@ import {
8
8
  isAtCapacity,
9
9
  isWithinRelaunchCooldown,
10
10
  pollCapacityDead
11
- } from "./chunk-WGOVSJNR.js";
11
+ } from "./chunk-PZCC4YWO.js";
12
12
  import "./chunk-3S3ERUUH.js";
13
- import "./chunk-4EOXPKWA.js";
13
+ import "./chunk-A3K7V6SW.js";
14
14
  import "./chunk-FYJCMGTD.js";
15
15
  import "./chunk-QI4IXJN7.js";
16
16
  import "./chunk-IR4L6K5L.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  lightweightSearch
3
- } from "./chunk-T4TMVXF5.js";
4
- import "./chunk-KJVFW5C7.js";
3
+ } from "./chunk-LEVLIEBX.js";
4
+ import "./chunk-E3Q4R3K6.js";
5
5
  import "./chunk-CHCA3ZM2.js";
6
6
  import "./chunk-XJQASQPO.js";
7
7
  import {
8
8
  sessionScopeFilter,
9
9
  strictSessionScopeFilter
10
- } from "./chunk-4EOXPKWA.js";
10
+ } from "./chunk-A3K7V6SW.js";
11
11
  import "./chunk-FYJCMGTD.js";
12
12
  import "./chunk-QI4IXJN7.js";
13
13
  import "./chunk-IR4L6K5L.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getCurrentSessionScope,
3
3
  strictSessionScopeFilter
4
- } from "./chunk-4EOXPKWA.js";
4
+ } from "./chunk-A3K7V6SW.js";
5
5
  import {
6
6
  getProjectName
7
7
  } from "./chunk-OPU3NYOO.js";
@@ -9,7 +9,7 @@ import {
9
9
  isEmployeeAlive,
10
10
  sessionScopeFilter,
11
11
  updateTaskStatus
12
- } from "./chunk-4EOXPKWA.js";
12
+ } from "./chunk-A3K7V6SW.js";
13
13
  import {
14
14
  DEFAULT_COORDINATOR_TEMPLATE_NAME,
15
15
  getCoordinatorName
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  MultiAgentOrchestrator
3
- } from "./chunk-MGPVDQIM.js";
3
+ } from "./chunk-5452FPV5.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";
9
13
  import {
10
14
  checkPathSafety,
11
15
  checkReadPathSafety,
12
16
  containsPathTraversal
13
17
  } from "./chunk-NGVOA6ZQ.js";
14
- import {
15
- checkDangerousPatterns,
16
- hasCriticalPattern
17
- } from "./chunk-AVE2B4DQ.js";
18
18
  import {
19
19
  ContextManager,
20
20
  agentLoop,
@@ -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-LQRP3MQ2.js");
330
+ const { sessionScopeFilter } = await import("./task-scope-4CBJ3QI2.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-LQRP3MQ2.js");
422
+ const { sessionScopeFilter: cpScopeFilter } = await import("./task-scope-4CBJ3QI2.js");
423
423
  const client = getClient();
424
424
  const cpScope = cpScopeFilter();
425
425
  const tasks = await client.execute({
@@ -182,6 +182,93 @@ import os2 from "os";
182
182
  import { execSync } from "child_process";
183
183
  import { mkdir, writeFile, appendFile } from "fs/promises";
184
184
  import { existsSync as existsSync2, readFileSync } from "fs";
185
+ var TASK_COMPLETION_REPORT_HEADING = "# Task Completion Report";
186
+ var REPORTABLE_COMPLETION_STATUSES = /* @__PURE__ */ new Set(["needs_review"]);
187
+ var FILE_PATH_RE = /(?:^|\s)([\w./-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|sql|go|py|css|scss|html|sh))(?:\b|$)/g;
188
+ function isStructuredTaskCompletionReport(text) {
189
+ return (text ?? "").trimStart().startsWith(TASK_COMPLETION_REPORT_HEADING);
190
+ }
191
+ function cleanReportLine(line) {
192
+ return line.replace(/^[-*]\s+/, "").replace(/^#+\s+/, "").trim();
193
+ }
194
+ function formatReportList(lines, fallback) {
195
+ const cleaned = lines.map(cleanReportLine).filter((line) => line.length > 0).slice(0, 12);
196
+ if (cleaned.length === 0) return [`- ${fallback}`];
197
+ return cleaned.map((line) => `- ${line}`);
198
+ }
199
+ function linesMatching(lines, pattern) {
200
+ return lines.filter((line) => pattern.test(line));
201
+ }
202
+ function extractMentionedArtifacts(text) {
203
+ const artifacts = /* @__PURE__ */ new Set();
204
+ for (const match of text.matchAll(FILE_PATH_RE)) {
205
+ if (match[1]) artifacts.add(match[1]);
206
+ if (artifacts.size >= 12) break;
207
+ }
208
+ return [...artifacts];
209
+ }
210
+ function agentRoleForReport(agentId) {
211
+ try {
212
+ const employee = loadEmployeesSync().find((e) => e.name === agentId);
213
+ return employee?.role ?? "employee";
214
+ } catch {
215
+ return "employee";
216
+ }
217
+ }
218
+ function buildTaskCompletionReport(input) {
219
+ const rawResult = (input.result ?? "").trim();
220
+ if (isStructuredTaskCompletionReport(rawResult)) return rawResult;
221
+ const sourceLines = rawResult.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
222
+ const artifacts = extractMentionedArtifacts(rawResult);
223
+ const verificationLines = linesMatching(
224
+ sourceLines,
225
+ /\b(test|tests|tested|verify|verified|verification|typecheck|build|vitest|npm run|curl|passed|failed)\b/i
226
+ );
227
+ const findingLines = linesMatching(
228
+ sourceLines,
229
+ /\b(finding|findings|root cause|decision|discovered|discovery|constraint|gotcha|learned)\b/i
230
+ );
231
+ const followupLines = linesMatching(
232
+ sourceLines,
233
+ /\b(follow[- ]?up|risk|risks|blocker|blocked|todo|next action|remaining|caveat)\b/i
234
+ );
235
+ const statusNote = input.requestedStatus === input.status ? input.status : `${input.status} (requested ${input.requestedStatus})`;
236
+ const parts = [
237
+ TASK_COMPLETION_REPORT_HEADING,
238
+ "",
239
+ `Task: ${input.title}`,
240
+ `Task ID: ${input.taskId}`,
241
+ `Agent: ${input.agentId} (${agentRoleForReport(input.agentId)})`,
242
+ `Project: ${input.projectName}`,
243
+ `Status: ${statusNote}`,
244
+ `Date: ${input.completedAt}`,
245
+ `Reviewer: ${input.reviewer || "not specified"}`,
246
+ `Task file: ${input.taskFile}`,
247
+ "",
248
+ "## Outcome",
249
+ ...formatReportList(sourceLines, "No result summary provided."),
250
+ "",
251
+ "## What Changed",
252
+ ...artifacts.length > 0 ? formatReportList(artifacts, "No changed files or artifacts specified.") : ["- See outcome above; no changed files or artifacts were explicitly listed."],
253
+ "",
254
+ "## Verification",
255
+ ...formatReportList(verificationLines, "Not specified in completion result."),
256
+ "",
257
+ "## Key Findings",
258
+ ...formatReportList(findingLines, "Not specified."),
259
+ "",
260
+ "## Follow-ups / Risks",
261
+ ...formatReportList(followupLines, "None specified."),
262
+ "",
263
+ "## Handoff Notes",
264
+ "- Reviewer should verify this report against the original task requirements before closing.",
265
+ `- Use the task ID (${input.taskId}) and task file (${input.taskFile}) for full context.`
266
+ ];
267
+ return parts.join("\n");
268
+ }
269
+ function shouldNormalizeTaskResult(requestedStatus, finalStatus) {
270
+ return requestedStatus === "done" || REPORTABLE_COMPLETION_STATUSES.has(finalStatus);
271
+ }
185
272
  async function writeCheckpoint(input) {
186
273
  const client = getClient();
187
274
  const row = await resolveTask(client, input.taskId);
@@ -374,7 +461,7 @@ async function createTaskCore(input) {
374
461
  if (isCoordinatorSession) {
375
462
  earlySessionScope = resolved;
376
463
  } else {
377
- const { getSessionProject } = await import("./session-scope-PKBCQOLO.js");
464
+ const { getSessionProject } = await import("./session-scope-RGIEAQRR.js");
378
465
  const sessionProject = getSessionProject(resolved);
379
466
  if (sessionProject && sessionProject !== input.projectName) {
380
467
  scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
@@ -823,7 +910,7 @@ async function updateTaskStatus(input) {
823
910
  } catch {
824
911
  }
825
912
  try {
826
- const { writeNotification: writeNotification2 } = await import("./notifications-25FGAXTC.js");
913
+ const { writeNotification: writeNotification2 } = await import("./notifications-YF7ANNPB.js");
827
914
  await writeNotification2({
828
915
  agentId: reviewer,
829
916
  agentRole: isCoordinatorName(reviewer) ? "COO" : "manager",
@@ -907,6 +994,21 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
907
994
  }
908
995
  }
909
996
  }
997
+ const shouldWriteCompletionMemory = shouldNormalizeTaskResult(requestedStatus, input.status) && previousStatus !== input.status && (requestedStatus === "done" || input.status === "needs_review");
998
+ if (shouldNormalizeTaskResult(requestedStatus, input.status)) {
999
+ input.result = buildTaskCompletionReport({
1000
+ taskId,
1001
+ title: String(row.title),
1002
+ agentId: String(row.assigned_to),
1003
+ projectName: String(row.project_name ?? ""),
1004
+ status: input.status,
1005
+ requestedStatus,
1006
+ taskFile,
1007
+ reviewer: row.reviewer ? String(row.reviewer) : null,
1008
+ completedAt: now,
1009
+ result: input.result
1010
+ });
1011
+ }
910
1012
  if (input.status === "in_progress") {
911
1013
  const tmuxSession = process.env.TMUX_PANE ?? process.env.MY_TMUX_SESSION ?? "unknown";
912
1014
  const claimAgent = process.env.AGENT_ID ?? String(row.assigned_to ?? "unknown");
@@ -1090,6 +1192,26 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
1090
1192
  result: input.status
1091
1193
  });
1092
1194
  }
1195
+ if (shouldWriteCompletionMemory && input.result) {
1196
+ try {
1197
+ const { writeMemoryViaDaemon } = await import("./memory-queue-client-BKEAVZHZ.js");
1198
+ await writeMemoryViaDaemon({
1199
+ raw_text: input.result,
1200
+ agent_id: String(row.assigned_to),
1201
+ agent_role: agentRoleForReport(String(row.assigned_to)),
1202
+ session_id: eventSessionScope ?? "task-completion",
1203
+ tool_name: "task-completion-report",
1204
+ project_name: eventProjectName ?? "",
1205
+ timestamp: now,
1206
+ importance: 8,
1207
+ task_id: taskId,
1208
+ memory_type: "checkpoint",
1209
+ trajectory: "completed",
1210
+ session_scope: eventSessionScope ?? void 0
1211
+ });
1212
+ } catch {
1213
+ }
1214
+ }
1093
1215
  if (input.status === "needs_review" && previousStatus !== "needs_review" && previousStatus !== "closed") {
1094
1216
  recordOrchestrationEventBestEffort({
1095
1217
  eventType: "review.ready",
@@ -1175,7 +1297,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
1175
1297
  }
1176
1298
  if (input.status === "done" || input.status === "needs_review") {
1177
1299
  try {
1178
- const { incrementSkillSuccess } = await import("./skill-refinement-KL2INB5E.js");
1300
+ const { incrementSkillSuccess } = await import("./skill-refinement-BGWMSERG.js");
1179
1301
  await incrementSkillSuccess(
1180
1302
  String(row.assigned_to),
1181
1303
  row.project_name ? String(row.project_name) : null
@@ -2304,7 +2426,7 @@ async function verifyPaneAtCapacity(sessionName) {
2304
2426
  reason: `capture-pane failed: ${err instanceof Error ? err.message : String(err)}`
2305
2427
  };
2306
2428
  }
2307
- const { isAtCapacity } = await import("./capacity-monitor-EHXIFEE2.js");
2429
+ const { isAtCapacity } = await import("./capacity-monitor-PQ7EZ5ES.js");
2308
2430
  if (!isAtCapacity(pane)) {
2309
2431
  return {
2310
2432
  atCapacity: false,
@@ -3083,6 +3205,8 @@ export {
3083
3205
  markDoneTaskNotificationsAsRead,
3084
3206
  formatNotifications,
3085
3207
  migrateJsonNotifications,
3208
+ isStructuredTaskCompletionReport,
3209
+ buildTaskCompletionReport,
3086
3210
  writeCheckpoint,
3087
3211
  extractParentFromContext,
3088
3212
  slugify,
@@ -11,7 +11,7 @@ import {
11
11
  sessionScopeFilter,
12
12
  updateTaskStatus,
13
13
  writeNotification
14
- } from "./chunk-4EOXPKWA.js";
14
+ } from "./chunk-A3K7V6SW.js";
15
15
  import {
16
16
  getTransport
17
17
  } from "./chunk-5YDHBZCO.js";
@@ -159,7 +159,7 @@ async function dispatchTaskToEmployee(input) {
159
159
  let crossProject = false;
160
160
  if (input.projectName) {
161
161
  try {
162
- const { assertSessionScope } = await import("./session-scope-PKBCQOLO.js");
162
+ const { assertSessionScope } = await import("./session-scope-RGIEAQRR.js");
163
163
  const check = assertSessionScope("dispatch_task", input.projectName);
164
164
  if (check.reason === "cross_session_denied") {
165
165
  crossProject = true;
@@ -500,7 +500,7 @@ async function updateTask(input) {
500
500
  await markTaskNotificationsRead(taskFile);
501
501
  if (input.status === "needs_review" && !isCoordinator) {
502
502
  try {
503
- const { writeNotification: writeNotification2 } = await import("./notifications-25FGAXTC.js");
503
+ const { writeNotification: writeNotification2 } = await import("./notifications-YF7ANNPB.js");
504
504
  await writeNotification2({
505
505
  agentId: String(row.assigned_to),
506
506
  agentRole: String(row.assigned_to),
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-3S3ERUUH.js";
4
4
  import {
5
5
  updateTask
6
- } from "./chunk-7VDMUMHM.js";
6
+ } from "./chunk-AOBTVA7I.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-4EOXPKWA.js";
17
+ } from "./chunk-A3K7V6SW.js";
18
18
  import {
19
19
  queueIntercom
20
20
  } from "./chunk-QI4IXJN7.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-MLXJ5EZG.js";
4
4
  import {
5
5
  createTask
6
- } from "./chunk-7VDMUMHM.js";
6
+ } from "./chunk-AOBTVA7I.js";
7
7
  import {
8
8
  getActiveAgent
9
9
  } from "./chunk-3N4ZEPZI.js";
@@ -11,7 +11,7 @@ import {
11
11
  ensureEmployee,
12
12
  logTaskDispatch,
13
13
  resolveExeSession
14
- } from "./chunk-4EOXPKWA.js";
14
+ } from "./chunk-A3K7V6SW.js";
15
15
  import {
16
16
  recordOrchestrationEventBestEffort
17
17
  } from "./chunk-ITYWLFYC.js";
@@ -243,7 +243,7 @@ function registerCreateTask(server) {
243
243
  let projectConflictOpts = {};
244
244
  try {
245
245
  const { getClient } = await import("./lib/database.js");
246
- const { sessionScopeFilter } = await import("./task-scope-LQRP3MQ2.js");
246
+ const { sessionScopeFilter } = await import("./task-scope-4CBJ3QI2.js");
247
247
  const client = getClient();
248
248
  const scope = sessionScopeFilter();
249
249
  const existing = await client.execute({
@@ -1,10 +1,19 @@
1
+ import {
2
+ TelegramAdapter
3
+ } from "./chunk-Q3V7K4ME.js";
4
+ import {
5
+ DiscordAdapter
6
+ } from "./chunk-N5RRQOAC.js";
7
+ import {
8
+ SlackAdapter
9
+ } from "./chunk-ORCCI2VV.js";
1
10
  import {
2
11
  IMessageAdapter
3
12
  } from "./chunk-FLSASUV3.js";
4
13
  import {
5
14
  createCRMWebhookHandler,
6
15
  parseTwentyWebhook
7
- } from "./chunk-MB7PRC5E.js";
16
+ } from "./chunk-VBPNKKOP.js";
8
17
  import {
9
18
  WhatsAppAdapter
10
19
  } from "./chunk-ECSNSHZ7.js";
@@ -12,14 +21,12 @@ import {
12
21
  SignalAdapter
13
22
  } from "./chunk-RJT7H2KR.js";
14
23
  import {
15
- TelegramAdapter
16
- } from "./chunk-Q3V7K4ME.js";
17
- import {
18
- DiscordAdapter
19
- } from "./chunk-N5RRQOAC.js";
24
+ OllamaProvider
25
+ } from "./chunk-FWFFZGSC.js";
20
26
  import {
21
- SlackAdapter
22
- } from "./chunk-ORCCI2VV.js";
27
+ AnthropicProvider,
28
+ OpenAICompatProvider
29
+ } from "./chunk-ECGTESAP.js";
23
30
  import {
24
31
  BotRegistry,
25
32
  BotRuntime,
@@ -42,14 +49,7 @@ import {
42
49
  retryWithBackoff,
43
50
  routeMessage,
44
51
  validateGatewayConfig
45
- } from "./chunk-3BV34EJB.js";
46
- import {
47
- OllamaProvider
48
- } from "./chunk-FWFFZGSC.js";
49
- import {
50
- AnthropicProvider,
51
- OpenAICompatProvider
52
- } from "./chunk-ECGTESAP.js";
52
+ } from "./chunk-GD5AQDZL.js";
53
53
  import {
54
54
  getAccountByName,
55
55
  getAccountByPhoneNumberId,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  updateTask
3
- } from "./chunk-7VDMUMHM.js";
3
+ } from "./chunk-AOBTVA7I.js";
4
4
  import {
5
5
  TASK_ALREADY_CLAIMED_PREFIX
6
- } from "./chunk-4EOXPKWA.js";
6
+ } from "./chunk-A3K7V6SW.js";
7
7
 
8
8
  // src/mcp/tools/update-task.ts
9
9
  import { z } from "zod";
@@ -2,7 +2,7 @@ import {
2
2
  listWorkflowDefinitions,
3
3
  runWorkflow,
4
4
  startWorkflow
5
- } from "./chunk-3M2CCVXM.js";
5
+ } from "./chunk-VUJHFM4F.js";
6
6
  import {
7
7
  initCRMBridge
8
8
  } from "./chunk-ONKIWA3R.js";