@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
|
@@ -1782,9 +1782,79 @@ __export(database_exports, {
|
|
|
1782
1782
|
isInitialized: () => isInitialized,
|
|
1783
1783
|
setExternalClient: () => setExternalClient
|
|
1784
1784
|
});
|
|
1785
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
1785
|
+
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";
|
|
1786
1786
|
import { createClient } from "@libsql/client";
|
|
1787
|
+
import { homedir } from "os";
|
|
1788
|
+
import { join } from "path";
|
|
1789
|
+
function logCatchDebug(context, err) {
|
|
1790
|
+
if (_debugDb) {
|
|
1791
|
+
process.stderr.write(
|
|
1792
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
1793
|
+
`
|
|
1794
|
+
);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
function acquireDbLock() {
|
|
1798
|
+
mkdirSync2(join(homedir(), ".exe-os"), { recursive: true });
|
|
1799
|
+
try {
|
|
1800
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1801
|
+
} catch (err) {
|
|
1802
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
1803
|
+
try {
|
|
1804
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
1805
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
1806
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1807
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1808
|
+
return;
|
|
1809
|
+
}
|
|
1810
|
+
} catch (e) {
|
|
1811
|
+
logCatchDebug("stale lock check", e);
|
|
1812
|
+
}
|
|
1813
|
+
process.stderr.write(
|
|
1814
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
1815
|
+
);
|
|
1816
|
+
return;
|
|
1817
|
+
}
|
|
1818
|
+
throw err;
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
function releaseDbLock() {
|
|
1822
|
+
if (_lockFd !== null) {
|
|
1823
|
+
try {
|
|
1824
|
+
closeSync2(_lockFd);
|
|
1825
|
+
} catch (e) {
|
|
1826
|
+
logCatchDebug("lock close", e);
|
|
1827
|
+
}
|
|
1828
|
+
_lockFd = null;
|
|
1829
|
+
}
|
|
1830
|
+
try {
|
|
1831
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1832
|
+
} catch (e) {
|
|
1833
|
+
logCatchDebug("lock unlink", e);
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1787
1836
|
async function initDatabase(config) {
|
|
1837
|
+
acquireDbLock();
|
|
1838
|
+
if (existsSync6(config.dbPath)) {
|
|
1839
|
+
const dbStat = statSync2(config.dbPath);
|
|
1840
|
+
if (dbStat.size === 0) {
|
|
1841
|
+
const walPath = config.dbPath + "-wal";
|
|
1842
|
+
if (existsSync6(walPath) && statSync2(walPath).size > 0) {
|
|
1843
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
1844
|
+
copyFileSync(config.dbPath, backupPath);
|
|
1845
|
+
unlinkSync3(config.dbPath);
|
|
1846
|
+
process.stderr.write(
|
|
1847
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
1848
|
+
`
|
|
1849
|
+
);
|
|
1850
|
+
} else {
|
|
1851
|
+
process.stderr.write(
|
|
1852
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
1853
|
+
`
|
|
1854
|
+
);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1788
1858
|
if (_walCheckpointTimer) {
|
|
1789
1859
|
clearInterval(_walCheckpointTimer);
|
|
1790
1860
|
_walCheckpointTimer = null;
|
|
@@ -1811,10 +1881,8 @@ async function initDatabase(config) {
|
|
|
1811
1881
|
_client = createClient(opts);
|
|
1812
1882
|
_resilientClient = wrapWithRetry(_client);
|
|
1813
1883
|
_adapterClient = _resilientClient;
|
|
1814
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
1815
|
-
|
|
1816
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
1817
|
-
});
|
|
1884
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
1885
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
1818
1886
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
1819
1887
|
_walCheckpointTimer = setInterval(() => {
|
|
1820
1888
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -1829,11 +1897,16 @@ async function initDatabase(config) {
|
|
|
1829
1897
|
for (const suffix of ["-wal", "-shm"]) {
|
|
1830
1898
|
try {
|
|
1831
1899
|
chmodSync2(config.dbPath + suffix, 384);
|
|
1832
|
-
} catch {
|
|
1900
|
+
} catch (chmodErr) {
|
|
1901
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1902
|
+
`);
|
|
1833
1903
|
}
|
|
1834
1904
|
}
|
|
1835
|
-
} catch {
|
|
1905
|
+
} catch (chmodErr) {
|
|
1906
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1907
|
+
`);
|
|
1836
1908
|
}
|
|
1909
|
+
releaseDbLock();
|
|
1837
1910
|
}
|
|
1838
1911
|
function isInitialized() {
|
|
1839
1912
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1888,7 +1961,8 @@ async function ensureSchema() {
|
|
|
1888
1961
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
1889
1962
|
try {
|
|
1890
1963
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1891
|
-
} catch {
|
|
1964
|
+
} catch (e) {
|
|
1965
|
+
logCatchDebug("migration", e);
|
|
1892
1966
|
}
|
|
1893
1967
|
await client.executeMultiple(`
|
|
1894
1968
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -1953,6 +2027,23 @@ async function ensureSchema() {
|
|
|
1953
2027
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
1954
2028
|
END;
|
|
1955
2029
|
`);
|
|
2030
|
+
try {
|
|
2031
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
2032
|
+
} catch (ftsErr) {
|
|
2033
|
+
process.stderr.write(
|
|
2034
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
2035
|
+
`
|
|
2036
|
+
);
|
|
2037
|
+
try {
|
|
2038
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
2039
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
2040
|
+
} catch (rebuildErr) {
|
|
2041
|
+
process.stderr.write(
|
|
2042
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
2043
|
+
`
|
|
2044
|
+
);
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
1956
2047
|
await client.executeMultiple(`
|
|
1957
2048
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
1958
2049
|
key TEXT PRIMARY KEY,
|
|
@@ -2011,35 +2102,40 @@ async function ensureSchema() {
|
|
|
2011
2102
|
});
|
|
2012
2103
|
}
|
|
2013
2104
|
}
|
|
2014
|
-
} catch {
|
|
2105
|
+
} catch (seedErr) {
|
|
2106
|
+
logCatchDebug("behavior seed", seedErr);
|
|
2015
2107
|
}
|
|
2016
2108
|
try {
|
|
2017
2109
|
await client.execute({
|
|
2018
2110
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
2019
2111
|
args: []
|
|
2020
2112
|
});
|
|
2021
|
-
} catch {
|
|
2113
|
+
} catch (e) {
|
|
2114
|
+
logCatchDebug("migration", e);
|
|
2022
2115
|
}
|
|
2023
2116
|
try {
|
|
2024
2117
|
await client.execute({
|
|
2025
2118
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2026
2119
|
args: []
|
|
2027
2120
|
});
|
|
2028
|
-
} catch {
|
|
2121
|
+
} catch (e) {
|
|
2122
|
+
logCatchDebug("migration", e);
|
|
2029
2123
|
}
|
|
2030
2124
|
try {
|
|
2031
2125
|
await client.execute({
|
|
2032
2126
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
2033
2127
|
args: []
|
|
2034
2128
|
});
|
|
2035
|
-
} catch {
|
|
2129
|
+
} catch (e) {
|
|
2130
|
+
logCatchDebug("migration", e);
|
|
2036
2131
|
}
|
|
2037
2132
|
try {
|
|
2038
2133
|
await client.execute({
|
|
2039
2134
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
2040
2135
|
args: []
|
|
2041
2136
|
});
|
|
2042
|
-
} catch {
|
|
2137
|
+
} catch (e) {
|
|
2138
|
+
logCatchDebug("migration", e);
|
|
2043
2139
|
}
|
|
2044
2140
|
try {
|
|
2045
2141
|
await client.execute({
|
|
@@ -2048,98 +2144,112 @@ async function ensureSchema() {
|
|
|
2048
2144
|
WHERE parent_task_id IS NOT NULL`,
|
|
2049
2145
|
args: []
|
|
2050
2146
|
});
|
|
2051
|
-
} catch {
|
|
2147
|
+
} catch (e) {
|
|
2148
|
+
logCatchDebug("migration", e);
|
|
2052
2149
|
}
|
|
2053
2150
|
try {
|
|
2054
2151
|
await client.execute({
|
|
2055
2152
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
2056
2153
|
args: []
|
|
2057
2154
|
});
|
|
2058
|
-
} catch {
|
|
2155
|
+
} catch (e) {
|
|
2156
|
+
logCatchDebug("migration", e);
|
|
2059
2157
|
}
|
|
2060
2158
|
try {
|
|
2061
2159
|
await client.execute({
|
|
2062
2160
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
2063
2161
|
args: []
|
|
2064
2162
|
});
|
|
2065
|
-
} catch {
|
|
2163
|
+
} catch (e) {
|
|
2164
|
+
logCatchDebug("migration", e);
|
|
2066
2165
|
}
|
|
2067
2166
|
try {
|
|
2068
2167
|
await client.execute({
|
|
2069
2168
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
2070
2169
|
args: []
|
|
2071
2170
|
});
|
|
2072
|
-
} catch {
|
|
2171
|
+
} catch (e) {
|
|
2172
|
+
logCatchDebug("migration", e);
|
|
2073
2173
|
}
|
|
2074
2174
|
try {
|
|
2075
2175
|
await client.execute({
|
|
2076
2176
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
2077
2177
|
args: []
|
|
2078
2178
|
});
|
|
2079
|
-
} catch {
|
|
2179
|
+
} catch (e) {
|
|
2180
|
+
logCatchDebug("migration", e);
|
|
2080
2181
|
}
|
|
2081
2182
|
try {
|
|
2082
2183
|
await client.execute({
|
|
2083
2184
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
2084
2185
|
args: []
|
|
2085
2186
|
});
|
|
2086
|
-
} catch {
|
|
2187
|
+
} catch (e) {
|
|
2188
|
+
logCatchDebug("migration", e);
|
|
2087
2189
|
}
|
|
2088
2190
|
try {
|
|
2089
2191
|
await client.execute({
|
|
2090
2192
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
2091
2193
|
args: []
|
|
2092
2194
|
});
|
|
2093
|
-
} catch {
|
|
2195
|
+
} catch (e) {
|
|
2196
|
+
logCatchDebug("migration", e);
|
|
2094
2197
|
}
|
|
2095
2198
|
try {
|
|
2096
2199
|
await client.execute({
|
|
2097
2200
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2098
2201
|
args: []
|
|
2099
2202
|
});
|
|
2100
|
-
} catch {
|
|
2203
|
+
} catch (e) {
|
|
2204
|
+
logCatchDebug("migration", e);
|
|
2101
2205
|
}
|
|
2102
2206
|
try {
|
|
2103
2207
|
await client.execute({
|
|
2104
2208
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2105
2209
|
args: []
|
|
2106
2210
|
});
|
|
2107
|
-
} catch {
|
|
2211
|
+
} catch (e) {
|
|
2212
|
+
logCatchDebug("migration", e);
|
|
2108
2213
|
}
|
|
2109
2214
|
try {
|
|
2110
2215
|
await client.execute({
|
|
2111
2216
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2112
2217
|
args: []
|
|
2113
2218
|
});
|
|
2114
|
-
} catch {
|
|
2219
|
+
} catch (e) {
|
|
2220
|
+
logCatchDebug("migration", e);
|
|
2115
2221
|
}
|
|
2116
2222
|
try {
|
|
2117
2223
|
await client.execute({
|
|
2118
2224
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2119
2225
|
args: []
|
|
2120
2226
|
});
|
|
2121
|
-
} catch {
|
|
2227
|
+
} catch (e) {
|
|
2228
|
+
logCatchDebug("migration", e);
|
|
2122
2229
|
}
|
|
2123
2230
|
try {
|
|
2124
2231
|
await client.execute({
|
|
2125
2232
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2126
2233
|
args: []
|
|
2127
2234
|
});
|
|
2128
|
-
} catch {
|
|
2235
|
+
} catch (e) {
|
|
2236
|
+
logCatchDebug("migration", e);
|
|
2129
2237
|
}
|
|
2130
2238
|
try {
|
|
2131
2239
|
await client.execute({
|
|
2132
2240
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2133
2241
|
args: []
|
|
2134
2242
|
});
|
|
2135
|
-
} catch {
|
|
2243
|
+
} catch (e) {
|
|
2244
|
+
logCatchDebug("migration", e);
|
|
2136
2245
|
}
|
|
2137
2246
|
try {
|
|
2138
2247
|
await client.execute({
|
|
2139
2248
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2140
2249
|
args: []
|
|
2141
2250
|
});
|
|
2142
|
-
} catch {
|
|
2251
|
+
} catch (e) {
|
|
2252
|
+
logCatchDebug("migration", e);
|
|
2143
2253
|
}
|
|
2144
2254
|
await client.executeMultiple(`
|
|
2145
2255
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2244,14 +2354,16 @@ async function ensureSchema() {
|
|
|
2244
2354
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2245
2355
|
args: []
|
|
2246
2356
|
});
|
|
2247
|
-
} catch {
|
|
2357
|
+
} catch (e) {
|
|
2358
|
+
logCatchDebug("migration", e);
|
|
2248
2359
|
}
|
|
2249
2360
|
try {
|
|
2250
2361
|
await client.execute({
|
|
2251
2362
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2252
2363
|
args: []
|
|
2253
2364
|
});
|
|
2254
|
-
} catch {
|
|
2365
|
+
} catch (e) {
|
|
2366
|
+
logCatchDebug("migration", e);
|
|
2255
2367
|
}
|
|
2256
2368
|
await client.executeMultiple(`
|
|
2257
2369
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2277,7 +2389,8 @@ async function ensureSchema() {
|
|
|
2277
2389
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2278
2390
|
args: []
|
|
2279
2391
|
});
|
|
2280
|
-
} catch {
|
|
2392
|
+
} catch (e) {
|
|
2393
|
+
logCatchDebug("migration", e);
|
|
2281
2394
|
}
|
|
2282
2395
|
await client.executeMultiple(`
|
|
2283
2396
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -2301,7 +2414,8 @@ async function ensureSchema() {
|
|
|
2301
2414
|
`);
|
|
2302
2415
|
try {
|
|
2303
2416
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
2304
|
-
} catch {
|
|
2417
|
+
} catch (e) {
|
|
2418
|
+
logCatchDebug("migration", e);
|
|
2305
2419
|
}
|
|
2306
2420
|
await client.executeMultiple(`
|
|
2307
2421
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2338,63 +2452,72 @@ async function ensureSchema() {
|
|
|
2338
2452
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2339
2453
|
args: []
|
|
2340
2454
|
});
|
|
2341
|
-
} catch {
|
|
2455
|
+
} catch (e) {
|
|
2456
|
+
logCatchDebug("migration", e);
|
|
2342
2457
|
}
|
|
2343
2458
|
try {
|
|
2344
2459
|
await client.execute({
|
|
2345
2460
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
2346
2461
|
args: []
|
|
2347
2462
|
});
|
|
2348
|
-
} catch {
|
|
2463
|
+
} catch (e) {
|
|
2464
|
+
logCatchDebug("migration", e);
|
|
2349
2465
|
}
|
|
2350
2466
|
try {
|
|
2351
2467
|
await client.execute({
|
|
2352
2468
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
2353
2469
|
args: []
|
|
2354
2470
|
});
|
|
2355
|
-
} catch {
|
|
2471
|
+
} catch (e) {
|
|
2472
|
+
logCatchDebug("migration", e);
|
|
2356
2473
|
}
|
|
2357
2474
|
try {
|
|
2358
2475
|
await client.execute({
|
|
2359
2476
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
2360
2477
|
args: []
|
|
2361
2478
|
});
|
|
2362
|
-
} catch {
|
|
2479
|
+
} catch (e) {
|
|
2480
|
+
logCatchDebug("migration", e);
|
|
2363
2481
|
}
|
|
2364
2482
|
try {
|
|
2365
2483
|
await client.execute({
|
|
2366
2484
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
2367
2485
|
args: []
|
|
2368
2486
|
});
|
|
2369
|
-
} catch {
|
|
2487
|
+
} catch (e) {
|
|
2488
|
+
logCatchDebug("migration", e);
|
|
2370
2489
|
}
|
|
2371
2490
|
try {
|
|
2372
2491
|
await client.execute({
|
|
2373
2492
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
2374
2493
|
args: []
|
|
2375
2494
|
});
|
|
2376
|
-
} catch {
|
|
2495
|
+
} catch (e) {
|
|
2496
|
+
logCatchDebug("migration", e);
|
|
2377
2497
|
}
|
|
2378
2498
|
try {
|
|
2379
2499
|
await client.execute({
|
|
2380
2500
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
2381
2501
|
args: []
|
|
2382
2502
|
});
|
|
2383
|
-
} catch {
|
|
2503
|
+
} catch (e) {
|
|
2504
|
+
logCatchDebug("migration", e);
|
|
2384
2505
|
}
|
|
2385
2506
|
try {
|
|
2386
2507
|
await client.execute({
|
|
2387
2508
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2388
2509
|
args: []
|
|
2389
2510
|
});
|
|
2390
|
-
} catch {
|
|
2511
|
+
} catch (e) {
|
|
2512
|
+
logCatchDebug("migration", e);
|
|
2391
2513
|
}
|
|
2392
2514
|
try {
|
|
2393
2515
|
await client.execute({
|
|
2394
2516
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2395
2517
|
args: []
|
|
2396
2518
|
});
|
|
2397
|
-
} catch {
|
|
2519
|
+
} catch (e) {
|
|
2520
|
+
logCatchDebug("migration", e);
|
|
2398
2521
|
}
|
|
2399
2522
|
for (const col of [
|
|
2400
2523
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2402,14 +2525,16 @@ async function ensureSchema() {
|
|
|
2402
2525
|
]) {
|
|
2403
2526
|
try {
|
|
2404
2527
|
await client.execute(col);
|
|
2405
|
-
} catch {
|
|
2528
|
+
} catch (e) {
|
|
2529
|
+
logCatchDebug("migration", e);
|
|
2406
2530
|
}
|
|
2407
2531
|
}
|
|
2408
2532
|
try {
|
|
2409
2533
|
await client.execute(
|
|
2410
2534
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2411
2535
|
);
|
|
2412
|
-
} catch {
|
|
2536
|
+
} catch (e) {
|
|
2537
|
+
logCatchDebug("migration", e);
|
|
2413
2538
|
}
|
|
2414
2539
|
try {
|
|
2415
2540
|
await client.execute(
|
|
@@ -2417,7 +2542,8 @@ async function ensureSchema() {
|
|
|
2417
2542
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2418
2543
|
WHERE content_hash IS NOT NULL`
|
|
2419
2544
|
);
|
|
2420
|
-
} catch {
|
|
2545
|
+
} catch (e) {
|
|
2546
|
+
logCatchDebug("migration", e);
|
|
2421
2547
|
}
|
|
2422
2548
|
await client.executeMultiple(`
|
|
2423
2549
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -2493,7 +2619,8 @@ async function ensureSchema() {
|
|
|
2493
2619
|
`);
|
|
2494
2620
|
try {
|
|
2495
2621
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
2496
|
-
} catch {
|
|
2622
|
+
} catch (e) {
|
|
2623
|
+
logCatchDebug("migration", e);
|
|
2497
2624
|
}
|
|
2498
2625
|
await client.executeMultiple(`
|
|
2499
2626
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -2508,14 +2635,16 @@ async function ensureSchema() {
|
|
|
2508
2635
|
]) {
|
|
2509
2636
|
try {
|
|
2510
2637
|
await client.execute(col);
|
|
2511
|
-
} catch {
|
|
2638
|
+
} catch (e) {
|
|
2639
|
+
logCatchDebug("migration", e);
|
|
2512
2640
|
}
|
|
2513
2641
|
}
|
|
2514
2642
|
try {
|
|
2515
2643
|
await client.execute(
|
|
2516
2644
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
2517
2645
|
);
|
|
2518
|
-
} catch {
|
|
2646
|
+
} catch (e) {
|
|
2647
|
+
logCatchDebug("migration", e);
|
|
2519
2648
|
}
|
|
2520
2649
|
await client.executeMultiple(`
|
|
2521
2650
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -2614,7 +2743,8 @@ async function ensureSchema() {
|
|
|
2614
2743
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
2615
2744
|
args: []
|
|
2616
2745
|
});
|
|
2617
|
-
} catch {
|
|
2746
|
+
} catch (e) {
|
|
2747
|
+
logCatchDebug("migration", e);
|
|
2618
2748
|
}
|
|
2619
2749
|
}
|
|
2620
2750
|
for (const col of [
|
|
@@ -2623,7 +2753,8 @@ async function ensureSchema() {
|
|
|
2623
2753
|
]) {
|
|
2624
2754
|
try {
|
|
2625
2755
|
await client.execute(col);
|
|
2626
|
-
} catch {
|
|
2756
|
+
} catch (e) {
|
|
2757
|
+
logCatchDebug("migration", e);
|
|
2627
2758
|
}
|
|
2628
2759
|
}
|
|
2629
2760
|
await client.executeMultiple(`
|
|
@@ -2808,56 +2939,64 @@ async function ensureSchema() {
|
|
|
2808
2939
|
args: []
|
|
2809
2940
|
});
|
|
2810
2941
|
}
|
|
2811
|
-
} catch {
|
|
2942
|
+
} catch (e) {
|
|
2943
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
2812
2944
|
}
|
|
2813
2945
|
try {
|
|
2814
2946
|
await client.execute({
|
|
2815
2947
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
2816
2948
|
args: []
|
|
2817
2949
|
});
|
|
2818
|
-
} catch {
|
|
2950
|
+
} catch (e) {
|
|
2951
|
+
logCatchDebug("migration", e);
|
|
2819
2952
|
}
|
|
2820
2953
|
try {
|
|
2821
2954
|
await client.execute({
|
|
2822
2955
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
2823
2956
|
args: []
|
|
2824
2957
|
});
|
|
2825
|
-
} catch {
|
|
2958
|
+
} catch (e) {
|
|
2959
|
+
logCatchDebug("migration", e);
|
|
2826
2960
|
}
|
|
2827
2961
|
try {
|
|
2828
2962
|
await client.execute({
|
|
2829
2963
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
2830
2964
|
args: []
|
|
2831
2965
|
});
|
|
2832
|
-
} catch {
|
|
2966
|
+
} catch (e) {
|
|
2967
|
+
logCatchDebug("migration", e);
|
|
2833
2968
|
}
|
|
2834
2969
|
try {
|
|
2835
2970
|
await client.execute({
|
|
2836
2971
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
2837
2972
|
args: []
|
|
2838
2973
|
});
|
|
2839
|
-
} catch {
|
|
2974
|
+
} catch (e) {
|
|
2975
|
+
logCatchDebug("migration", e);
|
|
2840
2976
|
}
|
|
2841
2977
|
try {
|
|
2842
2978
|
await client.execute({
|
|
2843
2979
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
2844
2980
|
args: []
|
|
2845
2981
|
});
|
|
2846
|
-
} catch {
|
|
2982
|
+
} catch (e) {
|
|
2983
|
+
logCatchDebug("migration", e);
|
|
2847
2984
|
}
|
|
2848
2985
|
try {
|
|
2849
2986
|
await client.execute({
|
|
2850
2987
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2851
2988
|
args: []
|
|
2852
2989
|
});
|
|
2853
|
-
} catch {
|
|
2990
|
+
} catch (e) {
|
|
2991
|
+
logCatchDebug("migration", e);
|
|
2854
2992
|
}
|
|
2855
2993
|
try {
|
|
2856
2994
|
await client.execute({
|
|
2857
2995
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2858
2996
|
args: []
|
|
2859
2997
|
});
|
|
2860
|
-
} catch {
|
|
2998
|
+
} catch (e) {
|
|
2999
|
+
logCatchDebug("migration", e);
|
|
2861
3000
|
}
|
|
2862
3001
|
await client.executeMultiple(`
|
|
2863
3002
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -3056,13 +3195,15 @@ async function ensureSchema() {
|
|
|
3056
3195
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
3057
3196
|
args: []
|
|
3058
3197
|
});
|
|
3059
|
-
} catch {
|
|
3198
|
+
} catch (e) {
|
|
3199
|
+
logCatchDebug("migration", e);
|
|
3060
3200
|
}
|
|
3061
3201
|
try {
|
|
3062
3202
|
await client.execute(
|
|
3063
3203
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
3064
3204
|
);
|
|
3065
|
-
} catch {
|
|
3205
|
+
} catch (e) {
|
|
3206
|
+
logCatchDebug("migration", e);
|
|
3066
3207
|
}
|
|
3067
3208
|
try {
|
|
3068
3209
|
await client.execute({
|
|
@@ -3073,20 +3214,23 @@ async function ensureSchema() {
|
|
|
3073
3214
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
3074
3215
|
args: []
|
|
3075
3216
|
});
|
|
3076
|
-
} catch {
|
|
3217
|
+
} catch (e) {
|
|
3218
|
+
logCatchDebug("migration", e);
|
|
3077
3219
|
}
|
|
3078
3220
|
try {
|
|
3079
3221
|
await client.execute({
|
|
3080
3222
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
3081
3223
|
args: []
|
|
3082
3224
|
});
|
|
3083
|
-
} catch {
|
|
3225
|
+
} catch (e) {
|
|
3226
|
+
logCatchDebug("migration", e);
|
|
3084
3227
|
}
|
|
3085
3228
|
try {
|
|
3086
3229
|
await client.execute(
|
|
3087
3230
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
3088
3231
|
);
|
|
3089
|
-
} catch {
|
|
3232
|
+
} catch (e) {
|
|
3233
|
+
logCatchDebug("migration", e);
|
|
3090
3234
|
}
|
|
3091
3235
|
for (const col of [
|
|
3092
3236
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -3094,7 +3238,8 @@ async function ensureSchema() {
|
|
|
3094
3238
|
]) {
|
|
3095
3239
|
try {
|
|
3096
3240
|
await client.execute(col);
|
|
3097
|
-
} catch {
|
|
3241
|
+
} catch (e) {
|
|
3242
|
+
logCatchDebug("migration", e);
|
|
3098
3243
|
}
|
|
3099
3244
|
}
|
|
3100
3245
|
try {
|
|
@@ -3102,13 +3247,15 @@ async function ensureSchema() {
|
|
|
3102
3247
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3103
3248
|
args: []
|
|
3104
3249
|
});
|
|
3105
|
-
} catch {
|
|
3250
|
+
} catch (e) {
|
|
3251
|
+
logCatchDebug("migration", e);
|
|
3106
3252
|
}
|
|
3107
3253
|
try {
|
|
3108
3254
|
await client.execute(
|
|
3109
3255
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3110
3256
|
);
|
|
3111
|
-
} catch {
|
|
3257
|
+
} catch (e) {
|
|
3258
|
+
logCatchDebug("migration", e);
|
|
3112
3259
|
}
|
|
3113
3260
|
for (const col of [
|
|
3114
3261
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3116,7 +3263,8 @@ async function ensureSchema() {
|
|
|
3116
3263
|
]) {
|
|
3117
3264
|
try {
|
|
3118
3265
|
await client.execute(col);
|
|
3119
|
-
} catch {
|
|
3266
|
+
} catch (e) {
|
|
3267
|
+
logCatchDebug("migration", e);
|
|
3120
3268
|
}
|
|
3121
3269
|
}
|
|
3122
3270
|
try {
|
|
@@ -3124,27 +3272,31 @@ async function ensureSchema() {
|
|
|
3124
3272
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3125
3273
|
args: []
|
|
3126
3274
|
});
|
|
3127
|
-
} catch {
|
|
3275
|
+
} catch (e) {
|
|
3276
|
+
logCatchDebug("migration", e);
|
|
3128
3277
|
}
|
|
3129
3278
|
try {
|
|
3130
3279
|
await client.execute({
|
|
3131
3280
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3132
3281
|
args: []
|
|
3133
3282
|
});
|
|
3134
|
-
} catch {
|
|
3283
|
+
} catch (e) {
|
|
3284
|
+
logCatchDebug("migration", e);
|
|
3135
3285
|
}
|
|
3136
3286
|
try {
|
|
3137
3287
|
await client.execute(
|
|
3138
3288
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3139
3289
|
);
|
|
3140
|
-
} catch {
|
|
3290
|
+
} catch (e) {
|
|
3291
|
+
logCatchDebug("migration", e);
|
|
3141
3292
|
}
|
|
3142
3293
|
try {
|
|
3143
3294
|
await client.execute({
|
|
3144
3295
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3145
3296
|
args: []
|
|
3146
3297
|
});
|
|
3147
|
-
} catch {
|
|
3298
|
+
} catch (e) {
|
|
3299
|
+
logCatchDebug("migration", e);
|
|
3148
3300
|
}
|
|
3149
3301
|
for (const col of [
|
|
3150
3302
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3165,7 +3317,8 @@ async function ensureSchema() {
|
|
|
3165
3317
|
]) {
|
|
3166
3318
|
try {
|
|
3167
3319
|
await client.execute(col);
|
|
3168
|
-
} catch {
|
|
3320
|
+
} catch (e) {
|
|
3321
|
+
logCatchDebug("migration", e);
|
|
3169
3322
|
}
|
|
3170
3323
|
}
|
|
3171
3324
|
try {
|
|
@@ -3173,14 +3326,16 @@ async function ensureSchema() {
|
|
|
3173
3326
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3174
3327
|
args: []
|
|
3175
3328
|
});
|
|
3176
|
-
} catch {
|
|
3329
|
+
} catch (e) {
|
|
3330
|
+
logCatchDebug("migration", e);
|
|
3177
3331
|
}
|
|
3178
3332
|
try {
|
|
3179
3333
|
await client.execute({
|
|
3180
3334
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3181
3335
|
args: []
|
|
3182
3336
|
});
|
|
3183
|
-
} catch {
|
|
3337
|
+
} catch (e) {
|
|
3338
|
+
logCatchDebug("migration", e);
|
|
3184
3339
|
}
|
|
3185
3340
|
}
|
|
3186
3341
|
async function disposeDatabase() {
|
|
@@ -3191,7 +3346,8 @@ async function disposeDatabase() {
|
|
|
3191
3346
|
if (_client) {
|
|
3192
3347
|
try {
|
|
3193
3348
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3194
|
-
} catch {
|
|
3349
|
+
} catch (e) {
|
|
3350
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3195
3351
|
}
|
|
3196
3352
|
}
|
|
3197
3353
|
if (_daemonClient) {
|
|
@@ -3207,8 +3363,9 @@ async function disposeDatabase() {
|
|
|
3207
3363
|
_client = null;
|
|
3208
3364
|
_resilientClient = null;
|
|
3209
3365
|
}
|
|
3366
|
+
releaseDbLock();
|
|
3210
3367
|
}
|
|
3211
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3368
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3212
3369
|
var init_database = __esm({
|
|
3213
3370
|
"src/lib/database.ts"() {
|
|
3214
3371
|
"use strict";
|
|
@@ -3216,11 +3373,14 @@ var init_database = __esm({
|
|
|
3216
3373
|
init_employees();
|
|
3217
3374
|
init_database_adapter();
|
|
3218
3375
|
init_memory();
|
|
3376
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3219
3377
|
_client = null;
|
|
3220
3378
|
_resilientClient = null;
|
|
3221
3379
|
_walCheckpointTimer = null;
|
|
3222
3380
|
_daemonClient = null;
|
|
3223
3381
|
_adapterClient = null;
|
|
3382
|
+
_lockFd = null;
|
|
3383
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3224
3384
|
initTurso = initDatabase;
|
|
3225
3385
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3226
3386
|
disposeTurso = disposeDatabase;
|
|
@@ -3229,7 +3389,7 @@ var init_database = __esm({
|
|
|
3229
3389
|
|
|
3230
3390
|
// src/lib/keychain.ts
|
|
3231
3391
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3232
|
-
import { existsSync as
|
|
3392
|
+
import { existsSync as existsSync7, statSync as statSync3 } from "fs";
|
|
3233
3393
|
import { execSync as execSync3 } from "child_process";
|
|
3234
3394
|
import path6 from "path";
|
|
3235
3395
|
import os5 from "os";
|
|
@@ -3264,7 +3424,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3264
3424
|
if (process.platform !== "linux") return false;
|
|
3265
3425
|
try {
|
|
3266
3426
|
const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
|
|
3267
|
-
const st =
|
|
3427
|
+
const st = statSync3(keyPath);
|
|
3268
3428
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3269
3429
|
if (uid === 0) return true;
|
|
3270
3430
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -3465,7 +3625,7 @@ async function getMasterKey() {
|
|
|
3465
3625
|
}
|
|
3466
3626
|
}
|
|
3467
3627
|
const keyPath = getKeyPath();
|
|
3468
|
-
if (!
|
|
3628
|
+
if (!existsSync7(keyPath)) {
|
|
3469
3629
|
process.stderr.write(
|
|
3470
3630
|
`[keychain] Key not found at ${keyPath} (HOME=${os5.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3471
3631
|
`
|
|
@@ -3800,18 +3960,54 @@ __export(shard_manager_exports, {
|
|
|
3800
3960
|
shardExists: () => shardExists
|
|
3801
3961
|
});
|
|
3802
3962
|
import path7 from "path";
|
|
3803
|
-
import { existsSync as
|
|
3963
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync3, statSync as statSync4 } from "fs";
|
|
3804
3964
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3805
3965
|
function initShardManager(encryptionKey) {
|
|
3806
3966
|
_encryptionKey = encryptionKey;
|
|
3807
|
-
|
|
3808
|
-
|
|
3967
|
+
_keyValidated = false;
|
|
3968
|
+
_keyValidationPromise = null;
|
|
3969
|
+
if (!existsSync8(SHARDS_DIR)) {
|
|
3970
|
+
mkdirSync3(SHARDS_DIR, { recursive: true });
|
|
3971
|
+
}
|
|
3972
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3973
|
+
if (existingShards.length === 0) {
|
|
3974
|
+
_keyValidated = true;
|
|
3809
3975
|
}
|
|
3810
3976
|
_shardingEnabled = true;
|
|
3811
3977
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
3812
3978
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
3813
3979
|
_evictionTimer.unref();
|
|
3814
3980
|
}
|
|
3981
|
+
async function validateEncryptionKey() {
|
|
3982
|
+
if (_keyValidated) return true;
|
|
3983
|
+
if (!_encryptionKey) return false;
|
|
3984
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3985
|
+
if (existingShards.length === 0) {
|
|
3986
|
+
_keyValidated = true;
|
|
3987
|
+
return true;
|
|
3988
|
+
}
|
|
3989
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
3990
|
+
const dbPath = path7.join(SHARDS_DIR, shardFile);
|
|
3991
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
3992
|
+
try {
|
|
3993
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
3994
|
+
testClient.close();
|
|
3995
|
+
_keyValidated = true;
|
|
3996
|
+
return true;
|
|
3997
|
+
} catch {
|
|
3998
|
+
try {
|
|
3999
|
+
testClient.close();
|
|
4000
|
+
} catch {
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
process.stderr.write(
|
|
4005
|
+
`[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.
|
|
4006
|
+
`
|
|
4007
|
+
);
|
|
4008
|
+
_shardingEnabled = false;
|
|
4009
|
+
return false;
|
|
4010
|
+
}
|
|
3815
4011
|
function isShardingEnabled() {
|
|
3816
4012
|
return _shardingEnabled;
|
|
3817
4013
|
}
|
|
@@ -3845,13 +4041,13 @@ function getShardClient(projectName) {
|
|
|
3845
4041
|
}
|
|
3846
4042
|
function shardExists(projectName) {
|
|
3847
4043
|
const safeName = safeShardName(projectName);
|
|
3848
|
-
return
|
|
4044
|
+
return existsSync8(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3849
4045
|
}
|
|
3850
4046
|
function safeShardName(projectName) {
|
|
3851
4047
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3852
4048
|
}
|
|
3853
4049
|
function listShards() {
|
|
3854
|
-
if (!
|
|
4050
|
+
if (!existsSync8(SHARDS_DIR)) return [];
|
|
3855
4051
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
3856
4052
|
}
|
|
3857
4053
|
async function auditShardHealth(options = {}) {
|
|
@@ -3864,7 +4060,7 @@ async function auditShardHealth(options = {}) {
|
|
|
3864
4060
|
const shards = [];
|
|
3865
4061
|
for (const name of names) {
|
|
3866
4062
|
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
3867
|
-
const stat =
|
|
4063
|
+
const stat = statSync4(dbPath);
|
|
3868
4064
|
const item = {
|
|
3869
4065
|
name,
|
|
3870
4066
|
path: dbPath,
|
|
@@ -4104,6 +4300,17 @@ async function ensureShardSchema(client) {
|
|
|
4104
4300
|
}
|
|
4105
4301
|
}
|
|
4106
4302
|
async function getReadyShardClient(projectName) {
|
|
4303
|
+
if (!_keyValidated) {
|
|
4304
|
+
if (!_keyValidationPromise) {
|
|
4305
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
4306
|
+
}
|
|
4307
|
+
const valid = await _keyValidationPromise;
|
|
4308
|
+
if (!valid) {
|
|
4309
|
+
throw new Error(
|
|
4310
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
4311
|
+
);
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4107
4314
|
const safeName = safeShardName(projectName);
|
|
4108
4315
|
let client = getShardClient(projectName);
|
|
4109
4316
|
try {
|
|
@@ -4116,8 +4323,8 @@ async function getReadyShardClient(projectName) {
|
|
|
4116
4323
|
_shards.delete(safeName);
|
|
4117
4324
|
_shardLastAccess.delete(safeName);
|
|
4118
4325
|
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
4119
|
-
if (
|
|
4120
|
-
const stat =
|
|
4326
|
+
if (existsSync8(dbPath)) {
|
|
4327
|
+
const stat = statSync4(dbPath);
|
|
4121
4328
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4122
4329
|
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4123
4330
|
renameSync3(dbPath, archivedPath);
|
|
@@ -4182,7 +4389,7 @@ function disposeShards() {
|
|
|
4182
4389
|
_shardingEnabled = false;
|
|
4183
4390
|
_encryptionKey = null;
|
|
4184
4391
|
}
|
|
4185
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
4392
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
4186
4393
|
var init_shard_manager = __esm({
|
|
4187
4394
|
"src/lib/shard-manager.ts"() {
|
|
4188
4395
|
"use strict";
|
|
@@ -4196,6 +4403,8 @@ var init_shard_manager = __esm({
|
|
|
4196
4403
|
_evictionTimer = null;
|
|
4197
4404
|
_encryptionKey = null;
|
|
4198
4405
|
_shardingEnabled = false;
|
|
4406
|
+
_keyValidated = false;
|
|
4407
|
+
_keyValidationPromise = null;
|
|
4199
4408
|
}
|
|
4200
4409
|
});
|
|
4201
4410
|
|
|
@@ -4391,6 +4600,18 @@ var init_platform_procedures = __esm({
|
|
|
4391
4600
|
priority: "p0",
|
|
4392
4601
|
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.'"
|
|
4393
4602
|
},
|
|
4603
|
+
{
|
|
4604
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
4605
|
+
domain: "workflow",
|
|
4606
|
+
priority: "p0",
|
|
4607
|
+
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."
|
|
4608
|
+
},
|
|
4609
|
+
{
|
|
4610
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
4611
|
+
domain: "workflow",
|
|
4612
|
+
priority: "p0",
|
|
4613
|
+
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."
|
|
4614
|
+
},
|
|
4394
4615
|
{
|
|
4395
4616
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
4396
4617
|
domain: "architecture",
|
|
@@ -4988,6 +5209,20 @@ __export(store_exports, {
|
|
|
4988
5209
|
vectorToBlob: () => vectorToBlob,
|
|
4989
5210
|
writeMemory: () => writeMemory
|
|
4990
5211
|
});
|
|
5212
|
+
function logStoreDebug(context, err) {
|
|
5213
|
+
if (_debugStore) {
|
|
5214
|
+
process.stderr.write(
|
|
5215
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5216
|
+
`
|
|
5217
|
+
);
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
function logStoreWarn(context, err) {
|
|
5221
|
+
process.stderr.write(
|
|
5222
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5223
|
+
`
|
|
5224
|
+
);
|
|
5225
|
+
}
|
|
4991
5226
|
function isBusyError2(err) {
|
|
4992
5227
|
if (err instanceof Error) {
|
|
4993
5228
|
const msg = err.message.toLowerCase();
|
|
@@ -5042,13 +5277,15 @@ async function initStore(options) {
|
|
|
5042
5277
|
try {
|
|
5043
5278
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5044
5279
|
await initDaemonClient2();
|
|
5045
|
-
} catch {
|
|
5280
|
+
} catch (e) {
|
|
5281
|
+
logStoreWarn("catch", e);
|
|
5046
5282
|
}
|
|
5047
5283
|
if (!options?.lightweight) {
|
|
5048
5284
|
try {
|
|
5049
5285
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
5050
5286
|
initShardManager2(hexKey);
|
|
5051
|
-
} catch {
|
|
5287
|
+
} catch (e) {
|
|
5288
|
+
logStoreWarn("catch", e);
|
|
5052
5289
|
}
|
|
5053
5290
|
const client = getClient();
|
|
5054
5291
|
const vResult = await retryOnBusy2(
|
|
@@ -5059,7 +5296,8 @@ async function initStore(options) {
|
|
|
5059
5296
|
try {
|
|
5060
5297
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
5061
5298
|
await loadGlobalProcedures2();
|
|
5062
|
-
} catch {
|
|
5299
|
+
} catch (e) {
|
|
5300
|
+
logStoreWarn("catch", e);
|
|
5063
5301
|
}
|
|
5064
5302
|
}
|
|
5065
5303
|
}
|
|
@@ -5119,7 +5357,8 @@ async function writeMemory(record) {
|
|
|
5119
5357
|
memoryType
|
|
5120
5358
|
});
|
|
5121
5359
|
if (existing) return;
|
|
5122
|
-
} catch {
|
|
5360
|
+
} catch (e) {
|
|
5361
|
+
logStoreWarn("catch", e);
|
|
5123
5362
|
}
|
|
5124
5363
|
const dbRow = {
|
|
5125
5364
|
id: record.id,
|
|
@@ -5320,12 +5559,14 @@ async function flushBatch() {
|
|
|
5320
5559
|
try {
|
|
5321
5560
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5322
5561
|
await insertMemoryCardsForBatch2(batch);
|
|
5323
|
-
} catch {
|
|
5562
|
+
} catch (e) {
|
|
5563
|
+
logStoreWarn("catch", e);
|
|
5324
5564
|
}
|
|
5325
5565
|
try {
|
|
5326
5566
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
5327
5567
|
await insertOntologyForBatch2(batch);
|
|
5328
|
-
} catch {
|
|
5568
|
+
} catch (e) {
|
|
5569
|
+
logStoreWarn("catch", e);
|
|
5329
5570
|
}
|
|
5330
5571
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
5331
5572
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -5364,7 +5605,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
5364
5605
|
}
|
|
5365
5606
|
}
|
|
5366
5607
|
}
|
|
5367
|
-
} catch {
|
|
5608
|
+
} catch (e) {
|
|
5609
|
+
logStoreWarn("catch", e);
|
|
5368
5610
|
}
|
|
5369
5611
|
return batch.length;
|
|
5370
5612
|
} finally {
|
|
@@ -5406,7 +5648,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5406
5648
|
} else {
|
|
5407
5649
|
client = getClient();
|
|
5408
5650
|
}
|
|
5409
|
-
} catch {
|
|
5651
|
+
} catch (e) {
|
|
5652
|
+
logStoreDebug("shard routing fallback", e);
|
|
5410
5653
|
client = getClient();
|
|
5411
5654
|
}
|
|
5412
5655
|
const limit = options?.limit ?? 10;
|
|
@@ -5522,7 +5765,8 @@ async function attachDocumentMetadata(records) {
|
|
|
5522
5765
|
if (!record.document_id) continue;
|
|
5523
5766
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
5524
5767
|
}
|
|
5525
|
-
} catch {
|
|
5768
|
+
} catch (e) {
|
|
5769
|
+
logStoreWarn("catch", e);
|
|
5526
5770
|
}
|
|
5527
5771
|
return records;
|
|
5528
5772
|
}
|
|
@@ -5583,11 +5827,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
5583
5827
|
args: [agentId]
|
|
5584
5828
|
});
|
|
5585
5829
|
return Number(result.rows[0]?.cnt) || 0;
|
|
5586
|
-
} catch {
|
|
5830
|
+
} catch (e) {
|
|
5831
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
5587
5832
|
return 0;
|
|
5588
5833
|
}
|
|
5589
5834
|
}
|
|
5590
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5835
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5591
5836
|
var init_store = __esm({
|
|
5592
5837
|
"src/lib/store.ts"() {
|
|
5593
5838
|
"use strict";
|
|
@@ -5597,6 +5842,7 @@ var init_store = __esm({
|
|
|
5597
5842
|
init_config();
|
|
5598
5843
|
init_state_bus();
|
|
5599
5844
|
init_memory_write_governor();
|
|
5845
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
5600
5846
|
INIT_MAX_RETRIES = 3;
|
|
5601
5847
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
5602
5848
|
_pendingRecords = [];
|
|
@@ -5681,13 +5927,13 @@ var init_fast_db_init = __esm({
|
|
|
5681
5927
|
});
|
|
5682
5928
|
|
|
5683
5929
|
// src/lib/session-registry.ts
|
|
5684
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as
|
|
5930
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync9 } from "fs";
|
|
5685
5931
|
import path8 from "path";
|
|
5686
5932
|
import os6 from "os";
|
|
5687
5933
|
function registerSession(entry) {
|
|
5688
5934
|
const dir = path8.dirname(REGISTRY_PATH);
|
|
5689
|
-
if (!
|
|
5690
|
-
|
|
5935
|
+
if (!existsSync9(dir)) {
|
|
5936
|
+
mkdirSync4(dir, { recursive: true });
|
|
5691
5937
|
}
|
|
5692
5938
|
const sessions = listSessions();
|
|
5693
5939
|
const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
|
|
@@ -6012,10 +6258,10 @@ var init_runtime_table = __esm({
|
|
|
6012
6258
|
});
|
|
6013
6259
|
|
|
6014
6260
|
// src/lib/agent-config.ts
|
|
6015
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as
|
|
6261
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync10 } from "fs";
|
|
6016
6262
|
import path9 from "path";
|
|
6017
6263
|
function loadAgentConfig() {
|
|
6018
|
-
if (!
|
|
6264
|
+
if (!existsSync10(AGENT_CONFIG_PATH)) return {};
|
|
6019
6265
|
try {
|
|
6020
6266
|
return JSON.parse(readFileSync6(AGENT_CONFIG_PATH, "utf-8"));
|
|
6021
6267
|
} catch {
|
|
@@ -6055,16 +6301,16 @@ __export(intercom_queue_exports, {
|
|
|
6055
6301
|
queueIntercom: () => queueIntercom,
|
|
6056
6302
|
readQueue: () => readQueue
|
|
6057
6303
|
});
|
|
6058
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, renameSync as renameSync4, existsSync as
|
|
6304
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, renameSync as renameSync4, existsSync as existsSync11, mkdirSync as mkdirSync5 } from "fs";
|
|
6059
6305
|
import path10 from "path";
|
|
6060
6306
|
import os7 from "os";
|
|
6061
6307
|
function ensureDir() {
|
|
6062
6308
|
const dir = path10.dirname(QUEUE_PATH);
|
|
6063
|
-
if (!
|
|
6309
|
+
if (!existsSync11(dir)) mkdirSync5(dir, { recursive: true });
|
|
6064
6310
|
}
|
|
6065
6311
|
function readQueue() {
|
|
6066
6312
|
try {
|
|
6067
|
-
if (!
|
|
6313
|
+
if (!existsSync11(QUEUE_PATH)) return [];
|
|
6068
6314
|
return JSON.parse(readFileSync7(QUEUE_PATH, "utf8"));
|
|
6069
6315
|
} catch {
|
|
6070
6316
|
return [];
|
|
@@ -6173,7 +6419,7 @@ var init_intercom_queue = __esm({
|
|
|
6173
6419
|
});
|
|
6174
6420
|
|
|
6175
6421
|
// src/lib/license.ts
|
|
6176
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as
|
|
6422
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync12, mkdirSync as mkdirSync6 } from "fs";
|
|
6177
6423
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
6178
6424
|
import { createRequire as createRequire2 } from "module";
|
|
6179
6425
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -6200,11 +6446,11 @@ var init_license = __esm({
|
|
|
6200
6446
|
});
|
|
6201
6447
|
|
|
6202
6448
|
// src/lib/plan-limits.ts
|
|
6203
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
6449
|
+
import { readFileSync as readFileSync9, existsSync as existsSync13 } from "fs";
|
|
6204
6450
|
import path12 from "path";
|
|
6205
6451
|
function getLicenseSync() {
|
|
6206
6452
|
try {
|
|
6207
|
-
if (!
|
|
6453
|
+
if (!existsSync13(CACHE_PATH2)) return freeLicense();
|
|
6208
6454
|
const raw = JSON.parse(readFileSync9(CACHE_PATH2, "utf8"));
|
|
6209
6455
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
6210
6456
|
const parts = raw.token.split(".");
|
|
@@ -6243,7 +6489,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
6243
6489
|
const filePath = rosterPath ?? EMPLOYEES_PATH;
|
|
6244
6490
|
let count = 0;
|
|
6245
6491
|
try {
|
|
6246
|
-
if (
|
|
6492
|
+
if (existsSync13(filePath)) {
|
|
6247
6493
|
const raw = readFileSync9(filePath, "utf8");
|
|
6248
6494
|
const employees = JSON.parse(raw);
|
|
6249
6495
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
@@ -6281,9 +6527,9 @@ var init_plan_limits = __esm({
|
|
|
6281
6527
|
import os9 from "os";
|
|
6282
6528
|
import path13 from "path";
|
|
6283
6529
|
import {
|
|
6284
|
-
existsSync as
|
|
6530
|
+
existsSync as existsSync14,
|
|
6285
6531
|
lstatSync,
|
|
6286
|
-
mkdirSync as
|
|
6532
|
+
mkdirSync as mkdirSync7,
|
|
6287
6533
|
readlinkSync as readlinkSync2,
|
|
6288
6534
|
symlinkSync as symlinkSync2
|
|
6289
6535
|
} from "fs";
|
|
@@ -6299,8 +6545,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
|
|
|
6299
6545
|
function ensureAgentSymlink(agentId, homeDir = os9.homedir()) {
|
|
6300
6546
|
const target = identitySourcePath(homeDir, agentId);
|
|
6301
6547
|
const link = claudeAgentLinkPath(homeDir, agentId);
|
|
6302
|
-
|
|
6303
|
-
if (
|
|
6548
|
+
mkdirSync7(claudeAgentsDir(homeDir), { recursive: true });
|
|
6549
|
+
if (existsSync14(link)) {
|
|
6304
6550
|
let stat;
|
|
6305
6551
|
try {
|
|
6306
6552
|
stat = lstatSync(link);
|
|
@@ -6494,7 +6740,7 @@ import path15 from "path";
|
|
|
6494
6740
|
import os10 from "os";
|
|
6495
6741
|
import { execSync as execSync7 } from "child_process";
|
|
6496
6742
|
import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
|
|
6497
|
-
import { existsSync as
|
|
6743
|
+
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "fs";
|
|
6498
6744
|
async function writeCheckpoint(input) {
|
|
6499
6745
|
const client = getClient();
|
|
6500
6746
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -6735,7 +6981,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
6735
6981
|
const EXE_OS_DIR = path15.join(os10.homedir(), ".exe-os");
|
|
6736
6982
|
const mdPath = path15.join(EXE_OS_DIR, taskFile);
|
|
6737
6983
|
const mdDir = path15.dirname(mdPath);
|
|
6738
|
-
if (!
|
|
6984
|
+
if (!existsSync15(mdDir)) await mkdir4(mdDir, { recursive: true });
|
|
6739
6985
|
const reviewer = input.reviewer ?? input.assignedBy;
|
|
6740
6986
|
const mdContent = `# ${input.title}
|
|
6741
6987
|
|
|
@@ -7041,7 +7287,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
7041
7287
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
7042
7288
|
const archPath = path15.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
7043
7289
|
try {
|
|
7044
|
-
if (
|
|
7290
|
+
if (existsSync15(archPath)) return;
|
|
7045
7291
|
const template = [
|
|
7046
7292
|
`# ${projectName} \u2014 System Architecture`,
|
|
7047
7293
|
"",
|
|
@@ -7076,7 +7322,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
7076
7322
|
async function ensureGitignoreExe(baseDir) {
|
|
7077
7323
|
const gitignorePath = path15.join(baseDir, ".gitignore");
|
|
7078
7324
|
try {
|
|
7079
|
-
if (
|
|
7325
|
+
if (existsSync15(gitignorePath)) {
|
|
7080
7326
|
const content = readFileSync10(gitignorePath, "utf-8");
|
|
7081
7327
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
7082
7328
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
@@ -7309,10 +7555,10 @@ async function disposeEmbedder() {
|
|
|
7309
7555
|
async function embedDirect(text) {
|
|
7310
7556
|
const llamaCpp = await import("node-llama-cpp");
|
|
7311
7557
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
7312
|
-
const { existsSync:
|
|
7558
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
7313
7559
|
const path22 = await import("path");
|
|
7314
7560
|
const modelPath = path22.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
7315
|
-
if (!
|
|
7561
|
+
if (!existsSync20(modelPath)) {
|
|
7316
7562
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
7317
7563
|
}
|
|
7318
7564
|
const llama = await llamaCpp.getLlama();
|
|
@@ -7679,7 +7925,7 @@ __export(tasks_exports, {
|
|
|
7679
7925
|
writeCheckpoint: () => writeCheckpoint
|
|
7680
7926
|
});
|
|
7681
7927
|
import path17 from "path";
|
|
7682
|
-
import { writeFileSync as writeFileSync7, mkdirSync as
|
|
7928
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, unlinkSync as unlinkSync4 } from "fs";
|
|
7683
7929
|
async function createTask(input) {
|
|
7684
7930
|
const result = await createTaskCore(input);
|
|
7685
7931
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -7701,11 +7947,11 @@ async function updateTask(input) {
|
|
|
7701
7947
|
const cacheDir = path17.join(EXE_AI_DIR, "session-cache");
|
|
7702
7948
|
const cachePath = path17.join(cacheDir, `current-task-${agent}.json`);
|
|
7703
7949
|
if (input.status === "in_progress") {
|
|
7704
|
-
|
|
7950
|
+
mkdirSync8(cacheDir, { recursive: true });
|
|
7705
7951
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
7706
7952
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
|
|
7707
7953
|
try {
|
|
7708
|
-
|
|
7954
|
+
unlinkSync4(cachePath);
|
|
7709
7955
|
} catch {
|
|
7710
7956
|
}
|
|
7711
7957
|
}
|
|
@@ -8173,11 +8419,11 @@ __export(tmux_routing_exports, {
|
|
|
8173
8419
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
8174
8420
|
});
|
|
8175
8421
|
import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
|
|
8176
|
-
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as
|
|
8422
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, existsSync as existsSync16, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
8177
8423
|
import path18 from "path";
|
|
8178
8424
|
import os11 from "os";
|
|
8179
8425
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8180
|
-
import { unlinkSync as
|
|
8426
|
+
import { unlinkSync as unlinkSync5 } from "fs";
|
|
8181
8427
|
function spawnLockPath(sessionName) {
|
|
8182
8428
|
return path18.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
8183
8429
|
}
|
|
@@ -8190,11 +8436,11 @@ function isProcessAlive(pid) {
|
|
|
8190
8436
|
}
|
|
8191
8437
|
}
|
|
8192
8438
|
function acquireSpawnLock2(sessionName) {
|
|
8193
|
-
if (!
|
|
8194
|
-
|
|
8439
|
+
if (!existsSync16(SPAWN_LOCK_DIR)) {
|
|
8440
|
+
mkdirSync9(SPAWN_LOCK_DIR, { recursive: true });
|
|
8195
8441
|
}
|
|
8196
8442
|
const lockFile = spawnLockPath(sessionName);
|
|
8197
|
-
if (
|
|
8443
|
+
if (existsSync16(lockFile)) {
|
|
8198
8444
|
try {
|
|
8199
8445
|
const lock = JSON.parse(readFileSync11(lockFile, "utf8"));
|
|
8200
8446
|
const age = Date.now() - lock.timestamp;
|
|
@@ -8209,7 +8455,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
8209
8455
|
}
|
|
8210
8456
|
function releaseSpawnLock2(sessionName) {
|
|
8211
8457
|
try {
|
|
8212
|
-
|
|
8458
|
+
unlinkSync5(spawnLockPath(sessionName));
|
|
8213
8459
|
} catch {
|
|
8214
8460
|
}
|
|
8215
8461
|
}
|
|
@@ -8222,7 +8468,7 @@ function resolveBehaviorsExporterScript() {
|
|
|
8222
8468
|
"bin",
|
|
8223
8469
|
"exe-export-behaviors.js"
|
|
8224
8470
|
);
|
|
8225
|
-
return
|
|
8471
|
+
return existsSync16(scriptPath) ? scriptPath : null;
|
|
8226
8472
|
} catch {
|
|
8227
8473
|
return null;
|
|
8228
8474
|
}
|
|
@@ -8288,8 +8534,8 @@ function extractRootExe(name) {
|
|
|
8288
8534
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
8289
8535
|
}
|
|
8290
8536
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
8291
|
-
if (!
|
|
8292
|
-
|
|
8537
|
+
if (!existsSync16(SESSION_CACHE)) {
|
|
8538
|
+
mkdirSync9(SESSION_CACHE, { recursive: true });
|
|
8293
8539
|
}
|
|
8294
8540
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
8295
8541
|
const filePath = path18.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
@@ -8319,11 +8565,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
8319
8565
|
}
|
|
8320
8566
|
}
|
|
8321
8567
|
function resolveExeSession() {
|
|
8322
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
8323
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
8324
|
-
}
|
|
8325
8568
|
const mySession = getMySession();
|
|
8326
|
-
if (!mySession)
|
|
8569
|
+
if (!mySession) {
|
|
8570
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
8571
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
8572
|
+
}
|
|
8573
|
+
return null;
|
|
8574
|
+
}
|
|
8327
8575
|
const fromSessionName = extractRootExe(mySession);
|
|
8328
8576
|
let candidate = null;
|
|
8329
8577
|
try {
|
|
@@ -8418,7 +8666,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
8418
8666
|
}
|
|
8419
8667
|
function readDebounceState() {
|
|
8420
8668
|
try {
|
|
8421
|
-
if (!
|
|
8669
|
+
if (!existsSync16(DEBOUNCE_FILE)) return {};
|
|
8422
8670
|
const raw = JSON.parse(readFileSync11(DEBOUNCE_FILE, "utf8"));
|
|
8423
8671
|
const state = {};
|
|
8424
8672
|
for (const [key, val] of Object.entries(raw)) {
|
|
@@ -8435,7 +8683,7 @@ function readDebounceState() {
|
|
|
8435
8683
|
}
|
|
8436
8684
|
function writeDebounceState(state) {
|
|
8437
8685
|
try {
|
|
8438
|
-
if (!
|
|
8686
|
+
if (!existsSync16(SESSION_CACHE)) mkdirSync9(SESSION_CACHE, { recursive: true });
|
|
8439
8687
|
writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
|
|
8440
8688
|
} catch {
|
|
8441
8689
|
}
|
|
@@ -8536,7 +8784,7 @@ function sendIntercom(targetSession) {
|
|
|
8536
8784
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
8537
8785
|
const agent = baseAgentName(rawAgent);
|
|
8538
8786
|
const markerPath = path18.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
8539
|
-
if (
|
|
8787
|
+
if (existsSync16(markerPath)) {
|
|
8540
8788
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
8541
8789
|
return "debounced";
|
|
8542
8790
|
}
|
|
@@ -8547,7 +8795,7 @@ function sendIntercom(targetSession) {
|
|
|
8547
8795
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
8548
8796
|
const agent = baseAgentName(rawAgent);
|
|
8549
8797
|
const taskDir = path18.join(process.cwd(), "exe", agent);
|
|
8550
|
-
if (
|
|
8798
|
+
if (existsSync16(taskDir)) {
|
|
8551
8799
|
const files = readdirSync2(taskDir).filter(
|
|
8552
8800
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
8553
8801
|
);
|
|
@@ -8708,15 +8956,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8708
8956
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
8709
8957
|
const logDir = path18.join(os11.homedir(), ".exe-os", "session-logs");
|
|
8710
8958
|
const logFile = path18.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
8711
|
-
if (!
|
|
8712
|
-
|
|
8959
|
+
if (!existsSync16(logDir)) {
|
|
8960
|
+
mkdirSync9(logDir, { recursive: true });
|
|
8713
8961
|
}
|
|
8714
8962
|
transport.kill(sessionName);
|
|
8715
8963
|
let cleanupSuffix = "";
|
|
8716
8964
|
try {
|
|
8717
8965
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
8718
8966
|
const cleanupScript = path18.join(path18.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
8719
|
-
if (
|
|
8967
|
+
if (existsSync16(cleanupScript)) {
|
|
8720
8968
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
8721
8969
|
}
|
|
8722
8970
|
} catch {
|
|
@@ -8771,7 +9019,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8771
9019
|
if (changed) {
|
|
8772
9020
|
perms.allow = allow;
|
|
8773
9021
|
settings.permissions = perms;
|
|
8774
|
-
|
|
9022
|
+
mkdirSync9(projSettingsDir, { recursive: true });
|
|
8775
9023
|
writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
8776
9024
|
}
|
|
8777
9025
|
} catch {
|
|
@@ -8809,7 +9057,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8809
9057
|
`
|
|
8810
9058
|
);
|
|
8811
9059
|
}
|
|
8812
|
-
} else if (
|
|
9060
|
+
} else if (existsSync16(identityPath)) {
|
|
8813
9061
|
identityFlag = ` --append-system-prompt-file ${identityPath}`;
|
|
8814
9062
|
legacyFallbackWarned = true;
|
|
8815
9063
|
}
|
|
@@ -8831,7 +9079,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8831
9079
|
let sessionContextFlag = "";
|
|
8832
9080
|
try {
|
|
8833
9081
|
const ctxDir = path18.join(os11.homedir(), ".exe-os", "session-cache");
|
|
8834
|
-
|
|
9082
|
+
mkdirSync9(ctxDir, { recursive: true });
|
|
8835
9083
|
const ctxFile = path18.join(ctxDir, `session-context-${sessionName}.md`);
|
|
8836
9084
|
const ctxContent = [
|
|
8837
9085
|
`## Session Context`,
|
|
@@ -9063,8 +9311,8 @@ import os12 from "os";
|
|
|
9063
9311
|
import {
|
|
9064
9312
|
readFileSync as readFileSync12,
|
|
9065
9313
|
readdirSync as readdirSync3,
|
|
9066
|
-
unlinkSync as
|
|
9067
|
-
existsSync as
|
|
9314
|
+
unlinkSync as unlinkSync6,
|
|
9315
|
+
existsSync as existsSync17,
|
|
9068
9316
|
rmdirSync
|
|
9069
9317
|
} from "fs";
|
|
9070
9318
|
async function writeNotification(notification) {
|
|
@@ -9212,7 +9460,7 @@ function formatNotifications(notifications) {
|
|
|
9212
9460
|
async function migrateJsonNotifications() {
|
|
9213
9461
|
const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path19.join(os12.homedir(), ".exe-os");
|
|
9214
9462
|
const notifDir = path19.join(base, "notifications");
|
|
9215
|
-
if (!
|
|
9463
|
+
if (!existsSync17(notifDir)) return 0;
|
|
9216
9464
|
let migrated = 0;
|
|
9217
9465
|
try {
|
|
9218
9466
|
const files = readdirSync3(notifDir).filter((f) => f.endsWith(".json"));
|
|
@@ -9238,7 +9486,7 @@ async function migrateJsonNotifications() {
|
|
|
9238
9486
|
data.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
9239
9487
|
]
|
|
9240
9488
|
});
|
|
9241
|
-
|
|
9489
|
+
unlinkSync6(filePath);
|
|
9242
9490
|
migrated++;
|
|
9243
9491
|
} catch {
|
|
9244
9492
|
}
|
|
@@ -9306,7 +9554,7 @@ __export(tasks_review_exports, {
|
|
|
9306
9554
|
listPendingReviews: () => listPendingReviews
|
|
9307
9555
|
});
|
|
9308
9556
|
import path20 from "path";
|
|
9309
|
-
import { existsSync as
|
|
9557
|
+
import { existsSync as existsSync18, readdirSync as readdirSync4, unlinkSync as unlinkSync7 } from "fs";
|
|
9310
9558
|
function formatAge(isoTimestamp) {
|
|
9311
9559
|
if (!isoTimestamp) return "";
|
|
9312
9560
|
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
@@ -9576,10 +9824,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
9576
9824
|
}
|
|
9577
9825
|
try {
|
|
9578
9826
|
const cacheDir = path20.join(EXE_AI_DIR, "session-cache");
|
|
9579
|
-
if (
|
|
9827
|
+
if (existsSync18(cacheDir)) {
|
|
9580
9828
|
for (const f of readdirSync4(cacheDir)) {
|
|
9581
9829
|
if (f.startsWith("review-notified-")) {
|
|
9582
|
-
|
|
9830
|
+
unlinkSync7(path20.join(cacheDir, f));
|
|
9583
9831
|
}
|
|
9584
9832
|
}
|
|
9585
9833
|
}
|
|
@@ -9627,7 +9875,7 @@ __export(scan_tasks_exports, {
|
|
|
9627
9875
|
getMcpHealthWarning: () => getMcpHealthWarning,
|
|
9628
9876
|
scanFromDb: () => scanFromDb
|
|
9629
9877
|
});
|
|
9630
|
-
import { existsSync as
|
|
9878
|
+
import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
|
|
9631
9879
|
import path21 from "path";
|
|
9632
9880
|
import os13 from "os";
|
|
9633
9881
|
function getMcpHealthWarning(runtime = getSessionRuntime(), homeDir = os13.homedir()) {
|
|
@@ -9637,7 +9885,7 @@ function getMcpHealthWarning(runtime = getSessionRuntime(), homeDir = os13.homed
|
|
|
9637
9885
|
try {
|
|
9638
9886
|
if (runtime === "opencode") {
|
|
9639
9887
|
const opencodeJson = path21.join(homeDir, ".config", "opencode", "opencode.json");
|
|
9640
|
-
if (!
|
|
9888
|
+
if (!existsSync19(opencodeJson)) {
|
|
9641
9889
|
return "\u26A0\uFE0F MCP config missing (~/.config/opencode/opencode.json not found) \u2014 exe-os task tools may be unavailable. Run `exe-os opencode`.\n";
|
|
9642
9890
|
}
|
|
9643
9891
|
const config2 = JSON.parse(readFileSync13(opencodeJson, "utf8"));
|
|
@@ -9647,7 +9895,7 @@ function getMcpHealthWarning(runtime = getSessionRuntime(), homeDir = os13.homed
|
|
|
9647
9895
|
return null;
|
|
9648
9896
|
}
|
|
9649
9897
|
const claudeJson = path21.join(homeDir, ".claude.json");
|
|
9650
|
-
if (!
|
|
9898
|
+
if (!existsSync19(claudeJson)) {
|
|
9651
9899
|
return "\u26A0\uFE0F MCP config missing (~/.claude.json not found) \u2014 close_task won't work. Run /exe-setup\n";
|
|
9652
9900
|
}
|
|
9653
9901
|
const config = JSON.parse(readFileSync13(claudeJson, "utf8"));
|