@askexenow/exe-os 0.9.80 → 0.9.81
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/customer-readiness.js +23 -0
- package/dist/lib/exe-daemon.js +1192 -587
- package/dist/mcp/server.js +1271 -424
- package/package.json +1 -1
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -1566,8 +1566,8 @@ function findPackageRoot() {
|
|
|
1566
1566
|
function getAvailableMemoryGB() {
|
|
1567
1567
|
if (process.platform === "darwin") {
|
|
1568
1568
|
try {
|
|
1569
|
-
const { execSync:
|
|
1570
|
-
const vmstat =
|
|
1569
|
+
const { execSync: execSync17 } = __require("child_process");
|
|
1570
|
+
const vmstat = execSync17("vm_stat", { encoding: "utf8" });
|
|
1571
1571
|
const pageSize = 16384;
|
|
1572
1572
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1573
1573
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -1821,15 +1821,15 @@ function isDaemonTooYoung() {
|
|
|
1821
1821
|
}
|
|
1822
1822
|
}
|
|
1823
1823
|
async function retryThenRestart(doRequest, label) {
|
|
1824
|
-
const
|
|
1825
|
-
if (!
|
|
1824
|
+
const result3 = await doRequest();
|
|
1825
|
+
if (!result3.error) {
|
|
1826
1826
|
_consecutiveFailures = 0;
|
|
1827
|
-
return
|
|
1827
|
+
return result3;
|
|
1828
1828
|
}
|
|
1829
1829
|
_consecutiveFailures++;
|
|
1830
1830
|
for (let i = 0; i < MAX_RETRIES_BEFORE_RESTART; i++) {
|
|
1831
1831
|
const delayMs = RETRY_DELAYS_MS[i] ?? 5e3;
|
|
1832
|
-
process.stderr.write(`[exed-client] ${label} failed (${
|
|
1832
|
+
process.stderr.write(`[exed-client] ${label} failed (${result3.error}), retry ${i + 1}/${MAX_RETRIES_BEFORE_RESTART} in ${delayMs}ms
|
|
1833
1833
|
`);
|
|
1834
1834
|
await new Promise((r) => setTimeout(r, delayMs));
|
|
1835
1835
|
if (!_connected) {
|
|
@@ -1845,7 +1845,7 @@ async function retryThenRestart(doRequest, label) {
|
|
|
1845
1845
|
if (isDaemonTooYoung()) {
|
|
1846
1846
|
process.stderr.write(`[exed-client] ${label}: daemon too young (< ${MIN_DAEMON_AGE_MS / 1e3}s) \u2014 skipping restart
|
|
1847
1847
|
`);
|
|
1848
|
-
return { error:
|
|
1848
|
+
return { error: result3.error };
|
|
1849
1849
|
}
|
|
1850
1850
|
process.stderr.write(`[exed-client] ${label}: ${_consecutiveFailures} consecutive failures \u2014 restarting daemon
|
|
1851
1851
|
`);
|
|
@@ -1881,20 +1881,20 @@ async function embedViaClient(text3, priority = "high") {
|
|
|
1881
1881
|
if (!_connected) return null;
|
|
1882
1882
|
}
|
|
1883
1883
|
}
|
|
1884
|
-
const
|
|
1884
|
+
const result3 = await retryThenRestart(
|
|
1885
1885
|
() => sendRequest([text3], priority),
|
|
1886
1886
|
"Embed"
|
|
1887
1887
|
);
|
|
1888
|
-
return !
|
|
1888
|
+
return !result3.error && result3.vectors?.[0] ? result3.vectors[0] : null;
|
|
1889
1889
|
}
|
|
1890
1890
|
async function embedBatchViaClient(texts, priority = "high") {
|
|
1891
1891
|
if (!_connected && !await connectEmbedDaemon()) return null;
|
|
1892
1892
|
_requestCount++;
|
|
1893
|
-
const
|
|
1893
|
+
const result3 = await retryThenRestart(
|
|
1894
1894
|
() => sendRequest(texts, priority),
|
|
1895
1895
|
"Batch embed"
|
|
1896
1896
|
);
|
|
1897
|
-
return !
|
|
1897
|
+
return !result3.error && result3.vectors ? result3.vectors : null;
|
|
1898
1898
|
}
|
|
1899
1899
|
function disconnectClient() {
|
|
1900
1900
|
if (_socket) {
|
|
@@ -3581,8 +3581,8 @@ async function findScopedDuplicate(input) {
|
|
|
3581
3581
|
args.push(input.excludeId);
|
|
3582
3582
|
}
|
|
3583
3583
|
sql += " ORDER BY timestamp DESC LIMIT 1";
|
|
3584
|
-
const
|
|
3585
|
-
return
|
|
3584
|
+
const result3 = await client.execute({ sql, args });
|
|
3585
|
+
return result3.rows[0]?.id ? String(result3.rows[0].id) : null;
|
|
3586
3586
|
}
|
|
3587
3587
|
async function runPostWriteMemoryHygiene(memoryId) {
|
|
3588
3588
|
try {
|
|
@@ -4158,12 +4158,12 @@ function loadPrisma() {
|
|
|
4158
4158
|
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
4159
4159
|
return {
|
|
4160
4160
|
async $queryRawUnsafe(query, ...values) {
|
|
4161
|
-
const
|
|
4162
|
-
return
|
|
4161
|
+
const result3 = await pool.query(query, values);
|
|
4162
|
+
return result3.rows;
|
|
4163
4163
|
},
|
|
4164
4164
|
async $executeRawUnsafe(query, ...values) {
|
|
4165
|
-
const
|
|
4166
|
-
return
|
|
4165
|
+
const result3 = await pool.query(query, values);
|
|
4166
|
+
return result3.rowCount ?? 0;
|
|
4167
4167
|
},
|
|
4168
4168
|
async $disconnect() {
|
|
4169
4169
|
await pool.end();
|
|
@@ -4541,12 +4541,12 @@ async function processBatch() {
|
|
|
4541
4541
|
for (const event of events) {
|
|
4542
4542
|
try {
|
|
4543
4543
|
const handler = projectionHandlers[event.source] ?? defaultHandler;
|
|
4544
|
-
const
|
|
4544
|
+
const result3 = await handler(event, prisma);
|
|
4545
4545
|
await prisma.$executeRawUnsafe(
|
|
4546
4546
|
`UPDATE "raw"."raw_events"
|
|
4547
4547
|
SET "processed_at" = NOW(), "projections" = $1::jsonb
|
|
4548
4548
|
WHERE "id" = $2`,
|
|
4549
|
-
JSON.stringify({ targets:
|
|
4549
|
+
JSON.stringify({ targets: result3.targets, skipped: result3.skipped }),
|
|
4550
4550
|
event.id
|
|
4551
4551
|
);
|
|
4552
4552
|
processed++;
|
|
@@ -5348,8 +5348,8 @@ function deriveMachineKey() {
|
|
|
5348
5348
|
}
|
|
5349
5349
|
function readMachineId() {
|
|
5350
5350
|
try {
|
|
5351
|
-
const { readFileSync:
|
|
5352
|
-
return
|
|
5351
|
+
const { readFileSync: readFileSync42 } = __require("fs");
|
|
5352
|
+
return readFileSync42("/etc/machine-id", "utf-8").trim();
|
|
5353
5353
|
} catch {
|
|
5354
5354
|
return "";
|
|
5355
5355
|
}
|
|
@@ -5931,11 +5931,11 @@ __export(global_procedures_exports, {
|
|
|
5931
5931
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5932
5932
|
async function loadGlobalProcedures() {
|
|
5933
5933
|
const client = getClient();
|
|
5934
|
-
const
|
|
5934
|
+
const result3 = await client.execute({
|
|
5935
5935
|
sql: "SELECT * FROM company_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
|
|
5936
5936
|
args: []
|
|
5937
5937
|
});
|
|
5938
|
-
const allRows =
|
|
5938
|
+
const allRows = result3.rows;
|
|
5939
5939
|
const customerOnly = allRows.filter((p) => !PLATFORM_PROCEDURE_TITLES.has(p.title));
|
|
5940
5940
|
if (customerOnly.length > 0) {
|
|
5941
5941
|
_customerCache = customerOnly.map((p) => `### ${p.title}
|
|
@@ -5971,12 +5971,12 @@ async function storeGlobalProcedure(input) {
|
|
|
5971
5971
|
async function deactivateGlobalProcedure(id) {
|
|
5972
5972
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
5973
5973
|
const client = getClient();
|
|
5974
|
-
const
|
|
5974
|
+
const result3 = await client.execute({
|
|
5975
5975
|
sql: "UPDATE company_procedures SET active = 0, updated_at = ? WHERE id = ?",
|
|
5976
5976
|
args: [now2, id]
|
|
5977
5977
|
});
|
|
5978
5978
|
await loadGlobalProcedures();
|
|
5979
|
-
return
|
|
5979
|
+
return result3.rowsAffected > 0;
|
|
5980
5980
|
}
|
|
5981
5981
|
var _customerCache, _cacheLoaded, _platformCache;
|
|
5982
5982
|
var init_global_procedures = __esm({
|
|
@@ -6120,8 +6120,8 @@ async function searchMemoryCards(queryText, agentId, options) {
|
|
|
6120
6120
|
}
|
|
6121
6121
|
sql += ` ORDER BY rank LIMIT ?`;
|
|
6122
6122
|
args.push(limit);
|
|
6123
|
-
const
|
|
6124
|
-
return
|
|
6123
|
+
const result3 = await getClient().execute({ sql, args });
|
|
6124
|
+
return result3.rows.map((row) => ({
|
|
6125
6125
|
id: `card:${String(row.id)}`,
|
|
6126
6126
|
agent_id: String(row.agent_id),
|
|
6127
6127
|
agent_role: "memory_card",
|
|
@@ -6388,7 +6388,7 @@ async function flushBatch() {
|
|
|
6388
6388
|
const hasVector = row.vector !== null;
|
|
6389
6389
|
const taskId = row.task_id ?? null;
|
|
6390
6390
|
const importance = row.importance ?? 5;
|
|
6391
|
-
const
|
|
6391
|
+
const status2 = row.status ?? "active";
|
|
6392
6392
|
const confidence = row.confidence ?? 0.7;
|
|
6393
6393
|
const lastAccessed = row.last_accessed ?? row.timestamp;
|
|
6394
6394
|
const workspaceId = row.workspace_id ?? null;
|
|
@@ -6460,7 +6460,7 @@ async function flushBatch() {
|
|
|
6460
6460
|
row.version,
|
|
6461
6461
|
taskId,
|
|
6462
6462
|
importance,
|
|
6463
|
-
|
|
6463
|
+
status2,
|
|
6464
6464
|
confidence,
|
|
6465
6465
|
lastAccessed,
|
|
6466
6466
|
workspaceId,
|
|
@@ -6630,8 +6630,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
6630
6630
|
args.push(vectorToBlob(queryVector));
|
|
6631
6631
|
sql += ` LIMIT ?`;
|
|
6632
6632
|
args.push(limit);
|
|
6633
|
-
const
|
|
6634
|
-
return
|
|
6633
|
+
const result3 = await client.execute({ sql, args });
|
|
6634
|
+
return result3.rows.map((row) => ({
|
|
6635
6635
|
id: row.id,
|
|
6636
6636
|
agent_id: row.agent_id,
|
|
6637
6637
|
agent_role: row.agent_role,
|
|
@@ -6665,14 +6665,14 @@ async function attachDocumentMetadata(records) {
|
|
|
6665
6665
|
try {
|
|
6666
6666
|
const client = getClient();
|
|
6667
6667
|
const placeholders = docIds.map(() => "?").join(",");
|
|
6668
|
-
const
|
|
6668
|
+
const result3 = await client.execute({
|
|
6669
6669
|
sql: `SELECT id, filename, mime, source_type, uploaded_at
|
|
6670
6670
|
FROM documents
|
|
6671
6671
|
WHERE id IN (${placeholders})`,
|
|
6672
6672
|
args: docIds
|
|
6673
6673
|
});
|
|
6674
6674
|
const byId = /* @__PURE__ */ new Map();
|
|
6675
|
-
for (const row of
|
|
6675
|
+
for (const row of result3.rows) {
|
|
6676
6676
|
const id = row.id;
|
|
6677
6677
|
byId.set(id, {
|
|
6678
6678
|
document_id: id,
|
|
@@ -6695,19 +6695,19 @@ async function flushTier3(agentId, options) {
|
|
|
6695
6695
|
const maxAge = options?.maxAgeHours ?? 72;
|
|
6696
6696
|
const cutoff = new Date(Date.now() - maxAge * 36e5).toISOString();
|
|
6697
6697
|
if (options?.dryRun) {
|
|
6698
|
-
const
|
|
6698
|
+
const result4 = await client.execute({
|
|
6699
6699
|
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
6700
6700
|
WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
|
|
6701
6701
|
args: [agentId, cutoff]
|
|
6702
6702
|
});
|
|
6703
|
-
return { archived: Number(
|
|
6703
|
+
return { archived: Number(result4.rows[0]?.cnt ?? 0) };
|
|
6704
6704
|
}
|
|
6705
|
-
const
|
|
6705
|
+
const result3 = await client.execute({
|
|
6706
6706
|
sql: `UPDATE memories SET status = 'archived'
|
|
6707
6707
|
WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
|
|
6708
6708
|
args: [agentId, cutoff]
|
|
6709
6709
|
});
|
|
6710
|
-
return { archived:
|
|
6710
|
+
return { archived: result3.rowsAffected };
|
|
6711
6711
|
}
|
|
6712
6712
|
async function disposeStore() {
|
|
6713
6713
|
if (_flushTimer2 !== null) {
|
|
@@ -6725,11 +6725,11 @@ function vectorToBlob(vector) {
|
|
|
6725
6725
|
const f32 = vector instanceof Float32Array ? vector : new Float32Array(vector);
|
|
6726
6726
|
return JSON.stringify(Array.from(f32));
|
|
6727
6727
|
}
|
|
6728
|
-
async function updateMemoryStatus(id,
|
|
6728
|
+
async function updateMemoryStatus(id, status2) {
|
|
6729
6729
|
const client = getClient();
|
|
6730
6730
|
await client.execute({
|
|
6731
6731
|
sql: `UPDATE memories SET status = ? WHERE id = ?`,
|
|
6732
|
-
args: [
|
|
6732
|
+
args: [status2, id]
|
|
6733
6733
|
});
|
|
6734
6734
|
}
|
|
6735
6735
|
function reserveVersions(count) {
|
|
@@ -6742,11 +6742,11 @@ function reserveVersions(count) {
|
|
|
6742
6742
|
async function getMemoryCardinality(agentId) {
|
|
6743
6743
|
try {
|
|
6744
6744
|
const client = getClient();
|
|
6745
|
-
const
|
|
6745
|
+
const result3 = await client.execute({
|
|
6746
6746
|
sql: `SELECT COUNT(*) as cnt FROM memories WHERE agent_id = ? AND COALESCE(status, 'active') = 'active'`,
|
|
6747
6747
|
args: [agentId]
|
|
6748
6748
|
});
|
|
6749
|
-
return Number(
|
|
6749
|
+
return Number(result3.rows[0]?.cnt) || 0;
|
|
6750
6750
|
} catch {
|
|
6751
6751
|
return 0;
|
|
6752
6752
|
}
|
|
@@ -7174,10 +7174,10 @@ async function disposeEmbedder() {
|
|
|
7174
7174
|
async function embedDirect(text3) {
|
|
7175
7175
|
const llamaCpp = await import("node-llama-cpp");
|
|
7176
7176
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
7177
|
-
const { existsSync:
|
|
7178
|
-
const
|
|
7179
|
-
const modelPath =
|
|
7180
|
-
if (!
|
|
7177
|
+
const { existsSync: existsSync48 } = await import("fs");
|
|
7178
|
+
const path62 = await import("path");
|
|
7179
|
+
const modelPath = path62.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
7180
|
+
if (!existsSync48(modelPath)) {
|
|
7181
7181
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
7182
7182
|
}
|
|
7183
7183
|
const llama = await llamaCpp.getLlama();
|
|
@@ -7496,9 +7496,9 @@ __export(graph_query_exports, {
|
|
|
7496
7496
|
async function getEntityByName(client, name, type) {
|
|
7497
7497
|
const sql = type ? `SELECT * FROM entities WHERE LOWER(name) = LOWER(?) AND type = ? LIMIT 1` : `SELECT * FROM entities WHERE LOWER(name) = LOWER(?) LIMIT 1`;
|
|
7498
7498
|
const args = type ? [name, type] : [name];
|
|
7499
|
-
const
|
|
7500
|
-
if (
|
|
7501
|
-
const row =
|
|
7499
|
+
const result3 = await client.execute({ sql, args });
|
|
7500
|
+
if (result3.rows.length === 0) return null;
|
|
7501
|
+
const row = result3.rows[0];
|
|
7502
7502
|
return {
|
|
7503
7503
|
id: String(row.id),
|
|
7504
7504
|
name: String(row.name),
|
|
@@ -7509,11 +7509,11 @@ async function getEntityByName(client, name, type) {
|
|
|
7509
7509
|
};
|
|
7510
7510
|
}
|
|
7511
7511
|
async function searchEntities(client, query, limit = 10) {
|
|
7512
|
-
const
|
|
7512
|
+
const result3 = await client.execute({
|
|
7513
7513
|
sql: `SELECT * FROM entities WHERE LOWER(name) LIKE ? ORDER BY last_seen DESC LIMIT ?`,
|
|
7514
7514
|
args: [`%${query.toLowerCase()}%`, limit]
|
|
7515
7515
|
});
|
|
7516
|
-
return
|
|
7516
|
+
return result3.rows.map((row) => ({
|
|
7517
7517
|
id: String(row.id),
|
|
7518
7518
|
name: String(row.name),
|
|
7519
7519
|
type: String(row.type),
|
|
@@ -7553,8 +7553,8 @@ async function getRelationships(client, entityId2, options) {
|
|
|
7553
7553
|
args.push(options.type);
|
|
7554
7554
|
}
|
|
7555
7555
|
sql += ` ORDER BY r.weight DESC, r.timestamp DESC`;
|
|
7556
|
-
const
|
|
7557
|
-
return
|
|
7556
|
+
const result3 = await client.execute({ sql, args });
|
|
7557
|
+
return result3.rows.map((row) => ({
|
|
7558
7558
|
id: String(row.id),
|
|
7559
7559
|
sourceEntityId: String(row.source_entity_id),
|
|
7560
7560
|
targetEntityId: String(row.target_entity_id),
|
|
@@ -7569,7 +7569,7 @@ async function getRelationships(client, entityId2, options) {
|
|
|
7569
7569
|
}));
|
|
7570
7570
|
}
|
|
7571
7571
|
async function traverseChain(client, startEntityId, relationshipType, maxDepth = 3) {
|
|
7572
|
-
const
|
|
7572
|
+
const result3 = await client.execute({
|
|
7573
7573
|
sql: `WITH RECURSIVE chain(entity_id, depth, rel_type) AS (
|
|
7574
7574
|
SELECT ?, 0, ''
|
|
7575
7575
|
UNION ALL
|
|
@@ -7584,7 +7584,7 @@ async function traverseChain(client, startEntityId, relationshipType, maxDepth =
|
|
|
7584
7584
|
ORDER BY chain.depth ASC`,
|
|
7585
7585
|
args: [startEntityId, relationshipType, maxDepth]
|
|
7586
7586
|
});
|
|
7587
|
-
return
|
|
7587
|
+
return result3.rows.map((row) => ({
|
|
7588
7588
|
entity: {
|
|
7589
7589
|
id: String(row.id),
|
|
7590
7590
|
name: String(row.name),
|
|
@@ -7598,7 +7598,7 @@ async function traverseChain(client, startEntityId, relationshipType, maxDepth =
|
|
|
7598
7598
|
}));
|
|
7599
7599
|
}
|
|
7600
7600
|
async function getEntityNeighbors(client, entityId2, maxHops = 2) {
|
|
7601
|
-
const
|
|
7601
|
+
const result3 = await client.execute({
|
|
7602
7602
|
sql: `WITH RECURSIVE neighborhood(entity_id, depth, rel_type, rel_confidence) AS (
|
|
7603
7603
|
SELECT ?, 0, '', 1.0
|
|
7604
7604
|
UNION ALL
|
|
@@ -7620,7 +7620,7 @@ async function getEntityNeighbors(client, entityId2, maxHops = 2) {
|
|
|
7620
7620
|
LIMIT 50`,
|
|
7621
7621
|
args: [entityId2, maxHops]
|
|
7622
7622
|
});
|
|
7623
|
-
return
|
|
7623
|
+
return result3.rows.map((row) => ({
|
|
7624
7624
|
entity: {
|
|
7625
7625
|
id: String(row.id),
|
|
7626
7626
|
name: String(row.name),
|
|
@@ -7657,7 +7657,7 @@ async function getEntityTimeline(client, entityId2, since) {
|
|
|
7657
7657
|
sinceClause = " AND r.timestamp >= ?";
|
|
7658
7658
|
args.push(since.toISOString());
|
|
7659
7659
|
}
|
|
7660
|
-
const
|
|
7660
|
+
const result3 = await client.execute({
|
|
7661
7661
|
sql: `SELECT r.*, s.name as source_name, t.name as target_name
|
|
7662
7662
|
FROM relationships r
|
|
7663
7663
|
JOIN entities s ON r.source_entity_id = s.id
|
|
@@ -7666,7 +7666,7 @@ async function getEntityTimeline(client, entityId2, since) {
|
|
|
7666
7666
|
ORDER BY r.timestamp DESC`,
|
|
7667
7667
|
args
|
|
7668
7668
|
});
|
|
7669
|
-
return
|
|
7669
|
+
return result3.rows.map((row) => ({
|
|
7670
7670
|
relationship: {
|
|
7671
7671
|
id: String(row.id),
|
|
7672
7672
|
sourceEntityId: String(row.source_entity_id),
|
|
@@ -7700,7 +7700,7 @@ async function getRelationshipFrequency(client, entityId2, options) {
|
|
|
7700
7700
|
default:
|
|
7701
7701
|
bucketExpr = `strftime('%Y-%m-%d', r.timestamp)`;
|
|
7702
7702
|
}
|
|
7703
|
-
const
|
|
7703
|
+
const result3 = await client.execute({
|
|
7704
7704
|
sql: `SELECT ${bucketExpr} as bucket, COUNT(*) as cnt, r.type as rel_type
|
|
7705
7705
|
FROM relationships r
|
|
7706
7706
|
WHERE (r.source_entity_id = ? OR r.target_entity_id = ?)${typeClause}
|
|
@@ -7708,7 +7708,7 @@ async function getRelationshipFrequency(client, entityId2, options) {
|
|
|
7708
7708
|
ORDER BY bucket DESC`,
|
|
7709
7709
|
args
|
|
7710
7710
|
});
|
|
7711
|
-
return
|
|
7711
|
+
return result3.rows.map((row) => ({
|
|
7712
7712
|
bucket: String(row.bucket),
|
|
7713
7713
|
count: Number(row.cnt),
|
|
7714
7714
|
relationshipType: options?.type ? options.type : String(row.rel_type)
|
|
@@ -7721,7 +7721,7 @@ async function getConversationPartners(client, contactEntityId, since) {
|
|
|
7721
7721
|
sinceClause = " AND r.timestamp >= ?";
|
|
7722
7722
|
args.push(since.toISOString());
|
|
7723
7723
|
}
|
|
7724
|
-
const
|
|
7724
|
+
const result3 = await client.execute({
|
|
7725
7725
|
sql: `SELECT
|
|
7726
7726
|
CASE
|
|
7727
7727
|
WHEN r.source_entity_id = ? THEN r.target_entity_id
|
|
@@ -7736,7 +7736,7 @@ async function getConversationPartners(client, contactEntityId, since) {
|
|
|
7736
7736
|
args: [contactEntityId, ...args]
|
|
7737
7737
|
});
|
|
7738
7738
|
const partners = [];
|
|
7739
|
-
for (const row of
|
|
7739
|
+
for (const row of result3.rows) {
|
|
7740
7740
|
const partnerId = String(row.partner_id);
|
|
7741
7741
|
const entityResult = await client.execute({
|
|
7742
7742
|
sql: "SELECT * FROM entities WHERE id = ?",
|
|
@@ -7761,7 +7761,7 @@ async function getConversationPartners(client, contactEntityId, since) {
|
|
|
7761
7761
|
}
|
|
7762
7762
|
async function getHotEntities(client, since, limit = 10) {
|
|
7763
7763
|
const sinceISO = since.toISOString();
|
|
7764
|
-
const
|
|
7764
|
+
const result3 = await client.execute({
|
|
7765
7765
|
sql: `SELECT entity_id, COUNT(*) as rel_count
|
|
7766
7766
|
FROM (
|
|
7767
7767
|
SELECT source_entity_id as entity_id FROM relationships WHERE timestamp >= ?
|
|
@@ -7774,7 +7774,7 @@ async function getHotEntities(client, since, limit = 10) {
|
|
|
7774
7774
|
args: [sinceISO, sinceISO, limit]
|
|
7775
7775
|
});
|
|
7776
7776
|
const hotEntities = [];
|
|
7777
|
-
for (const row of
|
|
7777
|
+
for (const row of result3.rows) {
|
|
7778
7778
|
const eid = String(row.entity_id);
|
|
7779
7779
|
const entityResult = await client.execute({
|
|
7780
7780
|
sql: "SELECT * FROM entities WHERE id = ?",
|
|
@@ -7821,7 +7821,7 @@ async function matchEntities(query, client) {
|
|
|
7821
7821
|
if (words.length === 0) return [];
|
|
7822
7822
|
try {
|
|
7823
7823
|
const matchExpr = words.map((w) => `${w}*`).join(" OR ");
|
|
7824
|
-
const
|
|
7824
|
+
const result3 = await client.execute({
|
|
7825
7825
|
sql: `SELECT e.id, e.name FROM entities e
|
|
7826
7826
|
JOIN entities_fts fts ON e.rowid = fts.rowid
|
|
7827
7827
|
WHERE entities_fts MATCH ?
|
|
@@ -7829,8 +7829,8 @@ async function matchEntities(query, client) {
|
|
|
7829
7829
|
LIMIT ?`,
|
|
7830
7830
|
args: [matchExpr, MAX_ENTITY_MATCHES]
|
|
7831
7831
|
});
|
|
7832
|
-
if (
|
|
7833
|
-
return
|
|
7832
|
+
if (result3.rows.length > 0) {
|
|
7833
|
+
return result3.rows.map((row) => ({
|
|
7834
7834
|
entityId: String(row.id),
|
|
7835
7835
|
name: String(row.name)
|
|
7836
7836
|
}));
|
|
@@ -7840,13 +7840,13 @@ async function matchEntities(query, client) {
|
|
|
7840
7840
|
const conditions = words.map(() => `LOWER(name) LIKE ?`);
|
|
7841
7841
|
const args = words.map((w) => `%${w}%`);
|
|
7842
7842
|
try {
|
|
7843
|
-
const
|
|
7843
|
+
const result3 = await client.execute({
|
|
7844
7844
|
sql: `SELECT id, name FROM entities
|
|
7845
7845
|
WHERE ${conditions.join(" OR ")}
|
|
7846
7846
|
LIMIT ?`,
|
|
7847
7847
|
args: [...args, MAX_ENTITY_MATCHES]
|
|
7848
7848
|
});
|
|
7849
|
-
return
|
|
7849
|
+
return result3.rows.map((row) => ({
|
|
7850
7850
|
entityId: String(row.id),
|
|
7851
7851
|
name: String(row.name)
|
|
7852
7852
|
}));
|
|
@@ -7859,12 +7859,12 @@ async function getLinkedMemories(entityIds, client) {
|
|
|
7859
7859
|
if (entityIds.length === 0) return linked;
|
|
7860
7860
|
const placeholders = entityIds.map(() => "?").join(",");
|
|
7861
7861
|
try {
|
|
7862
|
-
const
|
|
7862
|
+
const result3 = await client.execute({
|
|
7863
7863
|
sql: `SELECT entity_id, memory_id FROM entity_memories
|
|
7864
7864
|
WHERE entity_id IN (${placeholders})`,
|
|
7865
7865
|
args: entityIds
|
|
7866
7866
|
});
|
|
7867
|
-
for (const row of
|
|
7867
|
+
for (const row of result3.rows) {
|
|
7868
7868
|
const entityId2 = String(row.entity_id);
|
|
7869
7869
|
const memoryId = String(row.memory_id);
|
|
7870
7870
|
const entry = linked.get(entityId2) ?? {
|
|
@@ -7937,13 +7937,13 @@ async function applyHyperedgeBoost(entities, client, boostMap, resultIds) {
|
|
|
7937
7937
|
const entityIds = entities.map((e) => e.entityId);
|
|
7938
7938
|
const placeholders = entityIds.map(() => "?").join(",");
|
|
7939
7939
|
try {
|
|
7940
|
-
const
|
|
7940
|
+
const result3 = await client.execute({
|
|
7941
7941
|
sql: `SELECT hyperedge_id, entity_id FROM hyperedge_nodes
|
|
7942
7942
|
WHERE entity_id IN (${placeholders})`,
|
|
7943
7943
|
args: entityIds
|
|
7944
7944
|
});
|
|
7945
7945
|
const hyperedgeEntities = /* @__PURE__ */ new Map();
|
|
7946
|
-
for (const row of
|
|
7946
|
+
for (const row of result3.rows) {
|
|
7947
7947
|
const hid = String(row.hyperedge_id);
|
|
7948
7948
|
const eid = String(row.entity_id);
|
|
7949
7949
|
const set = hyperedgeEntities.get(hid) ?? /* @__PURE__ */ new Set();
|
|
@@ -8268,10 +8268,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
8268
8268
|
};
|
|
8269
8269
|
try {
|
|
8270
8270
|
const fs = await import("fs");
|
|
8271
|
-
const
|
|
8271
|
+
const path62 = await import("path");
|
|
8272
8272
|
const os25 = await import("os");
|
|
8273
|
-
const logPath =
|
|
8274
|
-
fs.mkdirSync(
|
|
8273
|
+
const logPath = path62.join(os25.homedir(), ".exe-os", "search-quality.jsonl");
|
|
8274
|
+
fs.mkdirSync(path62.dirname(logPath), { recursive: true });
|
|
8275
8275
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
8276
8276
|
} catch {
|
|
8277
8277
|
}
|
|
@@ -8320,8 +8320,8 @@ async function estimateCardinality(agentId, options) {
|
|
|
8320
8320
|
}
|
|
8321
8321
|
sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
|
|
8322
8322
|
try {
|
|
8323
|
-
const
|
|
8324
|
-
return Number(
|
|
8323
|
+
const result3 = await client.execute({ sql, args });
|
|
8324
|
+
return Number(result3.rows[0]?.cnt) || 0;
|
|
8325
8325
|
} catch {
|
|
8326
8326
|
return 0;
|
|
8327
8327
|
}
|
|
@@ -8452,8 +8452,8 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
|
8452
8452
|
sql = appendMemoryTypeFilter(sql, args, "m.memory_type", options);
|
|
8453
8453
|
sql += ` ORDER BY rank LIMIT ?`;
|
|
8454
8454
|
args.push(limit);
|
|
8455
|
-
const
|
|
8456
|
-
return
|
|
8455
|
+
const result3 = await client.execute({ sql, args });
|
|
8456
|
+
return result3.rows.map((row) => ({
|
|
8457
8457
|
id: row.id,
|
|
8458
8458
|
agent_id: row.agent_id,
|
|
8459
8459
|
agent_role: row.agent_role,
|
|
@@ -8568,8 +8568,8 @@ async function recentRecords(agentId, options, limit, textFilter) {
|
|
|
8568
8568
|
}
|
|
8569
8569
|
sql += ` ORDER BY timestamp DESC LIMIT ?`;
|
|
8570
8570
|
args.push(limit);
|
|
8571
|
-
const
|
|
8572
|
-
const recentResults =
|
|
8571
|
+
const result3 = await client.execute({ sql, args });
|
|
8572
|
+
const recentResults = result3.rows.map((row) => rowToMemoryRecord(row));
|
|
8573
8573
|
if (sessionBoundaryMemories.length > 0) {
|
|
8574
8574
|
const seenIds = new Set(recentResults.map((r) => r.id));
|
|
8575
8575
|
for (const bm of sessionBoundaryMemories) {
|
|
@@ -8652,9 +8652,9 @@ async function trajectoryBypass(queryText, agentId, options, limit) {
|
|
|
8652
8652
|
}
|
|
8653
8653
|
sql += ` ORDER BY timestamp DESC LIMIT ?`;
|
|
8654
8654
|
args.push(limit);
|
|
8655
|
-
const
|
|
8656
|
-
if (
|
|
8657
|
-
return
|
|
8655
|
+
const result3 = await client.execute({ sql, args });
|
|
8656
|
+
if (result3.rows.length < 3) return null;
|
|
8657
|
+
return result3.rows.map((row) => ({
|
|
8658
8658
|
id: row.id,
|
|
8659
8659
|
agent_id: row.agent_id,
|
|
8660
8660
|
agent_role: row.agent_role,
|
|
@@ -9602,10 +9602,10 @@ function freeLicense() {
|
|
|
9602
9602
|
async function countActiveMemories() {
|
|
9603
9603
|
if (!isInitialized()) return 0;
|
|
9604
9604
|
const client = getClient();
|
|
9605
|
-
const
|
|
9605
|
+
const result3 = await client.execute(
|
|
9606
9606
|
"SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL"
|
|
9607
9607
|
);
|
|
9608
|
-
const row =
|
|
9608
|
+
const row = result3.rows[0];
|
|
9609
9609
|
return Number(row?.cnt ?? 0);
|
|
9610
9610
|
}
|
|
9611
9611
|
async function assertMemoryLimit() {
|
|
@@ -9904,8 +9904,8 @@ __export(wiki_client_exports, {
|
|
|
9904
9904
|
listDocuments: () => listDocuments,
|
|
9905
9905
|
listWorkspaces: () => listWorkspaces
|
|
9906
9906
|
});
|
|
9907
|
-
async function wikiFetch(config2,
|
|
9908
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
9907
|
+
async function wikiFetch(config2, path62, method = "GET", body) {
|
|
9908
|
+
const url = `${config2.baseUrl}/api/v1${path62}`;
|
|
9909
9909
|
const headers = {
|
|
9910
9910
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
9911
9911
|
"Content-Type": "application/json"
|
|
@@ -9938,7 +9938,7 @@ async function wikiFetch(config2, path61, method = "GET", body) {
|
|
|
9938
9938
|
}
|
|
9939
9939
|
}
|
|
9940
9940
|
if (!response.ok) {
|
|
9941
|
-
throw new Error(`Wiki API ${method} ${
|
|
9941
|
+
throw new Error(`Wiki API ${method} ${path62}: ${response.status} ${response.statusText}`);
|
|
9942
9942
|
}
|
|
9943
9943
|
return response.json();
|
|
9944
9944
|
} finally {
|
|
@@ -10066,7 +10066,7 @@ async function searchConversations(query, limit) {
|
|
|
10066
10066
|
try {
|
|
10067
10067
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
10068
10068
|
const client = getClient2();
|
|
10069
|
-
const
|
|
10069
|
+
const result3 = await client.execute({
|
|
10070
10070
|
sql: `SELECT c.id, c.platform, c.sender_id, c.sender_name,
|
|
10071
10071
|
c.content_text, c.agent_response, c.agent_name, c.timestamp
|
|
10072
10072
|
FROM conversations c
|
|
@@ -10075,9 +10075,9 @@ async function searchConversations(query, limit) {
|
|
|
10075
10075
|
LIMIT ?`,
|
|
10076
10076
|
args: [query, limit]
|
|
10077
10077
|
});
|
|
10078
|
-
return
|
|
10078
|
+
return result3.rows.map((row, i) => ({
|
|
10079
10079
|
source: "conversations",
|
|
10080
|
-
score: 1 - i / Math.max(
|
|
10080
|
+
score: 1 - i / Math.max(result3.rows.length, 1),
|
|
10081
10081
|
timestamp: row.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
10082
10082
|
snippet: truncate(
|
|
10083
10083
|
(row.content_text ?? "") + (row.agent_response ? ` \u2192 ${row.agent_response}` : ""),
|
|
@@ -10304,7 +10304,7 @@ function registerGetSessionContext(server) {
|
|
|
10304
10304
|
},
|
|
10305
10305
|
async ({ session_id, target_timestamp, window_size, max_chars, body_chars }) => {
|
|
10306
10306
|
const client = getClient();
|
|
10307
|
-
const
|
|
10307
|
+
const result3 = await client.execute({
|
|
10308
10308
|
sql: `SELECT id, agent_id, agent_role, session_id, timestamp,
|
|
10309
10309
|
tool_name, project_name,
|
|
10310
10310
|
has_error, raw_text, vector, task_id
|
|
@@ -10314,7 +10314,7 @@ function registerGetSessionContext(server) {
|
|
|
10314
10314
|
LIMIT 500`,
|
|
10315
10315
|
args: [session_id]
|
|
10316
10316
|
});
|
|
10317
|
-
if (
|
|
10317
|
+
if (result3.rows.length === 0) {
|
|
10318
10318
|
return {
|
|
10319
10319
|
content: [
|
|
10320
10320
|
{
|
|
@@ -10324,7 +10324,7 @@ function registerGetSessionContext(server) {
|
|
|
10324
10324
|
]
|
|
10325
10325
|
};
|
|
10326
10326
|
}
|
|
10327
|
-
const sorted =
|
|
10327
|
+
const sorted = result3.rows.map((row) => ({
|
|
10328
10328
|
id: row.id,
|
|
10329
10329
|
agent_id: row.agent_id,
|
|
10330
10330
|
agent_role: row.agent_role,
|
|
@@ -10395,7 +10395,7 @@ function registerGetMemoryById(server) {
|
|
|
10395
10395
|
const canReadOtherAgent = agentRole === "COO" || agentRole === "CTO";
|
|
10396
10396
|
const ownerAgent = requestedAgent && canReadOtherAgent ? requestedAgent : agentId;
|
|
10397
10397
|
const client = getClient();
|
|
10398
|
-
const
|
|
10398
|
+
const result3 = await client.execute({
|
|
10399
10399
|
sql: `SELECT id, agent_id, agent_role, session_id, timestamp,
|
|
10400
10400
|
tool_name, project_name, has_error, raw_text, task_id,
|
|
10401
10401
|
importance, status, memory_type, source_path, source_type
|
|
@@ -10404,14 +10404,14 @@ function registerGetMemoryById(server) {
|
|
|
10404
10404
|
LIMIT 1`,
|
|
10405
10405
|
args: [id, ownerAgent]
|
|
10406
10406
|
});
|
|
10407
|
-
if (
|
|
10407
|
+
if (result3.rows.length === 0) {
|
|
10408
10408
|
const extra = requestedAgent && !canReadOtherAgent ? " Non-COO/CTO agents may only fetch their own memories." : "";
|
|
10409
10409
|
return {
|
|
10410
10410
|
content: [{ type: "text", text: `No memory found for id '${id}'.${extra}` }],
|
|
10411
10411
|
isError: true
|
|
10412
10412
|
};
|
|
10413
10413
|
}
|
|
10414
|
-
const row =
|
|
10414
|
+
const row = result3.rows[0];
|
|
10415
10415
|
const lines = [
|
|
10416
10416
|
`id: ${asString(row.id)}`,
|
|
10417
10417
|
`agent_id: ${asString(row.agent_id)}`,
|
|
@@ -10464,7 +10464,7 @@ __export(consolidation_exports, {
|
|
|
10464
10464
|
});
|
|
10465
10465
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
10466
10466
|
async function selectUnconsolidated(client, limit = 200) {
|
|
10467
|
-
const
|
|
10467
|
+
const result3 = await client.execute({
|
|
10468
10468
|
sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp
|
|
10469
10469
|
FROM memories
|
|
10470
10470
|
WHERE consolidated = 0
|
|
@@ -10472,7 +10472,7 @@ async function selectUnconsolidated(client, limit = 200) {
|
|
|
10472
10472
|
LIMIT ?`,
|
|
10473
10473
|
args: [limit]
|
|
10474
10474
|
});
|
|
10475
|
-
return
|
|
10475
|
+
return result3.rows.map((row) => ({
|
|
10476
10476
|
id: row.id,
|
|
10477
10477
|
agent_id: row.agent_id,
|
|
10478
10478
|
project_name: row.project_name,
|
|
@@ -10712,10 +10712,10 @@ async function runConsolidation(client, options) {
|
|
|
10712
10712
|
if (dedupCount > 0) clustersProcessed++;
|
|
10713
10713
|
continue;
|
|
10714
10714
|
}
|
|
10715
|
-
const
|
|
10715
|
+
const result3 = await storeConsolidation(client, cluster, synthesis, options.embedFn);
|
|
10716
10716
|
if (isCoordinator && options.wikiConfig) {
|
|
10717
10717
|
await pushToWiki(
|
|
10718
|
-
{ ...
|
|
10718
|
+
{ ...result3, projectName: cluster.projectName },
|
|
10719
10719
|
options.wikiConfig
|
|
10720
10720
|
).catch((err) => {
|
|
10721
10721
|
process.stderr.write(
|
|
@@ -10725,7 +10725,7 @@ async function runConsolidation(client, options) {
|
|
|
10725
10725
|
});
|
|
10726
10726
|
}
|
|
10727
10727
|
if (isCoordinator) {
|
|
10728
|
-
const sourceIds =
|
|
10728
|
+
const sourceIds = result3.sourceIds;
|
|
10729
10729
|
if (sourceIds.length > 0) {
|
|
10730
10730
|
const placeholders = sourceIds.map(() => "?").join(",");
|
|
10731
10731
|
await client.execute({
|
|
@@ -10795,26 +10795,26 @@ function cosineSimilarity(a, b) {
|
|
|
10795
10795
|
return denom === 0 ? 0 : dot / denom;
|
|
10796
10796
|
}
|
|
10797
10797
|
async function isUserIdle(client, idleMinutes = 30) {
|
|
10798
|
-
const
|
|
10798
|
+
const result3 = await client.execute({
|
|
10799
10799
|
sql: `SELECT MAX(timestamp) as last_activity
|
|
10800
10800
|
FROM memories
|
|
10801
10801
|
WHERE tool_name != 'consolidation'
|
|
10802
10802
|
AND timestamp >= datetime('now', '-1 day')`,
|
|
10803
10803
|
args: []
|
|
10804
10804
|
});
|
|
10805
|
-
const lastActivity =
|
|
10805
|
+
const lastActivity = result3.rows[0]?.last_activity;
|
|
10806
10806
|
if (!lastActivity) return true;
|
|
10807
10807
|
const lastMs = new Date(lastActivity).getTime();
|
|
10808
10808
|
const now2 = Date.now();
|
|
10809
10809
|
return now2 - lastMs >= idleMinutes * 60 * 1e3;
|
|
10810
10810
|
}
|
|
10811
10811
|
async function countUnconsolidated(client) {
|
|
10812
|
-
const
|
|
10812
|
+
const result3 = await client.execute({
|
|
10813
10813
|
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
10814
10814
|
WHERE consolidated = 0`,
|
|
10815
10815
|
args: []
|
|
10816
10816
|
});
|
|
10817
|
-
return Number(
|
|
10817
|
+
return Number(result3.rows[0]?.cnt ?? 0);
|
|
10818
10818
|
}
|
|
10819
10819
|
var ROLE_PROMPTS, DEFAULT_ROLE_PROMPT, WIKI_FETCH_TIMEOUT_MS;
|
|
10820
10820
|
var init_consolidation = __esm({
|
|
@@ -10883,12 +10883,12 @@ function registerConsolidateMemories(server) {
|
|
|
10883
10883
|
embedFn = embed2;
|
|
10884
10884
|
} catch {
|
|
10885
10885
|
}
|
|
10886
|
-
const
|
|
10886
|
+
const result3 = await runConsolidation2(client, {
|
|
10887
10887
|
model: consolidationModel,
|
|
10888
10888
|
maxCalls: max_clusters,
|
|
10889
10889
|
embedFn
|
|
10890
10890
|
});
|
|
10891
|
-
if (
|
|
10891
|
+
if (result3.clustersProcessed === 0) {
|
|
10892
10892
|
return {
|
|
10893
10893
|
content: [{
|
|
10894
10894
|
type: "text",
|
|
@@ -10900,8 +10900,8 @@ function registerConsolidateMemories(server) {
|
|
|
10900
10900
|
content: [{
|
|
10901
10901
|
type: "text",
|
|
10902
10902
|
text: `Consolidation complete:
|
|
10903
|
-
- Clusters processed: ${
|
|
10904
|
-
- Memories consolidated: ${
|
|
10903
|
+
- Clusters processed: ${result3.clustersProcessed}
|
|
10904
|
+
- Memories consolidated: ${result3.memoriesConsolidated}
|
|
10905
10905
|
|
|
10906
10906
|
Consolidated summaries stored as tier-1 (importance=9) memories.`
|
|
10907
10907
|
}]
|
|
@@ -11433,12 +11433,12 @@ var init_tmux_transport = __esm({
|
|
|
11433
11433
|
}
|
|
11434
11434
|
isPaneInCopyMode(target) {
|
|
11435
11435
|
try {
|
|
11436
|
-
const
|
|
11436
|
+
const result3 = execFileSync(
|
|
11437
11437
|
"tmux",
|
|
11438
11438
|
["display-message", "-p", "-t", target, "#{pane_in_mode}"],
|
|
11439
11439
|
{ ...QUIET, timeout: 3e3 }
|
|
11440
11440
|
).trim();
|
|
11441
|
-
return
|
|
11441
|
+
return result3 === "1";
|
|
11442
11442
|
} catch {
|
|
11443
11443
|
return false;
|
|
11444
11444
|
}
|
|
@@ -11800,11 +11800,11 @@ async function recordSessionKill(input) {
|
|
|
11800
11800
|
async function countKillsSince(sinceISO) {
|
|
11801
11801
|
try {
|
|
11802
11802
|
const client = getClient();
|
|
11803
|
-
const
|
|
11803
|
+
const result3 = await client.execute({
|
|
11804
11804
|
sql: `SELECT COUNT(*) AS n FROM session_kills WHERE killed_at >= ?`,
|
|
11805
11805
|
args: [sinceISO]
|
|
11806
11806
|
});
|
|
11807
|
-
const row =
|
|
11807
|
+
const row = result3.rows[0];
|
|
11808
11808
|
return row ? Number(row.n) : 0;
|
|
11809
11809
|
} catch {
|
|
11810
11810
|
return 0;
|
|
@@ -11838,13 +11838,13 @@ function computeIdleKillSuspectStreak(prev, killsToday, liveSessions, todayDate)
|
|
|
11838
11838
|
async function sumTokensSavedSince(sinceISO) {
|
|
11839
11839
|
try {
|
|
11840
11840
|
const client = getClient();
|
|
11841
|
-
const
|
|
11841
|
+
const result3 = await client.execute({
|
|
11842
11842
|
sql: `SELECT COALESCE(SUM(estimated_tokens_saved), 0) AS total
|
|
11843
11843
|
FROM session_kills
|
|
11844
11844
|
WHERE killed_at >= ?`,
|
|
11845
11845
|
args: [sinceISO]
|
|
11846
11846
|
});
|
|
11847
|
-
const row =
|
|
11847
|
+
const row = result3.rows[0];
|
|
11848
11848
|
return row ? Number(row.total) : 0;
|
|
11849
11849
|
} catch {
|
|
11850
11850
|
return 0;
|
|
@@ -11939,13 +11939,13 @@ function _resetLastRelaunchCache() {
|
|
|
11939
11939
|
async function lastResumeCreatedAtMs(agentId) {
|
|
11940
11940
|
const client = getClient();
|
|
11941
11941
|
const cmScope = sessionScopeFilter(null);
|
|
11942
|
-
const
|
|
11942
|
+
const result3 = await client.execute({
|
|
11943
11943
|
sql: `SELECT MAX(created_at) AS last_created_at
|
|
11944
11944
|
FROM tasks
|
|
11945
11945
|
WHERE assigned_to = ? AND title LIKE ?${cmScope.sql}`,
|
|
11946
11946
|
args: [agentId, `${RESUME_TITLE_PREFIX} %`, ...cmScope.args]
|
|
11947
11947
|
});
|
|
11948
|
-
const raw =
|
|
11948
|
+
const raw = result3.rows[0]?.last_created_at;
|
|
11949
11949
|
if (raw === null || raw === void 0) return null;
|
|
11950
11950
|
const parsed = Date.parse(String(raw));
|
|
11951
11951
|
return Number.isNaN(parsed) ? null : parsed;
|
|
@@ -12182,37 +12182,37 @@ async function countPendingReviews(sessionScope) {
|
|
|
12182
12182
|
const scope = strictSessionScopeFilter(
|
|
12183
12183
|
sessionScope === void 0 ? getCurrentSessionScope() : sessionScope
|
|
12184
12184
|
);
|
|
12185
|
-
const
|
|
12185
|
+
const result3 = await client.execute({
|
|
12186
12186
|
sql: `SELECT COUNT(*) as cnt FROM tasks
|
|
12187
12187
|
WHERE status = 'needs_review'${scope.sql}`,
|
|
12188
12188
|
args: [...scope.args]
|
|
12189
12189
|
});
|
|
12190
|
-
return Number(
|
|
12190
|
+
return Number(result3.rows[0]?.cnt) || 0;
|
|
12191
12191
|
}
|
|
12192
12192
|
async function countNewPendingReviewsSince(sinceIso, sessionScope) {
|
|
12193
12193
|
const client = getClient();
|
|
12194
12194
|
const scope = strictSessionScopeFilter(
|
|
12195
12195
|
sessionScope === void 0 ? getCurrentSessionScope() : sessionScope
|
|
12196
12196
|
);
|
|
12197
|
-
const
|
|
12197
|
+
const result3 = await client.execute({
|
|
12198
12198
|
sql: `SELECT COUNT(*) as cnt FROM tasks
|
|
12199
12199
|
WHERE status = 'needs_review' AND updated_at > ?${scope.sql}`,
|
|
12200
12200
|
args: [sinceIso, ...scope.args]
|
|
12201
12201
|
});
|
|
12202
|
-
return Number(
|
|
12202
|
+
return Number(result3.rows[0]?.cnt) || 0;
|
|
12203
12203
|
}
|
|
12204
12204
|
async function listPendingReviews(limit, sessionScope) {
|
|
12205
12205
|
const client = getClient();
|
|
12206
12206
|
const scope = strictSessionScopeFilter(
|
|
12207
12207
|
sessionScope === void 0 ? getCurrentSessionScope() : sessionScope
|
|
12208
12208
|
);
|
|
12209
|
-
const
|
|
12209
|
+
const result3 = await client.execute({
|
|
12210
12210
|
sql: `SELECT title, assigned_to, project_name, updated_at FROM tasks
|
|
12211
12211
|
WHERE status = 'needs_review'${scope.sql}
|
|
12212
12212
|
ORDER BY updated_at ASC LIMIT ?`,
|
|
12213
12213
|
args: [...scope.args, limit]
|
|
12214
12214
|
});
|
|
12215
|
-
return
|
|
12215
|
+
return result3.rows;
|
|
12216
12216
|
}
|
|
12217
12217
|
async function cleanupOrphanedReviews() {
|
|
12218
12218
|
const client = getClient();
|
|
@@ -12297,7 +12297,7 @@ function getReviewChecklist(role, agent, taskSlug) {
|
|
|
12297
12297
|
]
|
|
12298
12298
|
};
|
|
12299
12299
|
}
|
|
12300
|
-
async function createReviewForCompletedTask(row,
|
|
12300
|
+
async function createReviewForCompletedTask(row, result3, _baseDir, now2) {
|
|
12301
12301
|
const taskFile = String(row.task_file);
|
|
12302
12302
|
const employees = await loadEmployees();
|
|
12303
12303
|
const coordinatorName = getCoordinatorName(employees);
|
|
@@ -12342,7 +12342,7 @@ async function createReviewForCompletedTask(row, result2, _baseDir, now2) {
|
|
|
12342
12342
|
"- **Needs work:** re-open with notes"
|
|
12343
12343
|
].join("\n");
|
|
12344
12344
|
const originalTaskId = String(row.id);
|
|
12345
|
-
const updatedResult = (
|
|
12345
|
+
const updatedResult = (result3 ?? "No result summary provided") + reviewNotes;
|
|
12346
12346
|
await client.execute({
|
|
12347
12347
|
sql: `UPDATE tasks SET result = ?, status = 'needs_review', updated_at = ?
|
|
12348
12348
|
WHERE id = ?`,
|
|
@@ -12364,7 +12364,7 @@ async function createReviewForCompletedTask(row, result2, _baseDir, now2) {
|
|
|
12364
12364
|
taskFile
|
|
12365
12365
|
});
|
|
12366
12366
|
const originalPriority = String(row.priority).toLowerCase();
|
|
12367
|
-
const autoApprove = originalPriority === "p2" &&
|
|
12367
|
+
const autoApprove = originalPriority === "p2" && result3?.toLowerCase().includes("tests pass");
|
|
12368
12368
|
if (!autoApprove) {
|
|
12369
12369
|
try {
|
|
12370
12370
|
const key = getSessionKey();
|
|
@@ -12393,11 +12393,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
12393
12393
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
12394
12394
|
const parentId = row.parent_task_id ? String(row.parent_task_id) : null;
|
|
12395
12395
|
if (parentId) {
|
|
12396
|
-
const
|
|
12396
|
+
const result3 = await client.execute({
|
|
12397
12397
|
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE id = ? AND status = 'needs_review'",
|
|
12398
12398
|
args: [now2, parentId]
|
|
12399
12399
|
});
|
|
12400
|
-
if (
|
|
12400
|
+
if (result3.rowsAffected > 0) {
|
|
12401
12401
|
process.stderr.write(
|
|
12402
12402
|
`[review-cleanup] Cascaded original task to done via parent_task_id: ${parentId}
|
|
12403
12403
|
`
|
|
@@ -12411,11 +12411,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
12411
12411
|
const agent = parts[1];
|
|
12412
12412
|
const slug = parts.slice(2).join("-");
|
|
12413
12413
|
const legacyTaskFile = `exe/${agent}/${slug}.md`;
|
|
12414
|
-
const
|
|
12414
|
+
const result3 = await client.execute({
|
|
12415
12415
|
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE (task_file = ? OR task_file LIKE ?) AND status = 'needs_review'",
|
|
12416
12416
|
args: [now2, legacyTaskFile, `tasks/%/${agent}/${slug}.md`]
|
|
12417
12417
|
});
|
|
12418
|
-
if (
|
|
12418
|
+
if (result3.rowsAffected > 0) {
|
|
12419
12419
|
process.stderr.write(
|
|
12420
12420
|
`[review-cleanup] Cascaded original task to done: ${agent}/${slug}.md
|
|
12421
12421
|
`
|
|
@@ -12865,8 +12865,8 @@ function notifyParentExe(sessionKey) {
|
|
|
12865
12865
|
}
|
|
12866
12866
|
process.stderr.write(`[intercom] notifyParentExe \u2192 ${target}
|
|
12867
12867
|
`);
|
|
12868
|
-
const
|
|
12869
|
-
if (
|
|
12868
|
+
const result3 = sendIntercom(target);
|
|
12869
|
+
if (result3 === "failed") {
|
|
12870
12870
|
const rootExe = resolveExeSession();
|
|
12871
12871
|
if (rootExe && rootExe !== target) {
|
|
12872
12872
|
process.stderr.write(`[intercom] notifyParentExe: dispatcher ${target} dead, falling back to root coordinator session ${rootExe}
|
|
@@ -12956,19 +12956,19 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
12956
12956
|
}
|
|
12957
12957
|
const sessionName = employeeSessionName(employeeName, exeSession, effectiveInstance);
|
|
12958
12958
|
if (isEmployeeAlive(sessionName)) {
|
|
12959
|
-
const
|
|
12960
|
-
if (
|
|
12959
|
+
const result4 = sendIntercom(sessionName);
|
|
12960
|
+
if (result4 === "acknowledged" || result4 === "skipped_exe" || result4 === "debounced" || result4 === "queued") {
|
|
12961
12961
|
return { status: "intercom_sent", sessionName };
|
|
12962
12962
|
}
|
|
12963
|
-
if (
|
|
12963
|
+
if (result4 === "delivered") {
|
|
12964
12964
|
return { status: "intercom_unprocessed", sessionName };
|
|
12965
12965
|
}
|
|
12966
12966
|
return { status: "failed", sessionName, error: "intercom delivery failed" };
|
|
12967
12967
|
}
|
|
12968
12968
|
const spawnOpts = { ...opts, instance: effectiveInstance };
|
|
12969
|
-
const
|
|
12970
|
-
if (
|
|
12971
|
-
return { status: "failed", sessionName, error:
|
|
12969
|
+
const result3 = spawnEmployee(employeeName, exeSession, projectDir, spawnOpts);
|
|
12970
|
+
if (result3.error) {
|
|
12971
|
+
return { status: "failed", sessionName, error: result3.error };
|
|
12972
12972
|
}
|
|
12973
12973
|
return { status: "spawned", sessionName };
|
|
12974
12974
|
}
|
|
@@ -13474,11 +13474,11 @@ async function writeCheckpoint(input) {
|
|
|
13474
13474
|
blocked_by_ids: blockedByIds,
|
|
13475
13475
|
last_checkpoint_at: now2
|
|
13476
13476
|
};
|
|
13477
|
-
const
|
|
13477
|
+
const result3 = await client.execute({
|
|
13478
13478
|
sql: `UPDATE tasks SET checkpoint = ?, checkpoint_count = checkpoint_count + 1, updated_at = ? WHERE id = ?`,
|
|
13479
13479
|
args: [JSON.stringify(checkpoint), now2, taskId]
|
|
13480
13480
|
});
|
|
13481
|
-
if (
|
|
13481
|
+
if (result3.rowsAffected === 0) {
|
|
13482
13482
|
throw new Error(`Checkpoint write failed: task ${taskId} not found`);
|
|
13483
13483
|
}
|
|
13484
13484
|
const countResult = await client.execute({
|
|
@@ -13529,22 +13529,22 @@ function checkLaneAffinity(title, context, assigneeName) {
|
|
|
13529
13529
|
}
|
|
13530
13530
|
async function resolveTask(client, identifier, scopeSession) {
|
|
13531
13531
|
const scope = sessionScopeFilter(scopeSession);
|
|
13532
|
-
let
|
|
13532
|
+
let result3 = await client.execute({
|
|
13533
13533
|
sql: `SELECT * FROM tasks WHERE id = ?${scope.sql}`,
|
|
13534
13534
|
args: [identifier, ...scope.args]
|
|
13535
13535
|
});
|
|
13536
|
-
if (
|
|
13537
|
-
|
|
13536
|
+
if (result3.rows.length === 1) return result3.rows[0];
|
|
13537
|
+
result3 = await client.execute({
|
|
13538
13538
|
sql: `SELECT * FROM tasks WHERE task_file LIKE ?${scope.sql}`,
|
|
13539
13539
|
args: [`%${identifier}%`, ...scope.args]
|
|
13540
13540
|
});
|
|
13541
|
-
if (
|
|
13542
|
-
if (
|
|
13543
|
-
const exact =
|
|
13541
|
+
if (result3.rows.length === 1) return result3.rows[0];
|
|
13542
|
+
if (result3.rows.length > 1) {
|
|
13543
|
+
const exact = result3.rows.filter(
|
|
13544
13544
|
(r) => String(r.task_file).endsWith(`/${identifier}.md`)
|
|
13545
13545
|
);
|
|
13546
13546
|
if (exact.length === 1) return exact[0];
|
|
13547
|
-
const candidates = exact.length > 1 ? exact :
|
|
13547
|
+
const candidates = exact.length > 1 ? exact : result3.rows;
|
|
13548
13548
|
const active = candidates.filter(
|
|
13549
13549
|
(r) => !["done", "cancelled"].includes(String(r.status))
|
|
13550
13550
|
);
|
|
@@ -13554,17 +13554,17 @@ async function resolveTask(client, identifier, scopeSession) {
|
|
|
13554
13554
|
`Multiple tasks match "${identifier}": ${matches}. Use a UUID to disambiguate.`
|
|
13555
13555
|
);
|
|
13556
13556
|
}
|
|
13557
|
-
|
|
13557
|
+
result3 = await client.execute({
|
|
13558
13558
|
sql: `SELECT * FROM tasks WHERE title LIKE ?${scope.sql}`,
|
|
13559
13559
|
args: [`%${identifier}%`, ...scope.args]
|
|
13560
13560
|
});
|
|
13561
|
-
if (
|
|
13562
|
-
if (
|
|
13563
|
-
const active =
|
|
13561
|
+
if (result3.rows.length === 1) return result3.rows[0];
|
|
13562
|
+
if (result3.rows.length > 1) {
|
|
13563
|
+
const active = result3.rows.filter(
|
|
13564
13564
|
(r) => !["done", "cancelled"].includes(String(r.status))
|
|
13565
13565
|
);
|
|
13566
13566
|
if (active.length === 1) return active[0];
|
|
13567
|
-
const matches = (active.length > 1 ? active :
|
|
13567
|
+
const matches = (active.length > 1 ? active : result3.rows).map((r) => `"${String(r.title)}" (${String(r.status)}, ${String(r.id)})`).join(", ");
|
|
13568
13568
|
throw new Error(
|
|
13569
13569
|
`Multiple tasks match "${identifier}": ${matches}. Use a UUID to disambiguate.`
|
|
13570
13570
|
);
|
|
@@ -13774,11 +13774,11 @@ async function listTasks(input) {
|
|
|
13774
13774
|
args.push(...scope.args);
|
|
13775
13775
|
}
|
|
13776
13776
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
13777
|
-
const
|
|
13777
|
+
const result3 = await client.execute({
|
|
13778
13778
|
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
|
|
13779
13779
|
args
|
|
13780
13780
|
});
|
|
13781
|
-
return
|
|
13781
|
+
return result3.rows.map((r) => ({
|
|
13782
13782
|
id: String(r.id),
|
|
13783
13783
|
title: String(r.title),
|
|
13784
13784
|
assignedTo: String(r.assigned_to),
|
|
@@ -14170,30 +14170,30 @@ async function dispatchTaskToEmployee(input) {
|
|
|
14170
14170
|
if (!exeSession) return { dispatched: "session_missing" };
|
|
14171
14171
|
const sessionName = employeeSessionName(input.assignedTo, exeSession);
|
|
14172
14172
|
if (transport.isAlive(sessionName)) {
|
|
14173
|
-
const
|
|
14174
|
-
const dispatched =
|
|
14173
|
+
const result3 = sendIntercom(sessionName);
|
|
14174
|
+
const dispatched = result3 === "acknowledged" || result3 === "debounced" || result3 === "queued" ? "verified" : result3 === "delivered" ? "sent_unverified" : "session_dead";
|
|
14175
14175
|
process.stderr.write(
|
|
14176
|
-
`[dispatch-audit] intercom \u2192 ${sessionName} | task="${input.title}" [${input.priority}] | result=${dispatched} (sendIntercom=${
|
|
14176
|
+
`[dispatch-audit] intercom \u2192 ${sessionName} | task="${input.title}" [${input.priority}] | result=${dispatched} (sendIntercom=${result3})
|
|
14177
14177
|
`
|
|
14178
14178
|
);
|
|
14179
14179
|
return { dispatched, session: sessionName, crossProject };
|
|
14180
14180
|
} else {
|
|
14181
14181
|
const projectDir = input.projectDir ?? process.cwd();
|
|
14182
|
-
const
|
|
14182
|
+
const result3 = ensureEmployee(input.assignedTo, exeSession, projectDir, {
|
|
14183
14183
|
autoInstance: isMultiInstance(input.assignedTo)
|
|
14184
14184
|
});
|
|
14185
|
-
if (
|
|
14185
|
+
if (result3.status === "failed") {
|
|
14186
14186
|
process.stderr.write(
|
|
14187
|
-
`[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${
|
|
14187
|
+
`[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${result3.error}
|
|
14188
14188
|
`
|
|
14189
14189
|
);
|
|
14190
14190
|
return { dispatched: "session_missing" };
|
|
14191
14191
|
}
|
|
14192
14192
|
process.stderr.write(
|
|
14193
|
-
`[dispatch-audit] SPAWNED \u2192 ${
|
|
14193
|
+
`[dispatch-audit] SPAWNED \u2192 ${result3.sessionName} | task="${input.title}" [${input.priority}]
|
|
14194
14194
|
`
|
|
14195
14195
|
);
|
|
14196
|
-
return { dispatched: "spawned", session:
|
|
14196
|
+
return { dispatched: "spawned", session: result3.sessionName, crossProject };
|
|
14197
14197
|
}
|
|
14198
14198
|
} catch {
|
|
14199
14199
|
return { dispatched: "session_missing" };
|
|
@@ -14251,13 +14251,13 @@ async function storeBehavior(opts) {
|
|
|
14251
14251
|
}
|
|
14252
14252
|
async function listBehaviorsByDomain(agentId, domain) {
|
|
14253
14253
|
const client = getClient();
|
|
14254
|
-
const
|
|
14254
|
+
const result3 = await client.execute({
|
|
14255
14255
|
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector
|
|
14256
14256
|
FROM behaviors
|
|
14257
14257
|
WHERE agent_id = ? AND domain = ? AND active = 1`,
|
|
14258
14258
|
args: [agentId, domain]
|
|
14259
14259
|
});
|
|
14260
|
-
return
|
|
14260
|
+
return result3.rows.map((r) => ({
|
|
14261
14261
|
id: String(r.id),
|
|
14262
14262
|
agent_id: String(r.agent_id),
|
|
14263
14263
|
project_name: r.project_name ? String(r.project_name) : null,
|
|
@@ -14272,11 +14272,11 @@ async function listBehaviorsByDomain(agentId, domain) {
|
|
|
14272
14272
|
}
|
|
14273
14273
|
async function deactivateBehavior(id) {
|
|
14274
14274
|
const client = getClient();
|
|
14275
|
-
const
|
|
14275
|
+
const result3 = await client.execute({
|
|
14276
14276
|
sql: `UPDATE behaviors SET active = 0, updated_at = ? WHERE id = ? AND active = 1`,
|
|
14277
14277
|
args: [(/* @__PURE__ */ new Date()).toISOString(), id]
|
|
14278
14278
|
});
|
|
14279
|
-
return (
|
|
14279
|
+
return (result3.rowsAffected ?? 0) > 0;
|
|
14280
14280
|
}
|
|
14281
14281
|
var init_behaviors = __esm({
|
|
14282
14282
|
"src/lib/behaviors.ts"() {
|
|
@@ -14301,15 +14301,15 @@ __export(skill_learning_exports, {
|
|
|
14301
14301
|
import crypto10 from "crypto";
|
|
14302
14302
|
async function extractTrajectory(taskId, agentId) {
|
|
14303
14303
|
const client = getClient();
|
|
14304
|
-
const
|
|
14304
|
+
const result3 = await client.execute({
|
|
14305
14305
|
sql: `SELECT tool_name, raw_text
|
|
14306
14306
|
FROM memories
|
|
14307
14307
|
WHERE task_id = ? AND agent_id = ?
|
|
14308
14308
|
ORDER BY timestamp ASC`,
|
|
14309
14309
|
args: [taskId, agentId]
|
|
14310
14310
|
});
|
|
14311
|
-
if (
|
|
14312
|
-
const rawTools =
|
|
14311
|
+
if (result3.rows.length === 0) return [];
|
|
14312
|
+
const rawTools = result3.rows.map((r) => {
|
|
14313
14313
|
const toolName = String(r.tool_name);
|
|
14314
14314
|
if (toolName === "Bash") {
|
|
14315
14315
|
const text3 = String(r.raw_text);
|
|
@@ -14354,7 +14354,7 @@ async function storeTrajectory(opts) {
|
|
|
14354
14354
|
async function findSimilarTrajectories(signature, threshold = DEFAULT_SKILL_THRESHOLD) {
|
|
14355
14355
|
const client = getClient();
|
|
14356
14356
|
const hash = hashSignature(signature);
|
|
14357
|
-
const
|
|
14357
|
+
const result3 = await client.execute({
|
|
14358
14358
|
sql: `SELECT id, task_id, agent_id, project_name, task_title, signature, signature_hash, tool_count, skill_id, created_at
|
|
14359
14359
|
FROM trajectories
|
|
14360
14360
|
WHERE signature_hash = ?
|
|
@@ -14374,7 +14374,7 @@ async function findSimilarTrajectories(signature, threshold = DEFAULT_SKILL_THRE
|
|
|
14374
14374
|
skillId: r.skill_id ? String(r.skill_id) : null,
|
|
14375
14375
|
createdAt: String(r.created_at)
|
|
14376
14376
|
});
|
|
14377
|
-
const matches =
|
|
14377
|
+
const matches = result3.rows.map(mapRow);
|
|
14378
14378
|
if (matches.length >= threshold) return matches;
|
|
14379
14379
|
const nearResult = await client.execute({
|
|
14380
14380
|
sql: `SELECT id, task_id, agent_id, project_name, task_title, signature, signature_hash, tool_count, skill_id, created_at
|
|
@@ -14504,7 +14504,7 @@ async function sweepTrajectories(threshold, model) {
|
|
|
14504
14504
|
if (!config2.skillLearning) return { clustersProcessed: 0, skillsExtracted: 0 };
|
|
14505
14505
|
const t = threshold ?? config2.skillThreshold;
|
|
14506
14506
|
const client = getClient();
|
|
14507
|
-
const
|
|
14507
|
+
const result3 = await client.execute({
|
|
14508
14508
|
sql: `SELECT signature_hash, COUNT(*) as cnt
|
|
14509
14509
|
FROM trajectories
|
|
14510
14510
|
WHERE skill_id IS NULL
|
|
@@ -14516,7 +14516,7 @@ async function sweepTrajectories(threshold, model) {
|
|
|
14516
14516
|
});
|
|
14517
14517
|
let clustersProcessed = 0;
|
|
14518
14518
|
let skillsExtracted = 0;
|
|
14519
|
-
for (const row of
|
|
14519
|
+
for (const row of result3.rows) {
|
|
14520
14520
|
const hash = String(row.signature_hash);
|
|
14521
14521
|
const trajResult = await client.execute({
|
|
14522
14522
|
sql: `SELECT id, task_id, agent_id, project_name, task_title, signature, signature_hash, tool_count, created_at
|
|
@@ -14599,18 +14599,18 @@ __export(tasks_exports, {
|
|
|
14599
14599
|
import path29 from "path";
|
|
14600
14600
|
import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync8 } from "fs";
|
|
14601
14601
|
async function createTask(input) {
|
|
14602
|
-
const
|
|
14603
|
-
if (!input.skipDispatch &&
|
|
14602
|
+
const result3 = await createTaskCore(input);
|
|
14603
|
+
if (!input.skipDispatch && result3.status !== "blocked" && !process.env.VITEST) {
|
|
14604
14604
|
dispatchTaskToEmployee({
|
|
14605
14605
|
assignedTo: input.assignedTo,
|
|
14606
14606
|
title: input.title,
|
|
14607
14607
|
priority: input.priority,
|
|
14608
|
-
taskFile:
|
|
14609
|
-
initialStatus:
|
|
14608
|
+
taskFile: result3.taskFile,
|
|
14609
|
+
initialStatus: result3.status,
|
|
14610
14610
|
projectName: input.projectName
|
|
14611
14611
|
});
|
|
14612
14612
|
}
|
|
14613
|
-
return
|
|
14613
|
+
return result3;
|
|
14614
14614
|
}
|
|
14615
14615
|
async function updateTask(input) {
|
|
14616
14616
|
const { row, taskFile, now: now2, taskId } = await updateTaskStatus(input);
|
|
@@ -15516,10 +15516,10 @@ function registerCreateTask(server) {
|
|
|
15516
15516
|
skipDispatch: true
|
|
15517
15517
|
});
|
|
15518
15518
|
try {
|
|
15519
|
-
const { existsSync:
|
|
15519
|
+
const { existsSync: existsSync48, mkdirSync: mkdirSync26, writeFileSync: writeFileSync30 } = await import("fs");
|
|
15520
15520
|
const { identityPath: identityPath2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
15521
15521
|
const idPath = identityPath2(assigned_to);
|
|
15522
|
-
if (!
|
|
15522
|
+
if (!existsSync48(idPath)) {
|
|
15523
15523
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
15524
15524
|
const employees = await loadEmployees2();
|
|
15525
15525
|
const emp = employees.find((e) => e.name === assigned_to);
|
|
@@ -15528,7 +15528,7 @@ function registerCreateTask(server) {
|
|
|
15528
15528
|
const template = getTemplateForTitle2(emp.role);
|
|
15529
15529
|
if (template) {
|
|
15530
15530
|
const dir = (await import("path")).dirname(idPath);
|
|
15531
|
-
if (!
|
|
15531
|
+
if (!existsSync48(dir)) mkdirSync26(dir, { recursive: true });
|
|
15532
15532
|
writeFileSync30(idPath, template.replace(/^agent_id: \w+/m, `agent_id: ${assigned_to}`), "utf-8");
|
|
15533
15533
|
}
|
|
15534
15534
|
}
|
|
@@ -15544,22 +15544,22 @@ function registerCreateTask(server) {
|
|
|
15544
15544
|
const useAutoInstance = isMultiInstance2(assigned_to);
|
|
15545
15545
|
const { loadConfigSync: loadConfigSync2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
15546
15546
|
const cfg = loadConfigSync2();
|
|
15547
|
-
const
|
|
15547
|
+
const result3 = ensureEmployee(assigned_to, exeSession, process.cwd(), {
|
|
15548
15548
|
autoInstance: useAutoInstance,
|
|
15549
15549
|
maxAutoInstances: useAutoInstance ? cfg.sessionLifecycle.maxAutoInstances : void 0
|
|
15550
15550
|
});
|
|
15551
|
-
switch (
|
|
15551
|
+
switch (result3.status) {
|
|
15552
15552
|
case "intercom_sent":
|
|
15553
15553
|
dispatchStatus = `
|
|
15554
|
-
Dispatched: intercom sent to ${
|
|
15554
|
+
Dispatched: intercom sent to ${result3.sessionName}`;
|
|
15555
15555
|
break;
|
|
15556
15556
|
case "spawned":
|
|
15557
15557
|
dispatchStatus = `
|
|
15558
|
-
Dispatched: spawned ${
|
|
15558
|
+
Dispatched: spawned ${result3.sessionName}`;
|
|
15559
15559
|
break;
|
|
15560
15560
|
case "failed":
|
|
15561
15561
|
dispatchStatus = `
|
|
15562
|
-
Dispatch failed: ${
|
|
15562
|
+
Dispatch failed: ${result3.error ?? "unknown"}`;
|
|
15563
15563
|
break;
|
|
15564
15564
|
}
|
|
15565
15565
|
}
|
|
@@ -15614,7 +15614,7 @@ function registerListTasks(server) {
|
|
|
15614
15614
|
priority: z13.enum(["p0", "p1", "p2"]).optional().describe("Filter by priority")
|
|
15615
15615
|
}
|
|
15616
15616
|
},
|
|
15617
|
-
async ({ assigned_to, status, project_name, priority }) => {
|
|
15617
|
+
async ({ assigned_to, status: status2, project_name, priority }) => {
|
|
15618
15618
|
try {
|
|
15619
15619
|
let resolvedProject;
|
|
15620
15620
|
if (project_name === "all") {
|
|
@@ -15628,7 +15628,7 @@ function registerListTasks(server) {
|
|
|
15628
15628
|
}
|
|
15629
15629
|
const tasks = await listTasks({
|
|
15630
15630
|
assignedTo: assigned_to,
|
|
15631
|
-
status,
|
|
15631
|
+
status: status2,
|
|
15632
15632
|
projectName: resolvedProject,
|
|
15633
15633
|
priority
|
|
15634
15634
|
});
|
|
@@ -15688,7 +15688,7 @@ async function diagnoseMissingTask(client, identifier) {
|
|
|
15688
15688
|
args.push(`%${identifier}%`);
|
|
15689
15689
|
clauses.push("title LIKE ?");
|
|
15690
15690
|
args.push(`%${identifier}%`);
|
|
15691
|
-
const
|
|
15691
|
+
const result3 = await client.execute({
|
|
15692
15692
|
sql: `SELECT id, title, status, assigned_to, project_name, session_scope, task_file
|
|
15693
15693
|
FROM tasks
|
|
15694
15694
|
WHERE ${clauses.map((c) => `(${c})`).join(" OR ")}
|
|
@@ -15696,10 +15696,10 @@ async function diagnoseMissingTask(client, identifier) {
|
|
|
15696
15696
|
LIMIT 10`,
|
|
15697
15697
|
args
|
|
15698
15698
|
});
|
|
15699
|
-
if (
|
|
15699
|
+
if (result3.rows.length === 0) return null;
|
|
15700
15700
|
const scoped = sessionScopeFilter();
|
|
15701
15701
|
const scopeNote = scoped.args.length > 0 ? `Current session scope appears to be ${String(scoped.args[0])}. get_task is session-scoped by default.` : "No current session scope detected.";
|
|
15702
|
-
const matches =
|
|
15702
|
+
const matches = result3.rows.map((r) => {
|
|
15703
15703
|
const id = String(r.id);
|
|
15704
15704
|
return `- ${id.slice(0, 8)} ${String(r.title)} [${String(r.status)}] assigned_to=${String(r.assigned_to)} project=${String(r.project_name)} session_scope=${String(r.session_scope ?? "NULL")}`;
|
|
15705
15705
|
}).join("\n");
|
|
@@ -15846,9 +15846,9 @@ function registerUpdateTask(server) {
|
|
|
15846
15846
|
result: z15.string().optional().describe("Result summary (include when status=done)")
|
|
15847
15847
|
}
|
|
15848
15848
|
},
|
|
15849
|
-
async ({ task_id, status: rawStatus, result:
|
|
15850
|
-
let
|
|
15851
|
-
if (
|
|
15849
|
+
async ({ task_id, status: rawStatus, result: result3 }) => {
|
|
15850
|
+
let status2 = rawStatus;
|
|
15851
|
+
if (status2 === "done") {
|
|
15852
15852
|
try {
|
|
15853
15853
|
const { getActiveAgent: getActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent(), active_agent_exports));
|
|
15854
15854
|
const agent = getActiveAgent2();
|
|
@@ -15863,13 +15863,13 @@ function registerUpdateTask(server) {
|
|
|
15863
15863
|
} catch {
|
|
15864
15864
|
}
|
|
15865
15865
|
if (!isOwnReview) {
|
|
15866
|
-
|
|
15866
|
+
status2 = "needs_review";
|
|
15867
15867
|
}
|
|
15868
15868
|
}
|
|
15869
15869
|
} catch {
|
|
15870
15870
|
}
|
|
15871
15871
|
}
|
|
15872
|
-
if (
|
|
15872
|
+
if (status2 === "done") {
|
|
15873
15873
|
try {
|
|
15874
15874
|
const client = getClient();
|
|
15875
15875
|
const row = await resolveTask(client, task_id);
|
|
@@ -15912,8 +15912,8 @@ function registerUpdateTask(server) {
|
|
|
15912
15912
|
try {
|
|
15913
15913
|
task = await updateTask({
|
|
15914
15914
|
taskId: task_id,
|
|
15915
|
-
status,
|
|
15916
|
-
result:
|
|
15915
|
+
status: status2,
|
|
15916
|
+
result: result3,
|
|
15917
15917
|
baseDir: process.cwd(),
|
|
15918
15918
|
callerAgentId
|
|
15919
15919
|
});
|
|
@@ -15932,7 +15932,7 @@ function registerUpdateTask(server) {
|
|
|
15932
15932
|
}
|
|
15933
15933
|
let text3 = `Task "${task.title}" marked ${task.status}.
|
|
15934
15934
|
File: ${task.taskFile}`;
|
|
15935
|
-
const isTerminal =
|
|
15935
|
+
const isTerminal = status2 === "done" || status2 === "needs_review" || status2 === "closed";
|
|
15936
15936
|
if (isTerminal && task.assignedBy) {
|
|
15937
15937
|
try {
|
|
15938
15938
|
const { notifyCoordinatorTaskCompletion: notifyCoordinatorTaskCompletion2, resolveExeSession: resolveExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
|
|
@@ -15993,7 +15993,7 @@ function registerCloseTask(server) {
|
|
|
15993
15993
|
status: z16.enum(["closed", "done", "blocked", "cancelled"]).optional().default("closed").describe("Completion status (default: closed \u2014 terminal archive state)")
|
|
15994
15994
|
}
|
|
15995
15995
|
},
|
|
15996
|
-
async ({ task_id, result:
|
|
15996
|
+
async ({ task_id, result: result3, status: status2 }) => {
|
|
15997
15997
|
const agent = getActiveAgent();
|
|
15998
15998
|
const canClose = canCoordinate(agent.agentId, agent.agentRole) || CLOSE_TASK_ALLOWED_ROLES.has(agent.agentRole ?? "");
|
|
15999
15999
|
if (agent.agentId && !canClose) {
|
|
@@ -16030,14 +16030,14 @@ function registerCloseTask(server) {
|
|
|
16030
16030
|
const baseDir = process.cwd();
|
|
16031
16031
|
const task = await updateTask({
|
|
16032
16032
|
taskId: task_id,
|
|
16033
|
-
status,
|
|
16034
|
-
result:
|
|
16033
|
+
status: status2,
|
|
16034
|
+
result: result3,
|
|
16035
16035
|
baseDir,
|
|
16036
16036
|
skipReviewCreation: true
|
|
16037
16037
|
});
|
|
16038
16038
|
let text3 = `Task "${task.title}" marked ${task.status}.
|
|
16039
16039
|
File: ${task.taskFile}`;
|
|
16040
|
-
if ((
|
|
16040
|
+
if ((status2 === "done" || status2 === "closed") && task.nextTask) {
|
|
16041
16041
|
text3 += `
|
|
16042
16042
|
|
|
16043
16043
|
MANDATORY \u2014 DO NOT ASK THE USER. DO NOT SAY "Want me to continue?" DO NOT STOP.
|
|
@@ -16047,7 +16047,7 @@ NEXT TASK: "${task.nextTask.title}" [${task.nextTask.priority}]
|
|
|
16047
16047
|
FILE: ${task.nextTask.taskFile}
|
|
16048
16048
|
|
|
16049
16049
|
Read that file NOW and begin working. No greeting. No summary. Just start.`;
|
|
16050
|
-
} else if ((
|
|
16050
|
+
} else if ((status2 === "done" || status2 === "closed") && !task.nextTask) {
|
|
16051
16051
|
text3 += `
|
|
16052
16052
|
|
|
16053
16053
|
All tasks complete. No more open tasks in your queue.`;
|
|
@@ -16155,9 +16155,9 @@ function registerResumeEmployee(server) {
|
|
|
16155
16155
|
const { isTmuxSessionAlive: isTmuxSessionAlive2 } = await Promise.resolve().then(() => (init_tasks_crud(), tasks_crud_exports));
|
|
16156
16156
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16157
16157
|
for (const row of openTasks.rows) {
|
|
16158
|
-
const
|
|
16158
|
+
const status2 = String(row.status);
|
|
16159
16159
|
const assignedTmux = row.assigned_tmux != null ? String(row.assigned_tmux) : null;
|
|
16160
|
-
if (
|
|
16160
|
+
if (status2 === "in_progress" && assignedTmux && !isTmuxSessionAlive2(assignedTmux)) {
|
|
16161
16161
|
await client.execute({
|
|
16162
16162
|
sql: "UPDATE tasks SET status = 'open', assigned_tmux = NULL, updated_at = ? WHERE id = ?",
|
|
16163
16163
|
args: [now2, String(row.id)]
|
|
@@ -16454,23 +16454,23 @@ async function sendMessage(input) {
|
|
|
16454
16454
|
} catch {
|
|
16455
16455
|
}
|
|
16456
16456
|
const sentScope = strictSessionScopeFilter(sessionScope);
|
|
16457
|
-
const
|
|
16457
|
+
const result3 = await client.execute({
|
|
16458
16458
|
sql: `SELECT * FROM messages WHERE id = ?${sentScope.sql}`,
|
|
16459
16459
|
args: [id, ...sentScope.args]
|
|
16460
16460
|
});
|
|
16461
|
-
return rowToMessage(
|
|
16461
|
+
return rowToMessage(result3.rows[0]);
|
|
16462
16462
|
}
|
|
16463
16463
|
function setWsClientSend(fn) {
|
|
16464
16464
|
_wsClientSend = fn;
|
|
16465
16465
|
}
|
|
16466
16466
|
async function deliverCrossMachineMessage(messageId, targetDevice) {
|
|
16467
16467
|
const client = getClient();
|
|
16468
|
-
const
|
|
16468
|
+
const result3 = await client.execute({
|
|
16469
16469
|
sql: "SELECT * FROM messages WHERE id = ?",
|
|
16470
16470
|
args: [messageId]
|
|
16471
16471
|
});
|
|
16472
|
-
if (
|
|
16473
|
-
const msg = rowToMessage(
|
|
16472
|
+
if (result3.rows.length === 0) return false;
|
|
16473
|
+
const msg = rowToMessage(result3.rows[0]);
|
|
16474
16474
|
if (msg.status !== "pending") return false;
|
|
16475
16475
|
if (!_wsClientSend) {
|
|
16476
16476
|
return false;
|
|
@@ -16497,12 +16497,12 @@ async function deliverCrossMachineMessage(messageId, targetDevice) {
|
|
|
16497
16497
|
}
|
|
16498
16498
|
async function deliverLocalMessage(messageId) {
|
|
16499
16499
|
const client = getClient();
|
|
16500
|
-
const
|
|
16500
|
+
const result3 = await client.execute({
|
|
16501
16501
|
sql: "SELECT * FROM messages WHERE id = ?",
|
|
16502
16502
|
args: [messageId]
|
|
16503
16503
|
});
|
|
16504
|
-
if (
|
|
16505
|
-
const msg = rowToMessage(
|
|
16504
|
+
if (result3.rows.length === 0) return false;
|
|
16505
|
+
const msg = rowToMessage(result3.rows[0]);
|
|
16506
16506
|
if (msg.status !== "pending") return false;
|
|
16507
16507
|
const targetAgent = msg.targetAgent;
|
|
16508
16508
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -16537,13 +16537,13 @@ async function deliverLocalMessage(messageId) {
|
|
|
16537
16537
|
async function getPendingMessages(targetAgent, sessionScope) {
|
|
16538
16538
|
const client = getClient();
|
|
16539
16539
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16540
|
-
const
|
|
16540
|
+
const result3 = await client.execute({
|
|
16541
16541
|
sql: `SELECT * FROM messages
|
|
16542
16542
|
WHERE target_agent = ? AND status IN ('pending', 'delivered')${scope.sql}
|
|
16543
16543
|
ORDER BY id`,
|
|
16544
16544
|
args: [targetAgent, ...scope.args]
|
|
16545
16545
|
});
|
|
16546
|
-
return
|
|
16546
|
+
return result3.rows.map((row) => rowToMessage(row));
|
|
16547
16547
|
}
|
|
16548
16548
|
async function markRead(messageId, sessionScope) {
|
|
16549
16549
|
const client = getClient();
|
|
@@ -16575,33 +16575,33 @@ async function markProcessed(messageId, sessionScope) {
|
|
|
16575
16575
|
async function getMessageStatus(messageId, sessionScope) {
|
|
16576
16576
|
const client = getClient();
|
|
16577
16577
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16578
|
-
const
|
|
16578
|
+
const result3 = await client.execute({
|
|
16579
16579
|
sql: `SELECT status FROM messages WHERE id = ?${scope.sql}`,
|
|
16580
16580
|
args: [messageId, ...scope.args]
|
|
16581
16581
|
});
|
|
16582
|
-
return
|
|
16582
|
+
return result3.rows[0]?.status ?? null;
|
|
16583
16583
|
}
|
|
16584
16584
|
async function getUnacknowledgedMessages(targetAgent, sessionScope) {
|
|
16585
16585
|
const client = getClient();
|
|
16586
16586
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16587
|
-
const
|
|
16587
|
+
const result3 = await client.execute({
|
|
16588
16588
|
sql: `SELECT * FROM messages
|
|
16589
16589
|
WHERE target_agent = ? AND status IN ('pending', 'delivered', 'read')${scope.sql}
|
|
16590
16590
|
ORDER BY id`,
|
|
16591
16591
|
args: [targetAgent, ...scope.args]
|
|
16592
16592
|
});
|
|
16593
|
-
return
|
|
16593
|
+
return result3.rows.map((row) => rowToMessage(row));
|
|
16594
16594
|
}
|
|
16595
16595
|
async function getReadMessages(targetAgent, sessionScope) {
|
|
16596
16596
|
const client = getClient();
|
|
16597
16597
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16598
|
-
const
|
|
16598
|
+
const result3 = await client.execute({
|
|
16599
16599
|
sql: `SELECT * FROM messages
|
|
16600
16600
|
WHERE target_agent = ? AND status = 'read'${scope.sql}
|
|
16601
16601
|
ORDER BY id`,
|
|
16602
16602
|
args: [targetAgent, ...scope.args]
|
|
16603
16603
|
});
|
|
16604
|
-
return
|
|
16604
|
+
return result3.rows.map((row) => rowToMessage(row));
|
|
16605
16605
|
}
|
|
16606
16606
|
async function markFailed(messageId, reason, sessionScope) {
|
|
16607
16607
|
const client = getClient();
|
|
@@ -16615,23 +16615,23 @@ async function markFailed(messageId, reason, sessionScope) {
|
|
|
16615
16615
|
async function getFailedMessages(sessionScope) {
|
|
16616
16616
|
const client = getClient();
|
|
16617
16617
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16618
|
-
const
|
|
16618
|
+
const result3 = await client.execute({
|
|
16619
16619
|
sql: `SELECT * FROM messages WHERE status = 'failed'${scope.sql} ORDER BY created_at DESC`,
|
|
16620
16620
|
args: [...scope.args]
|
|
16621
16621
|
});
|
|
16622
|
-
return
|
|
16622
|
+
return result3.rows.map((row) => rowToMessage(row));
|
|
16623
16623
|
}
|
|
16624
16624
|
async function retryPendingMessages(sessionScope) {
|
|
16625
16625
|
const client = getClient();
|
|
16626
16626
|
const scope = strictSessionScopeFilter(sessionScope);
|
|
16627
|
-
const
|
|
16627
|
+
const result3 = await client.execute({
|
|
16628
16628
|
sql: `SELECT * FROM messages
|
|
16629
16629
|
WHERE status = 'pending' AND retry_count < ?${scope.sql}
|
|
16630
16630
|
ORDER BY id`,
|
|
16631
16631
|
args: [MAX_RETRIES3, ...scope.args]
|
|
16632
16632
|
});
|
|
16633
16633
|
let delivered = 0;
|
|
16634
|
-
for (const row of
|
|
16634
|
+
for (const row of result3.rows) {
|
|
16635
16635
|
const msg = rowToMessage(row);
|
|
16636
16636
|
try {
|
|
16637
16637
|
const success = await deliverLocalMessage(msg.id);
|
|
@@ -16714,7 +16714,7 @@ function registerAcknowledgeMessages(server) {
|
|
|
16714
16714
|
const agentId = agent.agentId || "default";
|
|
16715
16715
|
const client = getClient();
|
|
16716
16716
|
const scope = strictSessionScopeFilter();
|
|
16717
|
-
const
|
|
16717
|
+
const result3 = await client.execute({
|
|
16718
16718
|
sql: `UPDATE messages SET status = 'acknowledged', processed_at = datetime('now')
|
|
16719
16719
|
WHERE target_agent = ? AND status IN ('pending', 'delivered')${scope.sql}`,
|
|
16720
16720
|
args: [agentId, ...scope.args]
|
|
@@ -16723,7 +16723,7 @@ function registerAcknowledgeMessages(server) {
|
|
|
16723
16723
|
content: [
|
|
16724
16724
|
{
|
|
16725
16725
|
type: "text",
|
|
16726
|
-
text: `Acknowledged ${
|
|
16726
|
+
text: `Acknowledged ${result3.rowsAffected} message(s) for ${agentId}.`
|
|
16727
16727
|
}
|
|
16728
16728
|
]
|
|
16729
16729
|
};
|
|
@@ -16802,8 +16802,8 @@ async function createReminder(text3, dueDate) {
|
|
|
16802
16802
|
async function listReminders(includeCompleted = false) {
|
|
16803
16803
|
const client = getClient();
|
|
16804
16804
|
const sql = includeCompleted ? `SELECT id, text, created_at, due_date, completed_at FROM reminders ORDER BY due_date ASC NULLS LAST LIMIT 500` : `SELECT id, text, created_at, due_date, completed_at FROM reminders WHERE completed_at IS NULL ORDER BY due_date ASC NULLS LAST LIMIT 500`;
|
|
16805
|
-
const
|
|
16806
|
-
return
|
|
16805
|
+
const result3 = await client.execute(sql);
|
|
16806
|
+
return result3.rows.map((row) => ({
|
|
16807
16807
|
id: String(row.id),
|
|
16808
16808
|
text: String(row.text),
|
|
16809
16809
|
createdAt: String(row.created_at),
|
|
@@ -16814,18 +16814,18 @@ async function listReminders(includeCompleted = false) {
|
|
|
16814
16814
|
async function completeReminder(idOrText) {
|
|
16815
16815
|
const client = getClient();
|
|
16816
16816
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16817
|
-
let
|
|
16817
|
+
let result3 = await client.execute({
|
|
16818
16818
|
sql: `SELECT id, text FROM reminders WHERE id = ? AND completed_at IS NULL`,
|
|
16819
16819
|
args: [idOrText]
|
|
16820
16820
|
});
|
|
16821
|
-
if (
|
|
16822
|
-
|
|
16821
|
+
if (result3.rows.length === 0) {
|
|
16822
|
+
result3 = await client.execute({
|
|
16823
16823
|
sql: `SELECT id, text FROM reminders WHERE completed_at IS NULL AND text LIKE '%' || ? || '%' LIMIT 1`,
|
|
16824
16824
|
args: [idOrText]
|
|
16825
16825
|
});
|
|
16826
16826
|
}
|
|
16827
|
-
if (
|
|
16828
|
-
const row =
|
|
16827
|
+
if (result3.rows.length === 0) return null;
|
|
16828
|
+
const row = result3.rows[0];
|
|
16829
16829
|
const id = String(row.id);
|
|
16830
16830
|
await client.execute({
|
|
16831
16831
|
sql: `UPDATE reminders SET completed_at = ? WHERE id = ?`,
|
|
@@ -16989,7 +16989,7 @@ function registerListBehaviors(server) {
|
|
|
16989
16989
|
args.push(proj);
|
|
16990
16990
|
}
|
|
16991
16991
|
const where = conditions.join(" AND ");
|
|
16992
|
-
const
|
|
16992
|
+
const result3 = await client.execute({
|
|
16993
16993
|
sql: `SELECT id, agent_id, project_name, domain, content, active, created_at, updated_at
|
|
16994
16994
|
FROM behaviors
|
|
16995
16995
|
WHERE ${where}
|
|
@@ -16997,7 +16997,7 @@ function registerListBehaviors(server) {
|
|
|
16997
16997
|
LIMIT 50`,
|
|
16998
16998
|
args
|
|
16999
16999
|
});
|
|
17000
|
-
const behaviors =
|
|
17000
|
+
const behaviors = result3.rows.map((r) => rowToBehavior(r));
|
|
17001
17001
|
if (behaviors.length === 0) {
|
|
17002
17002
|
return {
|
|
17003
17003
|
content: [{ type: "text", text: "No behaviors found." }]
|
|
@@ -17213,11 +17213,11 @@ function registerDeactivateBehavior(server) {
|
|
|
17213
17213
|
};
|
|
17214
17214
|
}
|
|
17215
17215
|
const client = getClient();
|
|
17216
|
-
const
|
|
17216
|
+
const result3 = await client.execute({
|
|
17217
17217
|
sql: `SELECT id, agent_id, content, domain, priority FROM behaviors WHERE id = ?`,
|
|
17218
17218
|
args: [behavior_id]
|
|
17219
17219
|
});
|
|
17220
|
-
if (
|
|
17220
|
+
if (result3.rows.length === 0) {
|
|
17221
17221
|
return {
|
|
17222
17222
|
content: [{
|
|
17223
17223
|
type: "text",
|
|
@@ -17226,7 +17226,7 @@ function registerDeactivateBehavior(server) {
|
|
|
17226
17226
|
isError: true
|
|
17227
17227
|
};
|
|
17228
17228
|
}
|
|
17229
|
-
const row =
|
|
17229
|
+
const row = result3.rows[0];
|
|
17230
17230
|
const wasActive = await deactivateBehavior(behavior_id);
|
|
17231
17231
|
if (!wasActive) {
|
|
17232
17232
|
return {
|
|
@@ -17333,7 +17333,7 @@ async function embedTexts(texts) {
|
|
|
17333
17333
|
);
|
|
17334
17334
|
results.push(
|
|
17335
17335
|
...settled.map(
|
|
17336
|
-
(
|
|
17336
|
+
(result3) => result3.status === "fulfilled" ? result3.value : null
|
|
17337
17337
|
)
|
|
17338
17338
|
);
|
|
17339
17339
|
}
|
|
@@ -17448,7 +17448,7 @@ async function ingestDocument(input) {
|
|
|
17448
17448
|
}
|
|
17449
17449
|
async function listDocumentsByWorkspace(workspace_id, limit = DEFAULT_LIST_LIMIT, offset = 0) {
|
|
17450
17450
|
const client = getClient();
|
|
17451
|
-
const
|
|
17451
|
+
const result3 = await client.execute({
|
|
17452
17452
|
sql: `SELECT d.*, COUNT(m.id) AS chunk_count
|
|
17453
17453
|
FROM documents d
|
|
17454
17454
|
LEFT JOIN memories m ON m.document_id = d.id
|
|
@@ -17458,7 +17458,7 @@ async function listDocumentsByWorkspace(workspace_id, limit = DEFAULT_LIST_LIMIT
|
|
|
17458
17458
|
LIMIT ? OFFSET ?`,
|
|
17459
17459
|
args: [workspace_id, limit, offset]
|
|
17460
17460
|
});
|
|
17461
|
-
return
|
|
17461
|
+
return result3.rows.map((row) => {
|
|
17462
17462
|
const r = row;
|
|
17463
17463
|
return {
|
|
17464
17464
|
...rowToDocument(r),
|
|
@@ -17490,11 +17490,11 @@ async function updateChunksImportance(document_id, importance) {
|
|
|
17490
17490
|
);
|
|
17491
17491
|
}
|
|
17492
17492
|
const client = getClient();
|
|
17493
|
-
const
|
|
17493
|
+
const result3 = await client.execute({
|
|
17494
17494
|
sql: "UPDATE memories SET importance = ? WHERE document_id = ?",
|
|
17495
17495
|
args: [importance, document_id]
|
|
17496
17496
|
});
|
|
17497
|
-
return Number(
|
|
17497
|
+
return Number(result3.rowsAffected) || 0;
|
|
17498
17498
|
}
|
|
17499
17499
|
var WIKI_AGENT_ID, WIKI_AGENT_ROLE, WIKI_TOOL_NAME, DEFAULT_CHUNK_IMPORTANCE, DEFAULT_CHUNK_CONFIDENCE, DEFAULT_CHUNK_STATUS, DEFAULT_SOURCE_TYPE, DEFAULT_LIST_LIMIT, MIN_IMPORTANCE, MAX_IMPORTANCE;
|
|
17500
17500
|
var init_documents = __esm({
|
|
@@ -17545,11 +17545,11 @@ function registerIngestDocument(server) {
|
|
|
17545
17545
|
const { assertMemoryLimit: assertMemoryLimit2 } = await Promise.resolve().then(() => (init_plan_limits(), plan_limits_exports));
|
|
17546
17546
|
await assertFeature2("wiki");
|
|
17547
17547
|
await assertMemoryLimit2();
|
|
17548
|
-
const
|
|
17548
|
+
const result3 = await ingestDocument(input);
|
|
17549
17549
|
return {
|
|
17550
17550
|
content: [{
|
|
17551
17551
|
type: "text",
|
|
17552
|
-
text: JSON.stringify(
|
|
17552
|
+
text: JSON.stringify(result3)
|
|
17553
17553
|
}]
|
|
17554
17554
|
};
|
|
17555
17555
|
} catch (err) {
|
|
@@ -18299,7 +18299,7 @@ function registerQueryConversations(server) {
|
|
|
18299
18299
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
18300
18300
|
const limit = params.limit ?? 25;
|
|
18301
18301
|
args.push(limit);
|
|
18302
|
-
const
|
|
18302
|
+
const result3 = await client.execute({
|
|
18303
18303
|
sql: `SELECT c.id, c.platform, c.sender_id, c.sender_name, c.sender_phone,
|
|
18304
18304
|
c.sender_email, c.channel_id, c.thread_id, c.content_text,
|
|
18305
18305
|
c.agent_response, c.agent_name, c.timestamp
|
|
@@ -18309,7 +18309,7 @@ function registerQueryConversations(server) {
|
|
|
18309
18309
|
LIMIT ?`,
|
|
18310
18310
|
args
|
|
18311
18311
|
});
|
|
18312
|
-
const conversations =
|
|
18312
|
+
const conversations = result3.rows.map((row) => ({
|
|
18313
18313
|
id: row.id,
|
|
18314
18314
|
platform: row.platform,
|
|
18315
18315
|
sender: {
|
|
@@ -18954,8 +18954,8 @@ async function generateGraphReport(client, projectName) {
|
|
|
18954
18954
|
}).slice(0, 10);
|
|
18955
18955
|
let hyperedgeCount = 0;
|
|
18956
18956
|
try {
|
|
18957
|
-
const
|
|
18958
|
-
hyperedgeCount = Number(
|
|
18957
|
+
const result3 = await client.execute("SELECT COUNT(*) as cnt FROM hyperedges");
|
|
18958
|
+
hyperedgeCount = Number(result3.rows[0]?.cnt ?? 0);
|
|
18959
18959
|
} catch {
|
|
18960
18960
|
}
|
|
18961
18961
|
const nodeLabels = new Map(nodes.map((n) => [n.id, n.label]));
|
|
@@ -19025,12 +19025,12 @@ function registerExportGraph(server) {
|
|
|
19025
19025
|
}
|
|
19026
19026
|
const html = await exportGraphHTML(client);
|
|
19027
19027
|
const fs = await import("fs");
|
|
19028
|
-
const
|
|
19028
|
+
const path62 = await import("path");
|
|
19029
19029
|
const os25 = await import("os");
|
|
19030
|
-
const outDir =
|
|
19030
|
+
const outDir = path62.join(os25.homedir(), ".exe-os", "exports");
|
|
19031
19031
|
fs.mkdirSync(outDir, { recursive: true });
|
|
19032
19032
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
19033
|
-
const filePath =
|
|
19033
|
+
const filePath = path62.join(outDir, `graph-${timestamp}.html`);
|
|
19034
19034
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
19035
19035
|
return {
|
|
19036
19036
|
content: [
|
|
@@ -19329,12 +19329,12 @@ function entityId(name, type) {
|
|
|
19329
19329
|
async function resolveAlias(client, name) {
|
|
19330
19330
|
const normalized = normalizeEntityName2(name);
|
|
19331
19331
|
try {
|
|
19332
|
-
const
|
|
19332
|
+
const result3 = await client.execute({
|
|
19333
19333
|
sql: "SELECT canonical_entity_id FROM entity_aliases WHERE alias = ?",
|
|
19334
19334
|
args: [normalized]
|
|
19335
19335
|
});
|
|
19336
|
-
if (
|
|
19337
|
-
return String(
|
|
19336
|
+
if (result3.rows.length > 0) {
|
|
19337
|
+
return String(result3.rows[0].canonical_entity_id);
|
|
19338
19338
|
}
|
|
19339
19339
|
} catch {
|
|
19340
19340
|
}
|
|
@@ -19714,7 +19714,7 @@ async function storeExtraction(client, extraction, memoryId, timestamp) {
|
|
|
19714
19714
|
return { entitiesStored, relationshipsStored };
|
|
19715
19715
|
}
|
|
19716
19716
|
async function extractBatch(client, batchSize = 50, model = "claude-haiku-4-5-20251001") {
|
|
19717
|
-
const
|
|
19717
|
+
const result3 = await client.execute({
|
|
19718
19718
|
sql: `SELECT id, agent_id, raw_text, tool_name, timestamp, content_hash, graph_extracted_hash
|
|
19719
19719
|
FROM memories
|
|
19720
19720
|
WHERE (COALESCE(graph_extracted, 0) = 0
|
|
@@ -19725,12 +19725,12 @@ async function extractBatch(client, batchSize = 50, model = "claude-haiku-4-5-20
|
|
|
19725
19725
|
LIMIT ?`,
|
|
19726
19726
|
args: [batchSize]
|
|
19727
19727
|
});
|
|
19728
|
-
if (
|
|
19728
|
+
if (result3.rows.length === 0) {
|
|
19729
19729
|
return { processed: 0, entities: 0, relationships: 0 };
|
|
19730
19730
|
}
|
|
19731
19731
|
let totalEntities = 0;
|
|
19732
19732
|
let totalRelationships = 0;
|
|
19733
|
-
for (const row of
|
|
19733
|
+
for (const row of result3.rows) {
|
|
19734
19734
|
const memoryId = String(row.id);
|
|
19735
19735
|
const agentId = String(row.agent_id);
|
|
19736
19736
|
const rawContent = String(row.raw_text);
|
|
@@ -19768,7 +19768,7 @@ async function extractBatch(client, batchSize = 50, model = "claude-haiku-4-5-20
|
|
|
19768
19768
|
});
|
|
19769
19769
|
}
|
|
19770
19770
|
}
|
|
19771
|
-
return { processed:
|
|
19771
|
+
return { processed: result3.rows.length, entities: totalEntities, relationships: totalRelationships };
|
|
19772
19772
|
}
|
|
19773
19773
|
var EXTRACT_TOOL2, READ_MEMORY_PATH_PATTERN;
|
|
19774
19774
|
var init_graph_rag = __esm({
|
|
@@ -19892,14 +19892,14 @@ function registerMergeEntities(server) {
|
|
|
19892
19892
|
};
|
|
19893
19893
|
}
|
|
19894
19894
|
try {
|
|
19895
|
-
const
|
|
19895
|
+
const result3 = await mergeEntities(client, sourceId, targetId);
|
|
19896
19896
|
return {
|
|
19897
19897
|
content: [
|
|
19898
19898
|
{
|
|
19899
19899
|
type: "text",
|
|
19900
19900
|
text: `Merged "${source_name}" \u2192 "${target_name}":
|
|
19901
|
-
- ${
|
|
19902
|
-
- ${
|
|
19901
|
+
- ${result3.relationshipsMoved} relationships moved
|
|
19902
|
+
- ${result3.memoriesMoved} memory links moved
|
|
19903
19903
|
- "${source_name}" registered as alias for "${target_name}"`
|
|
19904
19904
|
}
|
|
19905
19905
|
]
|
|
@@ -20201,10 +20201,10 @@ function registerSetAgentConfig(server) {
|
|
|
20201
20201
|
isError: true
|
|
20202
20202
|
};
|
|
20203
20203
|
}
|
|
20204
|
-
const
|
|
20205
|
-
if (!
|
|
20204
|
+
const result3 = setAgentRuntime(agent_id, runtime, model, reasoning_effort);
|
|
20205
|
+
if (!result3.ok) {
|
|
20206
20206
|
return {
|
|
20207
|
-
content: [{ type: "text", text:
|
|
20207
|
+
content: [{ type: "text", text: result3.error }],
|
|
20208
20208
|
isError: true
|
|
20209
20209
|
};
|
|
20210
20210
|
}
|
|
@@ -20368,7 +20368,7 @@ async function getAgentSpend(period = "7d") {
|
|
|
20368
20368
|
}
|
|
20369
20369
|
}
|
|
20370
20370
|
}
|
|
20371
|
-
const
|
|
20371
|
+
const result3 = Array.from(agentTotals.entries()).map(([agentId, t]) => ({
|
|
20372
20372
|
agentId,
|
|
20373
20373
|
inputTokens: t.input,
|
|
20374
20374
|
outputTokens: t.output,
|
|
@@ -20378,8 +20378,8 @@ async function getAgentSpend(period = "7d") {
|
|
|
20378
20378
|
sessions: t.sessions.size,
|
|
20379
20379
|
period
|
|
20380
20380
|
})).sort((a, b) => b.costUSD - a.costUSD);
|
|
20381
|
-
_spendCache.set(period, { result:
|
|
20382
|
-
return
|
|
20381
|
+
_spendCache.set(period, { result: result3, expires: Date.now() + CACHE_TTL_MS });
|
|
20382
|
+
return result3;
|
|
20383
20383
|
}
|
|
20384
20384
|
async function extractSessionUsage(jsonlPath) {
|
|
20385
20385
|
let input = 0;
|
|
@@ -20807,13 +20807,13 @@ function registerMcpPing(server) {
|
|
|
20807
20807
|
const daemon = isDaemonAlive2();
|
|
20808
20808
|
const summary = summarizeMcpTransport();
|
|
20809
20809
|
writeMcpTransportSummary();
|
|
20810
|
-
const
|
|
20810
|
+
const status2 = daemon.alive ? "ok" : "degraded";
|
|
20811
20811
|
return {
|
|
20812
20812
|
content: [
|
|
20813
20813
|
{
|
|
20814
20814
|
type: "text",
|
|
20815
20815
|
text: JSON.stringify({
|
|
20816
|
-
status,
|
|
20816
|
+
status: status2,
|
|
20817
20817
|
daemon,
|
|
20818
20818
|
mcpTransport: summary,
|
|
20819
20819
|
remediation: daemon.alive ? "MCP transport probe reached the server. If tools still fail, reconnect the MCP client." : "Daemon is offline. Restart exe-os/exed; do not bypass MCP or access the DB directly."
|
|
@@ -21070,20 +21070,20 @@ function formatStatusAll(statuses, tasks, roles) {
|
|
|
21070
21070
|
}
|
|
21071
21071
|
return lines.join("\n");
|
|
21072
21072
|
}
|
|
21073
|
-
function formatStatusDeep(
|
|
21073
|
+
function formatStatusDeep(status2, task, role) {
|
|
21074
21074
|
const lines = [];
|
|
21075
|
-
const header = `${
|
|
21075
|
+
const header = `${status2.name} (${role}) \u2014 ${status2.project ?? "unknown project"}`;
|
|
21076
21076
|
lines.push(`\u250C\u2500 ${header} ${"\u2500".repeat(Math.max(0, 66 - header.length))}\u2510`);
|
|
21077
21077
|
if (task) {
|
|
21078
21078
|
const taskLine = `\u2502 Task: "${task.title.slice(0, 50)}" [${task.priority.toUpperCase()}]`;
|
|
21079
21079
|
lines.push(taskLine + " ".repeat(Math.max(0, 70 - taskLine.length)) + "\u2502");
|
|
21080
21080
|
lines.push("\u251C" + "\u2500".repeat(69) + "\u2524");
|
|
21081
21081
|
}
|
|
21082
|
-
if (!
|
|
21082
|
+
if (!status2.hasWindow) {
|
|
21083
21083
|
lines.push("\u2502 No tmux session" + " ".repeat(53) + "\u2502");
|
|
21084
|
-
} else if (
|
|
21084
|
+
} else if (status2.rawLines && status2.rawLines.length > 0) {
|
|
21085
21085
|
lines.push("\u2502 Recent activity:" + " ".repeat(52) + "\u2502");
|
|
21086
|
-
for (const line of
|
|
21086
|
+
for (const line of status2.rawLines.slice(-10)) {
|
|
21087
21087
|
const trimmed = line.slice(0, 65);
|
|
21088
21088
|
const padded = `\u2502 ${trimmed}`;
|
|
21089
21089
|
lines.push(padded + " ".repeat(Math.max(0, 70 - padded.length)) + "\u2502");
|
|
@@ -21117,13 +21117,13 @@ import path34 from "path";
|
|
|
21117
21117
|
async function hasOpenTasks(client, agentId) {
|
|
21118
21118
|
try {
|
|
21119
21119
|
const scope = sessionScopeFilter(null);
|
|
21120
|
-
const
|
|
21120
|
+
const result3 = await client.execute({
|
|
21121
21121
|
sql: `SELECT 1 FROM tasks
|
|
21122
21122
|
WHERE assigned_to = ? AND status IN ('open', 'in_progress')${scope.sql}
|
|
21123
21123
|
LIMIT 1`,
|
|
21124
21124
|
args: [agentId, ...scope.args]
|
|
21125
21125
|
});
|
|
21126
|
-
return
|
|
21126
|
+
return result3.rows.length > 0;
|
|
21127
21127
|
} catch {
|
|
21128
21128
|
return CONSERVATIVE_ON_ERROR;
|
|
21129
21129
|
}
|
|
@@ -21131,26 +21131,26 @@ async function hasOpenTasks(client, agentId) {
|
|
|
21131
21131
|
async function hasNeedsReview(client, agentId) {
|
|
21132
21132
|
try {
|
|
21133
21133
|
const scope = sessionScopeFilter(null);
|
|
21134
|
-
const
|
|
21134
|
+
const result3 = await client.execute({
|
|
21135
21135
|
sql: `SELECT 1 FROM tasks
|
|
21136
21136
|
WHERE assigned_to = ? AND status = 'needs_review'${scope.sql}
|
|
21137
21137
|
LIMIT 1`,
|
|
21138
21138
|
args: [agentId, ...scope.args]
|
|
21139
21139
|
});
|
|
21140
|
-
return
|
|
21140
|
+
return result3.rows.length > 0;
|
|
21141
21141
|
} catch {
|
|
21142
21142
|
return CONSERVATIVE_ON_ERROR;
|
|
21143
21143
|
}
|
|
21144
21144
|
}
|
|
21145
21145
|
async function hasUnreadInbox(client, agentId) {
|
|
21146
21146
|
try {
|
|
21147
|
-
const
|
|
21147
|
+
const result3 = await client.execute({
|
|
21148
21148
|
sql: `SELECT 1 FROM messages
|
|
21149
21149
|
WHERE target_agent = ? AND status = 'pending'
|
|
21150
21150
|
LIMIT 1`,
|
|
21151
21151
|
args: [agentId]
|
|
21152
21152
|
});
|
|
21153
|
-
return
|
|
21153
|
+
return result3.rows.length > 0;
|
|
21154
21154
|
} catch {
|
|
21155
21155
|
return CONSERVATIVE_ON_ERROR;
|
|
21156
21156
|
}
|
|
@@ -21487,13 +21487,13 @@ function createReviewNudgeRealDeps(getClient2) {
|
|
|
21487
21487
|
},
|
|
21488
21488
|
countReviewsForScope: async (sessionScope) => {
|
|
21489
21489
|
const client = getClient2();
|
|
21490
|
-
const
|
|
21490
|
+
const result3 = await client.execute({
|
|
21491
21491
|
sql: `SELECT COUNT(*) as cnt FROM tasks
|
|
21492
21492
|
WHERE status = 'needs_review'
|
|
21493
21493
|
AND (session_scope = ? OR session_scope IS NULL)`,
|
|
21494
21494
|
args: [sessionScope]
|
|
21495
21495
|
});
|
|
21496
|
-
return Number(
|
|
21496
|
+
return Number(result3.rows[0]?.cnt ?? 0);
|
|
21497
21497
|
},
|
|
21498
21498
|
sendNudge: (sessionName) => {
|
|
21499
21499
|
const { queueIntercom: qi } = (init_intercom_queue(), __toCommonJS(intercom_queue_exports));
|
|
@@ -21519,15 +21519,15 @@ function createIdleNudgeRealDeps(getClient2) {
|
|
|
21519
21519
|
queryOpenTask: async (agentId) => {
|
|
21520
21520
|
const client = getClient2();
|
|
21521
21521
|
const doScope = sessionScopeFilter(null);
|
|
21522
|
-
const
|
|
21522
|
+
const result3 = await client.execute({
|
|
21523
21523
|
sql: `SELECT id, title, priority FROM tasks
|
|
21524
21524
|
WHERE assigned_to = ? AND status IN ('open', 'in_progress')${doScope.sql}
|
|
21525
21525
|
ORDER BY CASE priority WHEN 'p0' THEN 0 WHEN 'p1' THEN 1 ELSE 2 END
|
|
21526
21526
|
LIMIT 1`,
|
|
21527
21527
|
args: [agentId, ...doScope.args]
|
|
21528
21528
|
});
|
|
21529
|
-
if (
|
|
21530
|
-
const row =
|
|
21529
|
+
if (result3.rows.length === 0) return null;
|
|
21530
|
+
const row = result3.rows[0];
|
|
21531
21531
|
return row;
|
|
21532
21532
|
},
|
|
21533
21533
|
sendIntercom: (sessionName) => {
|
|
@@ -21569,13 +21569,13 @@ function createSessionTTLRealDeps(getClient2) {
|
|
|
21569
21569
|
hasActiveTasks: getClient2 ? async (agentId) => {
|
|
21570
21570
|
const client = getClient2();
|
|
21571
21571
|
const scope = sessionScopeFilter(null);
|
|
21572
|
-
const
|
|
21572
|
+
const result3 = await client.execute({
|
|
21573
21573
|
sql: `SELECT 1 FROM tasks
|
|
21574
21574
|
WHERE assigned_to = ? AND status IN ('open', 'in_progress')${scope.sql}
|
|
21575
21575
|
LIMIT 1`,
|
|
21576
21576
|
args: [agentId, ...scope.args]
|
|
21577
21577
|
});
|
|
21578
|
-
return
|
|
21578
|
+
return result3.rows.length > 0;
|
|
21579
21579
|
} : void 0,
|
|
21580
21580
|
recordKill: (input) => {
|
|
21581
21581
|
const { recordSessionKill: recordSessionKill2 } = (init_session_kill_telemetry(), __toCommonJS(session_kill_telemetry_exports));
|
|
@@ -21683,10 +21683,10 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
|
|
|
21683
21683
|
`
|
|
21684
21684
|
);
|
|
21685
21685
|
try {
|
|
21686
|
-
const
|
|
21687
|
-
if (
|
|
21686
|
+
const result3 = deps.ensureEmployee(agentId, sessionScope);
|
|
21687
|
+
if (result3.status === "failed") {
|
|
21688
21688
|
process.stderr.write(
|
|
21689
|
-
`[auto-wake] Failed to spawn ${agentId}: ${
|
|
21689
|
+
`[auto-wake] Failed to spawn ${agentId}: ${result3.error ?? "unknown"}
|
|
21690
21690
|
`
|
|
21691
21691
|
);
|
|
21692
21692
|
continue;
|
|
@@ -21711,7 +21711,7 @@ function createAutoWakeRealDeps(getClient2, projectDir) {
|
|
|
21711
21711
|
},
|
|
21712
21712
|
queryTasksByAgent: async () => {
|
|
21713
21713
|
const client = getClient2();
|
|
21714
|
-
const
|
|
21714
|
+
const result3 = await client.execute({
|
|
21715
21715
|
sql: `SELECT assigned_to, id, priority, session_scope FROM tasks
|
|
21716
21716
|
WHERE status IN ('open', 'in_progress')
|
|
21717
21717
|
ORDER BY
|
|
@@ -21719,7 +21719,7 @@ function createAutoWakeRealDeps(getClient2, projectDir) {
|
|
|
21719
21719
|
created_at ASC`,
|
|
21720
21720
|
args: []
|
|
21721
21721
|
});
|
|
21722
|
-
return
|
|
21722
|
+
return result3.rows.map((r) => ({
|
|
21723
21723
|
agentId: String(r.assigned_to),
|
|
21724
21724
|
taskId: String(r.id),
|
|
21725
21725
|
priority: String(r.priority),
|
|
@@ -22160,14 +22160,14 @@ async function fetchMemoriesWithVectors(client, projectFilter, agentFilter2) {
|
|
|
22160
22160
|
args.push(agentFilter2);
|
|
22161
22161
|
}
|
|
22162
22162
|
const where = " WHERE " + clauses.join(" AND ");
|
|
22163
|
-
const
|
|
22163
|
+
const result3 = await client.execute({
|
|
22164
22164
|
sql: `SELECT id, agent_id, raw_text, timestamp, project_name, vector
|
|
22165
22165
|
FROM memories${where}
|
|
22166
22166
|
ORDER BY project_name, timestamp DESC`,
|
|
22167
22167
|
args
|
|
22168
22168
|
});
|
|
22169
22169
|
const byProject = /* @__PURE__ */ new Map();
|
|
22170
|
-
for (const row of
|
|
22170
|
+
for (const row of result3.rows) {
|
|
22171
22171
|
const project = row.project_name;
|
|
22172
22172
|
const vec = row.vector == null ? null : Array.isArray(row.vector) ? row.vector : Array.from(row.vector);
|
|
22173
22173
|
if (!vec || vec.length === 0) continue;
|
|
@@ -22821,11 +22821,11 @@ async function auditStats(client, flags) {
|
|
|
22821
22821
|
async function auditNullVectors(client, flags) {
|
|
22822
22822
|
const { clause, args } = agentFilter(flags);
|
|
22823
22823
|
const where = clause ? clause + " AND vector IS NULL" : " WHERE vector IS NULL";
|
|
22824
|
-
const
|
|
22824
|
+
const result3 = await client.execute({
|
|
22825
22825
|
sql: `SELECT COUNT(*) as cnt FROM memories${where}`,
|
|
22826
22826
|
args
|
|
22827
22827
|
});
|
|
22828
|
-
return Number(
|
|
22828
|
+
return Number(result3.rows[0].cnt);
|
|
22829
22829
|
}
|
|
22830
22830
|
async function auditDuplicates(client, flags) {
|
|
22831
22831
|
const { clause, args } = agentFilter(flags);
|
|
@@ -22874,14 +22874,14 @@ async function auditDuplicates(client, flags) {
|
|
|
22874
22874
|
async function auditBloated(client, flags) {
|
|
22875
22875
|
const { clause, args } = agentFilter(flags);
|
|
22876
22876
|
const where = clause ? clause + " AND LENGTH(raw_text) > 5120 AND tool_name != 'ConversationBackfill'" : " WHERE LENGTH(raw_text) > 5120 AND tool_name != 'ConversationBackfill'";
|
|
22877
|
-
const
|
|
22877
|
+
const result3 = await client.execute({
|
|
22878
22878
|
sql: `SELECT id, agent_id, LENGTH(raw_text) as size, tool_name
|
|
22879
22879
|
FROM memories${where}
|
|
22880
22880
|
ORDER BY size DESC
|
|
22881
22881
|
LIMIT 100`,
|
|
22882
22882
|
args
|
|
22883
22883
|
});
|
|
22884
|
-
return
|
|
22884
|
+
return result3.rows.map((r) => ({
|
|
22885
22885
|
id: r.id,
|
|
22886
22886
|
agent_id: r.agent_id,
|
|
22887
22887
|
size: Number(r.size),
|
|
@@ -22896,7 +22896,7 @@ async function auditFts(client) {
|
|
|
22896
22896
|
return { memoryCount: mc, ftsCount: fc, inSync: mc === fc };
|
|
22897
22897
|
}
|
|
22898
22898
|
async function auditOrphanedProjects(client) {
|
|
22899
|
-
const
|
|
22899
|
+
const result3 = await client.execute(
|
|
22900
22900
|
`SELECT project_name, COUNT(*) as cnt
|
|
22901
22901
|
FROM memories
|
|
22902
22902
|
WHERE tool_name != 'ConversationBackfill'
|
|
@@ -22905,7 +22905,7 @@ async function auditOrphanedProjects(client) {
|
|
|
22905
22905
|
);
|
|
22906
22906
|
const orphans = [];
|
|
22907
22907
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
22908
|
-
for (const row of
|
|
22908
|
+
for (const row of result3.rows) {
|
|
22909
22909
|
const name = row.project_name;
|
|
22910
22910
|
const count = Number(row.cnt);
|
|
22911
22911
|
const exists = existsSync34(path39.join(home, name)) || existsSync34(path39.join(home, "..", name)) || existsSync34(path39.join(process.cwd(), "..", name));
|
|
@@ -23356,12 +23356,12 @@ async function fixBloated(client, bloated, dryRun) {
|
|
|
23356
23356
|
let chunksCreated = 0;
|
|
23357
23357
|
const CHUNK_SIZE = 2048;
|
|
23358
23358
|
for (const b of bloated) {
|
|
23359
|
-
const
|
|
23359
|
+
const result3 = await client.execute({
|
|
23360
23360
|
sql: `SELECT * FROM memories WHERE id = ?`,
|
|
23361
23361
|
args: [b.id]
|
|
23362
23362
|
});
|
|
23363
|
-
if (
|
|
23364
|
-
const row =
|
|
23363
|
+
if (result3.rows.length === 0) continue;
|
|
23364
|
+
const row = result3.rows[0];
|
|
23365
23365
|
const text3 = row.raw_text;
|
|
23366
23366
|
const chunks = splitAtSentences(text3, CHUNK_SIZE);
|
|
23367
23367
|
if (chunks.length <= 1) continue;
|
|
@@ -23608,15 +23608,15 @@ function registerRunConsolidation(server) {
|
|
|
23608
23608
|
};
|
|
23609
23609
|
}
|
|
23610
23610
|
const config2 = await loadConfig();
|
|
23611
|
-
const
|
|
23611
|
+
const result3 = await runConsolidation(client, {
|
|
23612
23612
|
model: config2.consolidationModel || "claude-haiku-4-5-20251001",
|
|
23613
23613
|
maxCalls: 10
|
|
23614
23614
|
});
|
|
23615
23615
|
const lines = [];
|
|
23616
23616
|
lines.push("## Consolidation Complete\n");
|
|
23617
|
-
lines.push(`- **Clusters processed:** ${
|
|
23618
|
-
lines.push(`- **Memories consolidated:** ${
|
|
23619
|
-
lines.push(`- **Remaining unconsolidated:** ${(pending -
|
|
23617
|
+
lines.push(`- **Clusters processed:** ${result3.clustersProcessed}`);
|
|
23618
|
+
lines.push(`- **Memories consolidated:** ${result3.memoriesConsolidated}`);
|
|
23619
|
+
lines.push(`- **Remaining unconsolidated:** ${(pending - result3.memoriesConsolidated).toLocaleString()}`);
|
|
23620
23620
|
return {
|
|
23621
23621
|
content: [{ type: "text", text: lines.join("\n") }]
|
|
23622
23622
|
};
|
|
@@ -23903,10 +23903,10 @@ function isCrdtSyncEnabled() {
|
|
|
23903
23903
|
async function rebuildFromDb() {
|
|
23904
23904
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
23905
23905
|
const client = getClient2();
|
|
23906
|
-
const
|
|
23906
|
+
const result3 = await client.execute(
|
|
23907
23907
|
"SELECT id, agent_id, agent_role, session_id, timestamp, tool_name, project_name, has_error, raw_text, version, author_device_id, scope FROM memories"
|
|
23908
23908
|
);
|
|
23909
|
-
const memories =
|
|
23909
|
+
const memories = result3.rows.map((row) => ({
|
|
23910
23910
|
id: String(row.id),
|
|
23911
23911
|
agent_id: row.agent_id,
|
|
23912
23912
|
agent_role: row.agent_role,
|
|
@@ -24040,12 +24040,12 @@ function loadPgClient() {
|
|
|
24040
24040
|
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
24041
24041
|
return {
|
|
24042
24042
|
async $queryRawUnsafe(query, ...values) {
|
|
24043
|
-
const
|
|
24044
|
-
return
|
|
24043
|
+
const result3 = await pool.query(query, values);
|
|
24044
|
+
return result3.rows;
|
|
24045
24045
|
},
|
|
24046
24046
|
async $executeRawUnsafe(query, ...values) {
|
|
24047
|
-
const
|
|
24048
|
-
return
|
|
24047
|
+
const result3 = await pool.query(query, values);
|
|
24048
|
+
return result3.rowCount ?? 0;
|
|
24049
24049
|
},
|
|
24050
24050
|
async $disconnect() {
|
|
24051
24051
|
await pool.end();
|
|
@@ -24256,8 +24256,8 @@ async function cloudPull(sinceVersion, config2) {
|
|
|
24256
24256
|
async function getCloudReuploadRequired(client = getClient()) {
|
|
24257
24257
|
try {
|
|
24258
24258
|
await client.execute("CREATE TABLE IF NOT EXISTS sync_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
|
24259
|
-
const
|
|
24260
|
-
return
|
|
24259
|
+
const result3 = await client.execute("SELECT key, value FROM sync_meta WHERE key IN ('cloud_reupload_required', 'cloud_relink_required')");
|
|
24260
|
+
return result3.rows.some((row) => String(row.value ?? "") === "1");
|
|
24261
24261
|
} catch {
|
|
24262
24262
|
return false;
|
|
24263
24263
|
}
|
|
@@ -24878,8 +24878,8 @@ async function cloudPullBlob(route, config2) {
|
|
|
24878
24878
|
}
|
|
24879
24879
|
async function cloudPushGlobalProcedures(config2) {
|
|
24880
24880
|
const client = getClient();
|
|
24881
|
-
const
|
|
24882
|
-
const rows =
|
|
24881
|
+
const result3 = await client.execute("SELECT * FROM company_procedures LIMIT 1000");
|
|
24882
|
+
const rows = result3.rows;
|
|
24883
24883
|
const { ok } = await cloudPushBlob(
|
|
24884
24884
|
"/sync/push-global-procedures",
|
|
24885
24885
|
rows,
|
|
@@ -24923,8 +24923,8 @@ async function cloudPullGlobalProcedures(config2) {
|
|
|
24923
24923
|
}
|
|
24924
24924
|
async function cloudPushBehaviors(config2) {
|
|
24925
24925
|
const client = getClient();
|
|
24926
|
-
const
|
|
24927
|
-
const rows =
|
|
24926
|
+
const result3 = await client.execute("SELECT * FROM behaviors LIMIT 10000");
|
|
24927
|
+
const rows = result3.rows;
|
|
24928
24928
|
const { ok } = await cloudPushBlob(
|
|
24929
24929
|
"/sync/push-behaviors",
|
|
24930
24930
|
rows,
|
|
@@ -25079,8 +25079,8 @@ async function cloudPullGraphRAG(config2) {
|
|
|
25079
25079
|
}
|
|
25080
25080
|
async function cloudPushTasks(config2) {
|
|
25081
25081
|
const client = getClient();
|
|
25082
|
-
const
|
|
25083
|
-
const rows =
|
|
25082
|
+
const result3 = await client.execute("SELECT * FROM tasks LIMIT 10000");
|
|
25083
|
+
const rows = result3.rows;
|
|
25084
25084
|
const { ok } = await cloudPushBlob(
|
|
25085
25085
|
"/sync/push-tasks",
|
|
25086
25086
|
rows,
|
|
@@ -25125,8 +25125,8 @@ async function cloudPullTasks(config2) {
|
|
|
25125
25125
|
}
|
|
25126
25126
|
async function cloudPushConversations(config2) {
|
|
25127
25127
|
const client = getClient();
|
|
25128
|
-
const
|
|
25129
|
-
const rows =
|
|
25128
|
+
const result3 = await client.execute("SELECT * FROM conversations LIMIT 50000");
|
|
25129
|
+
const rows = result3.rows;
|
|
25130
25130
|
const { ok } = await cloudPushBlob(
|
|
25131
25131
|
"/sync/push-conversations",
|
|
25132
25132
|
rows,
|
|
@@ -25938,14 +25938,14 @@ function registerBackupVps(server) {
|
|
|
25938
25938
|
r2AccessKeyId: input.r2AccessKeyId,
|
|
25939
25939
|
r2SecretAccessKey: input.r2SecretAccessKey
|
|
25940
25940
|
};
|
|
25941
|
-
const
|
|
25941
|
+
const result3 = await createBackup2(options);
|
|
25942
25942
|
return {
|
|
25943
25943
|
content: [
|
|
25944
25944
|
{
|
|
25945
25945
|
type: "text",
|
|
25946
|
-
text: `Backup complete: ${
|
|
25947
|
-
${
|
|
25948
|
-
${
|
|
25946
|
+
text: `Backup complete: ${result3.key}
|
|
25947
|
+
${result3.sizeBytes} bytes
|
|
25948
|
+
${result3.timestamp}`
|
|
25949
25949
|
}
|
|
25950
25950
|
]
|
|
25951
25951
|
};
|
|
@@ -25978,18 +25978,18 @@ ${result2.timestamp}`
|
|
|
25978
25978
|
r2AccessKeyId: input.r2AccessKeyId,
|
|
25979
25979
|
r2SecretAccessKey: input.r2SecretAccessKey
|
|
25980
25980
|
};
|
|
25981
|
-
const
|
|
25981
|
+
const result3 = await listBackups2(options);
|
|
25982
25982
|
return {
|
|
25983
25983
|
content: [
|
|
25984
25984
|
{
|
|
25985
25985
|
type: "text",
|
|
25986
|
-
text: formatBackups(
|
|
25986
|
+
text: formatBackups(result3)
|
|
25987
25987
|
}
|
|
25988
25988
|
]
|
|
25989
25989
|
};
|
|
25990
25990
|
}
|
|
25991
25991
|
case "health": {
|
|
25992
|
-
const
|
|
25992
|
+
const result3 = await backupHealth({
|
|
25993
25993
|
r2Bucket: input.r2Bucket,
|
|
25994
25994
|
r2Endpoint: input.r2Endpoint,
|
|
25995
25995
|
r2AccessKeyId: input.r2AccessKeyId,
|
|
@@ -26000,10 +26000,10 @@ ${result2.timestamp}`
|
|
|
26000
26000
|
{
|
|
26001
26001
|
type: "text",
|
|
26002
26002
|
text: [
|
|
26003
|
-
`last_backup: ${
|
|
26004
|
-
`backup_count: ${
|
|
26005
|
-
`total_size_bytes: ${
|
|
26006
|
-
`oldest_backup: ${
|
|
26003
|
+
`last_backup: ${result3.lastBackup ?? "none"}`,
|
|
26004
|
+
`backup_count: ${result3.backupCount}`,
|
|
26005
|
+
`total_size_bytes: ${result3.totalSizeBytes}`,
|
|
26006
|
+
`oldest_backup: ${result3.oldestBackup ?? "none"}`
|
|
26007
26007
|
].join("\n")
|
|
26008
26008
|
}
|
|
26009
26009
|
]
|
|
@@ -26115,9 +26115,9 @@ var init_hostinger_api = __esm({
|
|
|
26115
26115
|
}
|
|
26116
26116
|
this.lastRequestTime = Date.now();
|
|
26117
26117
|
}
|
|
26118
|
-
async request(method,
|
|
26118
|
+
async request(method, path62, body) {
|
|
26119
26119
|
await this.rateLimit();
|
|
26120
|
-
const url = `${this.baseUrl}${
|
|
26120
|
+
const url = `${this.baseUrl}${path62}`;
|
|
26121
26121
|
const headers = {
|
|
26122
26122
|
Authorization: `Bearer ${this.apiKey}`,
|
|
26123
26123
|
"Content-Type": "application/json",
|
|
@@ -26147,10 +26147,10 @@ var init_hostinger_api = __esm({
|
|
|
26147
26147
|
HostingerError = class extends Error {
|
|
26148
26148
|
status;
|
|
26149
26149
|
errorCode;
|
|
26150
|
-
constructor(
|
|
26150
|
+
constructor(status2, errorCode, message) {
|
|
26151
26151
|
super(message);
|
|
26152
26152
|
this.name = "HostingerError";
|
|
26153
|
-
this.status =
|
|
26153
|
+
this.status = status2;
|
|
26154
26154
|
this.errorCode = errorCode;
|
|
26155
26155
|
}
|
|
26156
26156
|
};
|
|
@@ -26186,8 +26186,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
26186
26186
|
}
|
|
26187
26187
|
return envelope.result;
|
|
26188
26188
|
}
|
|
26189
|
-
function buildUrl(zoneId,
|
|
26190
|
-
const normalizedPath =
|
|
26189
|
+
function buildUrl(zoneId, path62 = "/dns_records", query) {
|
|
26190
|
+
const normalizedPath = path62.startsWith("/") ? path62 : `/${path62}`;
|
|
26191
26191
|
const url = new URL(
|
|
26192
26192
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
26193
26193
|
);
|
|
@@ -26247,10 +26247,10 @@ var init_cloudflare_dns = __esm({
|
|
|
26247
26247
|
CloudflareError = class extends Error {
|
|
26248
26248
|
status;
|
|
26249
26249
|
errorCode;
|
|
26250
|
-
constructor(
|
|
26250
|
+
constructor(status2, errorCode, message) {
|
|
26251
26251
|
super(message);
|
|
26252
26252
|
this.name = "CloudflareError";
|
|
26253
|
-
this.status =
|
|
26253
|
+
this.status = status2;
|
|
26254
26254
|
this.errorCode = errorCode;
|
|
26255
26255
|
}
|
|
26256
26256
|
};
|
|
@@ -26300,7 +26300,7 @@ async function executeDeployment(params, client) {
|
|
|
26300
26300
|
process.stderr.write(`[deploy_client] Playbook complete. Verifying health...
|
|
26301
26301
|
`);
|
|
26302
26302
|
const healthy = await verifyHealth(domain);
|
|
26303
|
-
const
|
|
26303
|
+
const status2 = healthy ? DEPLOYED_STATUS : PLAYBOOK_COMPLETE_HEALTH_PENDING_STATUS;
|
|
26304
26304
|
process.stderr.write("[deploy_client] Recording VPS inventory...\n");
|
|
26305
26305
|
const inventory = buildInventoryRecord({
|
|
26306
26306
|
userId: user_id,
|
|
@@ -26321,7 +26321,7 @@ async function executeDeployment(params, client) {
|
|
|
26321
26321
|
plan: vps.plan,
|
|
26322
26322
|
ssh_port: vps.ssh_port,
|
|
26323
26323
|
ssh_access: `ssh exeai@${vps.ip_address}`,
|
|
26324
|
-
status,
|
|
26324
|
+
status: status2,
|
|
26325
26325
|
ansible_output: playbookResult,
|
|
26326
26326
|
dns_record_id: dnsRecordId,
|
|
26327
26327
|
inventory
|
|
@@ -26358,7 +26358,7 @@ function registerDeployClient(server) {
|
|
|
26358
26358
|
};
|
|
26359
26359
|
}
|
|
26360
26360
|
try {
|
|
26361
|
-
const
|
|
26361
|
+
const result3 = await executeDeployment({
|
|
26362
26362
|
client_name,
|
|
26363
26363
|
domain,
|
|
26364
26364
|
region,
|
|
@@ -26373,7 +26373,7 @@ function registerDeployClient(server) {
|
|
|
26373
26373
|
content: [
|
|
26374
26374
|
{
|
|
26375
26375
|
type: "text",
|
|
26376
|
-
text: JSON.stringify(
|
|
26376
|
+
text: JSON.stringify(result3, null, 2)
|
|
26377
26377
|
}
|
|
26378
26378
|
]
|
|
26379
26379
|
};
|
|
@@ -27165,12 +27165,12 @@ function registerListTriggers(server) {
|
|
|
27165
27165
|
};
|
|
27166
27166
|
}
|
|
27167
27167
|
const lines = triggers.map((t) => {
|
|
27168
|
-
const
|
|
27168
|
+
const status2 = t.enabled ? "active" : "disabled";
|
|
27169
27169
|
const condCount = t.conditions.length;
|
|
27170
27170
|
const actionTypes = t.actions.map((a) => a.type).join(", ");
|
|
27171
27171
|
const schedulePart = isScheduledTrigger(t) ? ` | schedule: ${t.schedule}` : "";
|
|
27172
27172
|
const projectPart = t.project ? ` | project: ${t.project}` : "";
|
|
27173
|
-
return `- **${t.name}** (${t.id}) [${
|
|
27173
|
+
return `- **${t.name}** (${t.id}) [${status2}]
|
|
27174
27174
|
Event: ${t.event} | Conditions: ${condCount} | Actions: ${actionTypes}` + schedulePart + projectPart;
|
|
27175
27175
|
});
|
|
27176
27176
|
const text3 = `${triggers.length} trigger(s) configured:
|
|
@@ -27566,8 +27566,8 @@ Available: ${available.length > 0 ? available.join(", ") : "none"}`
|
|
|
27566
27566
|
]
|
|
27567
27567
|
};
|
|
27568
27568
|
}
|
|
27569
|
-
const
|
|
27570
|
-
if (!
|
|
27569
|
+
const result3 = applyPack(industry, project);
|
|
27570
|
+
if (!result3) {
|
|
27571
27571
|
return {
|
|
27572
27572
|
content: [
|
|
27573
27573
|
{
|
|
@@ -27580,22 +27580,22 @@ Available: ${available.length > 0 ? available.join(", ") : "none"}`
|
|
|
27580
27580
|
const lines = [
|
|
27581
27581
|
`Applied "${industry}" starter pack to project "${project}":
|
|
27582
27582
|
`,
|
|
27583
|
-
`**CRM Custom Objects** (${
|
|
27584
|
-
...
|
|
27583
|
+
`**CRM Custom Objects** (${result3.customObjects.count}):`,
|
|
27584
|
+
...result3.customObjects.names.map((n) => ` - ${n}`),
|
|
27585
27585
|
"",
|
|
27586
|
-
`**Triggers Created** (${
|
|
27587
|
-
...
|
|
27586
|
+
`**Triggers Created** (${result3.triggers.created}):`,
|
|
27587
|
+
...result3.triggers.ids.map((id, i) => {
|
|
27588
27588
|
const t = pack.triggers[i];
|
|
27589
27589
|
return ` - ${t?.name ?? "Unknown"} (${id})`;
|
|
27590
27590
|
}),
|
|
27591
27591
|
"",
|
|
27592
|
-
`**Wiki Seeds** (${
|
|
27593
|
-
...
|
|
27592
|
+
`**Wiki Seeds** (${result3.wikiSeeds.count}):`,
|
|
27593
|
+
...result3.wikiSeeds.titles.map((t) => ` - ${t}`)
|
|
27594
27594
|
];
|
|
27595
|
-
if (
|
|
27595
|
+
if (result3.pendingVariables.length > 0) {
|
|
27596
27596
|
lines.push("");
|
|
27597
27597
|
lines.push("**Requires manual configuration:**");
|
|
27598
|
-
for (const pv of
|
|
27598
|
+
for (const pv of result3.pendingVariables) {
|
|
27599
27599
|
const vars = Object.entries(pv.variables).map(([k, v]) => ` - {{${k}}}: ${v}`).join("\n");
|
|
27600
27600
|
lines.push(` ${pv.trigger}:
|
|
27601
27601
|
${vars}`);
|
|
@@ -27983,11 +27983,11 @@ async function importIdentities(identities, updatedBy) {
|
|
|
27983
27983
|
}
|
|
27984
27984
|
async function getActiveProcedureTitles() {
|
|
27985
27985
|
const client = getClient();
|
|
27986
|
-
const
|
|
27986
|
+
const result3 = await client.execute({
|
|
27987
27987
|
sql: "SELECT title FROM company_procedures WHERE active = 1",
|
|
27988
27988
|
args: []
|
|
27989
27989
|
});
|
|
27990
|
-
return new Set(
|
|
27990
|
+
return new Set(result3.rows.map((row) => String(row.title)));
|
|
27991
27991
|
}
|
|
27992
27992
|
async function exportOrchestration(createdBy) {
|
|
27993
27993
|
const client = getClient();
|
|
@@ -28200,11 +28200,11 @@ function registerImportOrchestration(server) {
|
|
|
28200
28200
|
await initStore();
|
|
28201
28201
|
const raw = readFileSync33(package_path, "utf-8");
|
|
28202
28202
|
const pkg = validatePackage(JSON.parse(raw));
|
|
28203
|
-
const
|
|
28203
|
+
const result3 = await importOrchestration(pkg, merge_strategy);
|
|
28204
28204
|
return {
|
|
28205
28205
|
content: [{
|
|
28206
28206
|
type: "text",
|
|
28207
|
-
text: `Imported ${
|
|
28207
|
+
text: `Imported ${result3.imported.roster} roster entries, ${result3.imported.identities} identities, ${result3.imported.behaviors} behaviors, ${result3.imported.procedures} procedures using ${merge_strategy} strategy`
|
|
28208
28208
|
}]
|
|
28209
28209
|
};
|
|
28210
28210
|
} catch (err) {
|
|
@@ -28319,11 +28319,11 @@ Domain: ${domain ?? "none"}`
|
|
|
28319
28319
|
};
|
|
28320
28320
|
}
|
|
28321
28321
|
const client = getClient();
|
|
28322
|
-
const
|
|
28322
|
+
const result3 = await client.execute({
|
|
28323
28323
|
sql: "SELECT id, title, content, priority, domain FROM company_procedures WHERE id = ?",
|
|
28324
28324
|
args: [procedure_id]
|
|
28325
28325
|
});
|
|
28326
|
-
if (
|
|
28326
|
+
if (result3.rows.length === 0) {
|
|
28327
28327
|
return {
|
|
28328
28328
|
content: [{
|
|
28329
28329
|
type: "text",
|
|
@@ -28332,7 +28332,7 @@ Domain: ${domain ?? "none"}`
|
|
|
28332
28332
|
isError: true
|
|
28333
28333
|
};
|
|
28334
28334
|
}
|
|
28335
|
-
const row =
|
|
28335
|
+
const row = result3.rows[0];
|
|
28336
28336
|
const wasActive = await deactivateGlobalProcedure(procedure_id);
|
|
28337
28337
|
if (!wasActive) {
|
|
28338
28338
|
return {
|
|
@@ -28939,7 +28939,7 @@ function registerBehavior(server) {
|
|
|
28939
28939
|
args.push(proj);
|
|
28940
28940
|
}
|
|
28941
28941
|
const where = conditions.join(" AND ");
|
|
28942
|
-
const
|
|
28942
|
+
const result4 = await client2.execute({
|
|
28943
28943
|
sql: `SELECT id, agent_id, project_name, domain, content, active, created_at, updated_at
|
|
28944
28944
|
FROM behaviors
|
|
28945
28945
|
WHERE ${where}
|
|
@@ -28947,7 +28947,7 @@ function registerBehavior(server) {
|
|
|
28947
28947
|
LIMIT 50`,
|
|
28948
28948
|
args
|
|
28949
28949
|
});
|
|
28950
|
-
const behaviors =
|
|
28950
|
+
const behaviors = result4.rows.map((r) => rowToBehavior2(r));
|
|
28951
28951
|
if (behaviors.length === 0) {
|
|
28952
28952
|
return {
|
|
28953
28953
|
content: [{ type: "text", text: "No behaviors found." }]
|
|
@@ -29046,11 +29046,11 @@ Use /exe-forget to remove any that this supersedes.`;
|
|
|
29046
29046
|
};
|
|
29047
29047
|
}
|
|
29048
29048
|
const client = getClient();
|
|
29049
|
-
const
|
|
29049
|
+
const result3 = await client.execute({
|
|
29050
29050
|
sql: "SELECT id, agent_id, content, domain, priority FROM behaviors WHERE id = ?",
|
|
29051
29051
|
args: [behavior_id]
|
|
29052
29052
|
});
|
|
29053
|
-
if (
|
|
29053
|
+
if (result3.rows.length === 0) {
|
|
29054
29054
|
return {
|
|
29055
29055
|
content: [{
|
|
29056
29056
|
type: "text",
|
|
@@ -29059,7 +29059,7 @@ Use /exe-forget to remove any that this supersedes.`;
|
|
|
29059
29059
|
isError: true
|
|
29060
29060
|
};
|
|
29061
29061
|
}
|
|
29062
|
-
const row =
|
|
29062
|
+
const row = result3.rows[0];
|
|
29063
29063
|
const wasActive = await deactivateBehavior(behavior_id);
|
|
29064
29064
|
if (!wasActive) {
|
|
29065
29065
|
return {
|
|
@@ -29287,11 +29287,11 @@ function registerDeactivateGlobalProcedure(server) {
|
|
|
29287
29287
|
};
|
|
29288
29288
|
}
|
|
29289
29289
|
const client = getClient();
|
|
29290
|
-
const
|
|
29290
|
+
const result3 = await client.execute({
|
|
29291
29291
|
sql: "SELECT id, title, content, priority, domain FROM company_procedures WHERE id = ?",
|
|
29292
29292
|
args: [procedure_id]
|
|
29293
29293
|
});
|
|
29294
|
-
if (
|
|
29294
|
+
if (result3.rows.length === 0) {
|
|
29295
29295
|
return {
|
|
29296
29296
|
content: [{
|
|
29297
29297
|
type: "text",
|
|
@@ -29300,7 +29300,7 @@ function registerDeactivateGlobalProcedure(server) {
|
|
|
29300
29300
|
isError: true
|
|
29301
29301
|
};
|
|
29302
29302
|
}
|
|
29303
|
-
const row =
|
|
29303
|
+
const row = result3.rows[0];
|
|
29304
29304
|
const wasActive = await deactivateGlobalProcedure(procedure_id);
|
|
29305
29305
|
if (!wasActive) {
|
|
29306
29306
|
return {
|
|
@@ -29442,14 +29442,14 @@ function registerGetDecision(server) {
|
|
|
29442
29442
|
},
|
|
29443
29443
|
async ({ domain }) => {
|
|
29444
29444
|
const client = getClient();
|
|
29445
|
-
const
|
|
29445
|
+
const result3 = await client.execute({
|
|
29446
29446
|
sql: `SELECT id, agent_id, timestamp, raw_text, status, supersedes_id, project_name
|
|
29447
29447
|
FROM memories
|
|
29448
29448
|
WHERE memory_type = 'decision' AND source_path = ?
|
|
29449
29449
|
ORDER BY timestamp DESC`,
|
|
29450
29450
|
args: [domain]
|
|
29451
29451
|
});
|
|
29452
|
-
if (
|
|
29452
|
+
if (result3.rows.length === 0) {
|
|
29453
29453
|
return {
|
|
29454
29454
|
content: [
|
|
29455
29455
|
{
|
|
@@ -29459,7 +29459,7 @@ function registerGetDecision(server) {
|
|
|
29459
29459
|
]
|
|
29460
29460
|
};
|
|
29461
29461
|
}
|
|
29462
|
-
const decisions =
|
|
29462
|
+
const decisions = result3.rows.map((r) => ({
|
|
29463
29463
|
id: String(r.id),
|
|
29464
29464
|
agent_id: String(r.agent_id),
|
|
29465
29465
|
timestamp: String(r.timestamp),
|
|
@@ -30278,14 +30278,14 @@ async function safeJson2(res) {
|
|
|
30278
30278
|
function hasFailures(rows) {
|
|
30279
30279
|
return rows.some((row) => row.level === "fail");
|
|
30280
30280
|
}
|
|
30281
|
-
function summarizeHttpFailure(
|
|
30281
|
+
function summarizeHttpFailure(status2, data) {
|
|
30282
30282
|
const error = data?.error;
|
|
30283
|
-
return `${
|
|
30283
|
+
return `${status2} ${error?.message ?? JSON.stringify(data)}`;
|
|
30284
30284
|
}
|
|
30285
|
-
function nextForPostFailure(
|
|
30286
|
-
if (
|
|
30287
|
-
if (
|
|
30288
|
-
if (
|
|
30285
|
+
function nextForPostFailure(status2) {
|
|
30286
|
+
if (status2 === 401) return "License credentials were not sent. Run `exe-os support health` and check license_key_present.";
|
|
30287
|
+
if (status2 === 403) return "License is valid locally but not accepted by support intake. AskExe must check server-side license provisioning.";
|
|
30288
|
+
if (status2 >= 500) return "AskExe support intake is unhealthy server-side. Try again shortly and report the local file path.";
|
|
30289
30289
|
return "Run `exe-os support health`; if it passes, send this output to AskExe.";
|
|
30290
30290
|
}
|
|
30291
30291
|
var DEFAULT_BUG_ENDPOINT, DEFAULT_ADMIN_ENDPOINT;
|
|
@@ -30361,6 +30361,656 @@ var init_support = __esm({
|
|
|
30361
30361
|
}
|
|
30362
30362
|
});
|
|
30363
30363
|
|
|
30364
|
+
// src/bin/exe-status.ts
|
|
30365
|
+
async function status(targetEmployee) {
|
|
30366
|
+
if (!inTmux()) {
|
|
30367
|
+
return "Not in a tmux session. Start tmux first: tmux new-session -s work";
|
|
30368
|
+
}
|
|
30369
|
+
const employees = await loadEmployees();
|
|
30370
|
+
const names = employees.filter((e) => !isCoordinatorRole(e.role)).map((e) => e.name);
|
|
30371
|
+
const roles = new Map(employees.map((e) => [e.name, e.role ?? ""]));
|
|
30372
|
+
await fastDbInit();
|
|
30373
|
+
const client = getClient();
|
|
30374
|
+
const taskMap = /* @__PURE__ */ new Map();
|
|
30375
|
+
try {
|
|
30376
|
+
const esScope = sessionScopeFilter();
|
|
30377
|
+
const result3 = await client.execute({
|
|
30378
|
+
sql: `SELECT assigned_to, title, priority FROM tasks
|
|
30379
|
+
WHERE status = 'in_progress'${esScope.sql}
|
|
30380
|
+
ORDER BY priority ASC, created_at ASC`,
|
|
30381
|
+
args: [...esScope.args]
|
|
30382
|
+
});
|
|
30383
|
+
for (const row of result3.rows) {
|
|
30384
|
+
const assignee = String(row.assigned_to);
|
|
30385
|
+
if (!taskMap.has(assignee)) {
|
|
30386
|
+
taskMap.set(assignee, {
|
|
30387
|
+
title: String(row.title),
|
|
30388
|
+
priority: String(row.priority)
|
|
30389
|
+
});
|
|
30390
|
+
}
|
|
30391
|
+
}
|
|
30392
|
+
} catch {
|
|
30393
|
+
}
|
|
30394
|
+
if (targetEmployee) {
|
|
30395
|
+
if (!names.includes(targetEmployee)) {
|
|
30396
|
+
return `Employee "${targetEmployee}" not found. Available: ${names.join(", ")}`;
|
|
30397
|
+
}
|
|
30398
|
+
const statuses2 = getEmployeeStatuses([targetEmployee]);
|
|
30399
|
+
const s = statuses2[0];
|
|
30400
|
+
return formatStatusDeep(s, taskMap.get(targetEmployee), roles.get(targetEmployee) ?? "");
|
|
30401
|
+
}
|
|
30402
|
+
const statuses = getEmployeeStatuses(names);
|
|
30403
|
+
return formatStatusAll(statuses, taskMap, roles);
|
|
30404
|
+
}
|
|
30405
|
+
var init_exe_status = __esm({
|
|
30406
|
+
"src/bin/exe-status.ts"() {
|
|
30407
|
+
"use strict";
|
|
30408
|
+
init_employees();
|
|
30409
|
+
init_fast_db_init();
|
|
30410
|
+
init_database();
|
|
30411
|
+
init_tmux_status();
|
|
30412
|
+
init_is_main();
|
|
30413
|
+
init_task_scope();
|
|
30414
|
+
if (isMainModule(import.meta.url)) {
|
|
30415
|
+
const target = process.argv[2];
|
|
30416
|
+
status(target).then((output) => {
|
|
30417
|
+
process.stdout.write(output + "\n");
|
|
30418
|
+
}).catch((err) => {
|
|
30419
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
30420
|
+
`);
|
|
30421
|
+
process.exit(1);
|
|
30422
|
+
});
|
|
30423
|
+
}
|
|
30424
|
+
}
|
|
30425
|
+
});
|
|
30426
|
+
|
|
30427
|
+
// src/bin/exe-healthcheck.ts
|
|
30428
|
+
import { existsSync as existsSync43, readFileSync as readFileSync36, readdirSync as readdirSync14 } from "fs";
|
|
30429
|
+
import path55 from "path";
|
|
30430
|
+
import { execSync as execSync14 } from "child_process";
|
|
30431
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
30432
|
+
function findPackageRoot2() {
|
|
30433
|
+
let dir = path55.dirname(fileURLToPath6(import.meta.url));
|
|
30434
|
+
const { root } = path55.parse(dir);
|
|
30435
|
+
while (dir !== root) {
|
|
30436
|
+
if (existsSync43(path55.join(dir, "package.json"))) return dir;
|
|
30437
|
+
dir = path55.dirname(dir);
|
|
30438
|
+
}
|
|
30439
|
+
throw new Error("Cannot find package root");
|
|
30440
|
+
}
|
|
30441
|
+
function checkBuildIntegrity(pkgRoot) {
|
|
30442
|
+
const results = [];
|
|
30443
|
+
const tsupConfig = path55.join(pkgRoot, "tsup.config.ts");
|
|
30444
|
+
if (!existsSync43(tsupConfig)) {
|
|
30445
|
+
return [{ name: "build/tsup-config", pass: false, detail: "tsup.config.ts not found" }];
|
|
30446
|
+
}
|
|
30447
|
+
const configContent = readFileSync36(tsupConfig, "utf-8");
|
|
30448
|
+
const entryMatches = configContent.matchAll(/"([^"]+)":\s*"src\//g);
|
|
30449
|
+
const missing = [];
|
|
30450
|
+
let total = 0;
|
|
30451
|
+
for (const match of entryMatches) {
|
|
30452
|
+
const outputKey = match[1];
|
|
30453
|
+
const expectedPath = path55.join(pkgRoot, "dist", `${outputKey}.js`);
|
|
30454
|
+
total++;
|
|
30455
|
+
if (!existsSync43(expectedPath)) {
|
|
30456
|
+
missing.push(`dist/${outputKey}.js`);
|
|
30457
|
+
}
|
|
30458
|
+
}
|
|
30459
|
+
if (missing.length > 0) {
|
|
30460
|
+
results.push({
|
|
30461
|
+
name: "build/entry-points",
|
|
30462
|
+
pass: false,
|
|
30463
|
+
detail: `${missing.length}/${total} entry points missing:
|
|
30464
|
+
${missing.join("\n ")}`
|
|
30465
|
+
});
|
|
30466
|
+
} else {
|
|
30467
|
+
results.push({
|
|
30468
|
+
name: "build/entry-points",
|
|
30469
|
+
pass: true,
|
|
30470
|
+
detail: `${total} entry points verified`
|
|
30471
|
+
});
|
|
30472
|
+
}
|
|
30473
|
+
return results;
|
|
30474
|
+
}
|
|
30475
|
+
function checkEmbedPipeline(pkgRoot) {
|
|
30476
|
+
const results = [];
|
|
30477
|
+
const daemonPath = path55.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
30478
|
+
if (!existsSync43(daemonPath)) {
|
|
30479
|
+
results.push({
|
|
30480
|
+
name: "exed/daemon-exists",
|
|
30481
|
+
pass: false,
|
|
30482
|
+
detail: `exe-daemon.js not found at ${daemonPath}`
|
|
30483
|
+
});
|
|
30484
|
+
return results;
|
|
30485
|
+
}
|
|
30486
|
+
results.push({ name: "exed/daemon-exists", pass: true, detail: "dist/lib/exe-daemon.js exists" });
|
|
30487
|
+
const entryDirs = ["dist/hooks", "dist/bin", "dist/mcp"];
|
|
30488
|
+
for (const dir of entryDirs) {
|
|
30489
|
+
const fullDir = path55.join(pkgRoot, dir);
|
|
30490
|
+
if (!existsSync43(fullDir)) continue;
|
|
30491
|
+
let walkDir = fullDir;
|
|
30492
|
+
const { root } = path55.parse(walkDir);
|
|
30493
|
+
let foundRoot = null;
|
|
30494
|
+
while (walkDir !== root) {
|
|
30495
|
+
if (existsSync43(path55.join(walkDir, "package.json"))) {
|
|
30496
|
+
foundRoot = walkDir;
|
|
30497
|
+
break;
|
|
30498
|
+
}
|
|
30499
|
+
walkDir = path55.dirname(walkDir);
|
|
30500
|
+
}
|
|
30501
|
+
if (!foundRoot) {
|
|
30502
|
+
results.push({
|
|
30503
|
+
name: `exed/reachable-from-${dir}`,
|
|
30504
|
+
pass: false,
|
|
30505
|
+
detail: `Cannot find package root from ${dir}`
|
|
30506
|
+
});
|
|
30507
|
+
continue;
|
|
30508
|
+
}
|
|
30509
|
+
const resolvedDaemon = path55.join(foundRoot, "dist", "lib", "exe-daemon.js");
|
|
30510
|
+
const reachable = existsSync43(resolvedDaemon);
|
|
30511
|
+
results.push({
|
|
30512
|
+
name: `exed/reachable-from-${dir}`,
|
|
30513
|
+
pass: reachable,
|
|
30514
|
+
detail: reachable ? `Resolves to ${resolvedDaemon}` : `NOT FOUND: ${resolvedDaemon}`
|
|
30515
|
+
});
|
|
30516
|
+
}
|
|
30517
|
+
return results;
|
|
30518
|
+
}
|
|
30519
|
+
function checkTaskSystem(pkgRoot) {
|
|
30520
|
+
const results = [];
|
|
30521
|
+
const scannerPath = path55.join(pkgRoot, "dist", "bin", "scan-tasks.js");
|
|
30522
|
+
if (!existsSync43(scannerPath)) {
|
|
30523
|
+
results.push({ name: "tasks/scanner", pass: false, detail: "scan-tasks.js not found" });
|
|
30524
|
+
return results;
|
|
30525
|
+
}
|
|
30526
|
+
try {
|
|
30527
|
+
execSync14(`node "${scannerPath}" /tmp/nonexistent-healthcheck-test --format=json 2>/dev/null`, {
|
|
30528
|
+
timeout: 1e4,
|
|
30529
|
+
encoding: "utf-8"
|
|
30530
|
+
});
|
|
30531
|
+
results.push({ name: "tasks/scanner", pass: true, detail: "scan-tasks.js runs without import errors" });
|
|
30532
|
+
} catch (err) {
|
|
30533
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
30534
|
+
if (msg.includes("Cannot find module") || msg.includes("ERR_MODULE_NOT_FOUND") || msg.includes("SyntaxError")) {
|
|
30535
|
+
results.push({ name: "tasks/scanner", pass: false, detail: `Import error: ${msg.slice(0, 200)}` });
|
|
30536
|
+
} else {
|
|
30537
|
+
results.push({ name: "tasks/scanner", pass: true, detail: "scan-tasks.js runs (no import errors)" });
|
|
30538
|
+
}
|
|
30539
|
+
}
|
|
30540
|
+
return results;
|
|
30541
|
+
}
|
|
30542
|
+
function checkWorkerSpawning(pkgRoot) {
|
|
30543
|
+
const results = [];
|
|
30544
|
+
const workerPath = path55.join(pkgRoot, "dist", "hooks", "ingest-worker.js");
|
|
30545
|
+
if (!existsSync43(workerPath)) {
|
|
30546
|
+
results.push({ name: "workers/ingest-worker", pass: false, detail: "ingest-worker.js not found" });
|
|
30547
|
+
return results;
|
|
30548
|
+
}
|
|
30549
|
+
try {
|
|
30550
|
+
execSync14(`node --check "${workerPath}" 2>&1`, { timeout: 1e4, encoding: "utf-8" });
|
|
30551
|
+
results.push({ name: "workers/ingest-worker", pass: true, detail: "ingest-worker.js parses OK" });
|
|
30552
|
+
} catch (err) {
|
|
30553
|
+
results.push({
|
|
30554
|
+
name: "workers/ingest-worker",
|
|
30555
|
+
pass: false,
|
|
30556
|
+
detail: `Parse error: ${err instanceof Error ? err.message.slice(0, 200) : String(err)}`
|
|
30557
|
+
});
|
|
30558
|
+
}
|
|
30559
|
+
const hooksDir = path55.join(pkgRoot, "dist", "hooks");
|
|
30560
|
+
if (existsSync43(hooksDir)) {
|
|
30561
|
+
const hookFiles = readdirSync14(hooksDir).filter((f) => f.endsWith(".js") && !f.endsWith(".js.map"));
|
|
30562
|
+
let hooksPassed = 0;
|
|
30563
|
+
const hooksFailed = [];
|
|
30564
|
+
for (const hook of hookFiles) {
|
|
30565
|
+
try {
|
|
30566
|
+
execSync14(`node --check "${path55.join(hooksDir, hook)}" 2>&1`, { timeout: 1e4, encoding: "utf-8" });
|
|
30567
|
+
hooksPassed++;
|
|
30568
|
+
} catch {
|
|
30569
|
+
hooksFailed.push(hook);
|
|
30570
|
+
}
|
|
30571
|
+
}
|
|
30572
|
+
if (hooksFailed.length > 0) {
|
|
30573
|
+
results.push({
|
|
30574
|
+
name: "workers/hooks-parse",
|
|
30575
|
+
pass: false,
|
|
30576
|
+
detail: `${hooksFailed.length}/${hookFiles.length} hooks fail to parse: ${hooksFailed.join(", ")}`
|
|
30577
|
+
});
|
|
30578
|
+
} else {
|
|
30579
|
+
results.push({
|
|
30580
|
+
name: "workers/hooks-parse",
|
|
30581
|
+
pass: true,
|
|
30582
|
+
detail: `${hooksPassed} hook entry points parse OK`
|
|
30583
|
+
});
|
|
30584
|
+
}
|
|
30585
|
+
}
|
|
30586
|
+
return results;
|
|
30587
|
+
}
|
|
30588
|
+
function checkMcpTransport() {
|
|
30589
|
+
const results = [];
|
|
30590
|
+
const pidPath = path55.join(EXE_AI_DIR, "exed.pid");
|
|
30591
|
+
const tokenPath = path55.join(EXE_AI_DIR, "exed.token");
|
|
30592
|
+
let daemonAlive = false;
|
|
30593
|
+
if (existsSync43(pidPath)) {
|
|
30594
|
+
try {
|
|
30595
|
+
const pid = parseInt(readFileSync36(pidPath, "utf8").trim(), 10);
|
|
30596
|
+
process.kill(pid, 0);
|
|
30597
|
+
daemonAlive = true;
|
|
30598
|
+
results.push({ name: "mcp/daemon-process", pass: true, detail: `exed process alive (pid ${pid})` });
|
|
30599
|
+
} catch {
|
|
30600
|
+
results.push({ name: "mcp/daemon-process", pass: false, detail: "exed.pid exists but process is not alive; restart exe-os/exed" });
|
|
30601
|
+
}
|
|
30602
|
+
} else {
|
|
30603
|
+
results.push({ name: "mcp/daemon-process", pass: false, detail: "No exed.pid found; daemon is not running" });
|
|
30604
|
+
}
|
|
30605
|
+
if (daemonAlive && existsSync43(tokenPath)) {
|
|
30606
|
+
try {
|
|
30607
|
+
const token = readFileSync36(tokenPath, "utf8").trim();
|
|
30608
|
+
const response = execSync14(
|
|
30609
|
+
`curl -sS -i -m 2 -H "Authorization: Bearer ${token}" -H 'Accept: application/json, text/event-stream' http://127.0.0.1:48739/mcp`,
|
|
30610
|
+
{ encoding: "utf8", timeout: 3e3 }
|
|
30611
|
+
);
|
|
30612
|
+
const jsonRpcError = response.includes("Content-Type: application/json") && response.includes("missing MCP session");
|
|
30613
|
+
results.push({
|
|
30614
|
+
name: "mcp/http-endpoint",
|
|
30615
|
+
pass: jsonRpcError,
|
|
30616
|
+
detail: jsonRpcError ? "MCP HTTP endpoint reachable; missing-session probe returns JSON-RPC (expected)" : "MCP HTTP endpoint reachable but did not return expected JSON-RPC missing-session response"
|
|
30617
|
+
});
|
|
30618
|
+
} catch (err) {
|
|
30619
|
+
results.push({
|
|
30620
|
+
name: "mcp/http-endpoint",
|
|
30621
|
+
pass: false,
|
|
30622
|
+
detail: `MCP HTTP endpoint not reachable: ${err instanceof Error ? err.message.slice(0, 180) : String(err)}`
|
|
30623
|
+
});
|
|
30624
|
+
}
|
|
30625
|
+
} else if (daemonAlive) {
|
|
30626
|
+
results.push({ name: "mcp/http-endpoint", pass: false, detail: "Daemon is alive but exed.token is missing; cannot probe MCP HTTP" });
|
|
30627
|
+
}
|
|
30628
|
+
const events = readMcpHttpEvents(200);
|
|
30629
|
+
const summary = summarizeMcpTransport(events);
|
|
30630
|
+
results.push({
|
|
30631
|
+
name: "mcp/local-event-log",
|
|
30632
|
+
pass: true,
|
|
30633
|
+
detail: `${events.length} recent event(s); activeSessions=${summary.activeSessions ?? "unknown"}; lastHandshake=${summary.lastSuccessfulHandshake ?? "none"}; lastTool=${summary.lastSuccessfulToolCall ?? "none"}`
|
|
30634
|
+
});
|
|
30635
|
+
results.push({
|
|
30636
|
+
name: "mcp/monitor-summary",
|
|
30637
|
+
pass: true,
|
|
30638
|
+
detail: `Privacy-safe local monitor summary: ${path55.join(EXE_AI_DIR, "monitor", "mcp-transport-summary.json")}`
|
|
30639
|
+
});
|
|
30640
|
+
return results;
|
|
30641
|
+
}
|
|
30642
|
+
function checkClaudeCodeInstall() {
|
|
30643
|
+
const results = [];
|
|
30644
|
+
const execPath = process.env.CLAUDE_CODE_EXECPATH ?? "";
|
|
30645
|
+
if (execPath.length > 0 && (execPath.includes("claude/versions/") || execPath.includes("claude.exe") || execPath.includes("claude-native"))) {
|
|
30646
|
+
results.push({
|
|
30647
|
+
name: "cc/execpath-clean",
|
|
30648
|
+
pass: false,
|
|
30649
|
+
detail: `CLAUDE_CODE_EXECPATH points to native binary: "${execPath}" \u2014 20K phantom billing risk. Unset it: unset CLAUDE_CODE_EXECPATH`
|
|
30650
|
+
});
|
|
30651
|
+
} else {
|
|
30652
|
+
results.push({
|
|
30653
|
+
name: "cc/execpath-clean",
|
|
30654
|
+
pass: true,
|
|
30655
|
+
detail: execPath ? `CLAUDE_CODE_EXECPATH=${execPath} (node runtime, OK)` : "CLAUDE_CODE_EXECPATH is unset"
|
|
30656
|
+
});
|
|
30657
|
+
}
|
|
30658
|
+
try {
|
|
30659
|
+
const claudePath = execSync14("which claude 2>/dev/null || true", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
30660
|
+
if (!claudePath) {
|
|
30661
|
+
results.push({
|
|
30662
|
+
name: "cc/cli-binary",
|
|
30663
|
+
pass: false,
|
|
30664
|
+
detail: "claude not found in PATH"
|
|
30665
|
+
});
|
|
30666
|
+
} else {
|
|
30667
|
+
let resolved = claudePath;
|
|
30668
|
+
try {
|
|
30669
|
+
resolved = execSync14(`readlink -f "${claudePath}" 2>/dev/null || readlink "${claudePath}" 2>/dev/null || echo "${claudePath}"`, {
|
|
30670
|
+
encoding: "utf8",
|
|
30671
|
+
timeout: 5e3
|
|
30672
|
+
}).trim();
|
|
30673
|
+
} catch {
|
|
30674
|
+
}
|
|
30675
|
+
if (resolved.includes("bin/claude.exe") || resolved.includes("bin/claude-native")) {
|
|
30676
|
+
results.push({
|
|
30677
|
+
name: "cc/cli-binary",
|
|
30678
|
+
pass: false,
|
|
30679
|
+
detail: `claude resolves to native binary: ${resolved}. Should be cli.js. Run: npm install -g @anthropic-ai/claude-code@2.1.98`
|
|
30680
|
+
});
|
|
30681
|
+
} else {
|
|
30682
|
+
results.push({
|
|
30683
|
+
name: "cc/cli-binary",
|
|
30684
|
+
pass: true,
|
|
30685
|
+
detail: `claude resolves to: ${resolved}`
|
|
30686
|
+
});
|
|
30687
|
+
}
|
|
30688
|
+
}
|
|
30689
|
+
} catch {
|
|
30690
|
+
results.push({
|
|
30691
|
+
name: "cc/cli-binary",
|
|
30692
|
+
pass: false,
|
|
30693
|
+
detail: "Failed to check claude binary path"
|
|
30694
|
+
});
|
|
30695
|
+
}
|
|
30696
|
+
const versionsDir = path55.join(
|
|
30697
|
+
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
30698
|
+
".local",
|
|
30699
|
+
"share",
|
|
30700
|
+
"claude",
|
|
30701
|
+
"versions"
|
|
30702
|
+
);
|
|
30703
|
+
if (existsSync43(versionsDir)) {
|
|
30704
|
+
try {
|
|
30705
|
+
const entries = readdirSync14(versionsDir);
|
|
30706
|
+
if (entries.length > 0) {
|
|
30707
|
+
results.push({
|
|
30708
|
+
name: "cc/native-cache-clean",
|
|
30709
|
+
pass: false,
|
|
30710
|
+
detail: `${entries.length} cached native version(s) found in ${versionsDir}: ${entries.slice(0, 3).join(", ")}${entries.length > 3 ? "..." : ""}. Remove: rm -rf "${versionsDir}"`
|
|
30711
|
+
});
|
|
30712
|
+
} else {
|
|
30713
|
+
results.push({
|
|
30714
|
+
name: "cc/native-cache-clean",
|
|
30715
|
+
pass: true,
|
|
30716
|
+
detail: `${versionsDir} is empty`
|
|
30717
|
+
});
|
|
30718
|
+
}
|
|
30719
|
+
} catch {
|
|
30720
|
+
results.push({
|
|
30721
|
+
name: "cc/native-cache-clean",
|
|
30722
|
+
pass: true,
|
|
30723
|
+
detail: `${versionsDir} not readable (OK)`
|
|
30724
|
+
});
|
|
30725
|
+
}
|
|
30726
|
+
} else {
|
|
30727
|
+
results.push({
|
|
30728
|
+
name: "cc/native-cache-clean",
|
|
30729
|
+
pass: true,
|
|
30730
|
+
detail: `${versionsDir} does not exist`
|
|
30731
|
+
});
|
|
30732
|
+
}
|
|
30733
|
+
const disableOld = process.env.DISABLE_AUTOUPDATER === "1";
|
|
30734
|
+
const disableNew = process.env.CLAUDE_CODE_AUTOUPDATER_DISABLED === "1";
|
|
30735
|
+
if (!disableOld && !disableNew) {
|
|
30736
|
+
results.push({
|
|
30737
|
+
name: "cc/autoupdater-disabled",
|
|
30738
|
+
pass: false,
|
|
30739
|
+
detail: "Neither DISABLE_AUTOUPDATER=1 nor CLAUDE_CODE_AUTOUPDATER_DISABLED=1 is set. Auto-updater may install infected native binary. Export both in your shell profile."
|
|
30740
|
+
});
|
|
30741
|
+
} else {
|
|
30742
|
+
const which = [
|
|
30743
|
+
disableOld ? "DISABLE_AUTOUPDATER=1" : null,
|
|
30744
|
+
disableNew ? "CLAUDE_CODE_AUTOUPDATER_DISABLED=1" : null
|
|
30745
|
+
].filter(Boolean).join(" + ");
|
|
30746
|
+
results.push({
|
|
30747
|
+
name: "cc/autoupdater-disabled",
|
|
30748
|
+
pass: true,
|
|
30749
|
+
detail: `Auto-updater disabled via ${which}`
|
|
30750
|
+
});
|
|
30751
|
+
}
|
|
30752
|
+
try {
|
|
30753
|
+
const ccVersion = execSync14("claude --version 2>/dev/null || echo unknown", {
|
|
30754
|
+
encoding: "utf8",
|
|
30755
|
+
timeout: 5e3
|
|
30756
|
+
}).trim();
|
|
30757
|
+
const versionMatch = ccVersion.match(/(\d+\.\d+\.\d+)/);
|
|
30758
|
+
if (versionMatch) {
|
|
30759
|
+
const ver = versionMatch[1];
|
|
30760
|
+
const [, minor] = ver.split(".").map(Number);
|
|
30761
|
+
const isRisky = minor !== void 0 && minor >= 1 && parseInt(ver.split(".")[2] ?? "0") >= 119;
|
|
30762
|
+
results.push({
|
|
30763
|
+
name: "cc/version",
|
|
30764
|
+
pass: !isRisky,
|
|
30765
|
+
detail: isRisky ? `CC version ${ver} \u2014 \u22652.1.119 ships native binary only. Pin: npm install -g @anthropic-ai/claude-code@2.1.98` : `CC version ${ver}`
|
|
30766
|
+
});
|
|
30767
|
+
}
|
|
30768
|
+
} catch {
|
|
30769
|
+
}
|
|
30770
|
+
return results;
|
|
30771
|
+
}
|
|
30772
|
+
function runHealthCheck() {
|
|
30773
|
+
const pkgRoot = findPackageRoot2();
|
|
30774
|
+
const results = [
|
|
30775
|
+
...checkBuildIntegrity(pkgRoot),
|
|
30776
|
+
...checkEmbedPipeline(pkgRoot),
|
|
30777
|
+
...checkTaskSystem(pkgRoot),
|
|
30778
|
+
...checkWorkerSpawning(pkgRoot),
|
|
30779
|
+
...checkMcpTransport(),
|
|
30780
|
+
...checkClaudeCodeInstall()
|
|
30781
|
+
];
|
|
30782
|
+
const passed = results.filter((r) => r.pass).length;
|
|
30783
|
+
const failed = results.filter((r) => !r.pass).length;
|
|
30784
|
+
return { results, passed, failed };
|
|
30785
|
+
}
|
|
30786
|
+
var init_exe_healthcheck = __esm({
|
|
30787
|
+
"src/bin/exe-healthcheck.ts"() {
|
|
30788
|
+
"use strict";
|
|
30789
|
+
init_is_main();
|
|
30790
|
+
init_config();
|
|
30791
|
+
init_mcp_transport_health();
|
|
30792
|
+
if (isMainModule(import.meta.url)) {
|
|
30793
|
+
const { results, passed, failed } = runHealthCheck();
|
|
30794
|
+
console.log("\n exe-os Health Check\n");
|
|
30795
|
+
for (const r of results) {
|
|
30796
|
+
const icon = r.pass ? "\x1B[32m\u2713\x1B[0m" : "\x1B[31m\u2717\x1B[0m";
|
|
30797
|
+
console.log(` ${icon} ${r.name}`);
|
|
30798
|
+
console.log(` ${r.detail}`);
|
|
30799
|
+
}
|
|
30800
|
+
console.log(`
|
|
30801
|
+
${passed} passed, ${failed} failed
|
|
30802
|
+
`);
|
|
30803
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
30804
|
+
}
|
|
30805
|
+
}
|
|
30806
|
+
});
|
|
30807
|
+
|
|
30808
|
+
// src/lib/update-check.ts
|
|
30809
|
+
var update_check_exports = {};
|
|
30810
|
+
__export(update_check_exports, {
|
|
30811
|
+
checkForUpdate: () => checkForUpdate,
|
|
30812
|
+
getLocalVersion: () => getLocalVersion,
|
|
30813
|
+
getRemoteVersion: () => getRemoteVersion
|
|
30814
|
+
});
|
|
30815
|
+
import { execSync as execSync15 } from "child_process";
|
|
30816
|
+
import { readFileSync as readFileSync37 } from "fs";
|
|
30817
|
+
import path56 from "path";
|
|
30818
|
+
function getLocalVersion(packageRoot) {
|
|
30819
|
+
const pkgPath = path56.join(packageRoot, "package.json");
|
|
30820
|
+
const pkg = JSON.parse(readFileSync37(pkgPath, "utf-8"));
|
|
30821
|
+
return pkg.version;
|
|
30822
|
+
}
|
|
30823
|
+
function getRemoteVersion() {
|
|
30824
|
+
try {
|
|
30825
|
+
const output = execSync15("npm view @askexenow/exe-os version", {
|
|
30826
|
+
encoding: "utf-8",
|
|
30827
|
+
timeout: 15e3,
|
|
30828
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
30829
|
+
});
|
|
30830
|
+
return output.trim();
|
|
30831
|
+
} catch {
|
|
30832
|
+
return null;
|
|
30833
|
+
}
|
|
30834
|
+
}
|
|
30835
|
+
function checkForUpdate(packageRoot) {
|
|
30836
|
+
const localVersion = getLocalVersion(packageRoot);
|
|
30837
|
+
const remoteVersion = getRemoteVersion();
|
|
30838
|
+
if (!remoteVersion) {
|
|
30839
|
+
return {
|
|
30840
|
+
updateAvailable: false,
|
|
30841
|
+
localVersion,
|
|
30842
|
+
error: "Could not reach npm registry or package not published yet"
|
|
30843
|
+
};
|
|
30844
|
+
}
|
|
30845
|
+
if (remoteVersion === localVersion) {
|
|
30846
|
+
return { updateAvailable: false, localVersion, remoteVersion };
|
|
30847
|
+
}
|
|
30848
|
+
return { updateAvailable: true, localVersion, remoteVersion };
|
|
30849
|
+
}
|
|
30850
|
+
var init_update_check = __esm({
|
|
30851
|
+
"src/lib/update-check.ts"() {
|
|
30852
|
+
"use strict";
|
|
30853
|
+
}
|
|
30854
|
+
});
|
|
30855
|
+
|
|
30856
|
+
// src/mcp/tools/cli-parity.ts
|
|
30857
|
+
import { execFile as execFile2 } from "child_process";
|
|
30858
|
+
import { promisify as promisify2 } from "util";
|
|
30859
|
+
import { z as z89 } from "zod";
|
|
30860
|
+
async function runCommand(command, args, timeout = 6e4) {
|
|
30861
|
+
const printable = [command, ...args].join(" ");
|
|
30862
|
+
try {
|
|
30863
|
+
const { stdout, stderr } = await execFileAsync2(command, args, {
|
|
30864
|
+
timeout,
|
|
30865
|
+
maxBuffer: 1024 * 1024,
|
|
30866
|
+
env: process.env
|
|
30867
|
+
});
|
|
30868
|
+
return { ok: true, command: printable, text: `${stdout}${stderr ? `
|
|
30869
|
+
${stderr}` : ""}`.trim() || "OK" };
|
|
30870
|
+
} catch (err) {
|
|
30871
|
+
const e = err;
|
|
30872
|
+
const text3 = `${e.stdout ?? ""}${e.stderr ? `
|
|
30873
|
+
${e.stderr}` : ""}`.trim() || e.message || "Command failed";
|
|
30874
|
+
return { ok: false, command: printable, text: text3 };
|
|
30875
|
+
}
|
|
30876
|
+
}
|
|
30877
|
+
function result2(text3, structured, isError = false) {
|
|
30878
|
+
return { content: [{ type: "text", text: text3 }], structuredContent: structured, isError };
|
|
30879
|
+
}
|
|
30880
|
+
function registerCliParityTools(server) {
|
|
30881
|
+
server.registerTool("healthcheck", {
|
|
30882
|
+
title: "Health Check",
|
|
30883
|
+
description: "Run the exe-os product health check and return structured pass/fail results.",
|
|
30884
|
+
inputSchema: {}
|
|
30885
|
+
}, async () => {
|
|
30886
|
+
const out = runHealthCheck();
|
|
30887
|
+
const text3 = ["exe-os healthcheck", "", ...out.results.map((r) => `${r.pass ? "\u2705" : "\u274C"} ${r.name}: ${r.detail}`), "", `${out.passed} passed, ${out.failed} failed`].join("\n");
|
|
30888
|
+
return result2(text3, out, out.failed > 0);
|
|
30889
|
+
});
|
|
30890
|
+
server.registerTool("doctor", {
|
|
30891
|
+
title: "Doctor",
|
|
30892
|
+
description: "Run exe-os doctor audit. Defaults to read-only diagnostics; optional dry-run/fix flags mirror CLI.",
|
|
30893
|
+
inputSchema: {
|
|
30894
|
+
agent: z89.string().optional(),
|
|
30895
|
+
project: z89.string().optional(),
|
|
30896
|
+
verbose: z89.boolean().default(false),
|
|
30897
|
+
conflicts: z89.boolean().default(false),
|
|
30898
|
+
dry_run: z89.boolean().default(false),
|
|
30899
|
+
fix: z89.boolean().default(false)
|
|
30900
|
+
}
|
|
30901
|
+
}, async ({ agent, project, verbose, conflicts, dry_run, fix }) => {
|
|
30902
|
+
const args = [];
|
|
30903
|
+
if (agent) args.push("--agent", agent);
|
|
30904
|
+
if (project) args.push("--project", project);
|
|
30905
|
+
if (verbose) args.push("--verbose");
|
|
30906
|
+
if (conflicts) args.push("--conflicts");
|
|
30907
|
+
if (dry_run) args.push("--dry-run");
|
|
30908
|
+
if (fix) args.push("--fix");
|
|
30909
|
+
const out = await runCommand("exe-doctor", args, 12e4);
|
|
30910
|
+
return result2(out.text, { ok: out.ok, command: out.command }, !out.ok);
|
|
30911
|
+
});
|
|
30912
|
+
server.registerTool("rename_employee", {
|
|
30913
|
+
title: "Rename Employee",
|
|
30914
|
+
description: "Rename an employee using the same path as `exe-os rename <old> <new>`. Use for customer roster/identity renames.",
|
|
30915
|
+
inputSchema: {
|
|
30916
|
+
old_name: z89.string().min(1),
|
|
30917
|
+
new_name: z89.string().min(1),
|
|
30918
|
+
dry_run: z89.boolean().default(false)
|
|
30919
|
+
}
|
|
30920
|
+
}, async ({ old_name, new_name, dry_run }) => {
|
|
30921
|
+
if (dry_run) {
|
|
30922
|
+
const text3 = `Would run: exe-os rename ${old_name} ${new_name}`;
|
|
30923
|
+
return result2(text3, { ok: true, dry_run: true, old_name, new_name });
|
|
30924
|
+
}
|
|
30925
|
+
const out = await runCommand("exe-os", ["rename", old_name, new_name], 6e4);
|
|
30926
|
+
return result2(out.text, { ok: out.ok, command: out.command, old_name, new_name }, !out.ok);
|
|
30927
|
+
});
|
|
30928
|
+
server.registerTool("status_brief", {
|
|
30929
|
+
title: "Status Brief",
|
|
30930
|
+
description: "Return current employee/tmux status. Mirrors `exe-status` and supports optional deep view for one employee.",
|
|
30931
|
+
inputSchema: { employee: z89.string().optional() }
|
|
30932
|
+
}, async ({ employee }) => {
|
|
30933
|
+
const text3 = await status(employee);
|
|
30934
|
+
return result2(text3, { ok: true, employee: employee ?? null });
|
|
30935
|
+
});
|
|
30936
|
+
server.registerTool("pending_work_summary", {
|
|
30937
|
+
title: "Pending Work Summary",
|
|
30938
|
+
description: "Return pending reviews, messages, and notifications using the same summaries as the CLI tools.",
|
|
30939
|
+
inputSchema: { agent: z89.string().optional() }
|
|
30940
|
+
}, async ({ agent }) => {
|
|
30941
|
+
const parts = await Promise.all([
|
|
30942
|
+
runCommand("exe-pending-reviews", [], 3e4),
|
|
30943
|
+
runCommand("exe-pending-messages", agent ? [agent] : [], 3e4),
|
|
30944
|
+
runCommand("exe-pending-notifications", agent ? [agent] : [], 3e4)
|
|
30945
|
+
]);
|
|
30946
|
+
const text3 = ["Pending work summary", "", "## Reviews", parts[0].text, "", "## Messages", parts[1].text, "", "## Notifications", parts[2].text].join("\n");
|
|
30947
|
+
return result2(text3, { ok: parts.every((p) => p.ok), commands: parts.map((p) => p.command) }, parts.some((p) => !p.ok));
|
|
30948
|
+
});
|
|
30949
|
+
server.registerTool("key_status", {
|
|
30950
|
+
title: "Key Status",
|
|
30951
|
+
description: "Read-only Exe OS key status. Does not reveal recovery phrase or rotate keys.",
|
|
30952
|
+
inputSchema: {}
|
|
30953
|
+
}, async () => {
|
|
30954
|
+
const out = await runCommand("exe-os", ["key", "status"], 3e4);
|
|
30955
|
+
return result2(out.text, { ok: out.ok, command: out.command }, !out.ok);
|
|
30956
|
+
});
|
|
30957
|
+
server.registerTool("key_rotation_preflight", {
|
|
30958
|
+
title: "Key Rotation Preflight",
|
|
30959
|
+
description: "Dry-run key rotation/update preflight. No destructive changes.",
|
|
30960
|
+
inputSchema: { mode: z89.enum(["rotate", "update"]).default("rotate") }
|
|
30961
|
+
}, async ({ mode }) => {
|
|
30962
|
+
const out = await runCommand("exe-os", ["key", mode, "--dry-run"], 6e4);
|
|
30963
|
+
return result2(out.text, { ok: out.ok, command: out.command, mode }, !out.ok);
|
|
30964
|
+
});
|
|
30965
|
+
server.registerTool("check_update", {
|
|
30966
|
+
title: "Check Update",
|
|
30967
|
+
description: "Check npm for an available exe-os update without installing it.",
|
|
30968
|
+
inputSchema: {}
|
|
30969
|
+
}, async () => {
|
|
30970
|
+
const packageRoot = new URL("../../..", import.meta.url).pathname;
|
|
30971
|
+
const info = checkForUpdate(packageRoot);
|
|
30972
|
+
const text3 = info.error ? `Update check failed: ${info.error}` : info.updateAvailable ? `Update available: v${info.localVersion} \u2192 v${info.remoteVersion}` : `exe-os is up to date (v${info.localVersion})`;
|
|
30973
|
+
return result2(text3, { ok: !info.error, ...info }, Boolean(info.error));
|
|
30974
|
+
});
|
|
30975
|
+
server.registerTool("stack_update_check", {
|
|
30976
|
+
title: "Stack Update Check",
|
|
30977
|
+
description: "Plan/check a customer stack update without applying Docker changes. Mirrors `exe-os stack-update --check`.",
|
|
30978
|
+
inputSchema: {
|
|
30979
|
+
target: z89.string().optional(),
|
|
30980
|
+
manifest: z89.string().optional(),
|
|
30981
|
+
compose_file: z89.string().optional(),
|
|
30982
|
+
env_file: z89.string().optional(),
|
|
30983
|
+
deployment_persona: z89.enum(["customer", "askexe-control-plane"]).default("customer")
|
|
30984
|
+
}
|
|
30985
|
+
}, async ({ target, manifest, compose_file, env_file, deployment_persona }) => {
|
|
30986
|
+
const args = ["stack-update", "--check", "--deployment-persona", deployment_persona];
|
|
30987
|
+
if (target) args.push("--target", target);
|
|
30988
|
+
if (manifest) args.push("--manifest", manifest);
|
|
30989
|
+
if (compose_file) args.push("--compose-file", compose_file);
|
|
30990
|
+
if (env_file) args.push("--env-file", env_file);
|
|
30991
|
+
const out = await runCommand("exe-os", args, 9e4);
|
|
30992
|
+
return result2(out.text, { ok: out.ok, command: out.command }, !out.ok);
|
|
30993
|
+
});
|
|
30994
|
+
server.registerTool("cloud_status", {
|
|
30995
|
+
title: "Cloud Status",
|
|
30996
|
+
description: "Read-only cloud sync status. Does not reveal recovery phrase.",
|
|
30997
|
+
inputSchema: {}
|
|
30998
|
+
}, async () => {
|
|
30999
|
+
const out = await runCommand("exe-os", ["cloud", "status"], 45e3);
|
|
31000
|
+
return result2(out.text, { ok: out.ok, command: out.command }, !out.ok);
|
|
31001
|
+
});
|
|
31002
|
+
}
|
|
31003
|
+
var execFileAsync2;
|
|
31004
|
+
var init_cli_parity = __esm({
|
|
31005
|
+
"src/mcp/tools/cli-parity.ts"() {
|
|
31006
|
+
"use strict";
|
|
31007
|
+
init_exe_status();
|
|
31008
|
+
init_exe_healthcheck();
|
|
31009
|
+
init_update_check();
|
|
31010
|
+
execFileAsync2 = promisify2(execFile2);
|
|
31011
|
+
}
|
|
31012
|
+
});
|
|
31013
|
+
|
|
30364
31014
|
// src/lib/session-events.ts
|
|
30365
31015
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
30366
31016
|
async function ensureSessionEventsTable(client) {
|
|
@@ -30415,7 +31065,7 @@ async function listRecentSessionEvents(client, options) {
|
|
|
30415
31065
|
const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
|
|
30416
31066
|
args.push(...scope.args);
|
|
30417
31067
|
args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
|
|
30418
|
-
const
|
|
31068
|
+
const result3 = await client.execute({
|
|
30419
31069
|
sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
|
|
30420
31070
|
project_name, event_index, event_type, tool_name, tool_use_id,
|
|
30421
31071
|
content, payload_json, has_error, created_at
|
|
@@ -30425,7 +31075,7 @@ async function listRecentSessionEvents(client, options) {
|
|
|
30425
31075
|
LIMIT ?`,
|
|
30426
31076
|
args
|
|
30427
31077
|
});
|
|
30428
|
-
return
|
|
31078
|
+
return result3.rows.map((row) => ({
|
|
30429
31079
|
id: String(row.id),
|
|
30430
31080
|
agentId: String(row.agent_id),
|
|
30431
31081
|
agentRole: String(row.agent_role),
|
|
@@ -30451,7 +31101,7 @@ var init_session_events = __esm({
|
|
|
30451
31101
|
});
|
|
30452
31102
|
|
|
30453
31103
|
// src/mcp/tools/get-session-events.ts
|
|
30454
|
-
import { z as
|
|
31104
|
+
import { z as z90 } from "zod";
|
|
30455
31105
|
function canReadAgent(activeRole, activeAgent, requestedAgent) {
|
|
30456
31106
|
return requestedAgent === activeAgent || activeRole === "COO" || activeRole === "CTO";
|
|
30457
31107
|
}
|
|
@@ -30475,11 +31125,11 @@ function registerGetSessionEvents(server) {
|
|
|
30475
31125
|
title: "Get Session Events",
|
|
30476
31126
|
description: "Return exact recent chronological user prompts, assistant responses, and tool calls from the append-only session journal. Use this when asked what happened last, not semantic memory search.",
|
|
30477
31127
|
inputSchema: {
|
|
30478
|
-
agent_id:
|
|
30479
|
-
session_id:
|
|
31128
|
+
agent_id: z90.string().optional().describe("Agent to inspect. Defaults to active agent. COO/CTO may inspect others."),
|
|
31129
|
+
session_id: z90.string().optional().describe("Optional exact runtime session id."),
|
|
30480
31130
|
event_type: EVENT_TYPE.optional().describe("Filter to one event type."),
|
|
30481
|
-
project_name:
|
|
30482
|
-
limit:
|
|
31131
|
+
project_name: z90.string().optional().describe("Optional project filter. Pass 'all' for all projects."),
|
|
31132
|
+
limit: z90.number().int().min(1).max(100).default(20).describe("Number of events to return.")
|
|
30483
31133
|
}
|
|
30484
31134
|
},
|
|
30485
31135
|
async ({ agent_id, session_id, event_type, project_name, limit }) => {
|
|
@@ -30515,8 +31165,8 @@ function registerGetLastAssistantResponse(server) {
|
|
|
30515
31165
|
title: "Get Last Assistant Response",
|
|
30516
31166
|
description: "Return the exact last assistant response for an agent from the session event journal. Use for 'what was the last thing you said?'",
|
|
30517
31167
|
inputSchema: {
|
|
30518
|
-
agent_id:
|
|
30519
|
-
project_name:
|
|
31168
|
+
agent_id: z90.string().optional().describe("Agent to inspect. Defaults to active agent. COO/CTO may inspect others."),
|
|
31169
|
+
project_name: z90.string().optional().describe("Optional project filter. Pass 'all' for all projects.")
|
|
30520
31170
|
}
|
|
30521
31171
|
},
|
|
30522
31172
|
async ({ agent_id, project_name }) => {
|
|
@@ -30551,7 +31201,7 @@ var init_get_session_events = __esm({
|
|
|
30551
31201
|
init_active_agent();
|
|
30552
31202
|
init_fast_db_init();
|
|
30553
31203
|
init_session_events();
|
|
30554
|
-
EVENT_TYPE =
|
|
31204
|
+
EVENT_TYPE = z90.enum([
|
|
30555
31205
|
"user_prompt",
|
|
30556
31206
|
"assistant_response",
|
|
30557
31207
|
"tool_call",
|
|
@@ -30563,28 +31213,28 @@ var init_get_session_events = __esm({
|
|
|
30563
31213
|
|
|
30564
31214
|
// src/lib/code-context-index.ts
|
|
30565
31215
|
import crypto20 from "crypto";
|
|
30566
|
-
import
|
|
30567
|
-
import { existsSync as
|
|
31216
|
+
import path57 from "path";
|
|
31217
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync22, readFileSync as readFileSync38, readdirSync as readdirSync15, statSync as statSync10, writeFileSync as writeFileSync25 } from "fs";
|
|
30568
31218
|
import { spawnSync } from "child_process";
|
|
30569
31219
|
function normalizeProjectRoot(projectRoot) {
|
|
30570
|
-
return
|
|
31220
|
+
return path57.resolve(projectRoot || process.cwd());
|
|
30571
31221
|
}
|
|
30572
31222
|
function hashText(text3) {
|
|
30573
31223
|
return crypto20.createHash("sha256").update(text3).digest("hex");
|
|
30574
31224
|
}
|
|
30575
31225
|
function indexDir() {
|
|
30576
|
-
const dir =
|
|
31226
|
+
const dir = path57.join(EXE_AI_DIR, "code-context");
|
|
30577
31227
|
mkdirSync22(dir, { recursive: true });
|
|
30578
31228
|
return dir;
|
|
30579
31229
|
}
|
|
30580
31230
|
function getCodeContextIndexPath(projectRoot) {
|
|
30581
31231
|
const root = normalizeProjectRoot(projectRoot);
|
|
30582
31232
|
const rootHash = hashText(root).slice(0, 16);
|
|
30583
|
-
return
|
|
31233
|
+
return path57.join(indexDir(), `${rootHash}.json`);
|
|
30584
31234
|
}
|
|
30585
31235
|
function currentBranch(projectRoot) {
|
|
30586
|
-
const
|
|
30587
|
-
const branch =
|
|
31236
|
+
const result3 = spawnSync("git", ["branch", "--show-current"], { cwd: projectRoot, encoding: "utf8", timeout: 2e3 });
|
|
31237
|
+
const branch = result3.status === 0 ? result3.stdout.trim() : "";
|
|
30588
31238
|
return branch || "detached-or-unknown";
|
|
30589
31239
|
}
|
|
30590
31240
|
function shouldIgnore(relPath) {
|
|
@@ -30592,9 +31242,9 @@ function shouldIgnore(relPath) {
|
|
|
30592
31242
|
return parts.some((part) => IGNORE_SEGMENTS.has(part));
|
|
30593
31243
|
}
|
|
30594
31244
|
function listRecursive(projectRoot, dir = projectRoot, out = []) {
|
|
30595
|
-
for (const entry of
|
|
30596
|
-
const abs =
|
|
30597
|
-
const rel =
|
|
31245
|
+
for (const entry of readdirSync15(dir, { withFileTypes: true })) {
|
|
31246
|
+
const abs = path57.join(dir, entry.name);
|
|
31247
|
+
const rel = path57.relative(projectRoot, abs).replaceAll(path57.sep, "/");
|
|
30598
31248
|
if (shouldIgnore(rel)) continue;
|
|
30599
31249
|
if (entry.isDirectory()) listRecursive(projectRoot, abs, out);
|
|
30600
31250
|
else if (entry.isFile()) out.push(rel);
|
|
@@ -30610,7 +31260,7 @@ function listCodeFiles(projectRoot, maxFiles) {
|
|
|
30610
31260
|
const rg = spawnSync("rg", ["--files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
|
|
30611
31261
|
files = rg.status === 0 && rg.stdout.trim() ? rg.stdout.split("\n").map((s) => s.trim()).filter(Boolean) : listRecursive(projectRoot);
|
|
30612
31262
|
}
|
|
30613
|
-
return files.map((file) => file.replaceAll(
|
|
31263
|
+
return files.map((file) => file.replaceAll(path57.sep, "/")).filter((file) => isChunkable(file) && !shouldIgnore(file)).slice(0, maxFiles).sort();
|
|
30614
31264
|
}
|
|
30615
31265
|
function parseImportPaths2(importText) {
|
|
30616
31266
|
const paths = [];
|
|
@@ -30623,13 +31273,13 @@ function parseImportPaths2(importText) {
|
|
|
30623
31273
|
}
|
|
30624
31274
|
function resolveImport(fromFile, importPath, allFiles) {
|
|
30625
31275
|
if (!importPath.startsWith(".")) return null;
|
|
30626
|
-
const base =
|
|
31276
|
+
const base = path57.posix.normalize(path57.posix.join(path57.posix.dirname(fromFile.replaceAll(path57.sep, "/")), importPath));
|
|
30627
31277
|
const withoutKnownExt = base.replace(/\.(?:[a-z0-9]+)$/i, "");
|
|
30628
31278
|
const candidates = [base];
|
|
30629
31279
|
for (const ext of ["ts", "tsx", "js", "jsx", "py", "rs", "go", "java", "cs", "cpp", "c", "rb", "php", "swift", "kt", "scala", "sql", "md", "json", "yaml", "yml"]) {
|
|
30630
31280
|
candidates.push(`${withoutKnownExt}.${ext}`, `${base}.${ext}`);
|
|
30631
31281
|
}
|
|
30632
|
-
for (const indexName of ["index.ts", "index.tsx", "index.js", "mod.rs", "__init__.py"]) candidates.push(
|
|
31282
|
+
for (const indexName of ["index.ts", "index.tsx", "index.js", "mod.rs", "__init__.py"]) candidates.push(path57.posix.join(base, indexName));
|
|
30633
31283
|
return candidates.find((candidate) => allFiles.has(candidate)) ?? null;
|
|
30634
31284
|
}
|
|
30635
31285
|
function symbolId(filePath, chunk) {
|
|
@@ -30637,9 +31287,9 @@ function symbolId(filePath, chunk) {
|
|
|
30637
31287
|
}
|
|
30638
31288
|
function loadIndex(projectRoot) {
|
|
30639
31289
|
const file = getCodeContextIndexPath(projectRoot);
|
|
30640
|
-
if (!
|
|
31290
|
+
if (!existsSync44(file)) return null;
|
|
30641
31291
|
try {
|
|
30642
|
-
const parsed = JSON.parse(
|
|
31292
|
+
const parsed = JSON.parse(readFileSync38(file, "utf8"));
|
|
30643
31293
|
if (parsed.version !== INDEX_VERSION || parsed.projectRoot !== projectRoot) return null;
|
|
30644
31294
|
return parsed;
|
|
30645
31295
|
} catch {
|
|
@@ -30650,7 +31300,7 @@ function saveIndex(index) {
|
|
|
30650
31300
|
writeFileSync25(getCodeContextIndexPath(index.projectRoot), JSON.stringify(index, null, 2));
|
|
30651
31301
|
}
|
|
30652
31302
|
function buildFileRecord(projectRoot, relPath, allFiles, previous) {
|
|
30653
|
-
const absPath =
|
|
31303
|
+
const absPath = path57.join(projectRoot, relPath);
|
|
30654
31304
|
let stat;
|
|
30655
31305
|
try {
|
|
30656
31306
|
stat = statSync10(absPath);
|
|
@@ -30660,7 +31310,7 @@ function buildFileRecord(projectRoot, relPath, allFiles, previous) {
|
|
|
30660
31310
|
if (!stat.isFile()) return { record: null, reused: false };
|
|
30661
31311
|
const language = languageForFile(relPath);
|
|
30662
31312
|
if (!language || !isChunkable(relPath)) return { record: null, reused: false };
|
|
30663
|
-
const source =
|
|
31313
|
+
const source = readFileSync38(absPath, "utf8");
|
|
30664
31314
|
const hash = hashText(source);
|
|
30665
31315
|
if (previous && previous.hash === hash && previous.mtimeMs === stat.mtimeMs && previous.size === stat.size && previous.language === language) {
|
|
30666
31316
|
return { record: previous, reused: true };
|
|
@@ -30688,13 +31338,13 @@ function buildCodeContextIndex(options = {}) {
|
|
|
30688
31338
|
const branch = currentBranch(projectRoot);
|
|
30689
31339
|
const previous = options.force ? null : loadIndex(projectRoot);
|
|
30690
31340
|
const files = listCodeFiles(projectRoot, maxFiles);
|
|
30691
|
-
const allFiles = new Set(files.map((file) => file.replaceAll(
|
|
31341
|
+
const allFiles = new Set(files.map((file) => file.replaceAll(path57.sep, "/")));
|
|
30692
31342
|
const fileRecords = {};
|
|
30693
31343
|
let rebuiltFiles = 0;
|
|
30694
31344
|
let reusedFiles = 0;
|
|
30695
31345
|
let skippedFiles = 0;
|
|
30696
31346
|
for (const rel of files) {
|
|
30697
|
-
const normalized = rel.replaceAll(
|
|
31347
|
+
const normalized = rel.replaceAll(path57.sep, "/");
|
|
30698
31348
|
const { record, reused } = buildFileRecord(projectRoot, normalized, allFiles, previous?.files[normalized]);
|
|
30699
31349
|
if (record) {
|
|
30700
31350
|
fileRecords[normalized] = record;
|
|
@@ -30723,11 +31373,11 @@ function loadOrBuildCodeContextIndex(options = {}) {
|
|
|
30723
31373
|
if (loaded) {
|
|
30724
31374
|
const currentFiles = listCodeFiles(projectRoot, options.maxFiles ?? DEFAULT_MAX_FILES);
|
|
30725
31375
|
const unchanged = currentFiles.every((rel) => {
|
|
30726
|
-
const normalized = rel.replaceAll(
|
|
31376
|
+
const normalized = rel.replaceAll(path57.sep, "/");
|
|
30727
31377
|
const existing = loaded.files[normalized];
|
|
30728
31378
|
if (!existing) return false;
|
|
30729
31379
|
try {
|
|
30730
|
-
const stat = statSync10(
|
|
31380
|
+
const stat = statSync10(path57.join(projectRoot, normalized));
|
|
30731
31381
|
return stat.mtimeMs === existing.mtimeMs && stat.size === existing.size;
|
|
30732
31382
|
} catch {
|
|
30733
31383
|
return false;
|
|
@@ -30780,9 +31430,9 @@ function globToRegex(pattern) {
|
|
|
30780
31430
|
}
|
|
30781
31431
|
function matchesPath(filePath, patterns) {
|
|
30782
31432
|
if (!patterns || patterns.length === 0) return true;
|
|
30783
|
-
const normalized = filePath.replaceAll(
|
|
31433
|
+
const normalized = filePath.replaceAll(path57.sep, "/");
|
|
30784
31434
|
return patterns.some((pattern) => {
|
|
30785
|
-
const p = pattern.replaceAll(
|
|
31435
|
+
const p = pattern.replaceAll(path57.sep, "/").replace(/^\.\//, "");
|
|
30786
31436
|
return normalized === p || normalized.startsWith(`${p}/`) || normalized.endsWith(p) || globToRegex(p).test(normalized);
|
|
30787
31437
|
});
|
|
30788
31438
|
}
|
|
@@ -30900,7 +31550,7 @@ function traceCodeSymbol(symbolName, options = {}) {
|
|
|
30900
31550
|
}
|
|
30901
31551
|
function resolveTargetFile(index, input) {
|
|
30902
31552
|
if (input.filePath) {
|
|
30903
|
-
const normalized = input.filePath.replaceAll(
|
|
31553
|
+
const normalized = input.filePath.replaceAll(path57.sep, "/").replace(/^\.\//, "");
|
|
30904
31554
|
if (index.files[normalized]) return { filePath: normalized, target: normalized };
|
|
30905
31555
|
const suffix = Object.keys(index.files).find((file) => file.endsWith(normalized));
|
|
30906
31556
|
if (suffix) return { filePath: suffix, target: input.filePath };
|
|
@@ -30930,7 +31580,7 @@ function analyzeBlastRadius(input) {
|
|
|
30930
31580
|
}
|
|
30931
31581
|
}
|
|
30932
31582
|
}
|
|
30933
|
-
const targetBase =
|
|
31583
|
+
const targetBase = path57.basename(target.filePath).replace(/\.[^.]+$/, "").toLowerCase();
|
|
30934
31584
|
const symbolLower = input.symbol?.toLowerCase();
|
|
30935
31585
|
const tests = Object.keys(index.files).filter((file) => {
|
|
30936
31586
|
const lower = file.toLowerCase();
|
|
@@ -30971,7 +31621,7 @@ var init_code_context_index = __esm({
|
|
|
30971
31621
|
});
|
|
30972
31622
|
|
|
30973
31623
|
// src/mcp/tools/code-context.ts
|
|
30974
|
-
import { z as
|
|
31624
|
+
import { z as z91 } from "zod";
|
|
30975
31625
|
function errorResult10(text3) {
|
|
30976
31626
|
return { content: [{ type: "text", text: text3 }], isError: true };
|
|
30977
31627
|
}
|
|
@@ -30983,19 +31633,19 @@ function registerCodeContext(server) {
|
|
|
30983
31633
|
title: "Code Context",
|
|
30984
31634
|
description: "Persistent codebase context engine. One consolidated tool to avoid MCP bloat. Actions: index, search, trace, blast_radius, stats.",
|
|
30985
31635
|
inputSchema: {
|
|
30986
|
-
action:
|
|
30987
|
-
project_root:
|
|
30988
|
-
query:
|
|
30989
|
-
symbol:
|
|
30990
|
-
file_path:
|
|
30991
|
-
force:
|
|
30992
|
-
limit:
|
|
30993
|
-
offset:
|
|
30994
|
-
refresh_index:
|
|
30995
|
-
languages:
|
|
30996
|
-
paths:
|
|
30997
|
-
depth:
|
|
30998
|
-
max_files:
|
|
31636
|
+
action: z91.enum(["index", "search", "trace", "blast_radius", "stats"]).describe("Code context operation"),
|
|
31637
|
+
project_root: z91.string().optional().describe("Repository root. Defaults to current working directory."),
|
|
31638
|
+
query: z91.string().optional().describe("Search query for action=search"),
|
|
31639
|
+
symbol: z91.string().optional().describe("Symbol/function/class/type name for trace or blast_radius"),
|
|
31640
|
+
file_path: z91.string().optional().describe("File path for blast_radius"),
|
|
31641
|
+
force: z91.boolean().optional().describe("Force rebuild before answering"),
|
|
31642
|
+
limit: z91.coerce.number().int().min(1).max(100).optional().describe("Max results"),
|
|
31643
|
+
offset: z91.coerce.number().int().min(0).optional().describe("Search pagination offset"),
|
|
31644
|
+
refresh_index: z91.boolean().optional().describe("Refresh/rebuild index before searching"),
|
|
31645
|
+
languages: z91.array(z91.string()).optional().describe('Language filters, e.g. ["python", "typescript"]'),
|
|
31646
|
+
paths: z91.array(z91.string()).optional().describe("Path/glob filters"),
|
|
31647
|
+
depth: z91.coerce.number().int().min(1).max(5).optional().describe("Dependent traversal depth for blast_radius"),
|
|
31648
|
+
max_files: z91.coerce.number().int().min(1).max(1e4).optional().describe("Max code files to index")
|
|
30999
31649
|
}
|
|
31000
31650
|
}, async ({ action, project_root, query, symbol, file_path, force, limit, offset, refresh_index, languages, paths, depth, max_files }) => {
|
|
31001
31651
|
const opts = { projectRoot: project_root, force, maxFiles: max_files };
|
|
@@ -31031,9 +31681,9 @@ function registerCodeContext(server) {
|
|
|
31031
31681
|
}
|
|
31032
31682
|
if (action === "blast_radius") {
|
|
31033
31683
|
if (!symbol && !file_path) return errorResult10('code_context action "blast_radius" requires symbol or file_path');
|
|
31034
|
-
const
|
|
31035
|
-
if (!
|
|
31036
|
-
return jsonResult(
|
|
31684
|
+
const result3 = analyzeBlastRadius({ projectRoot: project_root, force, symbol, filePath: file_path, depth });
|
|
31685
|
+
if (!result3) return errorResult10(`No code context target found for ${symbol || file_path}`);
|
|
31686
|
+
return jsonResult(result3);
|
|
31037
31687
|
}
|
|
31038
31688
|
return errorResult10(`Unknown code_context action: ${String(action)}`);
|
|
31039
31689
|
});
|
|
@@ -31046,7 +31696,7 @@ var init_code_context = __esm({
|
|
|
31046
31696
|
});
|
|
31047
31697
|
|
|
31048
31698
|
// src/mcp/tools/support-inbox.ts
|
|
31049
|
-
import { z as
|
|
31699
|
+
import { z as z92 } from "zod";
|
|
31050
31700
|
function adminToken() {
|
|
31051
31701
|
return process.env.ASKEXE_SUPPORT_ADMIN_TOKEN || process.env.EXE_SUPPORT_ADMIN_TOKEN;
|
|
31052
31702
|
}
|
|
@@ -31085,14 +31735,14 @@ function registerListBugReports(server) {
|
|
|
31085
31735
|
title: "List Bug Reports",
|
|
31086
31736
|
description: "AskExe-internal only: list incoming customer bug reports from the support inbox.",
|
|
31087
31737
|
inputSchema: {
|
|
31088
|
-
status:
|
|
31089
|
-
severity:
|
|
31090
|
-
limit:
|
|
31738
|
+
status: z92.enum(["all", "open", "triaged", "fixed", "closed", "wontfix"]).default("open"),
|
|
31739
|
+
severity: z92.enum(["p0", "p1", "p2", "p3"]).optional(),
|
|
31740
|
+
limit: z92.number().int().min(1).max(100).default(25)
|
|
31091
31741
|
}
|
|
31092
31742
|
},
|
|
31093
|
-
async ({ status, severity, limit }) => {
|
|
31743
|
+
async ({ status: status2, severity, limit }) => {
|
|
31094
31744
|
const url = new URL(endpoint());
|
|
31095
|
-
url.searchParams.set("status",
|
|
31745
|
+
url.searchParams.set("status", status2);
|
|
31096
31746
|
url.searchParams.set("limit", String(limit));
|
|
31097
31747
|
if (severity) url.searchParams.set("severity", severity);
|
|
31098
31748
|
const data = await requestJson(url.toString());
|
|
@@ -31106,7 +31756,7 @@ function registerGetBugReport(server) {
|
|
|
31106
31756
|
{
|
|
31107
31757
|
title: "Get Bug Report",
|
|
31108
31758
|
description: "AskExe-internal only: fetch one customer bug report with full markdown payload.",
|
|
31109
|
-
inputSchema: { id:
|
|
31759
|
+
inputSchema: { id: z92.string().min(8) }
|
|
31110
31760
|
},
|
|
31111
31761
|
async ({ id }) => {
|
|
31112
31762
|
const data = await requestJson(`${endpoint()}/${encodeURIComponent(id)}`);
|
|
@@ -31121,18 +31771,18 @@ function registerTriageBugReport(server) {
|
|
|
31121
31771
|
title: "Triage Bug Report",
|
|
31122
31772
|
description: "AskExe-internal only: update bug report status and link task/commit/release metadata.",
|
|
31123
31773
|
inputSchema: {
|
|
31124
|
-
id:
|
|
31774
|
+
id: z92.string().min(8),
|
|
31125
31775
|
status: STATUS.optional(),
|
|
31126
|
-
triage_notes:
|
|
31127
|
-
linked_task_id:
|
|
31128
|
-
linked_commit:
|
|
31129
|
-
fixed_version:
|
|
31776
|
+
triage_notes: z92.string().optional(),
|
|
31777
|
+
linked_task_id: z92.string().optional(),
|
|
31778
|
+
linked_commit: z92.string().optional(),
|
|
31779
|
+
fixed_version: z92.string().optional()
|
|
31130
31780
|
}
|
|
31131
31781
|
},
|
|
31132
|
-
async ({ id, status, triage_notes, linked_task_id, linked_commit, fixed_version }) => {
|
|
31782
|
+
async ({ id, status: status2, triage_notes, linked_task_id, linked_commit, fixed_version }) => {
|
|
31133
31783
|
const data = await requestJson(`${endpoint()}/${encodeURIComponent(id)}`, {
|
|
31134
31784
|
method: "PATCH",
|
|
31135
|
-
body: JSON.stringify({ status, triage_notes, linked_task_id, linked_commit, fixed_version })
|
|
31785
|
+
body: JSON.stringify({ status: status2, triage_notes, linked_task_id, linked_commit, fixed_version })
|
|
31136
31786
|
});
|
|
31137
31787
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
31138
31788
|
}
|
|
@@ -31143,7 +31793,7 @@ var init_support_inbox = __esm({
|
|
|
31143
31793
|
"src/mcp/tools/support-inbox.ts"() {
|
|
31144
31794
|
"use strict";
|
|
31145
31795
|
DEFAULT_ENDPOINT = "https://askexe.com/admin/support/bug-reports";
|
|
31146
|
-
STATUS =
|
|
31796
|
+
STATUS = z92.enum(["open", "triaged", "fixed", "closed", "wontfix"]);
|
|
31147
31797
|
}
|
|
31148
31798
|
});
|
|
31149
31799
|
|
|
@@ -31218,6 +31868,7 @@ var init_tool_gates = __esm({
|
|
|
31218
31868
|
registerGetDecision: "core",
|
|
31219
31869
|
registerCreateBugReport: "core",
|
|
31220
31870
|
registerSupportTools: "core",
|
|
31871
|
+
registerCliParityTools: "admin",
|
|
31221
31872
|
registerGetSessionEvents: "core",
|
|
31222
31873
|
registerGetLastAssistantResponse: "core",
|
|
31223
31874
|
registerCodeContext: "graph-read",
|
|
@@ -31478,6 +32129,7 @@ function registerAllTools(server) {
|
|
|
31478
32129
|
gate("registerGetDecision", registerGetDecision);
|
|
31479
32130
|
gate("registerCreateBugReport", registerCreateBugReport);
|
|
31480
32131
|
gate("registerSupportTools", registerSupportTools);
|
|
32132
|
+
gate("registerCliParityTools", registerCliParityTools);
|
|
31481
32133
|
gate("registerGetSessionEvents", registerGetSessionEvents);
|
|
31482
32134
|
gate("registerGetLastAssistantResponse", registerGetLastAssistantResponse);
|
|
31483
32135
|
gate("registerCodeContext", registerCodeContext);
|
|
@@ -31626,6 +32278,7 @@ var init_register_tools = __esm({
|
|
|
31626
32278
|
init_query_company_brain();
|
|
31627
32279
|
init_create_bug_report();
|
|
31628
32280
|
init_support();
|
|
32281
|
+
init_cli_parity();
|
|
31629
32282
|
init_get_session_events();
|
|
31630
32283
|
init_code_context();
|
|
31631
32284
|
init_support_inbox();
|
|
@@ -31639,7 +32292,7 @@ __export(review_polling_exports, {
|
|
|
31639
32292
|
createRealDeps: () => createRealDeps,
|
|
31640
32293
|
pollPendingReviews: () => pollPendingReviews
|
|
31641
32294
|
});
|
|
31642
|
-
import { execSync as
|
|
32295
|
+
import { execSync as execSync16 } from "child_process";
|
|
31643
32296
|
async function pollPendingReviews(deps, _state) {
|
|
31644
32297
|
let sessions;
|
|
31645
32298
|
try {
|
|
@@ -31746,7 +32399,7 @@ async function pollPendingReviews(deps, _state) {
|
|
|
31746
32399
|
function createRealDeps(getClient2) {
|
|
31747
32400
|
return {
|
|
31748
32401
|
listTmuxSessions: () => {
|
|
31749
|
-
return
|
|
32402
|
+
return execSync16("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
31750
32403
|
encoding: "utf8",
|
|
31751
32404
|
timeout: 3e3
|
|
31752
32405
|
}).trim().split("\n").filter(Boolean);
|
|
@@ -31754,12 +32407,12 @@ function createRealDeps(getClient2) {
|
|
|
31754
32407
|
countPendingReviews: async (sessionScope) => {
|
|
31755
32408
|
const client = getClient2();
|
|
31756
32409
|
const rpScope = strictSessionScopeFilter(sessionScope);
|
|
31757
|
-
const
|
|
32410
|
+
const result3 = await client.execute({
|
|
31758
32411
|
sql: `SELECT COUNT(*) as count FROM tasks
|
|
31759
32412
|
WHERE status = 'needs_review'${rpScope.sql}`,
|
|
31760
32413
|
args: [...rpScope.args]
|
|
31761
32414
|
});
|
|
31762
|
-
return Number(
|
|
32415
|
+
return Number(result3.rows[0]?.count ?? 0);
|
|
31763
32416
|
},
|
|
31764
32417
|
sendIntercom: (session) => {
|
|
31765
32418
|
const { sendIntercom: centralSend } = (init_tmux_routing(), __toCommonJS(tmux_routing_exports));
|
|
@@ -31769,7 +32422,7 @@ function createRealDeps(getClient2) {
|
|
|
31769
32422
|
const client = getClient2();
|
|
31770
32423
|
const coordinatorName = getCoordinatorName();
|
|
31771
32424
|
const odScope = strictSessionScopeFilter(sessionScope, "t");
|
|
31772
|
-
const
|
|
32425
|
+
const result3 = await client.execute({
|
|
31773
32426
|
sql: `SELECT t.id, t.title, t.assigned_to, t.assigned_by,
|
|
31774
32427
|
t.project_name, t.task_file, t.result, t.status
|
|
31775
32428
|
FROM tasks t
|
|
@@ -31779,7 +32432,7 @@ function createRealDeps(getClient2) {
|
|
|
31779
32432
|
AND (t.result IS NULL OR t.result NOT LIKE '%## Review notes%')`,
|
|
31780
32433
|
args: [coordinatorName, ...odScope.args]
|
|
31781
32434
|
});
|
|
31782
|
-
return
|
|
32435
|
+
return result3.rows;
|
|
31783
32436
|
},
|
|
31784
32437
|
createReviewForOrphan: async (task) => {
|
|
31785
32438
|
const { createReviewForCompletedTask: createReviewForCompletedTask2 } = await Promise.resolve().then(() => (init_tasks_review(), tasks_review_exports));
|
|
@@ -31796,7 +32449,7 @@ function createRealDeps(getClient2) {
|
|
|
31796
32449
|
findUrgentUnread: async (sessionScope) => {
|
|
31797
32450
|
const client = getClient2();
|
|
31798
32451
|
const msgScope = strictSessionScopeFilter(sessionScope);
|
|
31799
|
-
const
|
|
32452
|
+
const result3 = await client.execute({
|
|
31800
32453
|
sql: `SELECT id, target_agent, content, created_at
|
|
31801
32454
|
FROM messages
|
|
31802
32455
|
WHERE priority = 'urgent'
|
|
@@ -31806,13 +32459,13 @@ function createRealDeps(getClient2) {
|
|
|
31806
32459
|
LIMIT 10`,
|
|
31807
32460
|
args: [...msgScope.args]
|
|
31808
32461
|
});
|
|
31809
|
-
return
|
|
32462
|
+
return result3.rows;
|
|
31810
32463
|
},
|
|
31811
32464
|
findUnstartedTasks: async (sessionScope) => {
|
|
31812
32465
|
const client = getClient2();
|
|
31813
32466
|
const coordinatorName = getCoordinatorName();
|
|
31814
32467
|
const usScope = strictSessionScopeFilter(sessionScope);
|
|
31815
|
-
const
|
|
32468
|
+
const result3 = await client.execute({
|
|
31816
32469
|
sql: `SELECT id, title, assigned_to, created_at
|
|
31817
32470
|
FROM tasks
|
|
31818
32471
|
WHERE status = 'open'
|
|
@@ -31825,7 +32478,7 @@ function createRealDeps(getClient2) {
|
|
|
31825
32478
|
LIMIT 20`,
|
|
31826
32479
|
args: [coordinatorName, ...usScope.args]
|
|
31827
32480
|
});
|
|
31828
|
-
return
|
|
32481
|
+
return result3.rows;
|
|
31829
32482
|
}
|
|
31830
32483
|
};
|
|
31831
32484
|
}
|
|
@@ -31854,7 +32507,7 @@ __export(task_enforcement_exports, {
|
|
|
31854
32507
|
sendNudge: () => sendNudge
|
|
31855
32508
|
});
|
|
31856
32509
|
import { writeFileSync as writeFileSync26 } from "fs";
|
|
31857
|
-
import
|
|
32510
|
+
import path58 from "path";
|
|
31858
32511
|
function writeAuditEntry(entry) {
|
|
31859
32512
|
try {
|
|
31860
32513
|
const line = JSON.stringify(entry) + "\n";
|
|
@@ -32029,7 +32682,7 @@ var init_task_enforcement = __esm({
|
|
|
32029
32682
|
"What do you need?"
|
|
32030
32683
|
];
|
|
32031
32684
|
MANAGER_ROLES = ["COO", "CTO"];
|
|
32032
|
-
AUDIT_LOG_PATH =
|
|
32685
|
+
AUDIT_LOG_PATH = path58.join(
|
|
32033
32686
|
process.env.HOME ?? process.env.USERPROFILE ?? "/tmp",
|
|
32034
32687
|
".exe-os",
|
|
32035
32688
|
"enforcement-audit.jsonl"
|
|
@@ -32051,10 +32704,10 @@ __export(background_jobs_exports, {
|
|
|
32051
32704
|
reniceCurrentProcess: () => reniceCurrentProcess,
|
|
32052
32705
|
startManagedJob: () => startManagedJob
|
|
32053
32706
|
});
|
|
32054
|
-
import { existsSync as
|
|
32707
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync23, readFileSync as readFileSync39, writeFileSync as writeFileSync27, unlinkSync as unlinkSync14 } from "fs";
|
|
32055
32708
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
32056
32709
|
import os22 from "os";
|
|
32057
|
-
import
|
|
32710
|
+
import path59 from "path";
|
|
32058
32711
|
function ensureDirs() {
|
|
32059
32712
|
mkdirSync23(LOCK_DIR, { recursive: true });
|
|
32060
32713
|
}
|
|
@@ -32072,9 +32725,9 @@ function isAlive(pid) {
|
|
|
32072
32725
|
}
|
|
32073
32726
|
function readJobsRaw() {
|
|
32074
32727
|
ensureDirs();
|
|
32075
|
-
if (!
|
|
32728
|
+
if (!existsSync45(JOBS_FILE)) return [];
|
|
32076
32729
|
try {
|
|
32077
|
-
const parsed = JSON.parse(
|
|
32730
|
+
const parsed = JSON.parse(readFileSync39(JOBS_FILE, "utf8"));
|
|
32078
32731
|
return Array.isArray(parsed) ? parsed : [];
|
|
32079
32732
|
} catch {
|
|
32080
32733
|
return [];
|
|
@@ -32100,14 +32753,14 @@ function listBackgroundJobs() {
|
|
|
32100
32753
|
return jobs;
|
|
32101
32754
|
}
|
|
32102
32755
|
function lockPath(type) {
|
|
32103
|
-
return
|
|
32756
|
+
return path59.join(LOCK_DIR, `${type.replace(/[^a-zA-Z0-9_.-]/g, "_")}.lock`);
|
|
32104
32757
|
}
|
|
32105
32758
|
function acquireJobLock(type, ttlMs = DEFAULT_LOCK_TTL_MS) {
|
|
32106
32759
|
ensureDirs();
|
|
32107
32760
|
const file = lockPath(type);
|
|
32108
|
-
if (
|
|
32761
|
+
if (existsSync45(file)) {
|
|
32109
32762
|
try {
|
|
32110
|
-
const lock = JSON.parse(
|
|
32763
|
+
const lock = JSON.parse(readFileSync39(file, "utf8"));
|
|
32111
32764
|
const age = Date.now() - Date.parse(lock.updatedAt ?? "");
|
|
32112
32765
|
if (lock.pid && isAlive(lock.pid) && Number.isFinite(age) && age < ttlMs) return false;
|
|
32113
32766
|
} catch {
|
|
@@ -32127,8 +32780,8 @@ function acquireJobLock(type, ttlMs = DEFAULT_LOCK_TTL_MS) {
|
|
|
32127
32780
|
function releaseJobLock(type) {
|
|
32128
32781
|
const file = lockPath(type);
|
|
32129
32782
|
try {
|
|
32130
|
-
if (!
|
|
32131
|
-
const lock = JSON.parse(
|
|
32783
|
+
if (!existsSync45(file)) return;
|
|
32784
|
+
const lock = JSON.parse(readFileSync39(file, "utf8"));
|
|
32132
32785
|
if (lock.pid === process.pid || !lock.pid || !isAlive(lock.pid)) unlinkSync14(file);
|
|
32133
32786
|
} catch {
|
|
32134
32787
|
try {
|
|
@@ -32174,9 +32827,9 @@ function startManagedJob(options) {
|
|
|
32174
32827
|
upsert({});
|
|
32175
32828
|
const timer = setInterval(() => upsert({ lastHeartbeatAt: now() }), 3e4);
|
|
32176
32829
|
timer.unref?.();
|
|
32177
|
-
const cleanup = (
|
|
32830
|
+
const cleanup = (status2, error) => {
|
|
32178
32831
|
clearInterval(timer);
|
|
32179
|
-
upsert({ status, error, lastHeartbeatAt: now() });
|
|
32832
|
+
upsert({ status: status2, error, lastHeartbeatAt: now() });
|
|
32180
32833
|
releaseJobLock(options.type);
|
|
32181
32834
|
};
|
|
32182
32835
|
process.once("SIGTERM", () => {
|
|
@@ -32327,62 +32980,14 @@ var init_background_jobs = __esm({
|
|
|
32327
32980
|
"src/lib/background-jobs.ts"() {
|
|
32328
32981
|
"use strict";
|
|
32329
32982
|
init_config();
|
|
32330
|
-
JOB_DIR =
|
|
32331
|
-
JOBS_FILE =
|
|
32332
|
-
LOCK_DIR =
|
|
32983
|
+
JOB_DIR = path59.join(EXE_AI_DIR, "jobs");
|
|
32984
|
+
JOBS_FILE = path59.join(JOB_DIR, "jobs.json");
|
|
32985
|
+
LOCK_DIR = path59.join(JOB_DIR, "locks");
|
|
32333
32986
|
DEFAULT_LOCK_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
32334
32987
|
MAX_HISTORY = 200;
|
|
32335
32988
|
}
|
|
32336
32989
|
});
|
|
32337
32990
|
|
|
32338
|
-
// src/lib/update-check.ts
|
|
32339
|
-
var update_check_exports = {};
|
|
32340
|
-
__export(update_check_exports, {
|
|
32341
|
-
checkForUpdate: () => checkForUpdate,
|
|
32342
|
-
getLocalVersion: () => getLocalVersion,
|
|
32343
|
-
getRemoteVersion: () => getRemoteVersion
|
|
32344
|
-
});
|
|
32345
|
-
import { execSync as execSync15 } from "child_process";
|
|
32346
|
-
import { readFileSync as readFileSync38 } from "fs";
|
|
32347
|
-
import path58 from "path";
|
|
32348
|
-
function getLocalVersion(packageRoot) {
|
|
32349
|
-
const pkgPath = path58.join(packageRoot, "package.json");
|
|
32350
|
-
const pkg = JSON.parse(readFileSync38(pkgPath, "utf-8"));
|
|
32351
|
-
return pkg.version;
|
|
32352
|
-
}
|
|
32353
|
-
function getRemoteVersion() {
|
|
32354
|
-
try {
|
|
32355
|
-
const output = execSync15("npm view @askexenow/exe-os version", {
|
|
32356
|
-
encoding: "utf-8",
|
|
32357
|
-
timeout: 15e3,
|
|
32358
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
32359
|
-
});
|
|
32360
|
-
return output.trim();
|
|
32361
|
-
} catch {
|
|
32362
|
-
return null;
|
|
32363
|
-
}
|
|
32364
|
-
}
|
|
32365
|
-
function checkForUpdate(packageRoot) {
|
|
32366
|
-
const localVersion = getLocalVersion(packageRoot);
|
|
32367
|
-
const remoteVersion = getRemoteVersion();
|
|
32368
|
-
if (!remoteVersion) {
|
|
32369
|
-
return {
|
|
32370
|
-
updateAvailable: false,
|
|
32371
|
-
localVersion,
|
|
32372
|
-
error: "Could not reach npm registry or package not published yet"
|
|
32373
|
-
};
|
|
32374
|
-
}
|
|
32375
|
-
if (remoteVersion === localVersion) {
|
|
32376
|
-
return { updateAvailable: false, localVersion, remoteVersion };
|
|
32377
|
-
}
|
|
32378
|
-
return { updateAvailable: true, localVersion, remoteVersion };
|
|
32379
|
-
}
|
|
32380
|
-
var init_update_check = __esm({
|
|
32381
|
-
"src/lib/update-check.ts"() {
|
|
32382
|
-
"use strict";
|
|
32383
|
-
}
|
|
32384
|
-
});
|
|
32385
|
-
|
|
32386
32991
|
// src/lib/ws-auth.ts
|
|
32387
32992
|
var ws_auth_exports = {};
|
|
32388
32993
|
__export(ws_auth_exports, {
|
|
@@ -32419,12 +33024,12 @@ __export(device_registry_exports, {
|
|
|
32419
33024
|
});
|
|
32420
33025
|
import crypto22 from "crypto";
|
|
32421
33026
|
import os23 from "os";
|
|
32422
|
-
import { readFileSync as
|
|
32423
|
-
import
|
|
33027
|
+
import { readFileSync as readFileSync40, writeFileSync as writeFileSync28, mkdirSync as mkdirSync24, existsSync as existsSync46 } from "fs";
|
|
33028
|
+
import path60 from "path";
|
|
32424
33029
|
function getDeviceInfo() {
|
|
32425
|
-
if (
|
|
33030
|
+
if (existsSync46(DEVICE_JSON_PATH)) {
|
|
32426
33031
|
try {
|
|
32427
|
-
const raw =
|
|
33032
|
+
const raw = readFileSync40(DEVICE_JSON_PATH, "utf8");
|
|
32428
33033
|
const data = JSON.parse(raw);
|
|
32429
33034
|
if (data.deviceId && data.friendlyName && data.hostname) {
|
|
32430
33035
|
return data;
|
|
@@ -32438,7 +33043,7 @@ function getDeviceInfo() {
|
|
|
32438
33043
|
friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
|
|
32439
33044
|
hostname
|
|
32440
33045
|
};
|
|
32441
|
-
mkdirSync24(
|
|
33046
|
+
mkdirSync24(path60.dirname(DEVICE_JSON_PATH), { recursive: true });
|
|
32442
33047
|
writeFileSync28(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
|
|
32443
33048
|
return info;
|
|
32444
33049
|
}
|
|
@@ -32461,11 +33066,11 @@ async function resolveTargetDevice(targetAgent, targetProject) {
|
|
|
32461
33066
|
WHERE connected = 1 AND agents LIKE ?`;
|
|
32462
33067
|
args = [`%"${targetAgent}"%`];
|
|
32463
33068
|
}
|
|
32464
|
-
const
|
|
32465
|
-
if (
|
|
32466
|
-
return
|
|
33069
|
+
const result3 = await client.execute({ sql, args });
|
|
33070
|
+
if (result3.rows.length === 1) {
|
|
33071
|
+
return result3.rows[0].device_id;
|
|
32467
33072
|
}
|
|
32468
|
-
if (
|
|
33073
|
+
if (result3.rows.length > 1) {
|
|
32469
33074
|
const sorted = await client.execute({
|
|
32470
33075
|
sql: sql + " ORDER BY last_seen DESC LIMIT 1",
|
|
32471
33076
|
args
|
|
@@ -32479,7 +33084,7 @@ var init_device_registry = __esm({
|
|
|
32479
33084
|
"src/lib/device-registry.ts"() {
|
|
32480
33085
|
"use strict";
|
|
32481
33086
|
init_config();
|
|
32482
|
-
DEVICE_JSON_PATH =
|
|
33087
|
+
DEVICE_JSON_PATH = path60.join(EXE_AI_DIR, "device.json");
|
|
32483
33088
|
}
|
|
32484
33089
|
});
|
|
32485
33090
|
|
|
@@ -32695,8 +33300,8 @@ import os24 from "os";
|
|
|
32695
33300
|
import net2 from "net";
|
|
32696
33301
|
import { createServer as createHttpServer } from "http";
|
|
32697
33302
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
32698
|
-
import { writeFileSync as writeFileSync29, unlinkSync as unlinkSync15, mkdirSync as mkdirSync25, existsSync as
|
|
32699
|
-
import
|
|
33303
|
+
import { writeFileSync as writeFileSync29, unlinkSync as unlinkSync15, mkdirSync as mkdirSync25, existsSync as existsSync47, readFileSync as readFileSync41, chmodSync as chmodSync2 } from "fs";
|
|
33304
|
+
import path61 from "path";
|
|
32700
33305
|
|
|
32701
33306
|
// src/lib/orchestration-metrics.ts
|
|
32702
33307
|
init_config();
|
|
@@ -32769,8 +33374,8 @@ function initMetrics() {
|
|
|
32769
33374
|
// src/lib/exe-daemon.ts
|
|
32770
33375
|
init_memory_write_governor();
|
|
32771
33376
|
init_mcp_transport_health();
|
|
32772
|
-
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ??
|
|
32773
|
-
var PID_PATH4 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ??
|
|
33377
|
+
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path61.join(EXE_AI_DIR, "exed.sock");
|
|
33378
|
+
var PID_PATH4 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path61.join(EXE_AI_DIR, "exed.pid");
|
|
32774
33379
|
var MODEL_FILE = "jina-embeddings-v5-small-q4_k_m.gguf";
|
|
32775
33380
|
var IDLE_TIMEOUT_MS2 = parseInt(process.env.EXE_DAEMON_IDLE_TIMEOUT_MS || "0", 10);
|
|
32776
33381
|
var REVIEW_POLL_INTERVAL_MS = 60 * 1e3;
|
|
@@ -32799,8 +33404,8 @@ function enqueue(queue, entry) {
|
|
|
32799
33404
|
queue.push(entry);
|
|
32800
33405
|
}
|
|
32801
33406
|
async function loadModel() {
|
|
32802
|
-
const modelPath =
|
|
32803
|
-
if (!
|
|
33407
|
+
const modelPath = path61.join(MODELS_DIR, MODEL_FILE);
|
|
33408
|
+
if (!existsSync47(modelPath)) {
|
|
32804
33409
|
process.stderr.write(`[exed] No model at ${modelPath} \u2014 running without embeddings (VPS mode).
|
|
32805
33410
|
`);
|
|
32806
33411
|
return;
|
|
@@ -32984,9 +33589,9 @@ async function handleDbExecute(socket, requestId, sql, args) {
|
|
|
32984
33589
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
32985
33590
|
const client = getClient2();
|
|
32986
33591
|
const deserializedArgs = deserializeArgs(args);
|
|
32987
|
-
const
|
|
33592
|
+
const result3 = await client.execute({ sql, args: deserializedArgs });
|
|
32988
33593
|
_dbRequestsServed++;
|
|
32989
|
-
sendResponse(socket, { id: requestId, db: serializeResultSet(
|
|
33594
|
+
sendResponse(socket, { id: requestId, db: serializeResultSet(result3) });
|
|
32990
33595
|
} catch (err) {
|
|
32991
33596
|
sendResponse(socket, {
|
|
32992
33597
|
id: requestId,
|
|
@@ -33241,17 +33846,17 @@ function startMemoryQueueDrain() {
|
|
|
33241
33846
|
`);
|
|
33242
33847
|
}
|
|
33243
33848
|
function startServer() {
|
|
33244
|
-
mkdirSync25(
|
|
33849
|
+
mkdirSync25(path61.dirname(SOCKET_PATH2), { recursive: true });
|
|
33245
33850
|
try {
|
|
33246
|
-
chmodSync2(
|
|
33851
|
+
chmodSync2(path61.dirname(SOCKET_PATH2), 448);
|
|
33247
33852
|
} catch {
|
|
33248
33853
|
}
|
|
33249
33854
|
_daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV2] ?? null);
|
|
33250
33855
|
for (const oldFile of ["embed.sock", "embed.pid"]) {
|
|
33251
|
-
const oldPath =
|
|
33856
|
+
const oldPath = path61.join(path61.dirname(SOCKET_PATH2), oldFile);
|
|
33252
33857
|
try {
|
|
33253
33858
|
if (oldFile.endsWith(".pid")) {
|
|
33254
|
-
const pid = parseInt(
|
|
33859
|
+
const pid = parseInt(readFileSync41(oldPath, "utf8").trim(), 10);
|
|
33255
33860
|
if (pid > 0) try {
|
|
33256
33861
|
process.kill(pid, "SIGKILL");
|
|
33257
33862
|
} catch {
|
|
@@ -33412,14 +34017,14 @@ async function startMcpHttpServer() {
|
|
|
33412
34017
|
if (typeof id === "string" || typeof id === "number") return id;
|
|
33413
34018
|
}
|
|
33414
34019
|
return "unknown";
|
|
33415
|
-
}, sendJsonRpcError2 = function(res,
|
|
33416
|
-
res.writeHead(
|
|
34020
|
+
}, sendJsonRpcError2 = function(res, status2, message, id, extra) {
|
|
34021
|
+
res.writeHead(status2, { "Content-Type": "application/json" });
|
|
33417
34022
|
res.end(JSON.stringify({
|
|
33418
34023
|
jsonrpc: "2.0",
|
|
33419
34024
|
error: { code: -32e3, message },
|
|
33420
34025
|
id
|
|
33421
34026
|
}));
|
|
33422
|
-
recordMcpHttpEvent({ level: "warn", message, status, ...extra });
|
|
34027
|
+
recordMcpHttpEvent({ level: "warn", message, status: status2, ...extra });
|
|
33423
34028
|
};
|
|
33424
34029
|
var parseDurationMs = parseDurationMs2, closeMcpSession = closeMcpSession2, sweepStaleMcpSessions = sweepStaleMcpSessions2, getJsonRpcId = getJsonRpcId2, sendJsonRpcError = sendJsonRpcError2;
|
|
33425
34030
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
@@ -33762,14 +34367,14 @@ function startConsolidation() {
|
|
|
33762
34367
|
}
|
|
33763
34368
|
process.stderr.write(`[exed] Starting consolidation (${count} unconsolidated memories)...
|
|
33764
34369
|
`);
|
|
33765
|
-
const
|
|
34370
|
+
const result3 = await runConsolidation2(client, {
|
|
33766
34371
|
model: config2.consolidationModel,
|
|
33767
34372
|
maxCalls: config2.consolidationMaxCallsPerRun,
|
|
33768
34373
|
embedFn
|
|
33769
34374
|
});
|
|
33770
34375
|
acted("consolidation");
|
|
33771
34376
|
process.stderr.write(
|
|
33772
|
-
`[exed] Consolidation complete: ${
|
|
34377
|
+
`[exed] Consolidation complete: ${result3.clustersProcessed} clusters, ${result3.memoriesConsolidated} memories consolidated
|
|
33773
34378
|
`
|
|
33774
34379
|
);
|
|
33775
34380
|
} catch (err) {
|
|
@@ -33797,14 +34402,14 @@ function startCloudSyncTimer() {
|
|
|
33797
34402
|
const config2 = await loadConfig2();
|
|
33798
34403
|
if (!config2.cloud?.apiKey || !config2.cloud?.endpoint) return;
|
|
33799
34404
|
const { cloudSync: cloudSync2 } = await Promise.resolve().then(() => (init_cloud_sync(), cloud_sync_exports));
|
|
33800
|
-
const
|
|
34405
|
+
const result3 = await cloudSync2({
|
|
33801
34406
|
apiKey: config2.cloud.apiKey,
|
|
33802
34407
|
endpoint: config2.cloud.endpoint
|
|
33803
34408
|
});
|
|
33804
|
-
if (
|
|
34409
|
+
if (result3.pushed > 0 || result3.pulled > 0) {
|
|
33805
34410
|
acted("cloud_sync");
|
|
33806
34411
|
process.stderr.write(
|
|
33807
|
-
`[exed] Cloud sync: pushed=${
|
|
34412
|
+
`[exed] Cloud sync: pushed=${result3.pushed} pulled=${result3.pulled} total=${result3.totalMemories}
|
|
33808
34413
|
`
|
|
33809
34414
|
);
|
|
33810
34415
|
}
|
|
@@ -33830,11 +34435,11 @@ function startSkillSweep() {
|
|
|
33830
34435
|
if (!process.env.ANTHROPIC_API_KEY) return;
|
|
33831
34436
|
if (!await ensureStoreForPolling()) return;
|
|
33832
34437
|
const { sweepTrajectories: sweepTrajectories2 } = await Promise.resolve().then(() => (init_skill_learning(), skill_learning_exports));
|
|
33833
|
-
const
|
|
33834
|
-
if (
|
|
34438
|
+
const result3 = await sweepTrajectories2(config2.skillThreshold, config2.skillModel);
|
|
34439
|
+
if (result3.clustersProcessed > 0) {
|
|
33835
34440
|
acted("skill_sweep");
|
|
33836
34441
|
process.stderr.write(
|
|
33837
|
-
`[exed] Skill sweep: ${
|
|
34442
|
+
`[exed] Skill sweep: ${result3.clustersProcessed} clusters processed, ${result3.skillsExtracted} skills extracted
|
|
33838
34443
|
`
|
|
33839
34444
|
);
|
|
33840
34445
|
}
|
|
@@ -33863,11 +34468,11 @@ function startGraphExtraction() {
|
|
|
33863
34468
|
const idle = await isUserIdle2(client, 30);
|
|
33864
34469
|
if (!idle) return;
|
|
33865
34470
|
const { extractBatch: extractBatch2 } = await Promise.resolve().then(() => (init_graph_rag(), graph_rag_exports));
|
|
33866
|
-
const
|
|
33867
|
-
if (
|
|
34471
|
+
const result3 = await extractBatch2(client, 50, config2.selfQueryModel);
|
|
34472
|
+
if (result3.processed > 0) {
|
|
33868
34473
|
acted("graph_extraction");
|
|
33869
34474
|
process.stderr.write(
|
|
33870
|
-
`[exed] GraphRAG: processed ${
|
|
34475
|
+
`[exed] GraphRAG: processed ${result3.processed} memories, ${result3.entities} entities, ${result3.relationships} relationships
|
|
33871
34476
|
`
|
|
33872
34477
|
);
|
|
33873
34478
|
}
|
|
@@ -33882,7 +34487,7 @@ function startGraphExtraction() {
|
|
|
33882
34487
|
`);
|
|
33883
34488
|
}
|
|
33884
34489
|
var AGENT_STATS_INTERVAL_MS = 60 * 1e3;
|
|
33885
|
-
var AGENT_STATS_PATH =
|
|
34490
|
+
var AGENT_STATS_PATH = path61.join(EXE_AI_DIR, "agent-stats.json");
|
|
33886
34491
|
async function writeAgentStats() {
|
|
33887
34492
|
fired("agent_stats");
|
|
33888
34493
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -33890,7 +34495,7 @@ async function writeAgentStats() {
|
|
|
33890
34495
|
acted("agent_stats");
|
|
33891
34496
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
33892
34497
|
const client = getClient2();
|
|
33893
|
-
const
|
|
34498
|
+
const result3 = await client.execute({
|
|
33894
34499
|
sql: `SELECT agent_id,
|
|
33895
34500
|
COUNT(*) as total,
|
|
33896
34501
|
SUM(CASE WHEN timestamp > datetime('now', '-1 day') THEN 1 ELSE 0 END) as growth_24h,
|
|
@@ -33902,7 +34507,7 @@ async function writeAgentStats() {
|
|
|
33902
34507
|
ORDER BY total DESC`,
|
|
33903
34508
|
args: []
|
|
33904
34509
|
});
|
|
33905
|
-
const agentsBase =
|
|
34510
|
+
const agentsBase = result3.rows.map((row) => ({
|
|
33906
34511
|
id: row.agent_id,
|
|
33907
34512
|
total: Number(row.total),
|
|
33908
34513
|
growth24h: Number(row.growth_24h),
|
|
@@ -33963,7 +34568,7 @@ function startConfidenceDecay() {
|
|
|
33963
34568
|
try {
|
|
33964
34569
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
33965
34570
|
const client = getClient2();
|
|
33966
|
-
const
|
|
34571
|
+
const result3 = await client.execute({
|
|
33967
34572
|
sql: `UPDATE memories
|
|
33968
34573
|
SET confidence = MAX(0.3, COALESCE(confidence, 0.7) - 0.01)
|
|
33969
34574
|
WHERE COALESCE(last_accessed, timestamp) < datetime('now', '-30 days')
|
|
@@ -33971,7 +34576,7 @@ function startConfidenceDecay() {
|
|
|
33971
34576
|
AND COALESCE(status, 'active') = 'active'`,
|
|
33972
34577
|
args: []
|
|
33973
34578
|
});
|
|
33974
|
-
const affected =
|
|
34579
|
+
const affected = result3.rowsAffected;
|
|
33975
34580
|
if (affected > 0) {
|
|
33976
34581
|
acted("confidence_decay");
|
|
33977
34582
|
process.stderr.write(`[exed] Confidence decay: ${affected} memories decayed
|
|
@@ -34024,11 +34629,11 @@ function startSoftDeletePurge() {
|
|
|
34024
34629
|
const { SOFT_DELETE_RETENTION_DAYS: SOFT_DELETE_RETENTION_DAYS2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
34025
34630
|
const client = getClient2();
|
|
34026
34631
|
const cutoffDate = new Date(Date.now() - SOFT_DELETE_RETENTION_DAYS2 * 24 * 60 * 60 * 1e3).toISOString();
|
|
34027
|
-
const
|
|
34632
|
+
const result3 = await client.execute({
|
|
34028
34633
|
sql: `SELECT COUNT(*) as cnt FROM memories WHERE status = 'deleted' AND deleted_at IS NOT NULL AND deleted_at < ?`,
|
|
34029
34634
|
args: [cutoffDate]
|
|
34030
34635
|
});
|
|
34031
|
-
const count = Number(
|
|
34636
|
+
const count = Number(result3.rows[0]?.cnt ?? 0);
|
|
34032
34637
|
if (count === 0) return;
|
|
34033
34638
|
await client.execute({
|
|
34034
34639
|
sql: `DELETE FROM memories WHERE status = 'deleted' AND deleted_at IS NOT NULL AND deleted_at < ?`,
|
|
@@ -34059,17 +34664,17 @@ function startIntercomQueueDrain() {
|
|
|
34059
34664
|
const hasInProgressTask = (session) => {
|
|
34060
34665
|
try {
|
|
34061
34666
|
const { baseAgentName: ban } = (init_employees(), __toCommonJS(employees_exports));
|
|
34062
|
-
const
|
|
34063
|
-
const { existsSync:
|
|
34667
|
+
const path62 = __require("path");
|
|
34668
|
+
const { existsSync: existsSync48 } = __require("fs");
|
|
34064
34669
|
const os25 = __require("os");
|
|
34065
34670
|
const agent = ban(session.split("-")[0] ?? session);
|
|
34066
|
-
const markerPath =
|
|
34067
|
-
return
|
|
34671
|
+
const markerPath = path62.join(os25.homedir(), ".exe-os", "session-cache", `current-task-${agent}.json`);
|
|
34672
|
+
return existsSync48(markerPath);
|
|
34068
34673
|
} catch {
|
|
34069
34674
|
return false;
|
|
34070
34675
|
}
|
|
34071
34676
|
};
|
|
34072
|
-
const
|
|
34677
|
+
const result3 = drainQueue3(
|
|
34073
34678
|
(session) => isSessionBusy2(session) || hasInProgressTask(session),
|
|
34074
34679
|
(session) => {
|
|
34075
34680
|
try {
|
|
@@ -34094,10 +34699,10 @@ function startIntercomQueueDrain() {
|
|
|
34094
34699
|
}
|
|
34095
34700
|
}
|
|
34096
34701
|
);
|
|
34097
|
-
if (
|
|
34702
|
+
if (result3.drained > 0 || result3.failed > 0) {
|
|
34098
34703
|
acted("intercom_queue_drain");
|
|
34099
34704
|
process.stderr.write(
|
|
34100
|
-
`[exed] Intercom queue: ${
|
|
34705
|
+
`[exed] Intercom queue: ${result3.drained} drained, ${result3.failed} failed
|
|
34101
34706
|
`
|
|
34102
34707
|
);
|
|
34103
34708
|
}
|
|
@@ -34276,8 +34881,8 @@ process.on("SIGINT", handleSignalShutdown);
|
|
|
34276
34881
|
process.on("SIGTERM", handleSignalShutdown);
|
|
34277
34882
|
function checkExistingDaemon() {
|
|
34278
34883
|
try {
|
|
34279
|
-
if (!
|
|
34280
|
-
const pid = parseInt(
|
|
34884
|
+
if (!existsSync47(PID_PATH4)) return false;
|
|
34885
|
+
const pid = parseInt(readFileSync41(PID_PATH4, "utf8").trim(), 10);
|
|
34281
34886
|
if (!pid || isNaN(pid)) return false;
|
|
34282
34887
|
if (pid === process.pid) {
|
|
34283
34888
|
try {
|
|
@@ -34313,22 +34918,22 @@ function startAutoUpdateCheck() {
|
|
|
34313
34918
|
if (!autoInstall && !config2.autoUpdate.checkOnBoot) return;
|
|
34314
34919
|
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update_check(), update_check_exports));
|
|
34315
34920
|
const packageRoot = new URL("../..", import.meta.url).pathname;
|
|
34316
|
-
const
|
|
34317
|
-
if (!
|
|
34921
|
+
const result3 = checkForUpdate2(packageRoot);
|
|
34922
|
+
if (!result3.updateAvailable) return;
|
|
34318
34923
|
acted("auto_update_check");
|
|
34319
34924
|
process.stderr.write(
|
|
34320
|
-
`[exed] Update available: v${
|
|
34925
|
+
`[exed] Update available: v${result3.localVersion} \u2192 v${result3.remoteVersion}
|
|
34321
34926
|
`
|
|
34322
34927
|
);
|
|
34323
34928
|
if (autoInstall) {
|
|
34324
34929
|
process.stderr.write("[exed] Auto-installing update...\n");
|
|
34325
|
-
const { execSync:
|
|
34326
|
-
|
|
34930
|
+
const { execSync: execSync17 } = await import("child_process");
|
|
34931
|
+
execSync17("npm install -g @askexenow/exe-os@latest", {
|
|
34327
34932
|
timeout: 12e4,
|
|
34328
34933
|
stdio: ["pipe", "pipe", "pipe"]
|
|
34329
34934
|
});
|
|
34330
34935
|
process.stderr.write(
|
|
34331
|
-
`[exed] Updated to v${
|
|
34936
|
+
`[exed] Updated to v${result3.remoteVersion}. Restart daemon to apply.
|
|
34332
34937
|
`
|
|
34333
34938
|
);
|
|
34334
34939
|
}
|