@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.
- package/dist/{backfill-metadata-4N22ZA6N.js → backfill-metadata-32SPFWL5.js} +1 -1
- package/dist/bin/agentic-ontology-backfill.js +1 -1
- package/dist/bin/agentic-reflection-backfill.js +1 -1
- package/dist/bin/agentic-semantic-label.js +1 -1
- package/dist/bin/backfill-conversations.js +1 -1
- package/dist/bin/backfill-responses.js +1 -1
- package/dist/bin/backfill-vectors.js +2 -2
- package/dist/bin/bulk-sync-postgres.js +1 -1
- package/dist/bin/cleanup-stale-review-tasks.js +2 -2
- package/dist/bin/cli.js +5 -5
- package/dist/bin/exe-agent.js +10 -10
- package/dist/bin/exe-assign.js +1 -1
- package/dist/bin/exe-boot.js +3 -3
- package/dist/bin/exe-dispatch.js +2 -2
- package/dist/bin/exe-doctor.js +1 -1
- package/dist/bin/exe-export-behaviors.js +2 -2
- package/dist/bin/exe-forget.js +3 -3
- package/dist/bin/exe-gateway.js +4 -4
- package/dist/bin/exe-heartbeat.js +2 -2
- package/dist/bin/exe-kill.js +3 -3
- package/dist/bin/exe-launch-agent.js +2 -2
- package/dist/bin/exe-pending-messages.js +3 -3
- package/dist/bin/exe-pending-notifications.js +2 -2
- package/dist/bin/exe-pending-reviews.js +2 -2
- package/dist/bin/exe-review.js +3 -3
- package/dist/bin/exe-search.js +2 -2
- package/dist/bin/exe-session-cleanup.js +5 -5
- package/dist/bin/exe-start-codex.js +1 -1
- package/dist/bin/exe-start-opencode.js +1 -1
- package/dist/bin/exe-status.js +3 -3
- package/dist/bin/exe-team.js +1 -1
- package/dist/bin/git-sweep.js +2 -2
- package/dist/bin/graph-backfill.js +1 -1
- package/dist/bin/graph-export.js +2 -2
- package/dist/bin/import-history.js +1 -1
- package/dist/bin/intercom-check.js +3 -3
- package/dist/bin/mcp-sessions.js +194 -0
- package/dist/bin/orchestration-metrics.js +1 -1
- package/dist/bin/scan-tasks.js +2 -2
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +1 -1
- package/dist/{capacity-monitor-EHXIFEE2.js → capacity-monitor-PQ7EZ5ES.js} +2 -2
- package/dist/{catchup-brief-AYLBTVRM.js → catchup-brief-FJM4C6R6.js} +3 -3
- package/dist/{chunk-EAHUS6WU.js → chunk-3GFXV46R.js} +1 -1
- package/dist/{chunk-MGPVDQIM.js → chunk-5452FPV5.js} +1 -1
- package/dist/{chunk-TV7ZTQ7L.js → chunk-6XAXYBCI.js} +7 -7
- package/dist/{chunk-4EOXPKWA.js → chunk-A3K7V6SW.js} +128 -4
- package/dist/{chunk-7VDMUMHM.js → chunk-AOBTVA7I.js} +3 -3
- package/dist/{chunk-QOAPYITU.js → chunk-BO6HP63V.js} +2 -2
- package/dist/{chunk-RRMPIH6C.js → chunk-DYY6DEA4.js} +3 -3
- package/dist/{chunk-SQK3Q6VY.js → chunk-EXRMA2QK.js} +16 -16
- package/dist/{chunk-YQKFNXGL.js → chunk-EYXCCLFI.js} +2 -2
- package/dist/{chunk-3BV34EJB.js → chunk-GD5AQDZL.js} +1 -1
- package/dist/{chunk-MMLE3M4J.js → chunk-IZPPTNXR.js} +1 -1
- package/dist/{chunk-FLCWUX6G.js → chunk-K5EXLDQD.js} +1 -1
- package/dist/{chunk-QOTQZAAE.js → chunk-K5O5UAO3.js} +1 -1
- package/dist/{chunk-T4TMVXF5.js → chunk-LEVLIEBX.js} +4 -4
- package/dist/{chunk-OBVXTLRM.js → chunk-MTZZHS73.js} +2 -2
- package/dist/{chunk-DBSMRM52.js → chunk-PQU74C7J.js} +2 -2
- package/dist/{chunk-WGOVSJNR.js → chunk-PZCC4YWO.js} +1 -1
- package/dist/{chunk-434A3L6O.js → chunk-Q72H4NTD.js} +99 -32
- package/dist/{chunk-T4BKQ3CX.js → chunk-RVT5AV3R.js} +48 -48
- package/dist/{chunk-PNQ74YDS.js → chunk-SNEP3JX2.js} +2 -2
- package/dist/{chunk-BS6YQM5R.js → chunk-UK5GYNHU.js} +1 -1
- package/dist/{chunk-MB7PRC5E.js → chunk-VBPNKKOP.js} +1 -1
- package/dist/{chunk-3M2CCVXM.js → chunk-VUJHFM4F.js} +1 -1
- package/dist/{chunk-4EKVVGVV.js → chunk-YDXCENQ5.js} +1 -1
- package/dist/{chunk-RS5JCKEP.js → chunk-ZCA2WOY3.js} +1 -1
- package/dist/{crm-webhook-VSPYINPL.js → crm-webhook-NGKBEDCE.js} +2 -2
- package/dist/{cto-delegation-gate-W7ESM5IQ.js → cto-delegation-gate-6YC3E5RL.js} +1 -1
- package/dist/{daemon-orchestration-TC3JWVDC.js → daemon-orchestration-QVJ26DDN.js} +3 -3
- package/dist/{exe-export-6NC4TNCZ.js → exe-export-3KLM55BC.js} +1 -1
- package/dist/{exe-import-GQRGZKW3.js → exe-import-SFRVKEGL.js} +1 -1
- package/dist/{fast-db-init-4ETTWASA.js → fast-db-init-WSVNCMIA.js} +1 -1
- package/dist/gateway/index.js +19 -19
- package/dist/{git-task-sweep-HMSTHZ6X.js → git-task-sweep-KBCSNNWI.js} +2 -2
- package/dist/hooks/bug-report-worker.js +3 -3
- package/dist/hooks/codex-stop-task-finalizer.js +3 -3
- package/dist/hooks/commit-complete.js +4 -4
- package/dist/hooks/error-recall.js +2 -2
- package/dist/hooks/ingest.js +2 -2
- package/dist/hooks/instructions-loaded.js +1 -1
- package/dist/hooks/manifest.json +18 -18
- package/dist/hooks/notification.js +1 -1
- package/dist/hooks/post-compact.js +2 -2
- package/dist/hooks/post-tool-combined.js +2 -2
- package/dist/hooks/pre-compact.js +3 -3
- package/dist/hooks/pre-tool-use.js +6 -6
- package/dist/hooks/prompt-submit.js +8 -8
- package/dist/hooks/session-end.js +4 -4
- package/dist/hooks/session-start.js +4 -4
- package/dist/hooks/stop.js +5 -5
- package/dist/hooks/subagent-stop.js +2 -2
- package/dist/hooks/summary-worker.js +5 -5
- package/dist/index.js +12 -12
- package/dist/lib/consolidation.js +2 -2
- package/dist/lib/exe-daemon.js +31 -14
- package/dist/lib/hybrid-search.js +2 -2
- package/dist/lib/messaging.js +2 -2
- package/dist/lib/schedules.js +2 -2
- package/dist/lib/store.js +1 -1
- package/dist/lib/tasks.js +2 -2
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/lib/token-spend.js +1 -1
- package/dist/mcp/register-tools.js +28 -28
- package/dist/mcp/server.js +31 -31
- package/dist/mcp/tools/create-task.js +3 -3
- package/dist/mcp/tools/list-tasks.js +3 -3
- package/dist/mcp/tools/send-message.js +3 -3
- package/dist/mcp/tools/update-task.js +3 -3
- package/dist/{notifications-25FGAXTC.js → notifications-YF7ANNPB.js} +1 -1
- package/dist/{orchestrator-ZWPDXMW4.js → orchestrator-3G7MW4XO.js} +2 -2
- package/dist/{reranker-TRLLNJHH.js → reranker-KKGT2QH5.js} +1 -1
- package/dist/{review-polling-QQMFB3Q4.js → review-polling-E2ZTZAR7.js} +2 -2
- package/dist/runtime/index.js +7 -7
- package/dist/{session-events-OWSPMDJV.js → session-events-RNEA3WRN.js} +2 -2
- package/dist/{session-scope-PKBCQOLO.js → session-scope-RGIEAQRR.js} +1 -1
- package/dist/{setup-wizard-2INM4CSL.js → setup-wizard-AZOKR4PP.js} +1 -1
- package/dist/{task-enforcement-M2NU3OVK.js → task-enforcement-OSPCFH5T.js} +1 -1
- package/dist/{task-scope-LQRP3MQ2.js → task-scope-4CBJ3QI2.js} +1 -1
- package/dist/{tasks-crud-TMYB245Z.js → tasks-crud-PQ23SS5C.js} +5 -1
- package/dist/{tasks-review-GJWB2BPT.js → tasks-review-XZSYVGRL.js} +1 -1
- package/dist/{telemetry-upload-Y3CPHI7M.js → telemetry-upload-DPF4WUMT.js} +21 -7
- package/dist/tui/App.js +7 -7
- package/dist/{tui-data-ZVRIZAIF.js → tui-data-SKVPBPBV.js} +1 -1
- package/dist/{worker-gate-VZLM2AU3.js → worker-gate-XHZWIMDA.js} +1 -1
- package/dist/{workflow-engine-ESXHBY55.js → workflow-engine-RN3ADPEN.js} +2 -2
- package/package.json +1 -1
- package/release-notes.json +71 -71
- /package/dist/{chunk-KJVFW5C7.js → chunk-E3Q4R3K6.js} +0 -0
- /package/dist/{chunk-MTR5SMNA.js → chunk-GMQKS5JD.js} +0 -0
- /package/dist/{chunk-P5J37OSU.js → chunk-MBF42HXN.js} +0 -0
- /package/dist/{chunk-ATKMIQXP.js → chunk-RUTQMSNJ.js} +0 -0
- /package/dist/{chunk-SEPXWHA3.js → chunk-UDSY3K33.js} +0 -0
- /package/dist/{chunk-5YFC6HQX.js → chunk-Z2HB2SXL.js} +0 -0
- /package/dist/{core-memory-6JX6V4QR.js → core-memory-U6ZYHCFK.js} +0 -0
- /package/dist/{exe-key-K7FHMOVL.js → exe-key-FLTUNYFH.js} +0 -0
- /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
|
+
};
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
queryTaskRows
|
|
4
|
-
} from "../chunk-
|
|
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-
|
|
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
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
isAtCapacity,
|
|
9
9
|
isWithinRelaunchCooldown,
|
|
10
10
|
pollCapacityDead
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PZCC4YWO.js";
|
|
12
12
|
import "./chunk-3S3ERUUH.js";
|
|
13
|
-
import "./chunk-
|
|
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-
|
|
4
|
-
import "./chunk-
|
|
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-
|
|
10
|
+
} from "./chunk-A3K7V6SW.js";
|
|
11
11
|
import "./chunk-FYJCMGTD.js";
|
|
12
12
|
import "./chunk-QI4IXJN7.js";
|
|
13
13
|
import "./chunk-IR4L6K5L.js";
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MultiAgentOrchestrator
|
|
3
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
DiscordAdapter
|
|
19
|
-
} from "./chunk-N5RRQOAC.js";
|
|
24
|
+
OllamaProvider
|
|
25
|
+
} from "./chunk-FWFFZGSC.js";
|
|
20
26
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
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-
|
|
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,
|