@askexenow/exe-os 0.8.0 → 0.8.1
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/README.md +178 -79
- package/dist/bin/backfill-responses.js +160 -8
- package/dist/bin/backfill-vectors.js +130 -1
- package/dist/bin/cleanup-stale-review-tasks.js +130 -1
- package/dist/bin/cli.js +10111 -7540
- package/dist/bin/exe-agent.js +159 -1
- package/dist/bin/exe-assign.js +235 -16
- package/dist/bin/exe-boot.js +344 -472
- package/dist/bin/exe-call.js +145 -1
- package/dist/bin/exe-cloud.js +11 -0
- package/dist/bin/exe-dispatch.js +37 -24
- package/dist/bin/exe-doctor.js +130 -1
- package/dist/bin/exe-export-behaviors.js +150 -7
- package/dist/bin/exe-forget.js +822 -665
- package/dist/bin/exe-gateway.js +470 -62
- package/dist/bin/exe-heartbeat.js +133 -2
- package/dist/bin/exe-kill.js +150 -7
- package/dist/bin/exe-launch-agent.js +150 -7
- package/dist/bin/exe-new-employee.js +756 -224
- package/dist/bin/exe-pending-messages.js +132 -2
- package/dist/bin/exe-pending-notifications.js +130 -1
- package/dist/bin/exe-pending-reviews.js +132 -2
- package/dist/bin/exe-review.js +160 -8
- package/dist/bin/exe-search.js +2473 -2008
- package/dist/bin/exe-session-cleanup.js +238 -51
- package/dist/bin/exe-settings.js +11 -0
- package/dist/bin/exe-status.js +130 -1
- package/dist/bin/exe-team.js +130 -1
- package/dist/bin/git-sweep.js +272 -16
- package/dist/bin/graph-backfill.js +150 -7
- package/dist/bin/graph-export.js +150 -7
- package/dist/bin/install.js +5 -0
- package/dist/bin/scan-tasks.js +238 -19
- package/dist/bin/setup.js +1776 -10
- package/dist/bin/shard-migrate.js +150 -7
- package/dist/bin/update.js +9 -6
- package/dist/bin/wiki-sync.js +150 -7
- package/dist/gateway/index.js +470 -62
- package/dist/hooks/bug-report-worker.js +195 -35
- package/dist/hooks/commit-complete.js +272 -16
- package/dist/hooks/error-recall.js +2313 -1847
- package/dist/hooks/exe-heartbeat-hook.js +5 -0
- package/dist/hooks/ingest-worker.js +330 -58
- package/dist/hooks/ingest.js +11 -0
- package/dist/hooks/instructions-loaded.js +199 -10
- package/dist/hooks/notification.js +199 -10
- package/dist/hooks/post-compact.js +199 -10
- package/dist/hooks/pre-compact.js +199 -10
- package/dist/hooks/pre-tool-use.js +199 -10
- package/dist/hooks/prompt-ingest-worker.js +179 -14
- package/dist/hooks/prompt-submit.js +781 -285
- package/dist/hooks/response-ingest-worker.js +1900 -1405
- package/dist/hooks/session-end.js +456 -12
- package/dist/hooks/session-start.js +2188 -1724
- package/dist/hooks/stop.js +200 -10
- package/dist/hooks/subagent-stop.js +199 -10
- package/dist/hooks/summary-worker.js +604 -334
- package/dist/index.js +554 -61
- package/dist/lib/cloud-sync.js +5 -0
- package/dist/lib/config.js +13 -0
- package/dist/lib/consolidation.js +5 -0
- package/dist/lib/database.js +104 -0
- package/dist/lib/device-registry.js +109 -0
- package/dist/lib/embedder.js +13 -0
- package/dist/lib/employee-templates.js +53 -26
- package/dist/lib/employees.js +5 -0
- package/dist/lib/exe-daemon-client.js +5 -0
- package/dist/lib/exe-daemon.js +493 -79
- package/dist/lib/file-grep.js +20 -4
- package/dist/lib/hybrid-search.js +1435 -190
- package/dist/lib/identity-templates.js +126 -5
- package/dist/lib/identity.js +5 -0
- package/dist/lib/license.js +5 -0
- package/dist/lib/messaging.js +37 -24
- package/dist/lib/schedules.js +130 -1
- package/dist/lib/skill-learning.js +11 -0
- package/dist/lib/status-brief.js +5 -0
- package/dist/lib/store.js +199 -10
- package/dist/lib/task-router.js +72 -6
- package/dist/lib/tasks.js +179 -50
- package/dist/lib/tmux-routing.js +179 -46
- package/dist/mcp/server.js +2129 -1855
- package/dist/mcp/tools/create-task.js +86 -36
- package/dist/mcp/tools/deactivate-behavior.js +5 -0
- package/dist/mcp/tools/list-tasks.js +39 -11
- package/dist/mcp/tools/send-message.js +37 -24
- package/dist/mcp/tools/update-task.js +153 -38
- package/dist/runtime/index.js +451 -59
- package/dist/tui/App.js +454 -59
- package/package.json +1 -1
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -236,6 +236,27 @@ async function ensureSchema() {
|
|
|
236
236
|
});
|
|
237
237
|
} catch {
|
|
238
238
|
}
|
|
239
|
+
try {
|
|
240
|
+
await client.execute({
|
|
241
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
242
|
+
args: []
|
|
243
|
+
});
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await client.execute({
|
|
248
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
249
|
+
args: []
|
|
250
|
+
});
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
await client.execute({
|
|
255
|
+
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
256
|
+
args: []
|
|
257
|
+
});
|
|
258
|
+
} catch {
|
|
259
|
+
}
|
|
239
260
|
try {
|
|
240
261
|
await client.execute({
|
|
241
262
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
@@ -646,6 +667,15 @@ async function ensureSchema() {
|
|
|
646
667
|
} catch {
|
|
647
668
|
}
|
|
648
669
|
}
|
|
670
|
+
for (const col of [
|
|
671
|
+
"ALTER TABLE memories ADD COLUMN source_path TEXT",
|
|
672
|
+
"ALTER TABLE memories ADD COLUMN source_type TEXT DEFAULT 'text'"
|
|
673
|
+
]) {
|
|
674
|
+
try {
|
|
675
|
+
await client.execute(col);
|
|
676
|
+
} catch {
|
|
677
|
+
}
|
|
678
|
+
}
|
|
649
679
|
await client.executeMultiple(`
|
|
650
680
|
CREATE INDEX IF NOT EXISTS idx_memories_workspace
|
|
651
681
|
ON memories(workspace_id);
|
|
@@ -710,6 +740,34 @@ async function ensureSchema() {
|
|
|
710
740
|
CREATE INDEX IF NOT EXISTS idx_conversations_channel
|
|
711
741
|
ON conversations(channel_id);
|
|
712
742
|
`);
|
|
743
|
+
try {
|
|
744
|
+
await client.execute({
|
|
745
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
746
|
+
args: []
|
|
747
|
+
});
|
|
748
|
+
} catch {
|
|
749
|
+
}
|
|
750
|
+
try {
|
|
751
|
+
await client.execute({
|
|
752
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
753
|
+
args: []
|
|
754
|
+
});
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
757
|
+
try {
|
|
758
|
+
await client.execute({
|
|
759
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
760
|
+
args: []
|
|
761
|
+
});
|
|
762
|
+
} catch {
|
|
763
|
+
}
|
|
764
|
+
try {
|
|
765
|
+
await client.execute({
|
|
766
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
767
|
+
args: []
|
|
768
|
+
});
|
|
769
|
+
} catch {
|
|
770
|
+
}
|
|
713
771
|
await client.executeMultiple(`
|
|
714
772
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
715
773
|
content_text,
|
|
@@ -736,6 +794,52 @@ async function ensureSchema() {
|
|
|
736
794
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
737
795
|
END;
|
|
738
796
|
`);
|
|
797
|
+
try {
|
|
798
|
+
await client.execute({
|
|
799
|
+
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
800
|
+
args: []
|
|
801
|
+
});
|
|
802
|
+
} catch {
|
|
803
|
+
}
|
|
804
|
+
try {
|
|
805
|
+
await client.execute(
|
|
806
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
807
|
+
);
|
|
808
|
+
} catch {
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
await client.execute({
|
|
812
|
+
sql: `UPDATE memories SET tier = 1 WHERE tool_name = 'commit_to_long_term_memory' AND importance >= 8 AND tier = 3`,
|
|
813
|
+
args: []
|
|
814
|
+
});
|
|
815
|
+
await client.execute({
|
|
816
|
+
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
817
|
+
args: []
|
|
818
|
+
});
|
|
819
|
+
} catch {
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
await client.execute({
|
|
823
|
+
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
824
|
+
args: []
|
|
825
|
+
});
|
|
826
|
+
} catch {
|
|
827
|
+
}
|
|
828
|
+
try {
|
|
829
|
+
await client.execute(
|
|
830
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
831
|
+
);
|
|
832
|
+
} catch {
|
|
833
|
+
}
|
|
834
|
+
for (const col of [
|
|
835
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
836
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER DEFAULT 0"
|
|
837
|
+
]) {
|
|
838
|
+
try {
|
|
839
|
+
await client.execute(col);
|
|
840
|
+
} catch {
|
|
841
|
+
}
|
|
842
|
+
}
|
|
739
843
|
}
|
|
740
844
|
async function disposeDatabase() {
|
|
741
845
|
if (_client) {
|
|
@@ -877,6 +981,11 @@ function normalizeSessionLifecycle(raw) {
|
|
|
877
981
|
const userSL = raw.sessionLifecycle ?? {};
|
|
878
982
|
raw.sessionLifecycle = { ...defaultSL, ...userSL };
|
|
879
983
|
}
|
|
984
|
+
function normalizeAutoUpdate(raw) {
|
|
985
|
+
const defaultAU = DEFAULT_CONFIG.autoUpdate;
|
|
986
|
+
const userAU = raw.autoUpdate ?? {};
|
|
987
|
+
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
988
|
+
}
|
|
880
989
|
async function loadConfig() {
|
|
881
990
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
882
991
|
await mkdir2(dir, { recursive: true });
|
|
@@ -899,6 +1008,7 @@ async function loadConfig() {
|
|
|
899
1008
|
}
|
|
900
1009
|
normalizeScalingRoadmap(migratedCfg);
|
|
901
1010
|
normalizeSessionLifecycle(migratedCfg);
|
|
1011
|
+
normalizeAutoUpdate(migratedCfg);
|
|
902
1012
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
903
1013
|
if (config.dbPath.startsWith("~")) {
|
|
904
1014
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -974,6 +1084,11 @@ var init_config = __esm({
|
|
|
974
1084
|
idleKillTicksRequired: 3,
|
|
975
1085
|
idleKillIntercomAckWindowMs: 1e4,
|
|
976
1086
|
maxAutoInstances: 10
|
|
1087
|
+
},
|
|
1088
|
+
autoUpdate: {
|
|
1089
|
+
checkOnBoot: true,
|
|
1090
|
+
autoInstall: false,
|
|
1091
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
977
1092
|
}
|
|
978
1093
|
};
|
|
979
1094
|
CONFIG_MIGRATIONS = [
|
|
@@ -1107,13 +1222,27 @@ async function ensureShardSchema(client) {
|
|
|
1107
1222
|
"ALTER TABLE memories ADD COLUMN document_id TEXT",
|
|
1108
1223
|
"ALTER TABLE memories ADD COLUMN user_id TEXT",
|
|
1109
1224
|
"ALTER TABLE memories ADD COLUMN char_offset INTEGER",
|
|
1110
|
-
"ALTER TABLE memories ADD COLUMN page_number INTEGER"
|
|
1225
|
+
"ALTER TABLE memories ADD COLUMN page_number INTEGER",
|
|
1226
|
+
// Source provenance columns (must match database.ts)
|
|
1227
|
+
"ALTER TABLE memories ADD COLUMN source_path TEXT",
|
|
1228
|
+
"ALTER TABLE memories ADD COLUMN source_type TEXT DEFAULT 'text'",
|
|
1229
|
+
"ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3",
|
|
1230
|
+
"ALTER TABLE memories ADD COLUMN supersedes_id TEXT"
|
|
1111
1231
|
]) {
|
|
1112
1232
|
try {
|
|
1113
1233
|
await client.execute(col);
|
|
1114
1234
|
} catch {
|
|
1115
1235
|
}
|
|
1116
1236
|
}
|
|
1237
|
+
for (const idx of [
|
|
1238
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)",
|
|
1239
|
+
"CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL"
|
|
1240
|
+
]) {
|
|
1241
|
+
try {
|
|
1242
|
+
await client.execute(idx);
|
|
1243
|
+
} catch {
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1117
1246
|
try {
|
|
1118
1247
|
await client.execute("CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)");
|
|
1119
1248
|
} catch {
|
|
@@ -1222,8 +1351,11 @@ var store_exports = {};
|
|
|
1222
1351
|
__export(store_exports, {
|
|
1223
1352
|
attachDocumentMetadata: () => attachDocumentMetadata,
|
|
1224
1353
|
buildWikiScopeFilter: () => buildWikiScopeFilter,
|
|
1354
|
+
classifyTier: () => classifyTier,
|
|
1225
1355
|
disposeStore: () => disposeStore,
|
|
1226
1356
|
flushBatch: () => flushBatch,
|
|
1357
|
+
flushTier3: () => flushTier3,
|
|
1358
|
+
getMemoryCardinality: () => getMemoryCardinality,
|
|
1227
1359
|
initStore: () => initStore,
|
|
1228
1360
|
reserveVersions: () => reserveVersions,
|
|
1229
1361
|
searchMemories: () => searchMemories,
|
|
@@ -1269,6 +1401,11 @@ async function initStore(options) {
|
|
|
1269
1401
|
const vResult = await client.execute("SELECT MAX(version) as max_v FROM memories");
|
|
1270
1402
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1271
1403
|
}
|
|
1404
|
+
function classifyTier(record) {
|
|
1405
|
+
if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
|
|
1406
|
+
if (["store_memory", "manual"].includes(record.tool_name ?? "") && (record.importance ?? 0) >= 5) return 2;
|
|
1407
|
+
return 3;
|
|
1408
|
+
}
|
|
1272
1409
|
async function writeMemory(record) {
|
|
1273
1410
|
if (record.vector !== null && record.vector.length !== EMBEDDING_DIM) {
|
|
1274
1411
|
throw new Error(
|
|
@@ -1296,7 +1433,11 @@ async function writeMemory(record) {
|
|
|
1296
1433
|
document_id: record.document_id ?? null,
|
|
1297
1434
|
user_id: record.user_id ?? null,
|
|
1298
1435
|
char_offset: record.char_offset ?? null,
|
|
1299
|
-
page_number: record.page_number ?? null
|
|
1436
|
+
page_number: record.page_number ?? null,
|
|
1437
|
+
source_path: record.source_path ?? null,
|
|
1438
|
+
source_type: record.source_type ?? null,
|
|
1439
|
+
tier: record.tier ?? classifyTier(record),
|
|
1440
|
+
supersedes_id: record.supersedes_id ?? null
|
|
1300
1441
|
};
|
|
1301
1442
|
_pendingRecords.push(dbRow);
|
|
1302
1443
|
if (_flushTimer === null) {
|
|
@@ -1328,20 +1469,26 @@ async function flushBatch() {
|
|
|
1328
1469
|
const userId = row.user_id ?? null;
|
|
1329
1470
|
const charOffset = row.char_offset ?? null;
|
|
1330
1471
|
const pageNumber = row.page_number ?? null;
|
|
1472
|
+
const sourcePath = row.source_path ?? null;
|
|
1473
|
+
const sourceType = row.source_type ?? null;
|
|
1474
|
+
const tier = row.tier ?? 3;
|
|
1475
|
+
const supersedesId = row.supersedes_id ?? null;
|
|
1331
1476
|
return {
|
|
1332
1477
|
sql: hasVector ? `INSERT OR IGNORE INTO memories
|
|
1333
1478
|
(id, agent_id, agent_role, session_id, timestamp,
|
|
1334
1479
|
tool_name, project_name,
|
|
1335
1480
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
1336
1481
|
confidence, last_accessed,
|
|
1337
|
-
workspace_id, document_id, user_id, char_offset, page_number
|
|
1338
|
-
|
|
1482
|
+
workspace_id, document_id, user_id, char_offset, page_number,
|
|
1483
|
+
source_path, source_type, tier, supersedes_id)
|
|
1484
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories
|
|
1339
1485
|
(id, agent_id, agent_role, session_id, timestamp,
|
|
1340
1486
|
tool_name, project_name,
|
|
1341
1487
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
1342
1488
|
confidence, last_accessed,
|
|
1343
|
-
workspace_id, document_id, user_id, char_offset, page_number
|
|
1344
|
-
|
|
1489
|
+
workspace_id, document_id, user_id, char_offset, page_number,
|
|
1490
|
+
source_path, source_type, tier, supersedes_id)
|
|
1491
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
1345
1492
|
args: hasVector ? [
|
|
1346
1493
|
row.id,
|
|
1347
1494
|
row.agent_id,
|
|
@@ -1363,7 +1510,11 @@ async function flushBatch() {
|
|
|
1363
1510
|
documentId,
|
|
1364
1511
|
userId,
|
|
1365
1512
|
charOffset,
|
|
1366
|
-
pageNumber
|
|
1513
|
+
pageNumber,
|
|
1514
|
+
sourcePath,
|
|
1515
|
+
sourceType,
|
|
1516
|
+
tier,
|
|
1517
|
+
supersedesId
|
|
1367
1518
|
] : [
|
|
1368
1519
|
row.id,
|
|
1369
1520
|
row.agent_id,
|
|
@@ -1384,7 +1535,11 @@ async function flushBatch() {
|
|
|
1384
1535
|
documentId,
|
|
1385
1536
|
userId,
|
|
1386
1537
|
charOffset,
|
|
1387
|
-
pageNumber
|
|
1538
|
+
pageNumber,
|
|
1539
|
+
sourcePath,
|
|
1540
|
+
sourceType,
|
|
1541
|
+
tier,
|
|
1542
|
+
supersedesId
|
|
1388
1543
|
]
|
|
1389
1544
|
};
|
|
1390
1545
|
};
|
|
@@ -1458,7 +1613,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
1458
1613
|
has_error, raw_text, vector, importance, status,
|
|
1459
1614
|
confidence, last_accessed,
|
|
1460
1615
|
workspace_id, document_id, user_id,
|
|
1461
|
-
char_offset, page_number
|
|
1616
|
+
char_offset, page_number,
|
|
1617
|
+
source_path, source_type
|
|
1462
1618
|
FROM memories
|
|
1463
1619
|
WHERE agent_id = ?
|
|
1464
1620
|
AND vector IS NOT NULL${statusFilter}
|
|
@@ -1507,7 +1663,9 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
1507
1663
|
document_id: row.document_id ?? null,
|
|
1508
1664
|
user_id: row.user_id ?? null,
|
|
1509
1665
|
char_offset: row.char_offset ?? null,
|
|
1510
|
-
page_number: row.page_number ?? null
|
|
1666
|
+
page_number: row.page_number ?? null,
|
|
1667
|
+
source_path: row.source_path ?? null,
|
|
1668
|
+
source_type: row.source_type ?? null
|
|
1511
1669
|
}));
|
|
1512
1670
|
}
|
|
1513
1671
|
async function attachDocumentMetadata(records) {
|
|
@@ -1545,6 +1703,25 @@ async function attachDocumentMetadata(records) {
|
|
|
1545
1703
|
}
|
|
1546
1704
|
return records;
|
|
1547
1705
|
}
|
|
1706
|
+
async function flushTier3(agentId, options) {
|
|
1707
|
+
const client = getClient();
|
|
1708
|
+
const maxAge = options?.maxAgeHours ?? 72;
|
|
1709
|
+
const cutoff = new Date(Date.now() - maxAge * 36e5).toISOString();
|
|
1710
|
+
if (options?.dryRun) {
|
|
1711
|
+
const result2 = await client.execute({
|
|
1712
|
+
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
1713
|
+
WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
|
|
1714
|
+
args: [agentId, cutoff]
|
|
1715
|
+
});
|
|
1716
|
+
return { archived: Number(result2.rows[0]?.cnt ?? 0) };
|
|
1717
|
+
}
|
|
1718
|
+
const result = await client.execute({
|
|
1719
|
+
sql: `UPDATE memories SET status = 'archived'
|
|
1720
|
+
WHERE agent_id = ? AND tier = 3 AND status = 'active' AND timestamp < ?`,
|
|
1721
|
+
args: [agentId, cutoff]
|
|
1722
|
+
});
|
|
1723
|
+
return { archived: result.rowsAffected };
|
|
1724
|
+
}
|
|
1548
1725
|
async function disposeStore() {
|
|
1549
1726
|
if (_flushTimer !== null) {
|
|
1550
1727
|
clearInterval(_flushTimer);
|
|
@@ -1575,6 +1752,18 @@ function reserveVersions(count) {
|
|
|
1575
1752
|
}
|
|
1576
1753
|
return reserved;
|
|
1577
1754
|
}
|
|
1755
|
+
async function getMemoryCardinality(agentId) {
|
|
1756
|
+
try {
|
|
1757
|
+
const client = getClient();
|
|
1758
|
+
const result = await client.execute({
|
|
1759
|
+
sql: `SELECT COUNT(*) as cnt FROM memories WHERE agent_id = ? AND COALESCE(status, 'active') = 'active'`,
|
|
1760
|
+
args: [agentId]
|
|
1761
|
+
});
|
|
1762
|
+
return Number(result.rows[0]?.cnt) || 0;
|
|
1763
|
+
} catch {
|
|
1764
|
+
return 0;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1578
1767
|
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1579
1768
|
var init_store = __esm({
|
|
1580
1769
|
"src/lib/store.ts"() {
|
|
@@ -1604,12 +1793,23 @@ function getProjectName(cwd) {
|
|
|
1604
1793
|
const dir = cwd ?? process.cwd();
|
|
1605
1794
|
if (_cached && _cachedCwd === dir) return _cached;
|
|
1606
1795
|
try {
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1796
|
+
let repoRoot;
|
|
1797
|
+
try {
|
|
1798
|
+
const gitCommonDir = execSync("git rev-parse --path-format=absolute --git-common-dir", {
|
|
1799
|
+
cwd: dir,
|
|
1800
|
+
encoding: "utf8",
|
|
1801
|
+
timeout: 2e3,
|
|
1802
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1803
|
+
}).trim();
|
|
1804
|
+
repoRoot = path4.dirname(gitCommonDir);
|
|
1805
|
+
} catch {
|
|
1806
|
+
repoRoot = execSync("git rev-parse --show-toplevel", {
|
|
1807
|
+
cwd: dir,
|
|
1808
|
+
encoding: "utf8",
|
|
1809
|
+
timeout: 2e3,
|
|
1810
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1811
|
+
}).trim();
|
|
1812
|
+
}
|
|
1613
1813
|
_cached = path4.basename(repoRoot);
|
|
1614
1814
|
_cachedCwd = dir;
|
|
1615
1815
|
return _cached;
|
|
@@ -1686,10 +1886,10 @@ async function scanFromDb(agentId, tmuxSession, projectName) {
|
|
|
1686
1886
|
} catch {
|
|
1687
1887
|
}
|
|
1688
1888
|
}
|
|
1689
|
-
const sql = resolvedProject ? `SELECT id, title, priority, status, assigned_tmux FROM tasks
|
|
1889
|
+
const sql = resolvedProject ? `SELECT id, title, priority, status, assigned_tmux, checkpoint, checkpoint_count FROM tasks
|
|
1690
1890
|
WHERE assigned_to = ? AND project_name = ? AND status IN ('open', 'in_progress', 'blocked', 'needs_review')
|
|
1691
1891
|
ORDER BY CASE status WHEN 'in_progress' THEN 0 WHEN 'open' THEN 1 WHEN 'blocked' THEN 2 ELSE 3 END,
|
|
1692
|
-
priority ASC, created_at DESC` : `SELECT id, title, priority, status, assigned_tmux FROM tasks
|
|
1892
|
+
priority ASC, created_at DESC` : `SELECT id, title, priority, status, assigned_tmux, checkpoint, checkpoint_count FROM tasks
|
|
1693
1893
|
WHERE assigned_to = ? AND status IN ('open', 'in_progress', 'blocked', 'needs_review')
|
|
1694
1894
|
ORDER BY CASE status WHEN 'in_progress' THEN 0 WHEN 'open' THEN 1 WHEN 'blocked' THEN 2 ELSE 3 END,
|
|
1695
1895
|
priority ASC, created_at DESC`;
|
|
@@ -1705,7 +1905,9 @@ async function scanFromDb(agentId, tmuxSession, projectName) {
|
|
|
1705
1905
|
id: String(row.id),
|
|
1706
1906
|
title: String(row.title),
|
|
1707
1907
|
priority: String(row.priority),
|
|
1708
|
-
status
|
|
1908
|
+
status,
|
|
1909
|
+
checkpoint: row.checkpoint == null ? null : String(row.checkpoint),
|
|
1910
|
+
checkpointCount: Number(row.checkpoint_count ?? 0)
|
|
1709
1911
|
};
|
|
1710
1912
|
if (status === "in_progress") {
|
|
1711
1913
|
if (claimedBy && claimedBy !== "unknown" && tmuxSession) {
|
|
@@ -1748,6 +1950,23 @@ function formatMandatory(_agentId, result) {
|
|
|
1748
1950
|
if (inProgress.length > 0) {
|
|
1749
1951
|
const current = inProgress[0];
|
|
1750
1952
|
lines.push(`Continue working on: ${current.title} [${current.priority}]`);
|
|
1953
|
+
if (current.checkpoint) {
|
|
1954
|
+
try {
|
|
1955
|
+
const cp = JSON.parse(current.checkpoint);
|
|
1956
|
+
lines.push("");
|
|
1957
|
+
lines.push("CRASH RECOVERY \u2014 Last checkpoint:");
|
|
1958
|
+
lines.push(` Step: ${cp.step}`);
|
|
1959
|
+
lines.push(` Summary: ${cp.context_summary}`);
|
|
1960
|
+
if (cp.files_touched.length > 0) {
|
|
1961
|
+
lines.push(` Files touched: ${cp.files_touched.join(", ")}`);
|
|
1962
|
+
}
|
|
1963
|
+
lines.push(` Checkpointed at: ${cp.last_checkpoint_at}`);
|
|
1964
|
+
lines.push(` Total checkpoints: ${current.checkpointCount ?? "?"}`);
|
|
1965
|
+
lines.push("");
|
|
1966
|
+
lines.push("Resume from where you left off. Do NOT restart from scratch.");
|
|
1967
|
+
} catch {
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1751
1970
|
lines.push(`Use get_task to read the full task context.`);
|
|
1752
1971
|
if (open.length > 0) {
|
|
1753
1972
|
lines.push("Queued: " + open.map((t) => `${t.title} [${t.priority}]`).join(", "));
|