@askexenow/exe-os 0.9.21 → 0.9.23
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 +17 -4
- package/dist/bin/backfill-responses.js +17 -4
- package/dist/bin/backfill-vectors.js +2 -2
- package/dist/bin/cleanup-stale-review-tasks.js +17 -4
- package/dist/bin/cli.js +378 -171
- package/dist/bin/exe-assign.js +17 -4
- package/dist/bin/exe-boot.js +2 -2
- package/dist/bin/exe-dispatch.js +17 -4
- package/dist/bin/exe-doctor.js +2 -2
- package/dist/bin/exe-export-behaviors.js +17 -4
- package/dist/bin/exe-forget.js +17 -4
- package/dist/bin/exe-gateway.js +17 -4
- package/dist/bin/exe-heartbeat.js +17 -4
- package/dist/bin/exe-kill.js +17 -4
- package/dist/bin/exe-launch-agent.js +17 -4
- package/dist/bin/exe-pending-messages.js +17 -4
- package/dist/bin/exe-pending-notifications.js +17 -4
- package/dist/bin/exe-pending-reviews.js +17 -4
- package/dist/bin/exe-review.js +17 -4
- package/dist/bin/exe-search.js +23 -8
- package/dist/bin/exe-session-cleanup.js +17 -4
- package/dist/bin/exe-start-codex.js +209 -32
- package/dist/bin/exe-start-opencode.js +17 -4
- package/dist/bin/exe-status.js +17 -4
- package/dist/bin/exe-team.js +17 -4
- package/dist/bin/git-sweep.js +17 -4
- package/dist/bin/graph-backfill.js +17 -4
- package/dist/bin/graph-export.js +17 -4
- package/dist/bin/install.js +42 -0
- package/dist/bin/intercom-check.js +17 -4
- package/dist/bin/scan-tasks.js +17 -4
- package/dist/bin/shard-migrate.js +17 -4
- package/dist/bin/update.js +187 -42
- package/dist/gateway/index.js +17 -4
- package/dist/hooks/bug-report-worker.js +793 -150
- package/dist/hooks/codex-stop-task-finalizer.js +3020 -2375
- package/dist/hooks/commit-complete.js +156 -6
- package/dist/hooks/error-recall.js +23 -8
- package/dist/hooks/ingest.js +17 -4
- package/dist/hooks/instructions-loaded.js +17 -4
- package/dist/hooks/notification.js +17 -4
- package/dist/hooks/post-compact.js +17 -4
- package/dist/hooks/post-tool-combined.js +23 -8
- package/dist/hooks/pre-compact.js +156 -8
- package/dist/hooks/pre-tool-use.js +21 -12
- package/dist/hooks/prompt-submit.js +23 -8
- package/dist/hooks/session-end.js +156 -8
- package/dist/hooks/session-start.js +23 -8
- package/dist/hooks/stop.js +306 -9
- package/dist/hooks/subagent-stop.js +306 -9
- package/dist/hooks/summary-worker.js +2 -2
- package/dist/index.js +17 -4
- package/dist/lib/exe-daemon.js +37 -14
- package/dist/lib/hybrid-search.js +23 -8
- package/dist/lib/schedules.js +2 -2
- package/dist/lib/store.js +17 -4
- package/dist/mcp/server.js +36 -10
- package/dist/runtime/index.js +17 -4
- package/dist/tui/App.js +17 -4
- package/package.json +1 -1
|
@@ -1266,6 +1266,17 @@ var init_daemon_auth = __esm({
|
|
|
1266
1266
|
});
|
|
1267
1267
|
|
|
1268
1268
|
// src/lib/exe-daemon-client.ts
|
|
1269
|
+
var exe_daemon_client_exports = {};
|
|
1270
|
+
__export(exe_daemon_client_exports, {
|
|
1271
|
+
connectEmbedDaemon: () => connectEmbedDaemon,
|
|
1272
|
+
disconnectClient: () => disconnectClient,
|
|
1273
|
+
embedBatchViaClient: () => embedBatchViaClient,
|
|
1274
|
+
embedViaClient: () => embedViaClient,
|
|
1275
|
+
isClientConnected: () => isClientConnected,
|
|
1276
|
+
pingDaemon: () => pingDaemon,
|
|
1277
|
+
sendDaemonRequest: () => sendDaemonRequest,
|
|
1278
|
+
sendIngestRequest: () => sendIngestRequest
|
|
1279
|
+
});
|
|
1269
1280
|
import net from "net";
|
|
1270
1281
|
import os6 from "os";
|
|
1271
1282
|
import { spawn } from "child_process";
|
|
@@ -1502,6 +1513,9 @@ async function connectEmbedDaemon() {
|
|
|
1502
1513
|
}
|
|
1503
1514
|
return false;
|
|
1504
1515
|
}
|
|
1516
|
+
function sendRequest(texts, priority) {
|
|
1517
|
+
return sendDaemonRequest({ texts, priority });
|
|
1518
|
+
}
|
|
1505
1519
|
function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
1506
1520
|
return new Promise((resolve) => {
|
|
1507
1521
|
if (!_socket || !_connected) {
|
|
@@ -1524,10 +1538,170 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1524
1538
|
}
|
|
1525
1539
|
});
|
|
1526
1540
|
}
|
|
1541
|
+
async function pingDaemon() {
|
|
1542
|
+
if (!_socket || !_connected) return null;
|
|
1543
|
+
const response = await sendDaemonRequest({ type: "health" }, 5e3);
|
|
1544
|
+
if (response.health) {
|
|
1545
|
+
return response.health;
|
|
1546
|
+
}
|
|
1547
|
+
return null;
|
|
1548
|
+
}
|
|
1549
|
+
function killAndRespawnDaemon() {
|
|
1550
|
+
if (!acquireSpawnLock()) {
|
|
1551
|
+
process.stderr.write("[exed-client] Another process is already restarting daemon \u2014 skipping\n");
|
|
1552
|
+
if (_socket) {
|
|
1553
|
+
_socket.destroy();
|
|
1554
|
+
_socket = null;
|
|
1555
|
+
}
|
|
1556
|
+
_connected = false;
|
|
1557
|
+
_buffer = "";
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
try {
|
|
1561
|
+
process.stderr.write("[exed-client] Killing daemon for restart...\n");
|
|
1562
|
+
if (existsSync7(PID_PATH)) {
|
|
1563
|
+
try {
|
|
1564
|
+
const pid = parseInt(readFileSync7(PID_PATH, "utf8").trim(), 10);
|
|
1565
|
+
if (pid > 0) {
|
|
1566
|
+
try {
|
|
1567
|
+
process.kill(pid, "SIGKILL");
|
|
1568
|
+
} catch {
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
} catch {
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
if (_socket) {
|
|
1575
|
+
_socket.destroy();
|
|
1576
|
+
_socket = null;
|
|
1577
|
+
}
|
|
1578
|
+
_connected = false;
|
|
1579
|
+
_buffer = "";
|
|
1580
|
+
try {
|
|
1581
|
+
unlinkSync3(PID_PATH);
|
|
1582
|
+
} catch {
|
|
1583
|
+
}
|
|
1584
|
+
try {
|
|
1585
|
+
unlinkSync3(SOCKET_PATH);
|
|
1586
|
+
} catch {
|
|
1587
|
+
}
|
|
1588
|
+
spawnDaemon();
|
|
1589
|
+
} finally {
|
|
1590
|
+
releaseSpawnLock();
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
function isDaemonTooYoung() {
|
|
1594
|
+
try {
|
|
1595
|
+
const stat = statSync(PID_PATH);
|
|
1596
|
+
return Date.now() - stat.mtimeMs < MIN_DAEMON_AGE_MS;
|
|
1597
|
+
} catch {
|
|
1598
|
+
return false;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
async function retryThenRestart(doRequest, label) {
|
|
1602
|
+
const result = await doRequest();
|
|
1603
|
+
if (!result.error) {
|
|
1604
|
+
_consecutiveFailures = 0;
|
|
1605
|
+
return result;
|
|
1606
|
+
}
|
|
1607
|
+
_consecutiveFailures++;
|
|
1608
|
+
for (let i = 0; i < MAX_RETRIES_BEFORE_RESTART; i++) {
|
|
1609
|
+
const delayMs = RETRY_DELAYS_MS[i] ?? 5e3;
|
|
1610
|
+
process.stderr.write(`[exed-client] ${label} failed (${result.error}), retry ${i + 1}/${MAX_RETRIES_BEFORE_RESTART} in ${delayMs}ms
|
|
1611
|
+
`);
|
|
1612
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
1613
|
+
if (!_connected) {
|
|
1614
|
+
if (!await connectToSocket()) continue;
|
|
1615
|
+
}
|
|
1616
|
+
const retry = await doRequest();
|
|
1617
|
+
if (!retry.error) {
|
|
1618
|
+
_consecutiveFailures = 0;
|
|
1619
|
+
return retry;
|
|
1620
|
+
}
|
|
1621
|
+
_consecutiveFailures++;
|
|
1622
|
+
}
|
|
1623
|
+
if (isDaemonTooYoung()) {
|
|
1624
|
+
process.stderr.write(`[exed-client] ${label}: daemon too young (< ${MIN_DAEMON_AGE_MS / 1e3}s) \u2014 skipping restart
|
|
1625
|
+
`);
|
|
1626
|
+
return { error: result.error };
|
|
1627
|
+
}
|
|
1628
|
+
process.stderr.write(`[exed-client] ${label}: ${_consecutiveFailures} consecutive failures \u2014 restarting daemon
|
|
1629
|
+
`);
|
|
1630
|
+
killAndRespawnDaemon();
|
|
1631
|
+
const start = Date.now();
|
|
1632
|
+
let delay2 = 200;
|
|
1633
|
+
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1634
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
1635
|
+
if (await connectToSocket()) break;
|
|
1636
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
1637
|
+
}
|
|
1638
|
+
if (!_connected) return { error: "Daemon restart failed" };
|
|
1639
|
+
const final = await doRequest();
|
|
1640
|
+
if (!final.error) _consecutiveFailures = 0;
|
|
1641
|
+
return final;
|
|
1642
|
+
}
|
|
1643
|
+
async function embedViaClient(text, priority = "high") {
|
|
1644
|
+
if (!_connected && !await connectEmbedDaemon()) return null;
|
|
1645
|
+
_requestCount++;
|
|
1646
|
+
if (_requestCount % HEALTH_CHECK_INTERVAL === 0) {
|
|
1647
|
+
const health = await pingDaemon();
|
|
1648
|
+
if (!health && !isDaemonTooYoung()) {
|
|
1649
|
+
process.stderr.write(`[exed-client] Periodic health check failed at request ${_requestCount} \u2014 restarting daemon
|
|
1650
|
+
`);
|
|
1651
|
+
killAndRespawnDaemon();
|
|
1652
|
+
const start = Date.now();
|
|
1653
|
+
let d = 200;
|
|
1654
|
+
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1655
|
+
await new Promise((r) => setTimeout(r, d));
|
|
1656
|
+
if (await connectToSocket()) break;
|
|
1657
|
+
d = Math.min(d * 2, 3e3);
|
|
1658
|
+
}
|
|
1659
|
+
if (!_connected) return null;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
const result = await retryThenRestart(
|
|
1663
|
+
() => sendRequest([text], priority),
|
|
1664
|
+
"Embed"
|
|
1665
|
+
);
|
|
1666
|
+
return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
|
|
1667
|
+
}
|
|
1668
|
+
async function embedBatchViaClient(texts, priority = "high") {
|
|
1669
|
+
if (!_connected && !await connectEmbedDaemon()) return null;
|
|
1670
|
+
_requestCount++;
|
|
1671
|
+
const result = await retryThenRestart(
|
|
1672
|
+
() => sendRequest(texts, priority),
|
|
1673
|
+
"Batch embed"
|
|
1674
|
+
);
|
|
1675
|
+
return !result.error && result.vectors ? result.vectors : null;
|
|
1676
|
+
}
|
|
1677
|
+
function disconnectClient() {
|
|
1678
|
+
if (_socket) {
|
|
1679
|
+
_socket.destroy();
|
|
1680
|
+
_socket = null;
|
|
1681
|
+
}
|
|
1682
|
+
_connected = false;
|
|
1683
|
+
_buffer = "";
|
|
1684
|
+
for (const [id, entry] of _pending) {
|
|
1685
|
+
clearTimeout(entry.timer);
|
|
1686
|
+
_pending.delete(id);
|
|
1687
|
+
entry.resolve({ error: "Client disconnected" });
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1527
1690
|
function isClientConnected() {
|
|
1528
1691
|
return _connected;
|
|
1529
1692
|
}
|
|
1530
|
-
|
|
1693
|
+
function sendIngestRequest(payload) {
|
|
1694
|
+
if (!_socket || !_connected) return false;
|
|
1695
|
+
try {
|
|
1696
|
+
const id = randomUUID();
|
|
1697
|
+
const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
|
|
1698
|
+
_socket.write(JSON.stringify({ id, token, type: "ingest", ...payload }) + "\n");
|
|
1699
|
+
return true;
|
|
1700
|
+
} catch {
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
|
|
1531
1705
|
var init_exe_daemon_client = __esm({
|
|
1532
1706
|
"src/lib/exe-daemon-client.ts"() {
|
|
1533
1707
|
"use strict";
|
|
@@ -1543,12 +1717,27 @@ var init_exe_daemon_client = __esm({
|
|
|
1543
1717
|
_socket = null;
|
|
1544
1718
|
_connected = false;
|
|
1545
1719
|
_buffer = "";
|
|
1720
|
+
_requestCount = 0;
|
|
1721
|
+
_consecutiveFailures = 0;
|
|
1722
|
+
HEALTH_CHECK_INTERVAL = 100;
|
|
1723
|
+
MAX_RETRIES_BEFORE_RESTART = 3;
|
|
1724
|
+
RETRY_DELAYS_MS = [1e3, 3e3, 5e3];
|
|
1725
|
+
MIN_DAEMON_AGE_MS = 3e4;
|
|
1546
1726
|
_pending = /* @__PURE__ */ new Map();
|
|
1547
1727
|
MAX_BUFFER = 1e7;
|
|
1548
1728
|
}
|
|
1549
1729
|
});
|
|
1550
1730
|
|
|
1551
1731
|
// src/lib/daemon-protocol.ts
|
|
1732
|
+
var daemon_protocol_exports = {};
|
|
1733
|
+
__export(daemon_protocol_exports, {
|
|
1734
|
+
deserializeArgs: () => deserializeArgs,
|
|
1735
|
+
deserializeResultSet: () => deserializeResultSet,
|
|
1736
|
+
deserializeValue: () => deserializeValue,
|
|
1737
|
+
serializeArgs: () => serializeArgs,
|
|
1738
|
+
serializeResultSet: () => serializeResultSet,
|
|
1739
|
+
serializeValue: () => serializeValue
|
|
1740
|
+
});
|
|
1552
1741
|
function serializeValue(v) {
|
|
1553
1742
|
if (v === null || v === void 0) return null;
|
|
1554
1743
|
if (typeof v === "bigint") return Number(v);
|
|
@@ -1573,6 +1762,32 @@ function deserializeValue(v) {
|
|
|
1573
1762
|
}
|
|
1574
1763
|
return v;
|
|
1575
1764
|
}
|
|
1765
|
+
function serializeArgs(args) {
|
|
1766
|
+
return args.map(serializeValue);
|
|
1767
|
+
}
|
|
1768
|
+
function deserializeArgs(args) {
|
|
1769
|
+
return args.map(deserializeValue);
|
|
1770
|
+
}
|
|
1771
|
+
function serializeResultSet(rs) {
|
|
1772
|
+
const rows = [];
|
|
1773
|
+
for (const row of rs.rows) {
|
|
1774
|
+
const obj = {};
|
|
1775
|
+
for (let i = 0; i < rs.columns.length; i++) {
|
|
1776
|
+
const col = rs.columns[i];
|
|
1777
|
+
if (col !== void 0) {
|
|
1778
|
+
obj[col] = serializeValue(row[i]);
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
rows.push(obj);
|
|
1782
|
+
}
|
|
1783
|
+
return {
|
|
1784
|
+
columns: [...rs.columns],
|
|
1785
|
+
columnTypes: [...rs.columnTypes ?? []],
|
|
1786
|
+
rows,
|
|
1787
|
+
rowsAffected: typeof rs.rowsAffected === "bigint" ? Number(rs.rowsAffected) : rs.rowsAffected ?? 0,
|
|
1788
|
+
lastInsertRowid: rs.lastInsertRowid != null ? typeof rs.lastInsertRowid === "bigint" ? Number(rs.lastInsertRowid) : rs.lastInsertRowid : null
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1576
1791
|
function deserializeResultSet(srs) {
|
|
1577
1792
|
const rows = srs.rows.map((obj) => {
|
|
1578
1793
|
const values = srs.columns.map(
|
|
@@ -3137,8 +3352,8 @@ function getShardClient(projectName) {
|
|
|
3137
3352
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3138
3353
|
}
|
|
3139
3354
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3140
|
-
if (!safeName) {
|
|
3141
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
3355
|
+
if (!safeName || safeName === "unknown") {
|
|
3356
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3142
3357
|
}
|
|
3143
3358
|
const cached = _shards.get(safeName);
|
|
3144
3359
|
if (cached) {
|
|
@@ -4007,19 +4222,32 @@ async function flushBatch() {
|
|
|
4007
4222
|
const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
4008
4223
|
if (isShardingEnabled2()) {
|
|
4009
4224
|
const byProject = /* @__PURE__ */ new Map();
|
|
4225
|
+
let skippedUnknown = 0;
|
|
4010
4226
|
for (const row of batch) {
|
|
4011
|
-
const proj = row.project_name
|
|
4227
|
+
const proj = row.project_name?.trim();
|
|
4228
|
+
if (!proj) {
|
|
4229
|
+
skippedUnknown++;
|
|
4230
|
+
continue;
|
|
4231
|
+
}
|
|
4012
4232
|
if (!byProject.has(proj)) byProject.set(proj, []);
|
|
4013
4233
|
byProject.get(proj).push(row);
|
|
4014
4234
|
}
|
|
4235
|
+
if (skippedUnknown > 0) {
|
|
4236
|
+
process.stderr.write(
|
|
4237
|
+
`[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
|
|
4238
|
+
`
|
|
4239
|
+
);
|
|
4240
|
+
}
|
|
4015
4241
|
for (const [project, rows] of byProject) {
|
|
4016
4242
|
try {
|
|
4017
4243
|
const shardClient = await getReadyShardClient2(project);
|
|
4018
4244
|
const shardStmts = rows.map(buildStmt);
|
|
4019
4245
|
await shardClient.batch(shardStmts, "write");
|
|
4020
4246
|
} catch (err) {
|
|
4247
|
+
const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
|
|
4248
|
+
${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
4021
4249
|
process.stderr.write(
|
|
4022
|
-
`[store] Shard write failed for ${project}
|
|
4250
|
+
`[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
|
|
4023
4251
|
`
|
|
4024
4252
|
);
|
|
4025
4253
|
}
|
|
@@ -4258,6 +4486,77 @@ var init_store = __esm({
|
|
|
4258
4486
|
}
|
|
4259
4487
|
});
|
|
4260
4488
|
|
|
4489
|
+
// src/bin/fast-db-init.ts
|
|
4490
|
+
var fast_db_init_exports = {};
|
|
4491
|
+
__export(fast_db_init_exports, {
|
|
4492
|
+
fastDbInit: () => fastDbInit
|
|
4493
|
+
});
|
|
4494
|
+
async function fastDbInit() {
|
|
4495
|
+
const { isInitialized: isInitialized2, getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4496
|
+
if (isInitialized2()) {
|
|
4497
|
+
return getClient2();
|
|
4498
|
+
}
|
|
4499
|
+
try {
|
|
4500
|
+
const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
|
|
4501
|
+
const { deserializeResultSet: deserializeResultSet2 } = await Promise.resolve().then(() => (init_daemon_protocol(), daemon_protocol_exports));
|
|
4502
|
+
await connectEmbedDaemon2();
|
|
4503
|
+
if (isClientConnected2()) {
|
|
4504
|
+
const daemonClient = {
|
|
4505
|
+
async execute(stmt) {
|
|
4506
|
+
const sql = typeof stmt === "string" ? stmt : stmt.sql;
|
|
4507
|
+
const args = typeof stmt === "string" ? [] : Array.isArray(stmt.args) ? stmt.args : [];
|
|
4508
|
+
const resp = await sendDaemonRequest2({ type: "db-execute", sql, args });
|
|
4509
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
4510
|
+
if (resp.db) return deserializeResultSet2(resp.db);
|
|
4511
|
+
throw new Error("Unexpected daemon response");
|
|
4512
|
+
},
|
|
4513
|
+
async batch(stmts, mode) {
|
|
4514
|
+
const statements = stmts.map((s) => {
|
|
4515
|
+
const sql = typeof s === "string" ? s : s.sql;
|
|
4516
|
+
const args = typeof s === "string" ? [] : Array.isArray(s.args) ? s.args : [];
|
|
4517
|
+
return { sql, args };
|
|
4518
|
+
});
|
|
4519
|
+
const resp = await sendDaemonRequest2({ type: "db-batch", statements, mode: mode ?? "deferred" });
|
|
4520
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
4521
|
+
const batchResults = resp["db-batch"];
|
|
4522
|
+
if (batchResults) return batchResults.map(deserializeResultSet2);
|
|
4523
|
+
throw new Error("Unexpected daemon batch response");
|
|
4524
|
+
},
|
|
4525
|
+
async transaction(_mode) {
|
|
4526
|
+
throw new Error("Transactions not supported via daemon socket");
|
|
4527
|
+
},
|
|
4528
|
+
async executeMultiple(_sql) {
|
|
4529
|
+
throw new Error("executeMultiple not supported via daemon socket");
|
|
4530
|
+
},
|
|
4531
|
+
async migrate(_stmts) {
|
|
4532
|
+
throw new Error("migrate not supported via daemon socket");
|
|
4533
|
+
},
|
|
4534
|
+
sync() {
|
|
4535
|
+
return Promise.resolve(void 0);
|
|
4536
|
+
},
|
|
4537
|
+
close() {
|
|
4538
|
+
},
|
|
4539
|
+
get closed() {
|
|
4540
|
+
return false;
|
|
4541
|
+
},
|
|
4542
|
+
get protocol() {
|
|
4543
|
+
return "file";
|
|
4544
|
+
}
|
|
4545
|
+
};
|
|
4546
|
+
return daemonClient;
|
|
4547
|
+
}
|
|
4548
|
+
} catch {
|
|
4549
|
+
}
|
|
4550
|
+
const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
4551
|
+
await initStore2({ lightweight: true });
|
|
4552
|
+
return getClient2();
|
|
4553
|
+
}
|
|
4554
|
+
var init_fast_db_init = __esm({
|
|
4555
|
+
"src/bin/fast-db-init.ts"() {
|
|
4556
|
+
"use strict";
|
|
4557
|
+
}
|
|
4558
|
+
});
|
|
4559
|
+
|
|
4261
4560
|
// src/lib/active-agent.ts
|
|
4262
4561
|
init_config();
|
|
4263
4562
|
init_session_key();
|
|
@@ -4379,10 +4678,8 @@ process.stdin.on("end", async () => {
|
|
|
4379
4678
|
if (canCoordinate(agent.agentId, agent.agentRole)) {
|
|
4380
4679
|
process.exit(0);
|
|
4381
4680
|
}
|
|
4382
|
-
const {
|
|
4383
|
-
await
|
|
4384
|
-
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4385
|
-
const client = getClient2();
|
|
4681
|
+
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
4682
|
+
const client = await fastDbInit2();
|
|
4386
4683
|
const saScope = sessionScopeFilter();
|
|
4387
4684
|
const pendingResult = await client.execute({
|
|
4388
4685
|
sql: `SELECT title, status FROM tasks WHERE assigned_to = ? AND status IN ('open', 'in_progress')${saScope.sql} ORDER BY status DESC, priority ASC`,
|
|
@@ -3050,8 +3050,8 @@ function getShardClient(projectName) {
|
|
|
3050
3050
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3051
3051
|
}
|
|
3052
3052
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3053
|
-
if (!safeName) {
|
|
3054
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
3053
|
+
if (!safeName || safeName === "unknown") {
|
|
3054
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
3055
3055
|
}
|
|
3056
3056
|
const cached = _shards.get(safeName);
|
|
3057
3057
|
if (cached) {
|
package/dist/index.js
CHANGED
|
@@ -6892,8 +6892,8 @@ function getShardClient(projectName) {
|
|
|
6892
6892
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
6893
6893
|
}
|
|
6894
6894
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
6895
|
-
if (!safeName) {
|
|
6896
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
6895
|
+
if (!safeName || safeName === "unknown") {
|
|
6896
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
6897
6897
|
}
|
|
6898
6898
|
const cached = _shards.get(safeName);
|
|
6899
6899
|
if (cached) {
|
|
@@ -7762,19 +7762,32 @@ async function flushBatch() {
|
|
|
7762
7762
|
const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
7763
7763
|
if (isShardingEnabled2()) {
|
|
7764
7764
|
const byProject = /* @__PURE__ */ new Map();
|
|
7765
|
+
let skippedUnknown = 0;
|
|
7765
7766
|
for (const row of batch) {
|
|
7766
|
-
const proj = row.project_name
|
|
7767
|
+
const proj = row.project_name?.trim();
|
|
7768
|
+
if (!proj) {
|
|
7769
|
+
skippedUnknown++;
|
|
7770
|
+
continue;
|
|
7771
|
+
}
|
|
7767
7772
|
if (!byProject.has(proj)) byProject.set(proj, []);
|
|
7768
7773
|
byProject.get(proj).push(row);
|
|
7769
7774
|
}
|
|
7775
|
+
if (skippedUnknown > 0) {
|
|
7776
|
+
process.stderr.write(
|
|
7777
|
+
`[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
|
|
7778
|
+
`
|
|
7779
|
+
);
|
|
7780
|
+
}
|
|
7770
7781
|
for (const [project, rows] of byProject) {
|
|
7771
7782
|
try {
|
|
7772
7783
|
const shardClient = await getReadyShardClient2(project);
|
|
7773
7784
|
const shardStmts = rows.map(buildStmt);
|
|
7774
7785
|
await shardClient.batch(shardStmts, "write");
|
|
7775
7786
|
} catch (err) {
|
|
7787
|
+
const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
|
|
7788
|
+
${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
7776
7789
|
process.stderr.write(
|
|
7777
|
-
`[store] Shard write failed for ${project}
|
|
7790
|
+
`[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
|
|
7778
7791
|
`
|
|
7779
7792
|
);
|
|
7780
7793
|
}
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -723,8 +723,8 @@ function getShardClient(projectName) {
|
|
|
723
723
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
724
724
|
}
|
|
725
725
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
726
|
-
if (!safeName) {
|
|
727
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
726
|
+
if (!safeName || safeName === "unknown") {
|
|
727
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
728
728
|
}
|
|
729
729
|
const cached = _shards.get(safeName);
|
|
730
730
|
if (cached) {
|
|
@@ -4464,19 +4464,32 @@ async function flushBatch() {
|
|
|
4464
4464
|
const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
4465
4465
|
if (isShardingEnabled2()) {
|
|
4466
4466
|
const byProject = /* @__PURE__ */ new Map();
|
|
4467
|
+
let skippedUnknown = 0;
|
|
4467
4468
|
for (const row of batch) {
|
|
4468
|
-
const proj = row.project_name
|
|
4469
|
+
const proj = row.project_name?.trim();
|
|
4470
|
+
if (!proj) {
|
|
4471
|
+
skippedUnknown++;
|
|
4472
|
+
continue;
|
|
4473
|
+
}
|
|
4469
4474
|
if (!byProject.has(proj)) byProject.set(proj, []);
|
|
4470
4475
|
byProject.get(proj).push(row);
|
|
4471
4476
|
}
|
|
4477
|
+
if (skippedUnknown > 0) {
|
|
4478
|
+
process.stderr.write(
|
|
4479
|
+
`[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
|
|
4480
|
+
`
|
|
4481
|
+
);
|
|
4482
|
+
}
|
|
4472
4483
|
for (const [project, rows] of byProject) {
|
|
4473
4484
|
try {
|
|
4474
4485
|
const shardClient = await getReadyShardClient2(project);
|
|
4475
4486
|
const shardStmts = rows.map(buildStmt);
|
|
4476
4487
|
await shardClient.batch(shardStmts, "write");
|
|
4477
4488
|
} catch (err) {
|
|
4489
|
+
const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
|
|
4490
|
+
${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
4478
4491
|
process.stderr.write(
|
|
4479
|
-
`[store] Shard write failed for ${project}
|
|
4492
|
+
`[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
|
|
4480
4493
|
`
|
|
4481
4494
|
);
|
|
4482
4495
|
}
|
|
@@ -9330,8 +9343,8 @@ function createReviewNudgeRealDeps(getClient2) {
|
|
|
9330
9343
|
return Number(result.rows[0]?.cnt ?? 0);
|
|
9331
9344
|
},
|
|
9332
9345
|
sendNudge: (sessionName) => {
|
|
9333
|
-
const {
|
|
9334
|
-
|
|
9346
|
+
const { queueIntercom: qi } = (init_intercom_queue(), __toCommonJS(intercom_queue_exports));
|
|
9347
|
+
qi(sessionName, "review nudge: pending reviews");
|
|
9335
9348
|
},
|
|
9336
9349
|
persistState: saveNudgeState
|
|
9337
9350
|
};
|
|
@@ -12453,7 +12466,7 @@ function _resetNudgeState() {
|
|
|
12453
12466
|
_lastNudge.clear();
|
|
12454
12467
|
}
|
|
12455
12468
|
async function runTaskEnforcementTick(deps) {
|
|
12456
|
-
const { transport,
|
|
12469
|
+
const { transport, employees, client, scopeFilter } = deps;
|
|
12457
12470
|
const now = deps.now ?? Date.now();
|
|
12458
12471
|
const sessions = transport.listSessions();
|
|
12459
12472
|
for (const session of sessions) {
|
|
@@ -12466,6 +12479,17 @@ async function runTaskEnforcementTick(deps) {
|
|
|
12466
12479
|
}
|
|
12467
12480
|
const employee = employees.find((e) => e.name === agentName);
|
|
12468
12481
|
if (!employee) continue;
|
|
12482
|
+
let effectiveScope = scopeFilter;
|
|
12483
|
+
const dashIndex = session.indexOf("-");
|
|
12484
|
+
if (dashIndex > 0) {
|
|
12485
|
+
const coordinatorSession = session.slice(dashIndex + 1);
|
|
12486
|
+
if (coordinatorSession) {
|
|
12487
|
+
effectiveScope = {
|
|
12488
|
+
sql: " AND (session_scope IS NULL OR session_scope = ?)",
|
|
12489
|
+
args: [coordinatorSession]
|
|
12490
|
+
};
|
|
12491
|
+
}
|
|
12492
|
+
}
|
|
12469
12493
|
const isManager = MANAGER_ROLES.includes(employee.role);
|
|
12470
12494
|
try {
|
|
12471
12495
|
let action = "skip";
|
|
@@ -12475,8 +12499,8 @@ async function runTaskEnforcementTick(deps) {
|
|
|
12475
12499
|
let paneIdle;
|
|
12476
12500
|
if (isManager) {
|
|
12477
12501
|
const openResult = await client.execute({
|
|
12478
|
-
sql: `SELECT COUNT(*) as cnt FROM tasks WHERE assigned_to = ? AND status = 'open'${
|
|
12479
|
-
args: [agentName, ...
|
|
12502
|
+
sql: `SELECT COUNT(*) as cnt FROM tasks WHERE assigned_to = ? AND status = 'open'${effectiveScope.sql}`,
|
|
12503
|
+
args: [agentName, ...effectiveScope.args]
|
|
12480
12504
|
});
|
|
12481
12505
|
openTasks = Number(openResult.rows[0]?.cnt ?? 0);
|
|
12482
12506
|
if (openTasks > 0) {
|
|
@@ -12528,8 +12552,8 @@ async function runTaskEnforcementTick(deps) {
|
|
|
12528
12552
|
);
|
|
12529
12553
|
} else {
|
|
12530
12554
|
const taskResult = await client.execute({
|
|
12531
|
-
sql: `SELECT COUNT(*) as cnt FROM tasks WHERE assigned_to = ? AND status IN ('open', 'in_progress')${
|
|
12532
|
-
args: [agentName, ...
|
|
12555
|
+
sql: `SELECT COUNT(*) as cnt FROM tasks WHERE assigned_to = ? AND status IN ('open', 'in_progress')${effectiveScope.sql}`,
|
|
12556
|
+
args: [agentName, ...effectiveScope.args]
|
|
12533
12557
|
});
|
|
12534
12558
|
const taskCount = Number(taskResult.rows[0]?.cnt ?? 0);
|
|
12535
12559
|
openTasks = taskCount;
|
|
@@ -12557,9 +12581,7 @@ async function runTaskEnforcementTick(deps) {
|
|
|
12557
12581
|
);
|
|
12558
12582
|
}
|
|
12559
12583
|
if (action === "skip" || action === "idle" || action === "grace_period" || action === "active") continue;
|
|
12560
|
-
|
|
12561
|
-
const runtime = config?.runtime ?? "claude";
|
|
12562
|
-
sendNudge(transport, session, runtime, action);
|
|
12584
|
+
queueIntercom(session, `enforcement: ${reason}`);
|
|
12563
12585
|
_lastNudge.set(session, now);
|
|
12564
12586
|
} catch {
|
|
12565
12587
|
}
|
|
@@ -12569,6 +12591,7 @@ var TASK_ENFORCEMENT_INTERVAL_MS, TASK_ENFORCEMENT_DEBOUNCE_MS, MANAGER_GRACE_PE
|
|
|
12569
12591
|
var init_task_enforcement = __esm({
|
|
12570
12592
|
"src/lib/task-enforcement.ts"() {
|
|
12571
12593
|
"use strict";
|
|
12594
|
+
init_intercom_queue();
|
|
12572
12595
|
TASK_ENFORCEMENT_INTERVAL_MS = 6e4;
|
|
12573
12596
|
TASK_ENFORCEMENT_DEBOUNCE_MS = 18e4;
|
|
12574
12597
|
MANAGER_GRACE_PERIOD_MS = 6e5;
|
|
@@ -2911,8 +2911,8 @@ function getShardClient(projectName) {
|
|
|
2911
2911
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2912
2912
|
}
|
|
2913
2913
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2914
|
-
if (!safeName) {
|
|
2915
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
2914
|
+
if (!safeName || safeName === "unknown") {
|
|
2915
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
2916
2916
|
}
|
|
2917
2917
|
const cached = _shards.get(safeName);
|
|
2918
2918
|
if (cached) {
|
|
@@ -3781,19 +3781,32 @@ async function flushBatch() {
|
|
|
3781
3781
|
const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
3782
3782
|
if (isShardingEnabled2()) {
|
|
3783
3783
|
const byProject = /* @__PURE__ */ new Map();
|
|
3784
|
+
let skippedUnknown = 0;
|
|
3784
3785
|
for (const row of batch) {
|
|
3785
|
-
const proj = row.project_name
|
|
3786
|
+
const proj = row.project_name?.trim();
|
|
3787
|
+
if (!proj) {
|
|
3788
|
+
skippedUnknown++;
|
|
3789
|
+
continue;
|
|
3790
|
+
}
|
|
3786
3791
|
if (!byProject.has(proj)) byProject.set(proj, []);
|
|
3787
3792
|
byProject.get(proj).push(row);
|
|
3788
3793
|
}
|
|
3794
|
+
if (skippedUnknown > 0) {
|
|
3795
|
+
process.stderr.write(
|
|
3796
|
+
`[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
|
|
3797
|
+
`
|
|
3798
|
+
);
|
|
3799
|
+
}
|
|
3789
3800
|
for (const [project, rows] of byProject) {
|
|
3790
3801
|
try {
|
|
3791
3802
|
const shardClient = await getReadyShardClient2(project);
|
|
3792
3803
|
const shardStmts = rows.map(buildStmt);
|
|
3793
3804
|
await shardClient.batch(shardStmts, "write");
|
|
3794
3805
|
} catch (err) {
|
|
3806
|
+
const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
|
|
3807
|
+
${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
3795
3808
|
process.stderr.write(
|
|
3796
|
-
`[store] Shard write failed for ${project}
|
|
3809
|
+
`[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
|
|
3797
3810
|
`
|
|
3798
3811
|
);
|
|
3799
3812
|
}
|
|
@@ -5209,10 +5222,12 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
5209
5222
|
);
|
|
5210
5223
|
}
|
|
5211
5224
|
let rerankerAvailable = false;
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5225
|
+
if (process.env.EXE_IS_DAEMON === "1") {
|
|
5226
|
+
try {
|
|
5227
|
+
const { isRerankerAvailable: isRerankerAvailable2 } = await Promise.resolve().then(() => (init_reranker(), reranker_exports));
|
|
5228
|
+
rerankerAvailable = isRerankerAvailable2();
|
|
5229
|
+
} catch {
|
|
5230
|
+
}
|
|
5216
5231
|
}
|
|
5217
5232
|
const broadFetchTopK = config.scalingRoadmap?.rerankerAutoTrigger?.fetchTopK ?? 150;
|
|
5218
5233
|
const fetchLimit = effectiveIsBroad ? Math.max(limit * 5, broadFetchTopK) : rerankerAvailable ? Math.max(limit * 4, 60) : Math.max(limit * 3, 30);
|
package/dist/lib/schedules.js
CHANGED
|
@@ -2595,8 +2595,8 @@ function getShardClient(projectName) {
|
|
|
2595
2595
|
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2596
2596
|
}
|
|
2597
2597
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2598
|
-
if (!safeName) {
|
|
2599
|
-
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
2598
|
+
if (!safeName || safeName === "unknown") {
|
|
2599
|
+
throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
|
|
2600
2600
|
}
|
|
2601
2601
|
const cached = _shards.get(safeName);
|
|
2602
2602
|
if (cached) {
|