@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
|
@@ -1684,9 +1684,79 @@ __export(database_exports, {
|
|
|
1684
1684
|
isInitialized: () => isInitialized,
|
|
1685
1685
|
setExternalClient: () => setExternalClient
|
|
1686
1686
|
});
|
|
1687
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
1687
|
+
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";
|
|
1688
1688
|
import { createClient } from "@libsql/client";
|
|
1689
|
+
import { homedir } from "os";
|
|
1690
|
+
import { join } from "path";
|
|
1691
|
+
function logCatchDebug(context, err) {
|
|
1692
|
+
if (_debugDb) {
|
|
1693
|
+
process.stderr.write(
|
|
1694
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
1695
|
+
`
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
function acquireDbLock() {
|
|
1700
|
+
mkdirSync2(join(homedir(), ".exe-os"), { recursive: true });
|
|
1701
|
+
try {
|
|
1702
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1703
|
+
} catch (err) {
|
|
1704
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
1705
|
+
try {
|
|
1706
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
1707
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
1708
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1709
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
} catch (e) {
|
|
1713
|
+
logCatchDebug("stale lock check", e);
|
|
1714
|
+
}
|
|
1715
|
+
process.stderr.write(
|
|
1716
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
1717
|
+
);
|
|
1718
|
+
return;
|
|
1719
|
+
}
|
|
1720
|
+
throw err;
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
function releaseDbLock() {
|
|
1724
|
+
if (_lockFd !== null) {
|
|
1725
|
+
try {
|
|
1726
|
+
closeSync2(_lockFd);
|
|
1727
|
+
} catch (e) {
|
|
1728
|
+
logCatchDebug("lock close", e);
|
|
1729
|
+
}
|
|
1730
|
+
_lockFd = null;
|
|
1731
|
+
}
|
|
1732
|
+
try {
|
|
1733
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1734
|
+
} catch (e) {
|
|
1735
|
+
logCatchDebug("lock unlink", e);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1689
1738
|
async function initDatabase(config) {
|
|
1739
|
+
acquireDbLock();
|
|
1740
|
+
if (existsSync6(config.dbPath)) {
|
|
1741
|
+
const dbStat = statSync2(config.dbPath);
|
|
1742
|
+
if (dbStat.size === 0) {
|
|
1743
|
+
const walPath = config.dbPath + "-wal";
|
|
1744
|
+
if (existsSync6(walPath) && statSync2(walPath).size > 0) {
|
|
1745
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
1746
|
+
copyFileSync(config.dbPath, backupPath);
|
|
1747
|
+
unlinkSync3(config.dbPath);
|
|
1748
|
+
process.stderr.write(
|
|
1749
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
1750
|
+
`
|
|
1751
|
+
);
|
|
1752
|
+
} else {
|
|
1753
|
+
process.stderr.write(
|
|
1754
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
1755
|
+
`
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1690
1760
|
if (_walCheckpointTimer) {
|
|
1691
1761
|
clearInterval(_walCheckpointTimer);
|
|
1692
1762
|
_walCheckpointTimer = null;
|
|
@@ -1713,10 +1783,8 @@ async function initDatabase(config) {
|
|
|
1713
1783
|
_client = createClient(opts);
|
|
1714
1784
|
_resilientClient = wrapWithRetry(_client);
|
|
1715
1785
|
_adapterClient = _resilientClient;
|
|
1716
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
1717
|
-
|
|
1718
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
1719
|
-
});
|
|
1786
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
1787
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
1720
1788
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
1721
1789
|
_walCheckpointTimer = setInterval(() => {
|
|
1722
1790
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -1731,11 +1799,16 @@ async function initDatabase(config) {
|
|
|
1731
1799
|
for (const suffix of ["-wal", "-shm"]) {
|
|
1732
1800
|
try {
|
|
1733
1801
|
chmodSync2(config.dbPath + suffix, 384);
|
|
1734
|
-
} catch {
|
|
1802
|
+
} catch (chmodErr) {
|
|
1803
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1804
|
+
`);
|
|
1735
1805
|
}
|
|
1736
1806
|
}
|
|
1737
|
-
} catch {
|
|
1807
|
+
} catch (chmodErr) {
|
|
1808
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1809
|
+
`);
|
|
1738
1810
|
}
|
|
1811
|
+
releaseDbLock();
|
|
1739
1812
|
}
|
|
1740
1813
|
function isInitialized() {
|
|
1741
1814
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1790,7 +1863,8 @@ async function ensureSchema() {
|
|
|
1790
1863
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
1791
1864
|
try {
|
|
1792
1865
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1793
|
-
} catch {
|
|
1866
|
+
} catch (e) {
|
|
1867
|
+
logCatchDebug("migration", e);
|
|
1794
1868
|
}
|
|
1795
1869
|
await client.executeMultiple(`
|
|
1796
1870
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -1855,6 +1929,23 @@ async function ensureSchema() {
|
|
|
1855
1929
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
1856
1930
|
END;
|
|
1857
1931
|
`);
|
|
1932
|
+
try {
|
|
1933
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
1934
|
+
} catch (ftsErr) {
|
|
1935
|
+
process.stderr.write(
|
|
1936
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
1937
|
+
`
|
|
1938
|
+
);
|
|
1939
|
+
try {
|
|
1940
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
1941
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
1942
|
+
} catch (rebuildErr) {
|
|
1943
|
+
process.stderr.write(
|
|
1944
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
1945
|
+
`
|
|
1946
|
+
);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1858
1949
|
await client.executeMultiple(`
|
|
1859
1950
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
1860
1951
|
key TEXT PRIMARY KEY,
|
|
@@ -1913,35 +2004,40 @@ async function ensureSchema() {
|
|
|
1913
2004
|
});
|
|
1914
2005
|
}
|
|
1915
2006
|
}
|
|
1916
|
-
} catch {
|
|
2007
|
+
} catch (seedErr) {
|
|
2008
|
+
logCatchDebug("behavior seed", seedErr);
|
|
1917
2009
|
}
|
|
1918
2010
|
try {
|
|
1919
2011
|
await client.execute({
|
|
1920
2012
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
1921
2013
|
args: []
|
|
1922
2014
|
});
|
|
1923
|
-
} catch {
|
|
2015
|
+
} catch (e) {
|
|
2016
|
+
logCatchDebug("migration", e);
|
|
1924
2017
|
}
|
|
1925
2018
|
try {
|
|
1926
2019
|
await client.execute({
|
|
1927
2020
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
1928
2021
|
args: []
|
|
1929
2022
|
});
|
|
1930
|
-
} catch {
|
|
2023
|
+
} catch (e) {
|
|
2024
|
+
logCatchDebug("migration", e);
|
|
1931
2025
|
}
|
|
1932
2026
|
try {
|
|
1933
2027
|
await client.execute({
|
|
1934
2028
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
1935
2029
|
args: []
|
|
1936
2030
|
});
|
|
1937
|
-
} catch {
|
|
2031
|
+
} catch (e) {
|
|
2032
|
+
logCatchDebug("migration", e);
|
|
1938
2033
|
}
|
|
1939
2034
|
try {
|
|
1940
2035
|
await client.execute({
|
|
1941
2036
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
1942
2037
|
args: []
|
|
1943
2038
|
});
|
|
1944
|
-
} catch {
|
|
2039
|
+
} catch (e) {
|
|
2040
|
+
logCatchDebug("migration", e);
|
|
1945
2041
|
}
|
|
1946
2042
|
try {
|
|
1947
2043
|
await client.execute({
|
|
@@ -1950,98 +2046,112 @@ async function ensureSchema() {
|
|
|
1950
2046
|
WHERE parent_task_id IS NOT NULL`,
|
|
1951
2047
|
args: []
|
|
1952
2048
|
});
|
|
1953
|
-
} catch {
|
|
2049
|
+
} catch (e) {
|
|
2050
|
+
logCatchDebug("migration", e);
|
|
1954
2051
|
}
|
|
1955
2052
|
try {
|
|
1956
2053
|
await client.execute({
|
|
1957
2054
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
1958
2055
|
args: []
|
|
1959
2056
|
});
|
|
1960
|
-
} catch {
|
|
2057
|
+
} catch (e) {
|
|
2058
|
+
logCatchDebug("migration", e);
|
|
1961
2059
|
}
|
|
1962
2060
|
try {
|
|
1963
2061
|
await client.execute({
|
|
1964
2062
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
1965
2063
|
args: []
|
|
1966
2064
|
});
|
|
1967
|
-
} catch {
|
|
2065
|
+
} catch (e) {
|
|
2066
|
+
logCatchDebug("migration", e);
|
|
1968
2067
|
}
|
|
1969
2068
|
try {
|
|
1970
2069
|
await client.execute({
|
|
1971
2070
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
1972
2071
|
args: []
|
|
1973
2072
|
});
|
|
1974
|
-
} catch {
|
|
2073
|
+
} catch (e) {
|
|
2074
|
+
logCatchDebug("migration", e);
|
|
1975
2075
|
}
|
|
1976
2076
|
try {
|
|
1977
2077
|
await client.execute({
|
|
1978
2078
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
1979
2079
|
args: []
|
|
1980
2080
|
});
|
|
1981
|
-
} catch {
|
|
2081
|
+
} catch (e) {
|
|
2082
|
+
logCatchDebug("migration", e);
|
|
1982
2083
|
}
|
|
1983
2084
|
try {
|
|
1984
2085
|
await client.execute({
|
|
1985
2086
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
1986
2087
|
args: []
|
|
1987
2088
|
});
|
|
1988
|
-
} catch {
|
|
2089
|
+
} catch (e) {
|
|
2090
|
+
logCatchDebug("migration", e);
|
|
1989
2091
|
}
|
|
1990
2092
|
try {
|
|
1991
2093
|
await client.execute({
|
|
1992
2094
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
1993
2095
|
args: []
|
|
1994
2096
|
});
|
|
1995
|
-
} catch {
|
|
2097
|
+
} catch (e) {
|
|
2098
|
+
logCatchDebug("migration", e);
|
|
1996
2099
|
}
|
|
1997
2100
|
try {
|
|
1998
2101
|
await client.execute({
|
|
1999
2102
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2000
2103
|
args: []
|
|
2001
2104
|
});
|
|
2002
|
-
} catch {
|
|
2105
|
+
} catch (e) {
|
|
2106
|
+
logCatchDebug("migration", e);
|
|
2003
2107
|
}
|
|
2004
2108
|
try {
|
|
2005
2109
|
await client.execute({
|
|
2006
2110
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2007
2111
|
args: []
|
|
2008
2112
|
});
|
|
2009
|
-
} catch {
|
|
2113
|
+
} catch (e) {
|
|
2114
|
+
logCatchDebug("migration", e);
|
|
2010
2115
|
}
|
|
2011
2116
|
try {
|
|
2012
2117
|
await client.execute({
|
|
2013
2118
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2014
2119
|
args: []
|
|
2015
2120
|
});
|
|
2016
|
-
} catch {
|
|
2121
|
+
} catch (e) {
|
|
2122
|
+
logCatchDebug("migration", e);
|
|
2017
2123
|
}
|
|
2018
2124
|
try {
|
|
2019
2125
|
await client.execute({
|
|
2020
2126
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2021
2127
|
args: []
|
|
2022
2128
|
});
|
|
2023
|
-
} catch {
|
|
2129
|
+
} catch (e) {
|
|
2130
|
+
logCatchDebug("migration", e);
|
|
2024
2131
|
}
|
|
2025
2132
|
try {
|
|
2026
2133
|
await client.execute({
|
|
2027
2134
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2028
2135
|
args: []
|
|
2029
2136
|
});
|
|
2030
|
-
} catch {
|
|
2137
|
+
} catch (e) {
|
|
2138
|
+
logCatchDebug("migration", e);
|
|
2031
2139
|
}
|
|
2032
2140
|
try {
|
|
2033
2141
|
await client.execute({
|
|
2034
2142
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2035
2143
|
args: []
|
|
2036
2144
|
});
|
|
2037
|
-
} catch {
|
|
2145
|
+
} catch (e) {
|
|
2146
|
+
logCatchDebug("migration", e);
|
|
2038
2147
|
}
|
|
2039
2148
|
try {
|
|
2040
2149
|
await client.execute({
|
|
2041
2150
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2042
2151
|
args: []
|
|
2043
2152
|
});
|
|
2044
|
-
} catch {
|
|
2153
|
+
} catch (e) {
|
|
2154
|
+
logCatchDebug("migration", e);
|
|
2045
2155
|
}
|
|
2046
2156
|
await client.executeMultiple(`
|
|
2047
2157
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2146,14 +2256,16 @@ async function ensureSchema() {
|
|
|
2146
2256
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2147
2257
|
args: []
|
|
2148
2258
|
});
|
|
2149
|
-
} catch {
|
|
2259
|
+
} catch (e) {
|
|
2260
|
+
logCatchDebug("migration", e);
|
|
2150
2261
|
}
|
|
2151
2262
|
try {
|
|
2152
2263
|
await client.execute({
|
|
2153
2264
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2154
2265
|
args: []
|
|
2155
2266
|
});
|
|
2156
|
-
} catch {
|
|
2267
|
+
} catch (e) {
|
|
2268
|
+
logCatchDebug("migration", e);
|
|
2157
2269
|
}
|
|
2158
2270
|
await client.executeMultiple(`
|
|
2159
2271
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2179,7 +2291,8 @@ async function ensureSchema() {
|
|
|
2179
2291
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2180
2292
|
args: []
|
|
2181
2293
|
});
|
|
2182
|
-
} catch {
|
|
2294
|
+
} catch (e) {
|
|
2295
|
+
logCatchDebug("migration", e);
|
|
2183
2296
|
}
|
|
2184
2297
|
await client.executeMultiple(`
|
|
2185
2298
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -2203,7 +2316,8 @@ async function ensureSchema() {
|
|
|
2203
2316
|
`);
|
|
2204
2317
|
try {
|
|
2205
2318
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
2206
|
-
} catch {
|
|
2319
|
+
} catch (e) {
|
|
2320
|
+
logCatchDebug("migration", e);
|
|
2207
2321
|
}
|
|
2208
2322
|
await client.executeMultiple(`
|
|
2209
2323
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2240,63 +2354,72 @@ async function ensureSchema() {
|
|
|
2240
2354
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2241
2355
|
args: []
|
|
2242
2356
|
});
|
|
2243
|
-
} catch {
|
|
2357
|
+
} catch (e) {
|
|
2358
|
+
logCatchDebug("migration", e);
|
|
2244
2359
|
}
|
|
2245
2360
|
try {
|
|
2246
2361
|
await client.execute({
|
|
2247
2362
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
2248
2363
|
args: []
|
|
2249
2364
|
});
|
|
2250
|
-
} catch {
|
|
2365
|
+
} catch (e) {
|
|
2366
|
+
logCatchDebug("migration", e);
|
|
2251
2367
|
}
|
|
2252
2368
|
try {
|
|
2253
2369
|
await client.execute({
|
|
2254
2370
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
2255
2371
|
args: []
|
|
2256
2372
|
});
|
|
2257
|
-
} catch {
|
|
2373
|
+
} catch (e) {
|
|
2374
|
+
logCatchDebug("migration", e);
|
|
2258
2375
|
}
|
|
2259
2376
|
try {
|
|
2260
2377
|
await client.execute({
|
|
2261
2378
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
2262
2379
|
args: []
|
|
2263
2380
|
});
|
|
2264
|
-
} catch {
|
|
2381
|
+
} catch (e) {
|
|
2382
|
+
logCatchDebug("migration", e);
|
|
2265
2383
|
}
|
|
2266
2384
|
try {
|
|
2267
2385
|
await client.execute({
|
|
2268
2386
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
2269
2387
|
args: []
|
|
2270
2388
|
});
|
|
2271
|
-
} catch {
|
|
2389
|
+
} catch (e) {
|
|
2390
|
+
logCatchDebug("migration", e);
|
|
2272
2391
|
}
|
|
2273
2392
|
try {
|
|
2274
2393
|
await client.execute({
|
|
2275
2394
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
2276
2395
|
args: []
|
|
2277
2396
|
});
|
|
2278
|
-
} catch {
|
|
2397
|
+
} catch (e) {
|
|
2398
|
+
logCatchDebug("migration", e);
|
|
2279
2399
|
}
|
|
2280
2400
|
try {
|
|
2281
2401
|
await client.execute({
|
|
2282
2402
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
2283
2403
|
args: []
|
|
2284
2404
|
});
|
|
2285
|
-
} catch {
|
|
2405
|
+
} catch (e) {
|
|
2406
|
+
logCatchDebug("migration", e);
|
|
2286
2407
|
}
|
|
2287
2408
|
try {
|
|
2288
2409
|
await client.execute({
|
|
2289
2410
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2290
2411
|
args: []
|
|
2291
2412
|
});
|
|
2292
|
-
} catch {
|
|
2413
|
+
} catch (e) {
|
|
2414
|
+
logCatchDebug("migration", e);
|
|
2293
2415
|
}
|
|
2294
2416
|
try {
|
|
2295
2417
|
await client.execute({
|
|
2296
2418
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2297
2419
|
args: []
|
|
2298
2420
|
});
|
|
2299
|
-
} catch {
|
|
2421
|
+
} catch (e) {
|
|
2422
|
+
logCatchDebug("migration", e);
|
|
2300
2423
|
}
|
|
2301
2424
|
for (const col of [
|
|
2302
2425
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2304,14 +2427,16 @@ async function ensureSchema() {
|
|
|
2304
2427
|
]) {
|
|
2305
2428
|
try {
|
|
2306
2429
|
await client.execute(col);
|
|
2307
|
-
} catch {
|
|
2430
|
+
} catch (e) {
|
|
2431
|
+
logCatchDebug("migration", e);
|
|
2308
2432
|
}
|
|
2309
2433
|
}
|
|
2310
2434
|
try {
|
|
2311
2435
|
await client.execute(
|
|
2312
2436
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2313
2437
|
);
|
|
2314
|
-
} catch {
|
|
2438
|
+
} catch (e) {
|
|
2439
|
+
logCatchDebug("migration", e);
|
|
2315
2440
|
}
|
|
2316
2441
|
try {
|
|
2317
2442
|
await client.execute(
|
|
@@ -2319,7 +2444,8 @@ async function ensureSchema() {
|
|
|
2319
2444
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2320
2445
|
WHERE content_hash IS NOT NULL`
|
|
2321
2446
|
);
|
|
2322
|
-
} catch {
|
|
2447
|
+
} catch (e) {
|
|
2448
|
+
logCatchDebug("migration", e);
|
|
2323
2449
|
}
|
|
2324
2450
|
await client.executeMultiple(`
|
|
2325
2451
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -2395,7 +2521,8 @@ async function ensureSchema() {
|
|
|
2395
2521
|
`);
|
|
2396
2522
|
try {
|
|
2397
2523
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
2398
|
-
} catch {
|
|
2524
|
+
} catch (e) {
|
|
2525
|
+
logCatchDebug("migration", e);
|
|
2399
2526
|
}
|
|
2400
2527
|
await client.executeMultiple(`
|
|
2401
2528
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -2410,14 +2537,16 @@ async function ensureSchema() {
|
|
|
2410
2537
|
]) {
|
|
2411
2538
|
try {
|
|
2412
2539
|
await client.execute(col);
|
|
2413
|
-
} catch {
|
|
2540
|
+
} catch (e) {
|
|
2541
|
+
logCatchDebug("migration", e);
|
|
2414
2542
|
}
|
|
2415
2543
|
}
|
|
2416
2544
|
try {
|
|
2417
2545
|
await client.execute(
|
|
2418
2546
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
2419
2547
|
);
|
|
2420
|
-
} catch {
|
|
2548
|
+
} catch (e) {
|
|
2549
|
+
logCatchDebug("migration", e);
|
|
2421
2550
|
}
|
|
2422
2551
|
await client.executeMultiple(`
|
|
2423
2552
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -2516,7 +2645,8 @@ async function ensureSchema() {
|
|
|
2516
2645
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
2517
2646
|
args: []
|
|
2518
2647
|
});
|
|
2519
|
-
} catch {
|
|
2648
|
+
} catch (e) {
|
|
2649
|
+
logCatchDebug("migration", e);
|
|
2520
2650
|
}
|
|
2521
2651
|
}
|
|
2522
2652
|
for (const col of [
|
|
@@ -2525,7 +2655,8 @@ async function ensureSchema() {
|
|
|
2525
2655
|
]) {
|
|
2526
2656
|
try {
|
|
2527
2657
|
await client.execute(col);
|
|
2528
|
-
} catch {
|
|
2658
|
+
} catch (e) {
|
|
2659
|
+
logCatchDebug("migration", e);
|
|
2529
2660
|
}
|
|
2530
2661
|
}
|
|
2531
2662
|
await client.executeMultiple(`
|
|
@@ -2710,56 +2841,64 @@ async function ensureSchema() {
|
|
|
2710
2841
|
args: []
|
|
2711
2842
|
});
|
|
2712
2843
|
}
|
|
2713
|
-
} catch {
|
|
2844
|
+
} catch (e) {
|
|
2845
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
2714
2846
|
}
|
|
2715
2847
|
try {
|
|
2716
2848
|
await client.execute({
|
|
2717
2849
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
2718
2850
|
args: []
|
|
2719
2851
|
});
|
|
2720
|
-
} catch {
|
|
2852
|
+
} catch (e) {
|
|
2853
|
+
logCatchDebug("migration", e);
|
|
2721
2854
|
}
|
|
2722
2855
|
try {
|
|
2723
2856
|
await client.execute({
|
|
2724
2857
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
2725
2858
|
args: []
|
|
2726
2859
|
});
|
|
2727
|
-
} catch {
|
|
2860
|
+
} catch (e) {
|
|
2861
|
+
logCatchDebug("migration", e);
|
|
2728
2862
|
}
|
|
2729
2863
|
try {
|
|
2730
2864
|
await client.execute({
|
|
2731
2865
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
2732
2866
|
args: []
|
|
2733
2867
|
});
|
|
2734
|
-
} catch {
|
|
2868
|
+
} catch (e) {
|
|
2869
|
+
logCatchDebug("migration", e);
|
|
2735
2870
|
}
|
|
2736
2871
|
try {
|
|
2737
2872
|
await client.execute({
|
|
2738
2873
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
2739
2874
|
args: []
|
|
2740
2875
|
});
|
|
2741
|
-
} catch {
|
|
2876
|
+
} catch (e) {
|
|
2877
|
+
logCatchDebug("migration", e);
|
|
2742
2878
|
}
|
|
2743
2879
|
try {
|
|
2744
2880
|
await client.execute({
|
|
2745
2881
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
2746
2882
|
args: []
|
|
2747
2883
|
});
|
|
2748
|
-
} catch {
|
|
2884
|
+
} catch (e) {
|
|
2885
|
+
logCatchDebug("migration", e);
|
|
2749
2886
|
}
|
|
2750
2887
|
try {
|
|
2751
2888
|
await client.execute({
|
|
2752
2889
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2753
2890
|
args: []
|
|
2754
2891
|
});
|
|
2755
|
-
} catch {
|
|
2892
|
+
} catch (e) {
|
|
2893
|
+
logCatchDebug("migration", e);
|
|
2756
2894
|
}
|
|
2757
2895
|
try {
|
|
2758
2896
|
await client.execute({
|
|
2759
2897
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2760
2898
|
args: []
|
|
2761
2899
|
});
|
|
2762
|
-
} catch {
|
|
2900
|
+
} catch (e) {
|
|
2901
|
+
logCatchDebug("migration", e);
|
|
2763
2902
|
}
|
|
2764
2903
|
await client.executeMultiple(`
|
|
2765
2904
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -2958,13 +3097,15 @@ async function ensureSchema() {
|
|
|
2958
3097
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
2959
3098
|
args: []
|
|
2960
3099
|
});
|
|
2961
|
-
} catch {
|
|
3100
|
+
} catch (e) {
|
|
3101
|
+
logCatchDebug("migration", e);
|
|
2962
3102
|
}
|
|
2963
3103
|
try {
|
|
2964
3104
|
await client.execute(
|
|
2965
3105
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
2966
3106
|
);
|
|
2967
|
-
} catch {
|
|
3107
|
+
} catch (e) {
|
|
3108
|
+
logCatchDebug("migration", e);
|
|
2968
3109
|
}
|
|
2969
3110
|
try {
|
|
2970
3111
|
await client.execute({
|
|
@@ -2975,20 +3116,23 @@ async function ensureSchema() {
|
|
|
2975
3116
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
2976
3117
|
args: []
|
|
2977
3118
|
});
|
|
2978
|
-
} catch {
|
|
3119
|
+
} catch (e) {
|
|
3120
|
+
logCatchDebug("migration", e);
|
|
2979
3121
|
}
|
|
2980
3122
|
try {
|
|
2981
3123
|
await client.execute({
|
|
2982
3124
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
2983
3125
|
args: []
|
|
2984
3126
|
});
|
|
2985
|
-
} catch {
|
|
3127
|
+
} catch (e) {
|
|
3128
|
+
logCatchDebug("migration", e);
|
|
2986
3129
|
}
|
|
2987
3130
|
try {
|
|
2988
3131
|
await client.execute(
|
|
2989
3132
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
2990
3133
|
);
|
|
2991
|
-
} catch {
|
|
3134
|
+
} catch (e) {
|
|
3135
|
+
logCatchDebug("migration", e);
|
|
2992
3136
|
}
|
|
2993
3137
|
for (const col of [
|
|
2994
3138
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -2996,7 +3140,8 @@ async function ensureSchema() {
|
|
|
2996
3140
|
]) {
|
|
2997
3141
|
try {
|
|
2998
3142
|
await client.execute(col);
|
|
2999
|
-
} catch {
|
|
3143
|
+
} catch (e) {
|
|
3144
|
+
logCatchDebug("migration", e);
|
|
3000
3145
|
}
|
|
3001
3146
|
}
|
|
3002
3147
|
try {
|
|
@@ -3004,13 +3149,15 @@ async function ensureSchema() {
|
|
|
3004
3149
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3005
3150
|
args: []
|
|
3006
3151
|
});
|
|
3007
|
-
} catch {
|
|
3152
|
+
} catch (e) {
|
|
3153
|
+
logCatchDebug("migration", e);
|
|
3008
3154
|
}
|
|
3009
3155
|
try {
|
|
3010
3156
|
await client.execute(
|
|
3011
3157
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3012
3158
|
);
|
|
3013
|
-
} catch {
|
|
3159
|
+
} catch (e) {
|
|
3160
|
+
logCatchDebug("migration", e);
|
|
3014
3161
|
}
|
|
3015
3162
|
for (const col of [
|
|
3016
3163
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3018,7 +3165,8 @@ async function ensureSchema() {
|
|
|
3018
3165
|
]) {
|
|
3019
3166
|
try {
|
|
3020
3167
|
await client.execute(col);
|
|
3021
|
-
} catch {
|
|
3168
|
+
} catch (e) {
|
|
3169
|
+
logCatchDebug("migration", e);
|
|
3022
3170
|
}
|
|
3023
3171
|
}
|
|
3024
3172
|
try {
|
|
@@ -3026,27 +3174,31 @@ async function ensureSchema() {
|
|
|
3026
3174
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3027
3175
|
args: []
|
|
3028
3176
|
});
|
|
3029
|
-
} catch {
|
|
3177
|
+
} catch (e) {
|
|
3178
|
+
logCatchDebug("migration", e);
|
|
3030
3179
|
}
|
|
3031
3180
|
try {
|
|
3032
3181
|
await client.execute({
|
|
3033
3182
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3034
3183
|
args: []
|
|
3035
3184
|
});
|
|
3036
|
-
} catch {
|
|
3185
|
+
} catch (e) {
|
|
3186
|
+
logCatchDebug("migration", e);
|
|
3037
3187
|
}
|
|
3038
3188
|
try {
|
|
3039
3189
|
await client.execute(
|
|
3040
3190
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3041
3191
|
);
|
|
3042
|
-
} catch {
|
|
3192
|
+
} catch (e) {
|
|
3193
|
+
logCatchDebug("migration", e);
|
|
3043
3194
|
}
|
|
3044
3195
|
try {
|
|
3045
3196
|
await client.execute({
|
|
3046
3197
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3047
3198
|
args: []
|
|
3048
3199
|
});
|
|
3049
|
-
} catch {
|
|
3200
|
+
} catch (e) {
|
|
3201
|
+
logCatchDebug("migration", e);
|
|
3050
3202
|
}
|
|
3051
3203
|
for (const col of [
|
|
3052
3204
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3067,7 +3219,8 @@ async function ensureSchema() {
|
|
|
3067
3219
|
]) {
|
|
3068
3220
|
try {
|
|
3069
3221
|
await client.execute(col);
|
|
3070
|
-
} catch {
|
|
3222
|
+
} catch (e) {
|
|
3223
|
+
logCatchDebug("migration", e);
|
|
3071
3224
|
}
|
|
3072
3225
|
}
|
|
3073
3226
|
try {
|
|
@@ -3075,14 +3228,16 @@ async function ensureSchema() {
|
|
|
3075
3228
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3076
3229
|
args: []
|
|
3077
3230
|
});
|
|
3078
|
-
} catch {
|
|
3231
|
+
} catch (e) {
|
|
3232
|
+
logCatchDebug("migration", e);
|
|
3079
3233
|
}
|
|
3080
3234
|
try {
|
|
3081
3235
|
await client.execute({
|
|
3082
3236
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3083
3237
|
args: []
|
|
3084
3238
|
});
|
|
3085
|
-
} catch {
|
|
3239
|
+
} catch (e) {
|
|
3240
|
+
logCatchDebug("migration", e);
|
|
3086
3241
|
}
|
|
3087
3242
|
}
|
|
3088
3243
|
async function disposeDatabase() {
|
|
@@ -3093,7 +3248,8 @@ async function disposeDatabase() {
|
|
|
3093
3248
|
if (_client) {
|
|
3094
3249
|
try {
|
|
3095
3250
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3096
|
-
} catch {
|
|
3251
|
+
} catch (e) {
|
|
3252
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3097
3253
|
}
|
|
3098
3254
|
}
|
|
3099
3255
|
if (_daemonClient) {
|
|
@@ -3109,8 +3265,9 @@ async function disposeDatabase() {
|
|
|
3109
3265
|
_client = null;
|
|
3110
3266
|
_resilientClient = null;
|
|
3111
3267
|
}
|
|
3268
|
+
releaseDbLock();
|
|
3112
3269
|
}
|
|
3113
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3270
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3114
3271
|
var init_database = __esm({
|
|
3115
3272
|
"src/lib/database.ts"() {
|
|
3116
3273
|
"use strict";
|
|
@@ -3118,11 +3275,14 @@ var init_database = __esm({
|
|
|
3118
3275
|
init_employees();
|
|
3119
3276
|
init_database_adapter();
|
|
3120
3277
|
init_memory();
|
|
3278
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3121
3279
|
_client = null;
|
|
3122
3280
|
_resilientClient = null;
|
|
3123
3281
|
_walCheckpointTimer = null;
|
|
3124
3282
|
_daemonClient = null;
|
|
3125
3283
|
_adapterClient = null;
|
|
3284
|
+
_lockFd = null;
|
|
3285
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3126
3286
|
initTurso = initDatabase;
|
|
3127
3287
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3128
3288
|
disposeTurso = disposeDatabase;
|
|
@@ -3131,7 +3291,7 @@ var init_database = __esm({
|
|
|
3131
3291
|
|
|
3132
3292
|
// src/lib/keychain.ts
|
|
3133
3293
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3134
|
-
import { existsSync as
|
|
3294
|
+
import { existsSync as existsSync7, statSync as statSync3 } from "fs";
|
|
3135
3295
|
import { execSync as execSync3 } from "child_process";
|
|
3136
3296
|
import path6 from "path";
|
|
3137
3297
|
import os5 from "os";
|
|
@@ -3166,7 +3326,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3166
3326
|
if (process.platform !== "linux") return false;
|
|
3167
3327
|
try {
|
|
3168
3328
|
const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
|
|
3169
|
-
const st =
|
|
3329
|
+
const st = statSync3(keyPath);
|
|
3170
3330
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3171
3331
|
if (uid === 0) return true;
|
|
3172
3332
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -3367,7 +3527,7 @@ async function getMasterKey() {
|
|
|
3367
3527
|
}
|
|
3368
3528
|
}
|
|
3369
3529
|
const keyPath = getKeyPath();
|
|
3370
|
-
if (!
|
|
3530
|
+
if (!existsSync7(keyPath)) {
|
|
3371
3531
|
process.stderr.write(
|
|
3372
3532
|
`[keychain] Key not found at ${keyPath} (HOME=${os5.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3373
3533
|
`
|
|
@@ -3702,18 +3862,54 @@ __export(shard_manager_exports, {
|
|
|
3702
3862
|
shardExists: () => shardExists
|
|
3703
3863
|
});
|
|
3704
3864
|
import path7 from "path";
|
|
3705
|
-
import { existsSync as
|
|
3865
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync3, statSync as statSync4 } from "fs";
|
|
3706
3866
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3707
3867
|
function initShardManager(encryptionKey) {
|
|
3708
3868
|
_encryptionKey = encryptionKey;
|
|
3709
|
-
|
|
3710
|
-
|
|
3869
|
+
_keyValidated = false;
|
|
3870
|
+
_keyValidationPromise = null;
|
|
3871
|
+
if (!existsSync8(SHARDS_DIR)) {
|
|
3872
|
+
mkdirSync3(SHARDS_DIR, { recursive: true });
|
|
3873
|
+
}
|
|
3874
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3875
|
+
if (existingShards.length === 0) {
|
|
3876
|
+
_keyValidated = true;
|
|
3711
3877
|
}
|
|
3712
3878
|
_shardingEnabled = true;
|
|
3713
3879
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
3714
3880
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
3715
3881
|
_evictionTimer.unref();
|
|
3716
3882
|
}
|
|
3883
|
+
async function validateEncryptionKey() {
|
|
3884
|
+
if (_keyValidated) return true;
|
|
3885
|
+
if (!_encryptionKey) return false;
|
|
3886
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3887
|
+
if (existingShards.length === 0) {
|
|
3888
|
+
_keyValidated = true;
|
|
3889
|
+
return true;
|
|
3890
|
+
}
|
|
3891
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
3892
|
+
const dbPath = path7.join(SHARDS_DIR, shardFile);
|
|
3893
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
3894
|
+
try {
|
|
3895
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
3896
|
+
testClient.close();
|
|
3897
|
+
_keyValidated = true;
|
|
3898
|
+
return true;
|
|
3899
|
+
} catch {
|
|
3900
|
+
try {
|
|
3901
|
+
testClient.close();
|
|
3902
|
+
} catch {
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
process.stderr.write(
|
|
3907
|
+
`[shard-manager] WARNING: encryption key cannot read any existing shards (${existingShards.length} found). New shard creation disabled to prevent stranded files. Run /exe-doctor to audit.
|
|
3908
|
+
`
|
|
3909
|
+
);
|
|
3910
|
+
_shardingEnabled = false;
|
|
3911
|
+
return false;
|
|
3912
|
+
}
|
|
3717
3913
|
function isShardingEnabled() {
|
|
3718
3914
|
return _shardingEnabled;
|
|
3719
3915
|
}
|
|
@@ -3747,13 +3943,13 @@ function getShardClient(projectName) {
|
|
|
3747
3943
|
}
|
|
3748
3944
|
function shardExists(projectName) {
|
|
3749
3945
|
const safeName = safeShardName(projectName);
|
|
3750
|
-
return
|
|
3946
|
+
return existsSync8(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3751
3947
|
}
|
|
3752
3948
|
function safeShardName(projectName) {
|
|
3753
3949
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3754
3950
|
}
|
|
3755
3951
|
function listShards() {
|
|
3756
|
-
if (!
|
|
3952
|
+
if (!existsSync8(SHARDS_DIR)) return [];
|
|
3757
3953
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
3758
3954
|
}
|
|
3759
3955
|
async function auditShardHealth(options = {}) {
|
|
@@ -3766,7 +3962,7 @@ async function auditShardHealth(options = {}) {
|
|
|
3766
3962
|
const shards = [];
|
|
3767
3963
|
for (const name of names) {
|
|
3768
3964
|
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
3769
|
-
const stat =
|
|
3965
|
+
const stat = statSync4(dbPath);
|
|
3770
3966
|
const item = {
|
|
3771
3967
|
name,
|
|
3772
3968
|
path: dbPath,
|
|
@@ -4006,6 +4202,17 @@ async function ensureShardSchema(client) {
|
|
|
4006
4202
|
}
|
|
4007
4203
|
}
|
|
4008
4204
|
async function getReadyShardClient(projectName) {
|
|
4205
|
+
if (!_keyValidated) {
|
|
4206
|
+
if (!_keyValidationPromise) {
|
|
4207
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
4208
|
+
}
|
|
4209
|
+
const valid = await _keyValidationPromise;
|
|
4210
|
+
if (!valid) {
|
|
4211
|
+
throw new Error(
|
|
4212
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
4213
|
+
);
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4009
4216
|
const safeName = safeShardName(projectName);
|
|
4010
4217
|
let client = getShardClient(projectName);
|
|
4011
4218
|
try {
|
|
@@ -4018,8 +4225,8 @@ async function getReadyShardClient(projectName) {
|
|
|
4018
4225
|
_shards.delete(safeName);
|
|
4019
4226
|
_shardLastAccess.delete(safeName);
|
|
4020
4227
|
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
4021
|
-
if (
|
|
4022
|
-
const stat =
|
|
4228
|
+
if (existsSync8(dbPath)) {
|
|
4229
|
+
const stat = statSync4(dbPath);
|
|
4023
4230
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4024
4231
|
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4025
4232
|
renameSync3(dbPath, archivedPath);
|
|
@@ -4084,7 +4291,7 @@ function disposeShards() {
|
|
|
4084
4291
|
_shardingEnabled = false;
|
|
4085
4292
|
_encryptionKey = null;
|
|
4086
4293
|
}
|
|
4087
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
4294
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
4088
4295
|
var init_shard_manager = __esm({
|
|
4089
4296
|
"src/lib/shard-manager.ts"() {
|
|
4090
4297
|
"use strict";
|
|
@@ -4098,6 +4305,8 @@ var init_shard_manager = __esm({
|
|
|
4098
4305
|
_evictionTimer = null;
|
|
4099
4306
|
_encryptionKey = null;
|
|
4100
4307
|
_shardingEnabled = false;
|
|
4308
|
+
_keyValidated = false;
|
|
4309
|
+
_keyValidationPromise = null;
|
|
4101
4310
|
}
|
|
4102
4311
|
});
|
|
4103
4312
|
|
|
@@ -4293,6 +4502,18 @@ var init_platform_procedures = __esm({
|
|
|
4293
4502
|
priority: "p0",
|
|
4294
4503
|
content: "create_task is dispatch + delivery. Task lifecycle: open \u2192 in_progress (you start) \u2192 done (update_task when finished) \u2192 needs_review (reviewer nudged) \u2192 closed (COO only via close_task). DB is the reliable delivery \u2014 intercom is just a speedup nudge. If you finish a task, self-chain: check for next task immediately (step 7). Never wait for a nudge. Never say 'standing by.'"
|
|
4295
4504
|
},
|
|
4505
|
+
{
|
|
4506
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
4507
|
+
domain: "workflow",
|
|
4508
|
+
priority: "p0",
|
|
4509
|
+
content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
|
|
4510
|
+
},
|
|
4511
|
+
{
|
|
4512
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
4513
|
+
domain: "workflow",
|
|
4514
|
+
priority: "p0",
|
|
4515
|
+
content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
|
|
4516
|
+
},
|
|
4296
4517
|
{
|
|
4297
4518
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
4298
4519
|
domain: "architecture",
|
|
@@ -4890,6 +5111,20 @@ __export(store_exports, {
|
|
|
4890
5111
|
vectorToBlob: () => vectorToBlob,
|
|
4891
5112
|
writeMemory: () => writeMemory
|
|
4892
5113
|
});
|
|
5114
|
+
function logStoreDebug(context, err) {
|
|
5115
|
+
if (_debugStore) {
|
|
5116
|
+
process.stderr.write(
|
|
5117
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5118
|
+
`
|
|
5119
|
+
);
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5122
|
+
function logStoreWarn(context, err) {
|
|
5123
|
+
process.stderr.write(
|
|
5124
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5125
|
+
`
|
|
5126
|
+
);
|
|
5127
|
+
}
|
|
4893
5128
|
function isBusyError2(err) {
|
|
4894
5129
|
if (err instanceof Error) {
|
|
4895
5130
|
const msg = err.message.toLowerCase();
|
|
@@ -4944,13 +5179,15 @@ async function initStore(options) {
|
|
|
4944
5179
|
try {
|
|
4945
5180
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
4946
5181
|
await initDaemonClient2();
|
|
4947
|
-
} catch {
|
|
5182
|
+
} catch (e) {
|
|
5183
|
+
logStoreWarn("catch", e);
|
|
4948
5184
|
}
|
|
4949
5185
|
if (!options?.lightweight) {
|
|
4950
5186
|
try {
|
|
4951
5187
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
4952
5188
|
initShardManager2(hexKey);
|
|
4953
|
-
} catch {
|
|
5189
|
+
} catch (e) {
|
|
5190
|
+
logStoreWarn("catch", e);
|
|
4954
5191
|
}
|
|
4955
5192
|
const client = getClient();
|
|
4956
5193
|
const vResult = await retryOnBusy2(
|
|
@@ -4961,7 +5198,8 @@ async function initStore(options) {
|
|
|
4961
5198
|
try {
|
|
4962
5199
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
4963
5200
|
await loadGlobalProcedures2();
|
|
4964
|
-
} catch {
|
|
5201
|
+
} catch (e) {
|
|
5202
|
+
logStoreWarn("catch", e);
|
|
4965
5203
|
}
|
|
4966
5204
|
}
|
|
4967
5205
|
}
|
|
@@ -5021,7 +5259,8 @@ async function writeMemory(record) {
|
|
|
5021
5259
|
memoryType
|
|
5022
5260
|
});
|
|
5023
5261
|
if (existing) return;
|
|
5024
|
-
} catch {
|
|
5262
|
+
} catch (e) {
|
|
5263
|
+
logStoreWarn("catch", e);
|
|
5025
5264
|
}
|
|
5026
5265
|
const dbRow = {
|
|
5027
5266
|
id: record.id,
|
|
@@ -5222,12 +5461,14 @@ async function flushBatch() {
|
|
|
5222
5461
|
try {
|
|
5223
5462
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5224
5463
|
await insertMemoryCardsForBatch2(batch);
|
|
5225
|
-
} catch {
|
|
5464
|
+
} catch (e) {
|
|
5465
|
+
logStoreWarn("catch", e);
|
|
5226
5466
|
}
|
|
5227
5467
|
try {
|
|
5228
5468
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
5229
5469
|
await insertOntologyForBatch2(batch);
|
|
5230
|
-
} catch {
|
|
5470
|
+
} catch (e) {
|
|
5471
|
+
logStoreWarn("catch", e);
|
|
5231
5472
|
}
|
|
5232
5473
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
5233
5474
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -5266,7 +5507,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
5266
5507
|
}
|
|
5267
5508
|
}
|
|
5268
5509
|
}
|
|
5269
|
-
} catch {
|
|
5510
|
+
} catch (e) {
|
|
5511
|
+
logStoreWarn("catch", e);
|
|
5270
5512
|
}
|
|
5271
5513
|
return batch.length;
|
|
5272
5514
|
} finally {
|
|
@@ -5308,7 +5550,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5308
5550
|
} else {
|
|
5309
5551
|
client = getClient();
|
|
5310
5552
|
}
|
|
5311
|
-
} catch {
|
|
5553
|
+
} catch (e) {
|
|
5554
|
+
logStoreDebug("shard routing fallback", e);
|
|
5312
5555
|
client = getClient();
|
|
5313
5556
|
}
|
|
5314
5557
|
const limit = options?.limit ?? 10;
|
|
@@ -5424,7 +5667,8 @@ async function attachDocumentMetadata(records) {
|
|
|
5424
5667
|
if (!record.document_id) continue;
|
|
5425
5668
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
5426
5669
|
}
|
|
5427
|
-
} catch {
|
|
5670
|
+
} catch (e) {
|
|
5671
|
+
logStoreWarn("catch", e);
|
|
5428
5672
|
}
|
|
5429
5673
|
return records;
|
|
5430
5674
|
}
|
|
@@ -5485,11 +5729,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
5485
5729
|
args: [agentId]
|
|
5486
5730
|
});
|
|
5487
5731
|
return Number(result.rows[0]?.cnt) || 0;
|
|
5488
|
-
} catch {
|
|
5732
|
+
} catch (e) {
|
|
5733
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
5489
5734
|
return 0;
|
|
5490
5735
|
}
|
|
5491
5736
|
}
|
|
5492
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5737
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5493
5738
|
var init_store = __esm({
|
|
5494
5739
|
"src/lib/store.ts"() {
|
|
5495
5740
|
"use strict";
|
|
@@ -5499,6 +5744,7 @@ var init_store = __esm({
|
|
|
5499
5744
|
init_config();
|
|
5500
5745
|
init_state_bus();
|
|
5501
5746
|
init_memory_write_governor();
|
|
5747
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
5502
5748
|
INIT_MAX_RETRIES = 3;
|
|
5503
5749
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
5504
5750
|
_pendingRecords = [];
|
|
@@ -5762,7 +6008,7 @@ var init_runtime_table = __esm({
|
|
|
5762
6008
|
});
|
|
5763
6009
|
|
|
5764
6010
|
// src/lib/agent-config.ts
|
|
5765
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as
|
|
6011
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync9 } from "fs";
|
|
5766
6012
|
import path9 from "path";
|
|
5767
6013
|
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
5768
6014
|
var init_agent_config = __esm({
|
|
@@ -5781,7 +6027,7 @@ var init_agent_config = __esm({
|
|
|
5781
6027
|
});
|
|
5782
6028
|
|
|
5783
6029
|
// src/lib/intercom-queue.ts
|
|
5784
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync4, existsSync as
|
|
6030
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync4, existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
|
|
5785
6031
|
import path10 from "path";
|
|
5786
6032
|
import os7 from "os";
|
|
5787
6033
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
@@ -5795,7 +6041,7 @@ var init_intercom_queue = __esm({
|
|
|
5795
6041
|
});
|
|
5796
6042
|
|
|
5797
6043
|
// src/lib/license.ts
|
|
5798
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as
|
|
6044
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync11, mkdirSync as mkdirSync5 } from "fs";
|
|
5799
6045
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5800
6046
|
import { createRequire as createRequire2 } from "module";
|
|
5801
6047
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -5815,7 +6061,7 @@ var init_license = __esm({
|
|
|
5815
6061
|
});
|
|
5816
6062
|
|
|
5817
6063
|
// src/lib/plan-limits.ts
|
|
5818
|
-
import { readFileSync as readFileSync8, existsSync as
|
|
6064
|
+
import { readFileSync as readFileSync8, existsSync as existsSync12 } from "fs";
|
|
5819
6065
|
import path12 from "path";
|
|
5820
6066
|
var CACHE_PATH2;
|
|
5821
6067
|
var init_plan_limits = __esm({
|
|
@@ -5833,9 +6079,9 @@ var init_plan_limits = __esm({
|
|
|
5833
6079
|
import os9 from "os";
|
|
5834
6080
|
import path13 from "path";
|
|
5835
6081
|
import {
|
|
5836
|
-
existsSync as
|
|
6082
|
+
existsSync as existsSync13,
|
|
5837
6083
|
lstatSync,
|
|
5838
|
-
mkdirSync as
|
|
6084
|
+
mkdirSync as mkdirSync6,
|
|
5839
6085
|
readlinkSync as readlinkSync2,
|
|
5840
6086
|
symlinkSync as symlinkSync2
|
|
5841
6087
|
} from "fs";
|
|
@@ -5847,7 +6093,7 @@ var init_agent_symlinks = __esm({
|
|
|
5847
6093
|
});
|
|
5848
6094
|
|
|
5849
6095
|
// src/lib/tmux-routing.ts
|
|
5850
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as
|
|
6096
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync14, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
5851
6097
|
import path14 from "path";
|
|
5852
6098
|
import os10 from "os";
|
|
5853
6099
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -5872,11 +6118,13 @@ function getParentExe(sessionKey) {
|
|
|
5872
6118
|
}
|
|
5873
6119
|
}
|
|
5874
6120
|
function resolveExeSession() {
|
|
5875
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
5876
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
5877
|
-
}
|
|
5878
6121
|
const mySession = getMySession();
|
|
5879
|
-
if (!mySession)
|
|
6122
|
+
if (!mySession) {
|
|
6123
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
6124
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6125
|
+
}
|
|
6126
|
+
return null;
|
|
6127
|
+
}
|
|
5880
6128
|
const fromSessionName = extractRootExe(mySession);
|
|
5881
6129
|
let candidate = null;
|
|
5882
6130
|
try {
|