@askexenow/exe-os 0.8.40 → 0.8.42
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/bin/backfill-conversations.js +805 -642
- package/dist/bin/backfill-responses.js +804 -641
- package/dist/bin/backfill-vectors.js +791 -634
- package/dist/bin/cleanup-stale-review-tasks.js +788 -631
- package/dist/bin/cli.js +1376 -659
- package/dist/bin/exe-agent.js +20 -1
- package/dist/bin/exe-assign.js +1503 -1343
- package/dist/bin/exe-boot.js +2549 -1784
- package/dist/bin/exe-call.js +39 -1
- package/dist/bin/exe-cloud.js +12 -2
- package/dist/bin/exe-dispatch.js +39 -2
- package/dist/bin/exe-doctor.js +791 -634
- package/dist/bin/exe-export-behaviors.js +792 -637
- package/dist/bin/exe-forget.js +145 -0
- package/dist/bin/exe-gateway.js +2501 -1846
- package/dist/bin/exe-heartbeat.js +147 -1
- package/dist/bin/exe-kill.js +795 -640
- package/dist/bin/exe-launch-agent.js +2168 -2008
- package/dist/bin/exe-link.js +44 -12
- package/dist/bin/exe-new-employee.js +6 -2
- package/dist/bin/exe-pending-messages.js +146 -1
- package/dist/bin/exe-pending-notifications.js +788 -631
- package/dist/bin/exe-pending-reviews.js +176 -1
- package/dist/bin/exe-rename.js +23 -0
- package/dist/bin/exe-review.js +490 -327
- package/dist/bin/exe-search.js +157 -4
- package/dist/bin/exe-session-cleanup.js +2487 -403
- package/dist/bin/exe-settings.js +2 -1
- package/dist/bin/exe-status.js +474 -317
- package/dist/bin/exe-team.js +474 -317
- package/dist/bin/git-sweep.js +2691 -151
- package/dist/bin/graph-backfill.js +794 -637
- package/dist/bin/graph-export.js +798 -641
- package/dist/bin/scan-tasks.js +2951 -44
- package/dist/bin/setup.js +50 -26
- package/dist/bin/shard-migrate.js +792 -637
- package/dist/bin/wiki-sync.js +794 -637
- package/dist/gateway/index.js +2542 -1887
- package/dist/hooks/bug-report-worker.js +2118 -576
- package/dist/hooks/commit-complete.js +2690 -150
- package/dist/hooks/error-recall.js +157 -4
- package/dist/hooks/ingest-worker.js +1455 -803
- package/dist/hooks/instructions-loaded.js +151 -0
- package/dist/hooks/notification.js +153 -2
- package/dist/hooks/post-compact.js +164 -0
- package/dist/hooks/pre-compact.js +3073 -101
- package/dist/hooks/pre-tool-use.js +151 -0
- package/dist/hooks/prompt-ingest-worker.js +1670 -1509
- package/dist/hooks/prompt-submit.js +2650 -1074
- package/dist/hooks/response-ingest-worker.js +154 -6
- package/dist/hooks/session-end.js +153 -2
- package/dist/hooks/session-start.js +157 -4
- package/dist/hooks/stop.js +151 -0
- package/dist/hooks/subagent-stop.js +155 -2
- package/dist/hooks/summary-worker.js +190 -21
- package/dist/index.js +326 -102
- package/dist/lib/cloud-sync.js +31 -10
- package/dist/lib/config.js +2 -0
- package/dist/lib/consolidation.js +69 -2
- package/dist/lib/database.js +19 -0
- package/dist/lib/device-registry.js +19 -0
- package/dist/lib/embedder.js +3 -1
- package/dist/lib/employee-templates.js +20 -1
- package/dist/lib/exe-daemon.js +285 -18
- package/dist/lib/hybrid-search.js +157 -4
- package/dist/lib/messaging.js +39 -2
- package/dist/lib/schedules.js +792 -637
- package/dist/lib/store.js +796 -636
- package/dist/lib/tasks.js +1485 -918
- package/dist/lib/tmux-routing.js +194 -10
- package/dist/mcp/server.js +1643 -924
- package/dist/mcp/tools/create-task.js +2283 -829
- package/dist/mcp/tools/list-tasks.js +2788 -159
- package/dist/mcp/tools/send-message.js +39 -2
- package/dist/mcp/tools/update-task.js +79 -0
- package/dist/runtime/index.js +280 -68
- package/dist/tui/App.js +1485 -645
- package/package.json +3 -2
|
@@ -631,8 +631,28 @@ function getMySession() {
|
|
|
631
631
|
return getTransport().getMySession();
|
|
632
632
|
}
|
|
633
633
|
function employeeSessionName(employee, exeSession, instance) {
|
|
634
|
+
if (!/^exe\d+$/.test(exeSession)) {
|
|
635
|
+
const root = extractRootExe(exeSession);
|
|
636
|
+
if (root) {
|
|
637
|
+
process.stderr.write(
|
|
638
|
+
`[tmux-routing] WARN: exeSession="${exeSession}" is not a root exe session, using "${root}" instead
|
|
639
|
+
`
|
|
640
|
+
);
|
|
641
|
+
exeSession = root;
|
|
642
|
+
} else {
|
|
643
|
+
throw new Error(
|
|
644
|
+
`Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1"), not an agent session`
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
634
648
|
const suffix = instance != null && instance > 0 ? String(instance) : "";
|
|
635
|
-
|
|
649
|
+
const name = `${employee}${suffix}-${exeSession}`;
|
|
650
|
+
if (!VALID_SESSION_NAME.test(name)) {
|
|
651
|
+
throw new Error(
|
|
652
|
+
`Invalid session name "${name}" \u2014 must match {agent}-exe{N} or {agent}{instance}-exe{N}`
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
return name;
|
|
636
656
|
}
|
|
637
657
|
function extractRootExe(name) {
|
|
638
658
|
const match = name.match(/(exe\d+)$/);
|
|
@@ -791,6 +811,22 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
791
811
|
error: `Error: pass employee name ('${bare}'), not session name ('${employeeName}')`
|
|
792
812
|
};
|
|
793
813
|
}
|
|
814
|
+
if (!/^exe\d+$/.test(exeSession)) {
|
|
815
|
+
const root = extractRootExe(exeSession);
|
|
816
|
+
if (root) {
|
|
817
|
+
process.stderr.write(
|
|
818
|
+
`[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root exe). Auto-correcting to "${root}".
|
|
819
|
+
`
|
|
820
|
+
);
|
|
821
|
+
exeSession = root;
|
|
822
|
+
} else {
|
|
823
|
+
return {
|
|
824
|
+
status: "failed",
|
|
825
|
+
sessionName: "",
|
|
826
|
+
error: `Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1")`
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
}
|
|
794
830
|
let effectiveInstance = opts?.instance;
|
|
795
831
|
if (effectiveInstance === void 0 && opts?.autoInstance) {
|
|
796
832
|
const free = findFreeInstance(
|
|
@@ -1037,7 +1073,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
1037
1073
|
releaseSpawnLock(sessionName);
|
|
1038
1074
|
return { sessionName };
|
|
1039
1075
|
}
|
|
1040
|
-
var SPAWN_LOCK_DIR, SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
|
|
1076
|
+
var SPAWN_LOCK_DIR, SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, VALID_SESSION_NAME, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
|
|
1041
1077
|
var init_tmux_routing = __esm({
|
|
1042
1078
|
"src/lib/tmux-routing.ts"() {
|
|
1043
1079
|
"use strict";
|
|
@@ -1052,6 +1088,7 @@ var init_tmux_routing = __esm({
|
|
|
1052
1088
|
SPAWN_LOCK_DIR = path7.join(os4.homedir(), ".exe-os", "spawn-locks");
|
|
1053
1089
|
SESSION_CACHE = path7.join(os4.homedir(), ".exe-os", "session-cache");
|
|
1054
1090
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
1091
|
+
VALID_SESSION_NAME = /^[a-z]+-exe\d+$|^[a-z]+\d+-exe\d+$/;
|
|
1055
1092
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
1056
1093
|
INTERCOM_LOG2 = path7.join(os4.homedir(), ".exe-os", "intercom.log");
|
|
1057
1094
|
DEBOUNCE_FILE = path7.join(SESSION_CACHE, "intercom-debounce.json");
|
|
@@ -284,6 +284,61 @@ var init_notifications = __esm({
|
|
|
284
284
|
}
|
|
285
285
|
});
|
|
286
286
|
|
|
287
|
+
// src/lib/state-bus.ts
|
|
288
|
+
var StateBus, orgBus;
|
|
289
|
+
var init_state_bus = __esm({
|
|
290
|
+
"src/lib/state-bus.ts"() {
|
|
291
|
+
"use strict";
|
|
292
|
+
StateBus = class {
|
|
293
|
+
handlers = /* @__PURE__ */ new Map();
|
|
294
|
+
globalHandlers = /* @__PURE__ */ new Set();
|
|
295
|
+
/** Emit an event to all subscribers */
|
|
296
|
+
emit(event) {
|
|
297
|
+
const typeHandlers = this.handlers.get(event.type);
|
|
298
|
+
if (typeHandlers) {
|
|
299
|
+
for (const handler of typeHandlers) {
|
|
300
|
+
try {
|
|
301
|
+
handler(event);
|
|
302
|
+
} catch {
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
for (const handler of this.globalHandlers) {
|
|
307
|
+
try {
|
|
308
|
+
handler(event);
|
|
309
|
+
} catch {
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/** Subscribe to a specific event type */
|
|
314
|
+
on(type, handler) {
|
|
315
|
+
if (!this.handlers.has(type)) {
|
|
316
|
+
this.handlers.set(type, /* @__PURE__ */ new Set());
|
|
317
|
+
}
|
|
318
|
+
this.handlers.get(type).add(handler);
|
|
319
|
+
}
|
|
320
|
+
/** Subscribe to ALL events */
|
|
321
|
+
onAny(handler) {
|
|
322
|
+
this.globalHandlers.add(handler);
|
|
323
|
+
}
|
|
324
|
+
/** Unsubscribe from a specific event type */
|
|
325
|
+
off(type, handler) {
|
|
326
|
+
this.handlers.get(type)?.delete(handler);
|
|
327
|
+
}
|
|
328
|
+
/** Unsubscribe from ALL events */
|
|
329
|
+
offAny(handler) {
|
|
330
|
+
this.globalHandlers.delete(handler);
|
|
331
|
+
}
|
|
332
|
+
/** Remove all listeners */
|
|
333
|
+
clear() {
|
|
334
|
+
this.handlers.clear();
|
|
335
|
+
this.globalHandlers.clear();
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
orgBus = new StateBus();
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
287
342
|
// src/lib/tasks-crud.ts
|
|
288
343
|
import crypto2 from "crypto";
|
|
289
344
|
import path3 from "path";
|
|
@@ -1007,6 +1062,7 @@ var init_tasks_review = __esm({
|
|
|
1007
1062
|
init_tasks_crud();
|
|
1008
1063
|
init_tmux_routing();
|
|
1009
1064
|
init_session_key();
|
|
1065
|
+
init_state_bus();
|
|
1010
1066
|
}
|
|
1011
1067
|
});
|
|
1012
1068
|
|
|
@@ -1461,6 +1517,21 @@ async function updateTask(input) {
|
|
|
1461
1517
|
});
|
|
1462
1518
|
} catch {
|
|
1463
1519
|
}
|
|
1520
|
+
try {
|
|
1521
|
+
const client = getClient();
|
|
1522
|
+
const cascaded = await client.execute({
|
|
1523
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
1524
|
+
WHERE parent_task_id = ? AND status = 'needs_review'`,
|
|
1525
|
+
args: [now, taskId]
|
|
1526
|
+
});
|
|
1527
|
+
if (cascaded.rowsAffected > 0) {
|
|
1528
|
+
process.stderr.write(
|
|
1529
|
+
`[cascade] Closed ${cascaded.rowsAffected} orphaned review task(s) for parent ${taskId}
|
|
1530
|
+
`
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
} catch {
|
|
1534
|
+
}
|
|
1464
1535
|
}
|
|
1465
1536
|
const isTerminal = input.status === "done" || input.status === "needs_review";
|
|
1466
1537
|
if (isTerminal) {
|
|
@@ -1474,6 +1545,13 @@ async function updateTask(input) {
|
|
|
1474
1545
|
await cascadeUnblock(taskId, input.baseDir, now);
|
|
1475
1546
|
} catch {
|
|
1476
1547
|
}
|
|
1548
|
+
orgBus.emit({
|
|
1549
|
+
type: "task_completed",
|
|
1550
|
+
taskId,
|
|
1551
|
+
employee: String(row.assigned_to),
|
|
1552
|
+
result: input.result ?? "",
|
|
1553
|
+
timestamp: now
|
|
1554
|
+
});
|
|
1477
1555
|
if (row.parent_task_id) {
|
|
1478
1556
|
try {
|
|
1479
1557
|
await checkSubtaskCompletion(String(row.parent_task_id), String(row.project_name));
|
|
@@ -1528,6 +1606,7 @@ var init_tasks = __esm({
|
|
|
1528
1606
|
init_database();
|
|
1529
1607
|
init_config();
|
|
1530
1608
|
init_notifications();
|
|
1609
|
+
init_state_bus();
|
|
1531
1610
|
init_tasks_crud();
|
|
1532
1611
|
init_tasks_review();
|
|
1533
1612
|
init_tasks_crud();
|