@askexenow/exe-os 0.9.102 → 0.9.104
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/agentic-ontology-backfill.js +334 -100
- package/dist/bin/agentic-reflection-backfill.js +328 -97
- package/dist/bin/agentic-semantic-label.js +328 -97
- package/dist/bin/backfill-conversations.js +332 -97
- package/dist/bin/backfill-responses.js +332 -97
- package/dist/bin/backfill-vectors.js +337 -106
- package/dist/bin/bulk-sync-postgres.js +335 -101
- package/dist/bin/cleanup-stale-review-tasks.js +356 -108
- package/dist/bin/cli.js +653 -405
- package/dist/bin/exe-agent.js +21 -3
- package/dist/bin/exe-assign.js +338 -94
- package/dist/bin/exe-boot.js +472 -239
- package/dist/bin/exe-call.js +22 -5
- package/dist/bin/exe-cloud.js +404 -158
- package/dist/bin/exe-dispatch.js +390 -142
- package/dist/bin/exe-doctor.js +349 -103
- package/dist/bin/exe-export-behaviors.js +351 -105
- package/dist/bin/exe-forget.js +352 -103
- package/dist/bin/exe-gateway.js +420 -172
- package/dist/bin/exe-heartbeat.js +361 -113
- package/dist/bin/exe-kill.js +344 -98
- package/dist/bin/exe-launch-agent.js +375 -129
- package/dist/bin/exe-new-employee.js +83 -67
- package/dist/bin/exe-pending-messages.js +356 -108
- package/dist/bin/exe-pending-notifications.js +358 -110
- package/dist/bin/exe-pending-reviews.js +359 -111
- package/dist/bin/exe-rename.js +354 -108
- package/dist/bin/exe-review.js +343 -97
- package/dist/bin/exe-search.js +363 -113
- package/dist/bin/exe-session-cleanup.js +403 -155
- package/dist/bin/exe-settings.js +14 -9
- package/dist/bin/exe-start-codex.js +365 -131
- package/dist/bin/exe-start-opencode.js +359 -125
- package/dist/bin/exe-status.js +356 -108
- package/dist/bin/exe-team.js +343 -97
- package/dist/bin/git-sweep.js +390 -142
- package/dist/bin/graph-backfill.js +334 -100
- package/dist/bin/graph-export.js +346 -100
- package/dist/bin/install.js +1 -0
- package/dist/bin/intercom-check.js +403 -155
- package/dist/bin/pre-publish.js +12 -0
- package/dist/bin/scan-tasks.js +393 -145
- package/dist/bin/setup.js +331 -159
- package/dist/bin/shard-migrate.js +328 -94
- package/dist/gateway/index.js +406 -158
- package/dist/hooks/bug-report-worker.js +396 -148
- package/dist/hooks/codex-stop-task-finalizer.js +374 -126
- package/dist/hooks/commit-complete.js +390 -142
- package/dist/hooks/error-recall.js +365 -115
- package/dist/hooks/ingest.js +357 -111
- package/dist/hooks/instructions-loaded.js +351 -105
- package/dist/hooks/notification.js +343 -97
- package/dist/hooks/post-compact.js +358 -110
- package/dist/hooks/post-tool-combined.js +384 -132
- package/dist/hooks/pre-compact.js +391 -143
- package/dist/hooks/pre-tool-use.js +362 -114
- package/dist/hooks/prompt-submit.js +422 -170
- package/dist/hooks/session-end.js +393 -145
- package/dist/hooks/session-start.js +390 -138
- package/dist/hooks/stop.js +361 -113
- package/dist/hooks/subagent-stop.js +354 -106
- package/dist/hooks/summary-worker.js +418 -185
- package/dist/index.js +400 -152
- package/dist/lib/cloud-sync.js +291 -131
- package/dist/lib/consolidation.js +8 -2
- package/dist/lib/database.js +233 -73
- package/dist/lib/db.js +233 -73
- package/dist/lib/device-registry.js +237 -77
- package/dist/lib/employee-templates.js +19 -1
- package/dist/lib/exe-daemon.js +705 -409
- package/dist/lib/hybrid-search.js +363 -113
- package/dist/lib/identity.js +9 -5
- package/dist/lib/messaging.js +26 -20
- package/dist/lib/reminders.js +5 -1
- package/dist/lib/schedules.js +320 -89
- package/dist/lib/skill-learning.js +28 -24
- package/dist/lib/store.js +342 -96
- package/dist/lib/tasks.js +82 -76
- package/dist/lib/tmux-routing.js +74 -68
- package/dist/lib/token-spend.js +5 -1
- package/dist/mcp/server.js +628 -355
- package/dist/mcp/tools/complete-reminder.js +5 -1
- package/dist/mcp/tools/create-reminder.js +5 -1
- package/dist/mcp/tools/create-task.js +89 -83
- package/dist/mcp/tools/deactivate-behavior.js +7 -3
- package/dist/mcp/tools/list-reminders.js +5 -1
- package/dist/mcp/tools/list-tasks.js +28 -21
- package/dist/mcp/tools/send-message.js +28 -22
- package/dist/mcp/tools/update-task.js +89 -83
- package/dist/runtime/index.js +390 -142
- package/dist/tui/App.js +437 -189
- package/package.json +1 -1
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -1396,9 +1396,79 @@ __export(database_exports, {
|
|
|
1396
1396
|
isInitialized: () => isInitialized,
|
|
1397
1397
|
setExternalClient: () => setExternalClient
|
|
1398
1398
|
});
|
|
1399
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
1399
|
+
import { chmodSync as chmodSync2, existsSync as existsSync6, statSync as statSync2, copyFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
1400
1400
|
import { createClient } from "@libsql/client";
|
|
1401
|
+
import { homedir } from "os";
|
|
1402
|
+
import { join } from "path";
|
|
1403
|
+
function logCatchDebug(context, err) {
|
|
1404
|
+
if (_debugDb) {
|
|
1405
|
+
process.stderr.write(
|
|
1406
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
1407
|
+
`
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
function acquireDbLock() {
|
|
1412
|
+
mkdirSync2(join(homedir(), ".exe-os"), { recursive: true });
|
|
1413
|
+
try {
|
|
1414
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1415
|
+
} catch (err) {
|
|
1416
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
1417
|
+
try {
|
|
1418
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
1419
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
1420
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1421
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
} catch (e) {
|
|
1425
|
+
logCatchDebug("stale lock check", e);
|
|
1426
|
+
}
|
|
1427
|
+
process.stderr.write(
|
|
1428
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
1429
|
+
);
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
throw err;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
function releaseDbLock() {
|
|
1436
|
+
if (_lockFd !== null) {
|
|
1437
|
+
try {
|
|
1438
|
+
closeSync2(_lockFd);
|
|
1439
|
+
} catch (e) {
|
|
1440
|
+
logCatchDebug("lock close", e);
|
|
1441
|
+
}
|
|
1442
|
+
_lockFd = null;
|
|
1443
|
+
}
|
|
1444
|
+
try {
|
|
1445
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1446
|
+
} catch (e) {
|
|
1447
|
+
logCatchDebug("lock unlink", e);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1401
1450
|
async function initDatabase(config) {
|
|
1451
|
+
acquireDbLock();
|
|
1452
|
+
if (existsSync6(config.dbPath)) {
|
|
1453
|
+
const dbStat = statSync2(config.dbPath);
|
|
1454
|
+
if (dbStat.size === 0) {
|
|
1455
|
+
const walPath = config.dbPath + "-wal";
|
|
1456
|
+
if (existsSync6(walPath) && statSync2(walPath).size > 0) {
|
|
1457
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
1458
|
+
copyFileSync(config.dbPath, backupPath);
|
|
1459
|
+
unlinkSync3(config.dbPath);
|
|
1460
|
+
process.stderr.write(
|
|
1461
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
1462
|
+
`
|
|
1463
|
+
);
|
|
1464
|
+
} else {
|
|
1465
|
+
process.stderr.write(
|
|
1466
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
1467
|
+
`
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1402
1472
|
if (_walCheckpointTimer) {
|
|
1403
1473
|
clearInterval(_walCheckpointTimer);
|
|
1404
1474
|
_walCheckpointTimer = null;
|
|
@@ -1425,10 +1495,8 @@ async function initDatabase(config) {
|
|
|
1425
1495
|
_client = createClient(opts);
|
|
1426
1496
|
_resilientClient = wrapWithRetry(_client);
|
|
1427
1497
|
_adapterClient = _resilientClient;
|
|
1428
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
1429
|
-
|
|
1430
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
1431
|
-
});
|
|
1498
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
1499
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
1432
1500
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
1433
1501
|
_walCheckpointTimer = setInterval(() => {
|
|
1434
1502
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -1443,11 +1511,16 @@ async function initDatabase(config) {
|
|
|
1443
1511
|
for (const suffix of ["-wal", "-shm"]) {
|
|
1444
1512
|
try {
|
|
1445
1513
|
chmodSync2(config.dbPath + suffix, 384);
|
|
1446
|
-
} catch {
|
|
1514
|
+
} catch (chmodErr) {
|
|
1515
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1516
|
+
`);
|
|
1447
1517
|
}
|
|
1448
1518
|
}
|
|
1449
|
-
} catch {
|
|
1519
|
+
} catch (chmodErr) {
|
|
1520
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1521
|
+
`);
|
|
1450
1522
|
}
|
|
1523
|
+
releaseDbLock();
|
|
1451
1524
|
}
|
|
1452
1525
|
function isInitialized() {
|
|
1453
1526
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1502,7 +1575,8 @@ async function ensureSchema() {
|
|
|
1502
1575
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
1503
1576
|
try {
|
|
1504
1577
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1505
|
-
} catch {
|
|
1578
|
+
} catch (e) {
|
|
1579
|
+
logCatchDebug("migration", e);
|
|
1506
1580
|
}
|
|
1507
1581
|
await client.executeMultiple(`
|
|
1508
1582
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -1567,6 +1641,23 @@ async function ensureSchema() {
|
|
|
1567
1641
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
1568
1642
|
END;
|
|
1569
1643
|
`);
|
|
1644
|
+
try {
|
|
1645
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
1646
|
+
} catch (ftsErr) {
|
|
1647
|
+
process.stderr.write(
|
|
1648
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
1649
|
+
`
|
|
1650
|
+
);
|
|
1651
|
+
try {
|
|
1652
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
1653
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
1654
|
+
} catch (rebuildErr) {
|
|
1655
|
+
process.stderr.write(
|
|
1656
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
1657
|
+
`
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1570
1661
|
await client.executeMultiple(`
|
|
1571
1662
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
1572
1663
|
key TEXT PRIMARY KEY,
|
|
@@ -1625,35 +1716,40 @@ async function ensureSchema() {
|
|
|
1625
1716
|
});
|
|
1626
1717
|
}
|
|
1627
1718
|
}
|
|
1628
|
-
} catch {
|
|
1719
|
+
} catch (seedErr) {
|
|
1720
|
+
logCatchDebug("behavior seed", seedErr);
|
|
1629
1721
|
}
|
|
1630
1722
|
try {
|
|
1631
1723
|
await client.execute({
|
|
1632
1724
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
1633
1725
|
args: []
|
|
1634
1726
|
});
|
|
1635
|
-
} catch {
|
|
1727
|
+
} catch (e) {
|
|
1728
|
+
logCatchDebug("migration", e);
|
|
1636
1729
|
}
|
|
1637
1730
|
try {
|
|
1638
1731
|
await client.execute({
|
|
1639
1732
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
1640
1733
|
args: []
|
|
1641
1734
|
});
|
|
1642
|
-
} catch {
|
|
1735
|
+
} catch (e) {
|
|
1736
|
+
logCatchDebug("migration", e);
|
|
1643
1737
|
}
|
|
1644
1738
|
try {
|
|
1645
1739
|
await client.execute({
|
|
1646
1740
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
1647
1741
|
args: []
|
|
1648
1742
|
});
|
|
1649
|
-
} catch {
|
|
1743
|
+
} catch (e) {
|
|
1744
|
+
logCatchDebug("migration", e);
|
|
1650
1745
|
}
|
|
1651
1746
|
try {
|
|
1652
1747
|
await client.execute({
|
|
1653
1748
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
1654
1749
|
args: []
|
|
1655
1750
|
});
|
|
1656
|
-
} catch {
|
|
1751
|
+
} catch (e) {
|
|
1752
|
+
logCatchDebug("migration", e);
|
|
1657
1753
|
}
|
|
1658
1754
|
try {
|
|
1659
1755
|
await client.execute({
|
|
@@ -1662,98 +1758,112 @@ async function ensureSchema() {
|
|
|
1662
1758
|
WHERE parent_task_id IS NOT NULL`,
|
|
1663
1759
|
args: []
|
|
1664
1760
|
});
|
|
1665
|
-
} catch {
|
|
1761
|
+
} catch (e) {
|
|
1762
|
+
logCatchDebug("migration", e);
|
|
1666
1763
|
}
|
|
1667
1764
|
try {
|
|
1668
1765
|
await client.execute({
|
|
1669
1766
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
1670
1767
|
args: []
|
|
1671
1768
|
});
|
|
1672
|
-
} catch {
|
|
1769
|
+
} catch (e) {
|
|
1770
|
+
logCatchDebug("migration", e);
|
|
1673
1771
|
}
|
|
1674
1772
|
try {
|
|
1675
1773
|
await client.execute({
|
|
1676
1774
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
1677
1775
|
args: []
|
|
1678
1776
|
});
|
|
1679
|
-
} catch {
|
|
1777
|
+
} catch (e) {
|
|
1778
|
+
logCatchDebug("migration", e);
|
|
1680
1779
|
}
|
|
1681
1780
|
try {
|
|
1682
1781
|
await client.execute({
|
|
1683
1782
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
1684
1783
|
args: []
|
|
1685
1784
|
});
|
|
1686
|
-
} catch {
|
|
1785
|
+
} catch (e) {
|
|
1786
|
+
logCatchDebug("migration", e);
|
|
1687
1787
|
}
|
|
1688
1788
|
try {
|
|
1689
1789
|
await client.execute({
|
|
1690
1790
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
1691
1791
|
args: []
|
|
1692
1792
|
});
|
|
1693
|
-
} catch {
|
|
1793
|
+
} catch (e) {
|
|
1794
|
+
logCatchDebug("migration", e);
|
|
1694
1795
|
}
|
|
1695
1796
|
try {
|
|
1696
1797
|
await client.execute({
|
|
1697
1798
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
1698
1799
|
args: []
|
|
1699
1800
|
});
|
|
1700
|
-
} catch {
|
|
1801
|
+
} catch (e) {
|
|
1802
|
+
logCatchDebug("migration", e);
|
|
1701
1803
|
}
|
|
1702
1804
|
try {
|
|
1703
1805
|
await client.execute({
|
|
1704
1806
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
1705
1807
|
args: []
|
|
1706
1808
|
});
|
|
1707
|
-
} catch {
|
|
1809
|
+
} catch (e) {
|
|
1810
|
+
logCatchDebug("migration", e);
|
|
1708
1811
|
}
|
|
1709
1812
|
try {
|
|
1710
1813
|
await client.execute({
|
|
1711
1814
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
1712
1815
|
args: []
|
|
1713
1816
|
});
|
|
1714
|
-
} catch {
|
|
1817
|
+
} catch (e) {
|
|
1818
|
+
logCatchDebug("migration", e);
|
|
1715
1819
|
}
|
|
1716
1820
|
try {
|
|
1717
1821
|
await client.execute({
|
|
1718
1822
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
1719
1823
|
args: []
|
|
1720
1824
|
});
|
|
1721
|
-
} catch {
|
|
1825
|
+
} catch (e) {
|
|
1826
|
+
logCatchDebug("migration", e);
|
|
1722
1827
|
}
|
|
1723
1828
|
try {
|
|
1724
1829
|
await client.execute({
|
|
1725
1830
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
1726
1831
|
args: []
|
|
1727
1832
|
});
|
|
1728
|
-
} catch {
|
|
1833
|
+
} catch (e) {
|
|
1834
|
+
logCatchDebug("migration", e);
|
|
1729
1835
|
}
|
|
1730
1836
|
try {
|
|
1731
1837
|
await client.execute({
|
|
1732
1838
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
1733
1839
|
args: []
|
|
1734
1840
|
});
|
|
1735
|
-
} catch {
|
|
1841
|
+
} catch (e) {
|
|
1842
|
+
logCatchDebug("migration", e);
|
|
1736
1843
|
}
|
|
1737
1844
|
try {
|
|
1738
1845
|
await client.execute({
|
|
1739
1846
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
1740
1847
|
args: []
|
|
1741
1848
|
});
|
|
1742
|
-
} catch {
|
|
1849
|
+
} catch (e) {
|
|
1850
|
+
logCatchDebug("migration", e);
|
|
1743
1851
|
}
|
|
1744
1852
|
try {
|
|
1745
1853
|
await client.execute({
|
|
1746
1854
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
1747
1855
|
args: []
|
|
1748
1856
|
});
|
|
1749
|
-
} catch {
|
|
1857
|
+
} catch (e) {
|
|
1858
|
+
logCatchDebug("migration", e);
|
|
1750
1859
|
}
|
|
1751
1860
|
try {
|
|
1752
1861
|
await client.execute({
|
|
1753
1862
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
1754
1863
|
args: []
|
|
1755
1864
|
});
|
|
1756
|
-
} catch {
|
|
1865
|
+
} catch (e) {
|
|
1866
|
+
logCatchDebug("migration", e);
|
|
1757
1867
|
}
|
|
1758
1868
|
await client.executeMultiple(`
|
|
1759
1869
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -1858,14 +1968,16 @@ async function ensureSchema() {
|
|
|
1858
1968
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
1859
1969
|
args: []
|
|
1860
1970
|
});
|
|
1861
|
-
} catch {
|
|
1971
|
+
} catch (e) {
|
|
1972
|
+
logCatchDebug("migration", e);
|
|
1862
1973
|
}
|
|
1863
1974
|
try {
|
|
1864
1975
|
await client.execute({
|
|
1865
1976
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
1866
1977
|
args: []
|
|
1867
1978
|
});
|
|
1868
|
-
} catch {
|
|
1979
|
+
} catch (e) {
|
|
1980
|
+
logCatchDebug("migration", e);
|
|
1869
1981
|
}
|
|
1870
1982
|
await client.executeMultiple(`
|
|
1871
1983
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -1891,7 +2003,8 @@ async function ensureSchema() {
|
|
|
1891
2003
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
1892
2004
|
args: []
|
|
1893
2005
|
});
|
|
1894
|
-
} catch {
|
|
2006
|
+
} catch (e) {
|
|
2007
|
+
logCatchDebug("migration", e);
|
|
1895
2008
|
}
|
|
1896
2009
|
await client.executeMultiple(`
|
|
1897
2010
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -1915,7 +2028,8 @@ async function ensureSchema() {
|
|
|
1915
2028
|
`);
|
|
1916
2029
|
try {
|
|
1917
2030
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
1918
|
-
} catch {
|
|
2031
|
+
} catch (e) {
|
|
2032
|
+
logCatchDebug("migration", e);
|
|
1919
2033
|
}
|
|
1920
2034
|
await client.executeMultiple(`
|
|
1921
2035
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -1952,63 +2066,72 @@ async function ensureSchema() {
|
|
|
1952
2066
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
1953
2067
|
args: []
|
|
1954
2068
|
});
|
|
1955
|
-
} catch {
|
|
2069
|
+
} catch (e) {
|
|
2070
|
+
logCatchDebug("migration", e);
|
|
1956
2071
|
}
|
|
1957
2072
|
try {
|
|
1958
2073
|
await client.execute({
|
|
1959
2074
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
1960
2075
|
args: []
|
|
1961
2076
|
});
|
|
1962
|
-
} catch {
|
|
2077
|
+
} catch (e) {
|
|
2078
|
+
logCatchDebug("migration", e);
|
|
1963
2079
|
}
|
|
1964
2080
|
try {
|
|
1965
2081
|
await client.execute({
|
|
1966
2082
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
1967
2083
|
args: []
|
|
1968
2084
|
});
|
|
1969
|
-
} catch {
|
|
2085
|
+
} catch (e) {
|
|
2086
|
+
logCatchDebug("migration", e);
|
|
1970
2087
|
}
|
|
1971
2088
|
try {
|
|
1972
2089
|
await client.execute({
|
|
1973
2090
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
1974
2091
|
args: []
|
|
1975
2092
|
});
|
|
1976
|
-
} catch {
|
|
2093
|
+
} catch (e) {
|
|
2094
|
+
logCatchDebug("migration", e);
|
|
1977
2095
|
}
|
|
1978
2096
|
try {
|
|
1979
2097
|
await client.execute({
|
|
1980
2098
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
1981
2099
|
args: []
|
|
1982
2100
|
});
|
|
1983
|
-
} catch {
|
|
2101
|
+
} catch (e) {
|
|
2102
|
+
logCatchDebug("migration", e);
|
|
1984
2103
|
}
|
|
1985
2104
|
try {
|
|
1986
2105
|
await client.execute({
|
|
1987
2106
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
1988
2107
|
args: []
|
|
1989
2108
|
});
|
|
1990
|
-
} catch {
|
|
2109
|
+
} catch (e) {
|
|
2110
|
+
logCatchDebug("migration", e);
|
|
1991
2111
|
}
|
|
1992
2112
|
try {
|
|
1993
2113
|
await client.execute({
|
|
1994
2114
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
1995
2115
|
args: []
|
|
1996
2116
|
});
|
|
1997
|
-
} catch {
|
|
2117
|
+
} catch (e) {
|
|
2118
|
+
logCatchDebug("migration", e);
|
|
1998
2119
|
}
|
|
1999
2120
|
try {
|
|
2000
2121
|
await client.execute({
|
|
2001
2122
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2002
2123
|
args: []
|
|
2003
2124
|
});
|
|
2004
|
-
} catch {
|
|
2125
|
+
} catch (e) {
|
|
2126
|
+
logCatchDebug("migration", e);
|
|
2005
2127
|
}
|
|
2006
2128
|
try {
|
|
2007
2129
|
await client.execute({
|
|
2008
2130
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2009
2131
|
args: []
|
|
2010
2132
|
});
|
|
2011
|
-
} catch {
|
|
2133
|
+
} catch (e) {
|
|
2134
|
+
logCatchDebug("migration", e);
|
|
2012
2135
|
}
|
|
2013
2136
|
for (const col of [
|
|
2014
2137
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2016,14 +2139,16 @@ async function ensureSchema() {
|
|
|
2016
2139
|
]) {
|
|
2017
2140
|
try {
|
|
2018
2141
|
await client.execute(col);
|
|
2019
|
-
} catch {
|
|
2142
|
+
} catch (e) {
|
|
2143
|
+
logCatchDebug("migration", e);
|
|
2020
2144
|
}
|
|
2021
2145
|
}
|
|
2022
2146
|
try {
|
|
2023
2147
|
await client.execute(
|
|
2024
2148
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2025
2149
|
);
|
|
2026
|
-
} catch {
|
|
2150
|
+
} catch (e) {
|
|
2151
|
+
logCatchDebug("migration", e);
|
|
2027
2152
|
}
|
|
2028
2153
|
try {
|
|
2029
2154
|
await client.execute(
|
|
@@ -2031,7 +2156,8 @@ async function ensureSchema() {
|
|
|
2031
2156
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2032
2157
|
WHERE content_hash IS NOT NULL`
|
|
2033
2158
|
);
|
|
2034
|
-
} catch {
|
|
2159
|
+
} catch (e) {
|
|
2160
|
+
logCatchDebug("migration", e);
|
|
2035
2161
|
}
|
|
2036
2162
|
await client.executeMultiple(`
|
|
2037
2163
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -2107,7 +2233,8 @@ async function ensureSchema() {
|
|
|
2107
2233
|
`);
|
|
2108
2234
|
try {
|
|
2109
2235
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
2110
|
-
} catch {
|
|
2236
|
+
} catch (e) {
|
|
2237
|
+
logCatchDebug("migration", e);
|
|
2111
2238
|
}
|
|
2112
2239
|
await client.executeMultiple(`
|
|
2113
2240
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -2122,14 +2249,16 @@ async function ensureSchema() {
|
|
|
2122
2249
|
]) {
|
|
2123
2250
|
try {
|
|
2124
2251
|
await client.execute(col);
|
|
2125
|
-
} catch {
|
|
2252
|
+
} catch (e) {
|
|
2253
|
+
logCatchDebug("migration", e);
|
|
2126
2254
|
}
|
|
2127
2255
|
}
|
|
2128
2256
|
try {
|
|
2129
2257
|
await client.execute(
|
|
2130
2258
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
2131
2259
|
);
|
|
2132
|
-
} catch {
|
|
2260
|
+
} catch (e) {
|
|
2261
|
+
logCatchDebug("migration", e);
|
|
2133
2262
|
}
|
|
2134
2263
|
await client.executeMultiple(`
|
|
2135
2264
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -2228,7 +2357,8 @@ async function ensureSchema() {
|
|
|
2228
2357
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
2229
2358
|
args: []
|
|
2230
2359
|
});
|
|
2231
|
-
} catch {
|
|
2360
|
+
} catch (e) {
|
|
2361
|
+
logCatchDebug("migration", e);
|
|
2232
2362
|
}
|
|
2233
2363
|
}
|
|
2234
2364
|
for (const col of [
|
|
@@ -2237,7 +2367,8 @@ async function ensureSchema() {
|
|
|
2237
2367
|
]) {
|
|
2238
2368
|
try {
|
|
2239
2369
|
await client.execute(col);
|
|
2240
|
-
} catch {
|
|
2370
|
+
} catch (e) {
|
|
2371
|
+
logCatchDebug("migration", e);
|
|
2241
2372
|
}
|
|
2242
2373
|
}
|
|
2243
2374
|
await client.executeMultiple(`
|
|
@@ -2422,56 +2553,64 @@ async function ensureSchema() {
|
|
|
2422
2553
|
args: []
|
|
2423
2554
|
});
|
|
2424
2555
|
}
|
|
2425
|
-
} catch {
|
|
2556
|
+
} catch (e) {
|
|
2557
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
2426
2558
|
}
|
|
2427
2559
|
try {
|
|
2428
2560
|
await client.execute({
|
|
2429
2561
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
2430
2562
|
args: []
|
|
2431
2563
|
});
|
|
2432
|
-
} catch {
|
|
2564
|
+
} catch (e) {
|
|
2565
|
+
logCatchDebug("migration", e);
|
|
2433
2566
|
}
|
|
2434
2567
|
try {
|
|
2435
2568
|
await client.execute({
|
|
2436
2569
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
2437
2570
|
args: []
|
|
2438
2571
|
});
|
|
2439
|
-
} catch {
|
|
2572
|
+
} catch (e) {
|
|
2573
|
+
logCatchDebug("migration", e);
|
|
2440
2574
|
}
|
|
2441
2575
|
try {
|
|
2442
2576
|
await client.execute({
|
|
2443
2577
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
2444
2578
|
args: []
|
|
2445
2579
|
});
|
|
2446
|
-
} catch {
|
|
2580
|
+
} catch (e) {
|
|
2581
|
+
logCatchDebug("migration", e);
|
|
2447
2582
|
}
|
|
2448
2583
|
try {
|
|
2449
2584
|
await client.execute({
|
|
2450
2585
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
2451
2586
|
args: []
|
|
2452
2587
|
});
|
|
2453
|
-
} catch {
|
|
2588
|
+
} catch (e) {
|
|
2589
|
+
logCatchDebug("migration", e);
|
|
2454
2590
|
}
|
|
2455
2591
|
try {
|
|
2456
2592
|
await client.execute({
|
|
2457
2593
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
2458
2594
|
args: []
|
|
2459
2595
|
});
|
|
2460
|
-
} catch {
|
|
2596
|
+
} catch (e) {
|
|
2597
|
+
logCatchDebug("migration", e);
|
|
2461
2598
|
}
|
|
2462
2599
|
try {
|
|
2463
2600
|
await client.execute({
|
|
2464
2601
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2465
2602
|
args: []
|
|
2466
2603
|
});
|
|
2467
|
-
} catch {
|
|
2604
|
+
} catch (e) {
|
|
2605
|
+
logCatchDebug("migration", e);
|
|
2468
2606
|
}
|
|
2469
2607
|
try {
|
|
2470
2608
|
await client.execute({
|
|
2471
2609
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2472
2610
|
args: []
|
|
2473
2611
|
});
|
|
2474
|
-
} catch {
|
|
2612
|
+
} catch (e) {
|
|
2613
|
+
logCatchDebug("migration", e);
|
|
2475
2614
|
}
|
|
2476
2615
|
await client.executeMultiple(`
|
|
2477
2616
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -2670,13 +2809,15 @@ async function ensureSchema() {
|
|
|
2670
2809
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
2671
2810
|
args: []
|
|
2672
2811
|
});
|
|
2673
|
-
} catch {
|
|
2812
|
+
} catch (e) {
|
|
2813
|
+
logCatchDebug("migration", e);
|
|
2674
2814
|
}
|
|
2675
2815
|
try {
|
|
2676
2816
|
await client.execute(
|
|
2677
2817
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
2678
2818
|
);
|
|
2679
|
-
} catch {
|
|
2819
|
+
} catch (e) {
|
|
2820
|
+
logCatchDebug("migration", e);
|
|
2680
2821
|
}
|
|
2681
2822
|
try {
|
|
2682
2823
|
await client.execute({
|
|
@@ -2687,20 +2828,23 @@ async function ensureSchema() {
|
|
|
2687
2828
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
2688
2829
|
args: []
|
|
2689
2830
|
});
|
|
2690
|
-
} catch {
|
|
2831
|
+
} catch (e) {
|
|
2832
|
+
logCatchDebug("migration", e);
|
|
2691
2833
|
}
|
|
2692
2834
|
try {
|
|
2693
2835
|
await client.execute({
|
|
2694
2836
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
2695
2837
|
args: []
|
|
2696
2838
|
});
|
|
2697
|
-
} catch {
|
|
2839
|
+
} catch (e) {
|
|
2840
|
+
logCatchDebug("migration", e);
|
|
2698
2841
|
}
|
|
2699
2842
|
try {
|
|
2700
2843
|
await client.execute(
|
|
2701
2844
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
2702
2845
|
);
|
|
2703
|
-
} catch {
|
|
2846
|
+
} catch (e) {
|
|
2847
|
+
logCatchDebug("migration", e);
|
|
2704
2848
|
}
|
|
2705
2849
|
for (const col of [
|
|
2706
2850
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -2708,7 +2852,8 @@ async function ensureSchema() {
|
|
|
2708
2852
|
]) {
|
|
2709
2853
|
try {
|
|
2710
2854
|
await client.execute(col);
|
|
2711
|
-
} catch {
|
|
2855
|
+
} catch (e) {
|
|
2856
|
+
logCatchDebug("migration", e);
|
|
2712
2857
|
}
|
|
2713
2858
|
}
|
|
2714
2859
|
try {
|
|
@@ -2716,13 +2861,15 @@ async function ensureSchema() {
|
|
|
2716
2861
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
2717
2862
|
args: []
|
|
2718
2863
|
});
|
|
2719
|
-
} catch {
|
|
2864
|
+
} catch (e) {
|
|
2865
|
+
logCatchDebug("migration", e);
|
|
2720
2866
|
}
|
|
2721
2867
|
try {
|
|
2722
2868
|
await client.execute(
|
|
2723
2869
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
2724
2870
|
);
|
|
2725
|
-
} catch {
|
|
2871
|
+
} catch (e) {
|
|
2872
|
+
logCatchDebug("migration", e);
|
|
2726
2873
|
}
|
|
2727
2874
|
for (const col of [
|
|
2728
2875
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -2730,7 +2877,8 @@ async function ensureSchema() {
|
|
|
2730
2877
|
]) {
|
|
2731
2878
|
try {
|
|
2732
2879
|
await client.execute(col);
|
|
2733
|
-
} catch {
|
|
2880
|
+
} catch (e) {
|
|
2881
|
+
logCatchDebug("migration", e);
|
|
2734
2882
|
}
|
|
2735
2883
|
}
|
|
2736
2884
|
try {
|
|
@@ -2738,27 +2886,31 @@ async function ensureSchema() {
|
|
|
2738
2886
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
2739
2887
|
args: []
|
|
2740
2888
|
});
|
|
2741
|
-
} catch {
|
|
2889
|
+
} catch (e) {
|
|
2890
|
+
logCatchDebug("migration", e);
|
|
2742
2891
|
}
|
|
2743
2892
|
try {
|
|
2744
2893
|
await client.execute({
|
|
2745
2894
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
2746
2895
|
args: []
|
|
2747
2896
|
});
|
|
2748
|
-
} catch {
|
|
2897
|
+
} catch (e) {
|
|
2898
|
+
logCatchDebug("migration", e);
|
|
2749
2899
|
}
|
|
2750
2900
|
try {
|
|
2751
2901
|
await client.execute(
|
|
2752
2902
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
2753
2903
|
);
|
|
2754
|
-
} catch {
|
|
2904
|
+
} catch (e) {
|
|
2905
|
+
logCatchDebug("migration", e);
|
|
2755
2906
|
}
|
|
2756
2907
|
try {
|
|
2757
2908
|
await client.execute({
|
|
2758
2909
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
2759
2910
|
args: []
|
|
2760
2911
|
});
|
|
2761
|
-
} catch {
|
|
2912
|
+
} catch (e) {
|
|
2913
|
+
logCatchDebug("migration", e);
|
|
2762
2914
|
}
|
|
2763
2915
|
for (const col of [
|
|
2764
2916
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -2779,7 +2931,8 @@ async function ensureSchema() {
|
|
|
2779
2931
|
]) {
|
|
2780
2932
|
try {
|
|
2781
2933
|
await client.execute(col);
|
|
2782
|
-
} catch {
|
|
2934
|
+
} catch (e) {
|
|
2935
|
+
logCatchDebug("migration", e);
|
|
2783
2936
|
}
|
|
2784
2937
|
}
|
|
2785
2938
|
try {
|
|
@@ -2787,14 +2940,16 @@ async function ensureSchema() {
|
|
|
2787
2940
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
2788
2941
|
args: []
|
|
2789
2942
|
});
|
|
2790
|
-
} catch {
|
|
2943
|
+
} catch (e) {
|
|
2944
|
+
logCatchDebug("migration", e);
|
|
2791
2945
|
}
|
|
2792
2946
|
try {
|
|
2793
2947
|
await client.execute({
|
|
2794
2948
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
2795
2949
|
args: []
|
|
2796
2950
|
});
|
|
2797
|
-
} catch {
|
|
2951
|
+
} catch (e) {
|
|
2952
|
+
logCatchDebug("migration", e);
|
|
2798
2953
|
}
|
|
2799
2954
|
}
|
|
2800
2955
|
async function disposeDatabase() {
|
|
@@ -2805,7 +2960,8 @@ async function disposeDatabase() {
|
|
|
2805
2960
|
if (_client) {
|
|
2806
2961
|
try {
|
|
2807
2962
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2808
|
-
} catch {
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
logCatchDebug("WAL checkpoint", e);
|
|
2809
2965
|
}
|
|
2810
2966
|
}
|
|
2811
2967
|
if (_daemonClient) {
|
|
@@ -2821,8 +2977,9 @@ async function disposeDatabase() {
|
|
|
2821
2977
|
_client = null;
|
|
2822
2978
|
_resilientClient = null;
|
|
2823
2979
|
}
|
|
2980
|
+
releaseDbLock();
|
|
2824
2981
|
}
|
|
2825
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
2982
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
2826
2983
|
var init_database = __esm({
|
|
2827
2984
|
"src/lib/database.ts"() {
|
|
2828
2985
|
"use strict";
|
|
@@ -2830,11 +2987,14 @@ var init_database = __esm({
|
|
|
2830
2987
|
init_employees();
|
|
2831
2988
|
init_database_adapter();
|
|
2832
2989
|
init_memory();
|
|
2990
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
2833
2991
|
_client = null;
|
|
2834
2992
|
_resilientClient = null;
|
|
2835
2993
|
_walCheckpointTimer = null;
|
|
2836
2994
|
_daemonClient = null;
|
|
2837
2995
|
_adapterClient = null;
|
|
2996
|
+
_lockFd = null;
|
|
2997
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
2838
2998
|
initTurso = initDatabase;
|
|
2839
2999
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
2840
3000
|
disposeTurso = disposeDatabase;
|
|
@@ -2860,9 +3020,9 @@ __export(crdt_sync_exports, {
|
|
|
2860
3020
|
rebuildFromDb: () => rebuildFromDb
|
|
2861
3021
|
});
|
|
2862
3022
|
import * as Y from "yjs";
|
|
2863
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as
|
|
3023
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
|
|
2864
3024
|
import path7 from "path";
|
|
2865
|
-
import { homedir } from "os";
|
|
3025
|
+
import { homedir as homedir2 } from "os";
|
|
2866
3026
|
function getStatePath() {
|
|
2867
3027
|
return _statePathOverride ?? DEFAULT_STATE_PATH;
|
|
2868
3028
|
}
|
|
@@ -2873,14 +3033,14 @@ function initCrdtDoc() {
|
|
|
2873
3033
|
if (doc) return doc;
|
|
2874
3034
|
doc = new Y.Doc();
|
|
2875
3035
|
const sp = getStatePath();
|
|
2876
|
-
if (
|
|
3036
|
+
if (existsSync8(sp)) {
|
|
2877
3037
|
try {
|
|
2878
3038
|
const state = readFileSync6(sp);
|
|
2879
3039
|
Y.applyUpdate(doc, new Uint8Array(state));
|
|
2880
3040
|
} catch {
|
|
2881
3041
|
console.warn("[crdt-sync] WARN: corrupted state file, rebuilding from DB");
|
|
2882
3042
|
try {
|
|
2883
|
-
|
|
3043
|
+
unlinkSync4(sp);
|
|
2884
3044
|
} catch {
|
|
2885
3045
|
}
|
|
2886
3046
|
rebuildFromDb().catch((err) => {
|
|
@@ -3018,7 +3178,7 @@ function persistState() {
|
|
|
3018
3178
|
try {
|
|
3019
3179
|
const sp = getStatePath();
|
|
3020
3180
|
const dir = path7.dirname(sp);
|
|
3021
|
-
if (!
|
|
3181
|
+
if (!existsSync8(dir)) mkdirSync4(dir, { recursive: true });
|
|
3022
3182
|
const state = Y.encodeStateAsUpdate(doc);
|
|
3023
3183
|
writeFileSync4(sp, Buffer.from(state));
|
|
3024
3184
|
} catch {
|
|
@@ -3061,7 +3221,7 @@ var DEFAULT_STATE_PATH, _statePathOverride, doc;
|
|
|
3061
3221
|
var init_crdt_sync = __esm({
|
|
3062
3222
|
"src/lib/crdt-sync.ts"() {
|
|
3063
3223
|
"use strict";
|
|
3064
|
-
DEFAULT_STATE_PATH = path7.join(
|
|
3224
|
+
DEFAULT_STATE_PATH = path7.join(homedir2(), ".exe-os", "crdt-state.bin");
|
|
3065
3225
|
_statePathOverride = null;
|
|
3066
3226
|
doc = null;
|
|
3067
3227
|
}
|
|
@@ -3093,7 +3253,7 @@ __export(keychain_exports, {
|
|
|
3093
3253
|
setMasterKey: () => setMasterKey
|
|
3094
3254
|
});
|
|
3095
3255
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3096
|
-
import { existsSync as
|
|
3256
|
+
import { existsSync as existsSync9, statSync as statSync3 } from "fs";
|
|
3097
3257
|
import { execSync as execSync3 } from "child_process";
|
|
3098
3258
|
import path8 from "path";
|
|
3099
3259
|
import os6 from "os";
|
|
@@ -3128,7 +3288,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3128
3288
|
if (process.platform !== "linux") return false;
|
|
3129
3289
|
try {
|
|
3130
3290
|
const uid = typeof os6.userInfo().uid === "number" ? os6.userInfo().uid : -1;
|
|
3131
|
-
const st =
|
|
3291
|
+
const st = statSync3(keyPath);
|
|
3132
3292
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3133
3293
|
if (uid === 0) return true;
|
|
3134
3294
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -3329,7 +3489,7 @@ async function getMasterKey() {
|
|
|
3329
3489
|
}
|
|
3330
3490
|
}
|
|
3331
3491
|
const keyPath = getKeyPath();
|
|
3332
|
-
if (!
|
|
3492
|
+
if (!existsSync9(keyPath)) {
|
|
3333
3493
|
process.stderr.write(
|
|
3334
3494
|
`[keychain] Key not found at ${keyPath} (HOME=${os6.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3335
3495
|
`
|
|
@@ -3437,7 +3597,7 @@ async function getKeyStorageInfo() {
|
|
|
3437
3597
|
}
|
|
3438
3598
|
}
|
|
3439
3599
|
const keyPath = getKeyPath();
|
|
3440
|
-
if (!
|
|
3600
|
+
if (!existsSync9(keyPath)) {
|
|
3441
3601
|
return {
|
|
3442
3602
|
kind: "missing",
|
|
3443
3603
|
secure: false,
|
|
@@ -3533,7 +3693,7 @@ async function deleteMasterKey() {
|
|
|
3533
3693
|
}
|
|
3534
3694
|
}
|
|
3535
3695
|
const keyPath = getKeyPath();
|
|
3536
|
-
if (
|
|
3696
|
+
if (existsSync9(keyPath)) {
|
|
3537
3697
|
await unlink(keyPath);
|
|
3538
3698
|
}
|
|
3539
3699
|
}
|
|
@@ -3589,42 +3749,42 @@ __export(db_backup_exports, {
|
|
|
3589
3749
|
listBackups: () => listBackups,
|
|
3590
3750
|
rotateBackups: () => rotateBackups
|
|
3591
3751
|
});
|
|
3592
|
-
import { copyFileSync, existsSync as
|
|
3752
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync5, readdirSync, unlinkSync as unlinkSync5, statSync as statSync4 } from "fs";
|
|
3593
3753
|
import path9 from "path";
|
|
3594
3754
|
function findActiveDb() {
|
|
3595
3755
|
for (const name of DB_NAMES) {
|
|
3596
3756
|
const p = path9.join(EXE_AI_DIR, name);
|
|
3597
|
-
if (
|
|
3757
|
+
if (existsSync10(p)) return p;
|
|
3598
3758
|
}
|
|
3599
3759
|
return null;
|
|
3600
3760
|
}
|
|
3601
3761
|
function createBackup(reason = "manual") {
|
|
3602
3762
|
const dbPath = findActiveDb();
|
|
3603
3763
|
if (!dbPath) return null;
|
|
3604
|
-
|
|
3764
|
+
mkdirSync5(BACKUP_DIR, { recursive: true });
|
|
3605
3765
|
const dbName = path9.basename(dbPath, ".db");
|
|
3606
3766
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
3607
3767
|
const backupName = `${dbName}-${reason}-${timestamp}.db`;
|
|
3608
3768
|
const backupPath = path9.join(BACKUP_DIR, backupName);
|
|
3609
|
-
|
|
3769
|
+
copyFileSync2(dbPath, backupPath);
|
|
3610
3770
|
const walPath = dbPath + "-wal";
|
|
3611
|
-
if (
|
|
3771
|
+
if (existsSync10(walPath)) {
|
|
3612
3772
|
try {
|
|
3613
|
-
|
|
3773
|
+
copyFileSync2(walPath, backupPath + "-wal");
|
|
3614
3774
|
} catch {
|
|
3615
3775
|
}
|
|
3616
3776
|
}
|
|
3617
3777
|
const shmPath = dbPath + "-shm";
|
|
3618
|
-
if (
|
|
3778
|
+
if (existsSync10(shmPath)) {
|
|
3619
3779
|
try {
|
|
3620
|
-
|
|
3780
|
+
copyFileSync2(shmPath, backupPath + "-shm");
|
|
3621
3781
|
} catch {
|
|
3622
3782
|
}
|
|
3623
3783
|
}
|
|
3624
3784
|
return backupPath;
|
|
3625
3785
|
}
|
|
3626
3786
|
function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
3627
|
-
if (!
|
|
3787
|
+
if (!existsSync10(BACKUP_DIR)) return 0;
|
|
3628
3788
|
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1e3;
|
|
3629
3789
|
let deleted = 0;
|
|
3630
3790
|
try {
|
|
@@ -3633,9 +3793,9 @@ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
|
3633
3793
|
if (!file.endsWith(".db") && !file.endsWith(".db-wal") && !file.endsWith(".db-shm")) continue;
|
|
3634
3794
|
const filePath = path9.join(BACKUP_DIR, file);
|
|
3635
3795
|
try {
|
|
3636
|
-
const stat =
|
|
3796
|
+
const stat = statSync4(filePath);
|
|
3637
3797
|
if (stat.mtimeMs < cutoff) {
|
|
3638
|
-
|
|
3798
|
+
unlinkSync5(filePath);
|
|
3639
3799
|
deleted++;
|
|
3640
3800
|
}
|
|
3641
3801
|
} catch {
|
|
@@ -3646,12 +3806,12 @@ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
|
3646
3806
|
return deleted;
|
|
3647
3807
|
}
|
|
3648
3808
|
function listBackups() {
|
|
3649
|
-
if (!
|
|
3809
|
+
if (!existsSync10(BACKUP_DIR)) return [];
|
|
3650
3810
|
try {
|
|
3651
3811
|
const files = readdirSync(BACKUP_DIR).filter((f) => f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm"));
|
|
3652
3812
|
return files.map((name) => {
|
|
3653
3813
|
const p = path9.join(BACKUP_DIR, name);
|
|
3654
|
-
const stat =
|
|
3814
|
+
const stat = statSync4(p);
|
|
3655
3815
|
return { path: p, name, size: stat.size, date: stat.mtime };
|
|
3656
3816
|
}).sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
3657
3817
|
} catch {
|
|
@@ -3683,10 +3843,10 @@ var init_db_backup = __esm({
|
|
|
3683
3843
|
|
|
3684
3844
|
// src/lib/cloud-sync.ts
|
|
3685
3845
|
init_database();
|
|
3686
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as
|
|
3846
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync6, appendFileSync, unlinkSync as unlinkSync6, openSync as openSync3, closeSync as closeSync3, statSync as statSync5 } from "fs";
|
|
3687
3847
|
import crypto3 from "crypto";
|
|
3688
3848
|
import path10 from "path";
|
|
3689
|
-
import { homedir as
|
|
3849
|
+
import { homedir as homedir3 } from "os";
|
|
3690
3850
|
|
|
3691
3851
|
// src/lib/crypto.ts
|
|
3692
3852
|
import crypto2 from "crypto";
|
|
@@ -3751,7 +3911,7 @@ function decompress(input) {
|
|
|
3751
3911
|
|
|
3752
3912
|
// src/lib/license.ts
|
|
3753
3913
|
init_config();
|
|
3754
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as
|
|
3914
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
|
|
3755
3915
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3756
3916
|
import { createRequire as createRequire2 } from "module";
|
|
3757
3917
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -3765,21 +3925,21 @@ var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
|
3765
3925
|
function loadDeviceId() {
|
|
3766
3926
|
const deviceJsonPath = path6.join(EXE_AI_DIR, "device.json");
|
|
3767
3927
|
try {
|
|
3768
|
-
if (
|
|
3928
|
+
if (existsSync7(deviceJsonPath)) {
|
|
3769
3929
|
const data = JSON.parse(readFileSync5(deviceJsonPath, "utf8"));
|
|
3770
3930
|
if (data.deviceId) return data.deviceId;
|
|
3771
3931
|
}
|
|
3772
3932
|
} catch {
|
|
3773
3933
|
}
|
|
3774
3934
|
try {
|
|
3775
|
-
if (
|
|
3935
|
+
if (existsSync7(DEVICE_ID_PATH)) {
|
|
3776
3936
|
const id2 = readFileSync5(DEVICE_ID_PATH, "utf8").trim();
|
|
3777
3937
|
if (id2) return id2;
|
|
3778
3938
|
}
|
|
3779
3939
|
} catch {
|
|
3780
3940
|
}
|
|
3781
3941
|
const id = randomUUID2();
|
|
3782
|
-
|
|
3942
|
+
mkdirSync3(EXE_AI_DIR, { recursive: true });
|
|
3783
3943
|
writeFileSync3(DEVICE_ID_PATH, id, "utf8");
|
|
3784
3944
|
return id;
|
|
3785
3945
|
}
|
|
@@ -3794,7 +3954,7 @@ function sqlSafe(v) {
|
|
|
3794
3954
|
}
|
|
3795
3955
|
function logError(msg) {
|
|
3796
3956
|
try {
|
|
3797
|
-
const logPath = path10.join(
|
|
3957
|
+
const logPath = path10.join(homedir3(), ".exe-os", "workers.log");
|
|
3798
3958
|
appendFileSync(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
|
|
3799
3959
|
`);
|
|
3800
3960
|
} catch {
|
|
@@ -3816,7 +3976,7 @@ function loadPgClient() {
|
|
|
3816
3976
|
let cloudPostgresUrl;
|
|
3817
3977
|
let configEnabled = false;
|
|
3818
3978
|
try {
|
|
3819
|
-
if (
|
|
3979
|
+
if (existsSync11(configPath)) {
|
|
3820
3980
|
const cfg = JSON.parse(readFileSync7(configPath, "utf8"));
|
|
3821
3981
|
cloudPostgresUrl = cfg.cloud?.postgresUrl;
|
|
3822
3982
|
configEnabled = cfg.cloud?.syncToPostgres === true;
|
|
@@ -3844,9 +4004,9 @@ function loadPgClient() {
|
|
|
3844
4004
|
if (!Ctor) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
3845
4005
|
return new Ctor();
|
|
3846
4006
|
}
|
|
3847
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ?? path10.join(
|
|
4007
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path10.join(homedir3(), "exe-db");
|
|
3848
4008
|
const packagePath = path10.join(exeDbRoot, "package.json");
|
|
3849
|
-
if (
|
|
4009
|
+
if (existsSync11(packagePath)) {
|
|
3850
4010
|
const req = createRequire3(packagePath);
|
|
3851
4011
|
const entry = req.resolve("@prisma/client");
|
|
3852
4012
|
const mod = await import(pathToFileURL3(entry).href);
|
|
@@ -3907,8 +4067,8 @@ async function pushToPostgres(records) {
|
|
|
3907
4067
|
}
|
|
3908
4068
|
async function withRosterLock(fn) {
|
|
3909
4069
|
try {
|
|
3910
|
-
const fd =
|
|
3911
|
-
|
|
4070
|
+
const fd = openSync3(ROSTER_LOCK_PATH, "wx");
|
|
4071
|
+
closeSync3(fd);
|
|
3912
4072
|
writeFileSync5(ROSTER_LOCK_PATH, String(Date.now()));
|
|
3913
4073
|
} catch (err) {
|
|
3914
4074
|
if (err.code === "EEXIST") {
|
|
@@ -3917,9 +4077,9 @@ async function withRosterLock(fn) {
|
|
|
3917
4077
|
if (Date.now() - ts < LOCK_STALE_MS) {
|
|
3918
4078
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
3919
4079
|
}
|
|
3920
|
-
|
|
3921
|
-
const fd =
|
|
3922
|
-
|
|
4080
|
+
unlinkSync6(ROSTER_LOCK_PATH);
|
|
4081
|
+
const fd = openSync3(ROSTER_LOCK_PATH, "wx");
|
|
4082
|
+
closeSync3(fd);
|
|
3923
4083
|
writeFileSync5(ROSTER_LOCK_PATH, String(Date.now()));
|
|
3924
4084
|
} catch (retryErr) {
|
|
3925
4085
|
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
@@ -3933,7 +4093,7 @@ async function withRosterLock(fn) {
|
|
|
3933
4093
|
return await fn();
|
|
3934
4094
|
} finally {
|
|
3935
4095
|
try {
|
|
3936
|
-
|
|
4096
|
+
unlinkSync6(ROSTER_LOCK_PATH);
|
|
3937
4097
|
} catch {
|
|
3938
4098
|
}
|
|
3939
4099
|
}
|
|
@@ -4368,7 +4528,7 @@ async function cloudSync(config) {
|
|
|
4368
4528
|
const employees = await loadEmployees();
|
|
4369
4529
|
rosterResult.employees = employees.length;
|
|
4370
4530
|
const idDir = path10.join(EXE_AI_DIR, "identity");
|
|
4371
|
-
if (
|
|
4531
|
+
if (existsSync11(idDir)) {
|
|
4372
4532
|
rosterResult.identities = readdirSync2(idDir).filter((f) => f.endsWith(".md")).length;
|
|
4373
4533
|
}
|
|
4374
4534
|
} catch {
|
|
@@ -4378,7 +4538,7 @@ async function cloudSync(config) {
|
|
|
4378
4538
|
const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
|
|
4379
4539
|
const latestBackup = getLatestBackup2();
|
|
4380
4540
|
if (latestBackup) {
|
|
4381
|
-
const backupSize =
|
|
4541
|
+
const backupSize = statSync5(latestBackup).size;
|
|
4382
4542
|
const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
|
|
4383
4543
|
if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
|
|
4384
4544
|
const backupData = readFileSync7(latestBackup);
|
|
@@ -4430,7 +4590,7 @@ var ROSTER_DELETIONS_PATH = path10.join(EXE_AI_DIR, "roster-deletions.json");
|
|
|
4430
4590
|
function recordRosterDeletion(name) {
|
|
4431
4591
|
let deletions = [];
|
|
4432
4592
|
try {
|
|
4433
|
-
if (
|
|
4593
|
+
if (existsSync11(ROSTER_DELETIONS_PATH)) {
|
|
4434
4594
|
deletions = JSON.parse(readFileSync7(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
4435
4595
|
}
|
|
4436
4596
|
} catch {
|
|
@@ -4440,7 +4600,7 @@ function recordRosterDeletion(name) {
|
|
|
4440
4600
|
}
|
|
4441
4601
|
function consumeRosterDeletions() {
|
|
4442
4602
|
try {
|
|
4443
|
-
if (!
|
|
4603
|
+
if (!existsSync11(ROSTER_DELETIONS_PATH)) return [];
|
|
4444
4604
|
const deletions = JSON.parse(readFileSync7(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
4445
4605
|
writeFileSync5(ROSTER_DELETIONS_PATH, "[]");
|
|
4446
4606
|
return deletions;
|
|
@@ -4453,14 +4613,14 @@ function buildRosterBlob(paths) {
|
|
|
4453
4613
|
const identityDir = paths?.identityDir ?? path10.join(EXE_AI_DIR, "identity");
|
|
4454
4614
|
const configPath = paths?.configPath ?? path10.join(EXE_AI_DIR, "config.json");
|
|
4455
4615
|
let roster = [];
|
|
4456
|
-
if (
|
|
4616
|
+
if (existsSync11(rosterPath)) {
|
|
4457
4617
|
try {
|
|
4458
4618
|
roster = JSON.parse(readFileSync7(rosterPath, "utf-8"));
|
|
4459
4619
|
} catch {
|
|
4460
4620
|
}
|
|
4461
4621
|
}
|
|
4462
4622
|
const identities = {};
|
|
4463
|
-
if (
|
|
4623
|
+
if (existsSync11(identityDir)) {
|
|
4464
4624
|
for (const file of readdirSync2(identityDir).filter((f) => f.endsWith(".md"))) {
|
|
4465
4625
|
try {
|
|
4466
4626
|
identities[file] = readFileSync7(path10.join(identityDir, file), "utf-8");
|
|
@@ -4469,7 +4629,7 @@ function buildRosterBlob(paths) {
|
|
|
4469
4629
|
}
|
|
4470
4630
|
}
|
|
4471
4631
|
let config;
|
|
4472
|
-
if (
|
|
4632
|
+
if (existsSync11(configPath)) {
|
|
4473
4633
|
try {
|
|
4474
4634
|
config = JSON.parse(readFileSync7(configPath, "utf-8"));
|
|
4475
4635
|
} catch {
|
|
@@ -4477,7 +4637,7 @@ function buildRosterBlob(paths) {
|
|
|
4477
4637
|
}
|
|
4478
4638
|
let agentConfig;
|
|
4479
4639
|
const agentConfigPath = path10.join(EXE_AI_DIR, "agent-config.json");
|
|
4480
|
-
if (
|
|
4640
|
+
if (existsSync11(agentConfigPath)) {
|
|
4481
4641
|
try {
|
|
4482
4642
|
agentConfig = JSON.parse(readFileSync7(agentConfigPath, "utf-8"));
|
|
4483
4643
|
} catch {
|
|
@@ -4557,7 +4717,7 @@ async function cloudPullRoster(config) {
|
|
|
4557
4717
|
function mergeConfig(remoteConfig, configPath) {
|
|
4558
4718
|
const cfgPath = configPath ?? path10.join(EXE_AI_DIR, "config.json");
|
|
4559
4719
|
let local = {};
|
|
4560
|
-
if (
|
|
4720
|
+
if (existsSync11(cfgPath)) {
|
|
4561
4721
|
try {
|
|
4562
4722
|
local = JSON.parse(readFileSync7(cfgPath, "utf-8"));
|
|
4563
4723
|
} catch {
|
|
@@ -4593,11 +4753,11 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
4593
4753
|
) ?? lookupKey;
|
|
4594
4754
|
const remoteIdentity = remote.identities[matchedKey];
|
|
4595
4755
|
if (remoteIdentity) {
|
|
4596
|
-
if (!
|
|
4756
|
+
if (!existsSync11(identityDir)) mkdirSync6(identityDir, { recursive: true });
|
|
4597
4757
|
const idPath = path10.join(identityDir, `${remoteEmp.name}.md`);
|
|
4598
4758
|
let localIdentity = null;
|
|
4599
4759
|
try {
|
|
4600
|
-
localIdentity =
|
|
4760
|
+
localIdentity = existsSync11(idPath) ? readFileSync7(idPath, "utf-8") : null;
|
|
4601
4761
|
} catch {
|
|
4602
4762
|
}
|
|
4603
4763
|
if (localIdentity !== remoteIdentity) {
|
|
@@ -4629,7 +4789,7 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
4629
4789
|
try {
|
|
4630
4790
|
const agentConfigPath = path10.join(EXE_AI_DIR, "agent-config.json");
|
|
4631
4791
|
let local = {};
|
|
4632
|
-
if (
|
|
4792
|
+
if (existsSync11(agentConfigPath)) {
|
|
4633
4793
|
try {
|
|
4634
4794
|
local = JSON.parse(readFileSync7(agentConfigPath, "utf-8"));
|
|
4635
4795
|
} catch {
|
|
@@ -5065,14 +5225,14 @@ async function cloudPullDocuments(config) {
|
|
|
5065
5225
|
var CODE_CONTEXT_DIR = path10.join(EXE_AI_DIR, "code-context");
|
|
5066
5226
|
async function cloudPushCodeContext(config) {
|
|
5067
5227
|
assertSecureEndpoint(config.endpoint);
|
|
5068
|
-
if (!
|
|
5228
|
+
if (!existsSync11(CODE_CONTEXT_DIR)) return 0;
|
|
5069
5229
|
const files = readdirSync2(CODE_CONTEXT_DIR).filter(
|
|
5070
5230
|
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
5071
5231
|
);
|
|
5072
5232
|
if (files.length === 0) return 0;
|
|
5073
5233
|
const metaPath = path10.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
5074
5234
|
let syncMeta = {};
|
|
5075
|
-
if (
|
|
5235
|
+
if (existsSync11(metaPath)) {
|
|
5076
5236
|
try {
|
|
5077
5237
|
syncMeta = JSON.parse(readFileSync7(metaPath, "utf-8"));
|
|
5078
5238
|
} catch {
|
|
@@ -5082,7 +5242,7 @@ async function cloudPushCodeContext(config) {
|
|
|
5082
5242
|
for (const file of files) {
|
|
5083
5243
|
const filePath = path10.join(CODE_CONTEXT_DIR, file);
|
|
5084
5244
|
try {
|
|
5085
|
-
const stat =
|
|
5245
|
+
const stat = statSync5(filePath);
|
|
5086
5246
|
const lastPushed = syncMeta[file] ?? 0;
|
|
5087
5247
|
if (stat.mtimeMs <= lastPushed) continue;
|
|
5088
5248
|
const content = readFileSync7(filePath, "utf-8");
|
|
@@ -5127,7 +5287,7 @@ async function cloudPullCodeContext(config) {
|
|
|
5127
5287
|
if (!resp.ok) return 0;
|
|
5128
5288
|
const data = await resp.json();
|
|
5129
5289
|
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
5130
|
-
|
|
5290
|
+
mkdirSync6(CODE_CONTEXT_DIR, { recursive: true });
|
|
5131
5291
|
let pulled = 0;
|
|
5132
5292
|
for (const { key, blob } of data.indexes) {
|
|
5133
5293
|
try {
|
|
@@ -5135,7 +5295,7 @@ async function cloudPullCodeContext(config) {
|
|
|
5135
5295
|
const localPath = path10.join(CODE_CONTEXT_DIR, key);
|
|
5136
5296
|
const compressed = decryptSyncBlob(blob);
|
|
5137
5297
|
const content = decompress(compressed).toString("utf8");
|
|
5138
|
-
if (!
|
|
5298
|
+
if (!existsSync11(localPath)) {
|
|
5139
5299
|
writeFileSync5(localPath, content, "utf-8");
|
|
5140
5300
|
pulled++;
|
|
5141
5301
|
} else {
|