@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
|
@@ -1771,9 +1771,79 @@ __export(database_exports, {
|
|
|
1771
1771
|
isInitialized: () => isInitialized,
|
|
1772
1772
|
setExternalClient: () => setExternalClient
|
|
1773
1773
|
});
|
|
1774
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
1774
|
+
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";
|
|
1775
1775
|
import { createClient } from "@libsql/client";
|
|
1776
|
+
import { homedir } from "os";
|
|
1777
|
+
import { join } from "path";
|
|
1778
|
+
function logCatchDebug(context, err) {
|
|
1779
|
+
if (_debugDb) {
|
|
1780
|
+
process.stderr.write(
|
|
1781
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
1782
|
+
`
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
function acquireDbLock() {
|
|
1787
|
+
mkdirSync2(join(homedir(), ".exe-os"), { recursive: true });
|
|
1788
|
+
try {
|
|
1789
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1790
|
+
} catch (err) {
|
|
1791
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
1792
|
+
try {
|
|
1793
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
1794
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
1795
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1796
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
} catch (e) {
|
|
1800
|
+
logCatchDebug("stale lock check", e);
|
|
1801
|
+
}
|
|
1802
|
+
process.stderr.write(
|
|
1803
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
1804
|
+
);
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
throw err;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function releaseDbLock() {
|
|
1811
|
+
if (_lockFd !== null) {
|
|
1812
|
+
try {
|
|
1813
|
+
closeSync2(_lockFd);
|
|
1814
|
+
} catch (e) {
|
|
1815
|
+
logCatchDebug("lock close", e);
|
|
1816
|
+
}
|
|
1817
|
+
_lockFd = null;
|
|
1818
|
+
}
|
|
1819
|
+
try {
|
|
1820
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
1821
|
+
} catch (e) {
|
|
1822
|
+
logCatchDebug("lock unlink", e);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1776
1825
|
async function initDatabase(config) {
|
|
1826
|
+
acquireDbLock();
|
|
1827
|
+
if (existsSync6(config.dbPath)) {
|
|
1828
|
+
const dbStat = statSync2(config.dbPath);
|
|
1829
|
+
if (dbStat.size === 0) {
|
|
1830
|
+
const walPath = config.dbPath + "-wal";
|
|
1831
|
+
if (existsSync6(walPath) && statSync2(walPath).size > 0) {
|
|
1832
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
1833
|
+
copyFileSync(config.dbPath, backupPath);
|
|
1834
|
+
unlinkSync3(config.dbPath);
|
|
1835
|
+
process.stderr.write(
|
|
1836
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
1837
|
+
`
|
|
1838
|
+
);
|
|
1839
|
+
} else {
|
|
1840
|
+
process.stderr.write(
|
|
1841
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
1842
|
+
`
|
|
1843
|
+
);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1777
1847
|
if (_walCheckpointTimer) {
|
|
1778
1848
|
clearInterval(_walCheckpointTimer);
|
|
1779
1849
|
_walCheckpointTimer = null;
|
|
@@ -1800,10 +1870,8 @@ async function initDatabase(config) {
|
|
|
1800
1870
|
_client = createClient(opts);
|
|
1801
1871
|
_resilientClient = wrapWithRetry(_client);
|
|
1802
1872
|
_adapterClient = _resilientClient;
|
|
1803
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
1804
|
-
|
|
1805
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
1806
|
-
});
|
|
1873
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
1874
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
1807
1875
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
1808
1876
|
_walCheckpointTimer = setInterval(() => {
|
|
1809
1877
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -1818,11 +1886,16 @@ async function initDatabase(config) {
|
|
|
1818
1886
|
for (const suffix of ["-wal", "-shm"]) {
|
|
1819
1887
|
try {
|
|
1820
1888
|
chmodSync2(config.dbPath + suffix, 384);
|
|
1821
|
-
} catch {
|
|
1889
|
+
} catch (chmodErr) {
|
|
1890
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1891
|
+
`);
|
|
1822
1892
|
}
|
|
1823
1893
|
}
|
|
1824
|
-
} catch {
|
|
1894
|
+
} catch (chmodErr) {
|
|
1895
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
1896
|
+
`);
|
|
1825
1897
|
}
|
|
1898
|
+
releaseDbLock();
|
|
1826
1899
|
}
|
|
1827
1900
|
function isInitialized() {
|
|
1828
1901
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1877,7 +1950,8 @@ async function ensureSchema() {
|
|
|
1877
1950
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
1878
1951
|
try {
|
|
1879
1952
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1880
|
-
} catch {
|
|
1953
|
+
} catch (e) {
|
|
1954
|
+
logCatchDebug("migration", e);
|
|
1881
1955
|
}
|
|
1882
1956
|
await client.executeMultiple(`
|
|
1883
1957
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -1942,6 +2016,23 @@ async function ensureSchema() {
|
|
|
1942
2016
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
1943
2017
|
END;
|
|
1944
2018
|
`);
|
|
2019
|
+
try {
|
|
2020
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
2021
|
+
} catch (ftsErr) {
|
|
2022
|
+
process.stderr.write(
|
|
2023
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
2024
|
+
`
|
|
2025
|
+
);
|
|
2026
|
+
try {
|
|
2027
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
2028
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
2029
|
+
} catch (rebuildErr) {
|
|
2030
|
+
process.stderr.write(
|
|
2031
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
2032
|
+
`
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
1945
2036
|
await client.executeMultiple(`
|
|
1946
2037
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
1947
2038
|
key TEXT PRIMARY KEY,
|
|
@@ -2000,35 +2091,40 @@ async function ensureSchema() {
|
|
|
2000
2091
|
});
|
|
2001
2092
|
}
|
|
2002
2093
|
}
|
|
2003
|
-
} catch {
|
|
2094
|
+
} catch (seedErr) {
|
|
2095
|
+
logCatchDebug("behavior seed", seedErr);
|
|
2004
2096
|
}
|
|
2005
2097
|
try {
|
|
2006
2098
|
await client.execute({
|
|
2007
2099
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
2008
2100
|
args: []
|
|
2009
2101
|
});
|
|
2010
|
-
} catch {
|
|
2102
|
+
} catch (e) {
|
|
2103
|
+
logCatchDebug("migration", e);
|
|
2011
2104
|
}
|
|
2012
2105
|
try {
|
|
2013
2106
|
await client.execute({
|
|
2014
2107
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2015
2108
|
args: []
|
|
2016
2109
|
});
|
|
2017
|
-
} catch {
|
|
2110
|
+
} catch (e) {
|
|
2111
|
+
logCatchDebug("migration", e);
|
|
2018
2112
|
}
|
|
2019
2113
|
try {
|
|
2020
2114
|
await client.execute({
|
|
2021
2115
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
2022
2116
|
args: []
|
|
2023
2117
|
});
|
|
2024
|
-
} catch {
|
|
2118
|
+
} catch (e) {
|
|
2119
|
+
logCatchDebug("migration", e);
|
|
2025
2120
|
}
|
|
2026
2121
|
try {
|
|
2027
2122
|
await client.execute({
|
|
2028
2123
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
2029
2124
|
args: []
|
|
2030
2125
|
});
|
|
2031
|
-
} catch {
|
|
2126
|
+
} catch (e) {
|
|
2127
|
+
logCatchDebug("migration", e);
|
|
2032
2128
|
}
|
|
2033
2129
|
try {
|
|
2034
2130
|
await client.execute({
|
|
@@ -2037,98 +2133,112 @@ async function ensureSchema() {
|
|
|
2037
2133
|
WHERE parent_task_id IS NOT NULL`,
|
|
2038
2134
|
args: []
|
|
2039
2135
|
});
|
|
2040
|
-
} catch {
|
|
2136
|
+
} catch (e) {
|
|
2137
|
+
logCatchDebug("migration", e);
|
|
2041
2138
|
}
|
|
2042
2139
|
try {
|
|
2043
2140
|
await client.execute({
|
|
2044
2141
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
2045
2142
|
args: []
|
|
2046
2143
|
});
|
|
2047
|
-
} catch {
|
|
2144
|
+
} catch (e) {
|
|
2145
|
+
logCatchDebug("migration", e);
|
|
2048
2146
|
}
|
|
2049
2147
|
try {
|
|
2050
2148
|
await client.execute({
|
|
2051
2149
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
2052
2150
|
args: []
|
|
2053
2151
|
});
|
|
2054
|
-
} catch {
|
|
2152
|
+
} catch (e) {
|
|
2153
|
+
logCatchDebug("migration", e);
|
|
2055
2154
|
}
|
|
2056
2155
|
try {
|
|
2057
2156
|
await client.execute({
|
|
2058
2157
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
2059
2158
|
args: []
|
|
2060
2159
|
});
|
|
2061
|
-
} catch {
|
|
2160
|
+
} catch (e) {
|
|
2161
|
+
logCatchDebug("migration", e);
|
|
2062
2162
|
}
|
|
2063
2163
|
try {
|
|
2064
2164
|
await client.execute({
|
|
2065
2165
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
2066
2166
|
args: []
|
|
2067
2167
|
});
|
|
2068
|
-
} catch {
|
|
2168
|
+
} catch (e) {
|
|
2169
|
+
logCatchDebug("migration", e);
|
|
2069
2170
|
}
|
|
2070
2171
|
try {
|
|
2071
2172
|
await client.execute({
|
|
2072
2173
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
2073
2174
|
args: []
|
|
2074
2175
|
});
|
|
2075
|
-
} catch {
|
|
2176
|
+
} catch (e) {
|
|
2177
|
+
logCatchDebug("migration", e);
|
|
2076
2178
|
}
|
|
2077
2179
|
try {
|
|
2078
2180
|
await client.execute({
|
|
2079
2181
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
2080
2182
|
args: []
|
|
2081
2183
|
});
|
|
2082
|
-
} catch {
|
|
2184
|
+
} catch (e) {
|
|
2185
|
+
logCatchDebug("migration", e);
|
|
2083
2186
|
}
|
|
2084
2187
|
try {
|
|
2085
2188
|
await client.execute({
|
|
2086
2189
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2087
2190
|
args: []
|
|
2088
2191
|
});
|
|
2089
|
-
} catch {
|
|
2192
|
+
} catch (e) {
|
|
2193
|
+
logCatchDebug("migration", e);
|
|
2090
2194
|
}
|
|
2091
2195
|
try {
|
|
2092
2196
|
await client.execute({
|
|
2093
2197
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2094
2198
|
args: []
|
|
2095
2199
|
});
|
|
2096
|
-
} catch {
|
|
2200
|
+
} catch (e) {
|
|
2201
|
+
logCatchDebug("migration", e);
|
|
2097
2202
|
}
|
|
2098
2203
|
try {
|
|
2099
2204
|
await client.execute({
|
|
2100
2205
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2101
2206
|
args: []
|
|
2102
2207
|
});
|
|
2103
|
-
} catch {
|
|
2208
|
+
} catch (e) {
|
|
2209
|
+
logCatchDebug("migration", e);
|
|
2104
2210
|
}
|
|
2105
2211
|
try {
|
|
2106
2212
|
await client.execute({
|
|
2107
2213
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2108
2214
|
args: []
|
|
2109
2215
|
});
|
|
2110
|
-
} catch {
|
|
2216
|
+
} catch (e) {
|
|
2217
|
+
logCatchDebug("migration", e);
|
|
2111
2218
|
}
|
|
2112
2219
|
try {
|
|
2113
2220
|
await client.execute({
|
|
2114
2221
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2115
2222
|
args: []
|
|
2116
2223
|
});
|
|
2117
|
-
} catch {
|
|
2224
|
+
} catch (e) {
|
|
2225
|
+
logCatchDebug("migration", e);
|
|
2118
2226
|
}
|
|
2119
2227
|
try {
|
|
2120
2228
|
await client.execute({
|
|
2121
2229
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2122
2230
|
args: []
|
|
2123
2231
|
});
|
|
2124
|
-
} catch {
|
|
2232
|
+
} catch (e) {
|
|
2233
|
+
logCatchDebug("migration", e);
|
|
2125
2234
|
}
|
|
2126
2235
|
try {
|
|
2127
2236
|
await client.execute({
|
|
2128
2237
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2129
2238
|
args: []
|
|
2130
2239
|
});
|
|
2131
|
-
} catch {
|
|
2240
|
+
} catch (e) {
|
|
2241
|
+
logCatchDebug("migration", e);
|
|
2132
2242
|
}
|
|
2133
2243
|
await client.executeMultiple(`
|
|
2134
2244
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2233,14 +2343,16 @@ async function ensureSchema() {
|
|
|
2233
2343
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2234
2344
|
args: []
|
|
2235
2345
|
});
|
|
2236
|
-
} catch {
|
|
2346
|
+
} catch (e) {
|
|
2347
|
+
logCatchDebug("migration", e);
|
|
2237
2348
|
}
|
|
2238
2349
|
try {
|
|
2239
2350
|
await client.execute({
|
|
2240
2351
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2241
2352
|
args: []
|
|
2242
2353
|
});
|
|
2243
|
-
} catch {
|
|
2354
|
+
} catch (e) {
|
|
2355
|
+
logCatchDebug("migration", e);
|
|
2244
2356
|
}
|
|
2245
2357
|
await client.executeMultiple(`
|
|
2246
2358
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2266,7 +2378,8 @@ async function ensureSchema() {
|
|
|
2266
2378
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2267
2379
|
args: []
|
|
2268
2380
|
});
|
|
2269
|
-
} catch {
|
|
2381
|
+
} catch (e) {
|
|
2382
|
+
logCatchDebug("migration", e);
|
|
2270
2383
|
}
|
|
2271
2384
|
await client.executeMultiple(`
|
|
2272
2385
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -2290,7 +2403,8 @@ async function ensureSchema() {
|
|
|
2290
2403
|
`);
|
|
2291
2404
|
try {
|
|
2292
2405
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
2293
|
-
} catch {
|
|
2406
|
+
} catch (e) {
|
|
2407
|
+
logCatchDebug("migration", e);
|
|
2294
2408
|
}
|
|
2295
2409
|
await client.executeMultiple(`
|
|
2296
2410
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2327,63 +2441,72 @@ async function ensureSchema() {
|
|
|
2327
2441
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2328
2442
|
args: []
|
|
2329
2443
|
});
|
|
2330
|
-
} catch {
|
|
2444
|
+
} catch (e) {
|
|
2445
|
+
logCatchDebug("migration", e);
|
|
2331
2446
|
}
|
|
2332
2447
|
try {
|
|
2333
2448
|
await client.execute({
|
|
2334
2449
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
2335
2450
|
args: []
|
|
2336
2451
|
});
|
|
2337
|
-
} catch {
|
|
2452
|
+
} catch (e) {
|
|
2453
|
+
logCatchDebug("migration", e);
|
|
2338
2454
|
}
|
|
2339
2455
|
try {
|
|
2340
2456
|
await client.execute({
|
|
2341
2457
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
2342
2458
|
args: []
|
|
2343
2459
|
});
|
|
2344
|
-
} catch {
|
|
2460
|
+
} catch (e) {
|
|
2461
|
+
logCatchDebug("migration", e);
|
|
2345
2462
|
}
|
|
2346
2463
|
try {
|
|
2347
2464
|
await client.execute({
|
|
2348
2465
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
2349
2466
|
args: []
|
|
2350
2467
|
});
|
|
2351
|
-
} catch {
|
|
2468
|
+
} catch (e) {
|
|
2469
|
+
logCatchDebug("migration", e);
|
|
2352
2470
|
}
|
|
2353
2471
|
try {
|
|
2354
2472
|
await client.execute({
|
|
2355
2473
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
2356
2474
|
args: []
|
|
2357
2475
|
});
|
|
2358
|
-
} catch {
|
|
2476
|
+
} catch (e) {
|
|
2477
|
+
logCatchDebug("migration", e);
|
|
2359
2478
|
}
|
|
2360
2479
|
try {
|
|
2361
2480
|
await client.execute({
|
|
2362
2481
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
2363
2482
|
args: []
|
|
2364
2483
|
});
|
|
2365
|
-
} catch {
|
|
2484
|
+
} catch (e) {
|
|
2485
|
+
logCatchDebug("migration", e);
|
|
2366
2486
|
}
|
|
2367
2487
|
try {
|
|
2368
2488
|
await client.execute({
|
|
2369
2489
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
2370
2490
|
args: []
|
|
2371
2491
|
});
|
|
2372
|
-
} catch {
|
|
2492
|
+
} catch (e) {
|
|
2493
|
+
logCatchDebug("migration", e);
|
|
2373
2494
|
}
|
|
2374
2495
|
try {
|
|
2375
2496
|
await client.execute({
|
|
2376
2497
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2377
2498
|
args: []
|
|
2378
2499
|
});
|
|
2379
|
-
} catch {
|
|
2500
|
+
} catch (e) {
|
|
2501
|
+
logCatchDebug("migration", e);
|
|
2380
2502
|
}
|
|
2381
2503
|
try {
|
|
2382
2504
|
await client.execute({
|
|
2383
2505
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2384
2506
|
args: []
|
|
2385
2507
|
});
|
|
2386
|
-
} catch {
|
|
2508
|
+
} catch (e) {
|
|
2509
|
+
logCatchDebug("migration", e);
|
|
2387
2510
|
}
|
|
2388
2511
|
for (const col of [
|
|
2389
2512
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2391,14 +2514,16 @@ async function ensureSchema() {
|
|
|
2391
2514
|
]) {
|
|
2392
2515
|
try {
|
|
2393
2516
|
await client.execute(col);
|
|
2394
|
-
} catch {
|
|
2517
|
+
} catch (e) {
|
|
2518
|
+
logCatchDebug("migration", e);
|
|
2395
2519
|
}
|
|
2396
2520
|
}
|
|
2397
2521
|
try {
|
|
2398
2522
|
await client.execute(
|
|
2399
2523
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2400
2524
|
);
|
|
2401
|
-
} catch {
|
|
2525
|
+
} catch (e) {
|
|
2526
|
+
logCatchDebug("migration", e);
|
|
2402
2527
|
}
|
|
2403
2528
|
try {
|
|
2404
2529
|
await client.execute(
|
|
@@ -2406,7 +2531,8 @@ async function ensureSchema() {
|
|
|
2406
2531
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2407
2532
|
WHERE content_hash IS NOT NULL`
|
|
2408
2533
|
);
|
|
2409
|
-
} catch {
|
|
2534
|
+
} catch (e) {
|
|
2535
|
+
logCatchDebug("migration", e);
|
|
2410
2536
|
}
|
|
2411
2537
|
await client.executeMultiple(`
|
|
2412
2538
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -2482,7 +2608,8 @@ async function ensureSchema() {
|
|
|
2482
2608
|
`);
|
|
2483
2609
|
try {
|
|
2484
2610
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
2485
|
-
} catch {
|
|
2611
|
+
} catch (e) {
|
|
2612
|
+
logCatchDebug("migration", e);
|
|
2486
2613
|
}
|
|
2487
2614
|
await client.executeMultiple(`
|
|
2488
2615
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -2497,14 +2624,16 @@ async function ensureSchema() {
|
|
|
2497
2624
|
]) {
|
|
2498
2625
|
try {
|
|
2499
2626
|
await client.execute(col);
|
|
2500
|
-
} catch {
|
|
2627
|
+
} catch (e) {
|
|
2628
|
+
logCatchDebug("migration", e);
|
|
2501
2629
|
}
|
|
2502
2630
|
}
|
|
2503
2631
|
try {
|
|
2504
2632
|
await client.execute(
|
|
2505
2633
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
2506
2634
|
);
|
|
2507
|
-
} catch {
|
|
2635
|
+
} catch (e) {
|
|
2636
|
+
logCatchDebug("migration", e);
|
|
2508
2637
|
}
|
|
2509
2638
|
await client.executeMultiple(`
|
|
2510
2639
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -2603,7 +2732,8 @@ async function ensureSchema() {
|
|
|
2603
2732
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
2604
2733
|
args: []
|
|
2605
2734
|
});
|
|
2606
|
-
} catch {
|
|
2735
|
+
} catch (e) {
|
|
2736
|
+
logCatchDebug("migration", e);
|
|
2607
2737
|
}
|
|
2608
2738
|
}
|
|
2609
2739
|
for (const col of [
|
|
@@ -2612,7 +2742,8 @@ async function ensureSchema() {
|
|
|
2612
2742
|
]) {
|
|
2613
2743
|
try {
|
|
2614
2744
|
await client.execute(col);
|
|
2615
|
-
} catch {
|
|
2745
|
+
} catch (e) {
|
|
2746
|
+
logCatchDebug("migration", e);
|
|
2616
2747
|
}
|
|
2617
2748
|
}
|
|
2618
2749
|
await client.executeMultiple(`
|
|
@@ -2797,56 +2928,64 @@ async function ensureSchema() {
|
|
|
2797
2928
|
args: []
|
|
2798
2929
|
});
|
|
2799
2930
|
}
|
|
2800
|
-
} catch {
|
|
2931
|
+
} catch (e) {
|
|
2932
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
2801
2933
|
}
|
|
2802
2934
|
try {
|
|
2803
2935
|
await client.execute({
|
|
2804
2936
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
2805
2937
|
args: []
|
|
2806
2938
|
});
|
|
2807
|
-
} catch {
|
|
2939
|
+
} catch (e) {
|
|
2940
|
+
logCatchDebug("migration", e);
|
|
2808
2941
|
}
|
|
2809
2942
|
try {
|
|
2810
2943
|
await client.execute({
|
|
2811
2944
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
2812
2945
|
args: []
|
|
2813
2946
|
});
|
|
2814
|
-
} catch {
|
|
2947
|
+
} catch (e) {
|
|
2948
|
+
logCatchDebug("migration", e);
|
|
2815
2949
|
}
|
|
2816
2950
|
try {
|
|
2817
2951
|
await client.execute({
|
|
2818
2952
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
2819
2953
|
args: []
|
|
2820
2954
|
});
|
|
2821
|
-
} catch {
|
|
2955
|
+
} catch (e) {
|
|
2956
|
+
logCatchDebug("migration", e);
|
|
2822
2957
|
}
|
|
2823
2958
|
try {
|
|
2824
2959
|
await client.execute({
|
|
2825
2960
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
2826
2961
|
args: []
|
|
2827
2962
|
});
|
|
2828
|
-
} catch {
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
logCatchDebug("migration", e);
|
|
2829
2965
|
}
|
|
2830
2966
|
try {
|
|
2831
2967
|
await client.execute({
|
|
2832
2968
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
2833
2969
|
args: []
|
|
2834
2970
|
});
|
|
2835
|
-
} catch {
|
|
2971
|
+
} catch (e) {
|
|
2972
|
+
logCatchDebug("migration", e);
|
|
2836
2973
|
}
|
|
2837
2974
|
try {
|
|
2838
2975
|
await client.execute({
|
|
2839
2976
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2840
2977
|
args: []
|
|
2841
2978
|
});
|
|
2842
|
-
} catch {
|
|
2979
|
+
} catch (e) {
|
|
2980
|
+
logCatchDebug("migration", e);
|
|
2843
2981
|
}
|
|
2844
2982
|
try {
|
|
2845
2983
|
await client.execute({
|
|
2846
2984
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2847
2985
|
args: []
|
|
2848
2986
|
});
|
|
2849
|
-
} catch {
|
|
2987
|
+
} catch (e) {
|
|
2988
|
+
logCatchDebug("migration", e);
|
|
2850
2989
|
}
|
|
2851
2990
|
await client.executeMultiple(`
|
|
2852
2991
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -3045,13 +3184,15 @@ async function ensureSchema() {
|
|
|
3045
3184
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
3046
3185
|
args: []
|
|
3047
3186
|
});
|
|
3048
|
-
} catch {
|
|
3187
|
+
} catch (e) {
|
|
3188
|
+
logCatchDebug("migration", e);
|
|
3049
3189
|
}
|
|
3050
3190
|
try {
|
|
3051
3191
|
await client.execute(
|
|
3052
3192
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
3053
3193
|
);
|
|
3054
|
-
} catch {
|
|
3194
|
+
} catch (e) {
|
|
3195
|
+
logCatchDebug("migration", e);
|
|
3055
3196
|
}
|
|
3056
3197
|
try {
|
|
3057
3198
|
await client.execute({
|
|
@@ -3062,20 +3203,23 @@ async function ensureSchema() {
|
|
|
3062
3203
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
3063
3204
|
args: []
|
|
3064
3205
|
});
|
|
3065
|
-
} catch {
|
|
3206
|
+
} catch (e) {
|
|
3207
|
+
logCatchDebug("migration", e);
|
|
3066
3208
|
}
|
|
3067
3209
|
try {
|
|
3068
3210
|
await client.execute({
|
|
3069
3211
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
3070
3212
|
args: []
|
|
3071
3213
|
});
|
|
3072
|
-
} catch {
|
|
3214
|
+
} catch (e) {
|
|
3215
|
+
logCatchDebug("migration", e);
|
|
3073
3216
|
}
|
|
3074
3217
|
try {
|
|
3075
3218
|
await client.execute(
|
|
3076
3219
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
3077
3220
|
);
|
|
3078
|
-
} catch {
|
|
3221
|
+
} catch (e) {
|
|
3222
|
+
logCatchDebug("migration", e);
|
|
3079
3223
|
}
|
|
3080
3224
|
for (const col of [
|
|
3081
3225
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -3083,7 +3227,8 @@ async function ensureSchema() {
|
|
|
3083
3227
|
]) {
|
|
3084
3228
|
try {
|
|
3085
3229
|
await client.execute(col);
|
|
3086
|
-
} catch {
|
|
3230
|
+
} catch (e) {
|
|
3231
|
+
logCatchDebug("migration", e);
|
|
3087
3232
|
}
|
|
3088
3233
|
}
|
|
3089
3234
|
try {
|
|
@@ -3091,13 +3236,15 @@ async function ensureSchema() {
|
|
|
3091
3236
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3092
3237
|
args: []
|
|
3093
3238
|
});
|
|
3094
|
-
} catch {
|
|
3239
|
+
} catch (e) {
|
|
3240
|
+
logCatchDebug("migration", e);
|
|
3095
3241
|
}
|
|
3096
3242
|
try {
|
|
3097
3243
|
await client.execute(
|
|
3098
3244
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3099
3245
|
);
|
|
3100
|
-
} catch {
|
|
3246
|
+
} catch (e) {
|
|
3247
|
+
logCatchDebug("migration", e);
|
|
3101
3248
|
}
|
|
3102
3249
|
for (const col of [
|
|
3103
3250
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3105,7 +3252,8 @@ async function ensureSchema() {
|
|
|
3105
3252
|
]) {
|
|
3106
3253
|
try {
|
|
3107
3254
|
await client.execute(col);
|
|
3108
|
-
} catch {
|
|
3255
|
+
} catch (e) {
|
|
3256
|
+
logCatchDebug("migration", e);
|
|
3109
3257
|
}
|
|
3110
3258
|
}
|
|
3111
3259
|
try {
|
|
@@ -3113,27 +3261,31 @@ async function ensureSchema() {
|
|
|
3113
3261
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3114
3262
|
args: []
|
|
3115
3263
|
});
|
|
3116
|
-
} catch {
|
|
3264
|
+
} catch (e) {
|
|
3265
|
+
logCatchDebug("migration", e);
|
|
3117
3266
|
}
|
|
3118
3267
|
try {
|
|
3119
3268
|
await client.execute({
|
|
3120
3269
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3121
3270
|
args: []
|
|
3122
3271
|
});
|
|
3123
|
-
} catch {
|
|
3272
|
+
} catch (e) {
|
|
3273
|
+
logCatchDebug("migration", e);
|
|
3124
3274
|
}
|
|
3125
3275
|
try {
|
|
3126
3276
|
await client.execute(
|
|
3127
3277
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3128
3278
|
);
|
|
3129
|
-
} catch {
|
|
3279
|
+
} catch (e) {
|
|
3280
|
+
logCatchDebug("migration", e);
|
|
3130
3281
|
}
|
|
3131
3282
|
try {
|
|
3132
3283
|
await client.execute({
|
|
3133
3284
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3134
3285
|
args: []
|
|
3135
3286
|
});
|
|
3136
|
-
} catch {
|
|
3287
|
+
} catch (e) {
|
|
3288
|
+
logCatchDebug("migration", e);
|
|
3137
3289
|
}
|
|
3138
3290
|
for (const col of [
|
|
3139
3291
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3154,7 +3306,8 @@ async function ensureSchema() {
|
|
|
3154
3306
|
]) {
|
|
3155
3307
|
try {
|
|
3156
3308
|
await client.execute(col);
|
|
3157
|
-
} catch {
|
|
3309
|
+
} catch (e) {
|
|
3310
|
+
logCatchDebug("migration", e);
|
|
3158
3311
|
}
|
|
3159
3312
|
}
|
|
3160
3313
|
try {
|
|
@@ -3162,14 +3315,16 @@ async function ensureSchema() {
|
|
|
3162
3315
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3163
3316
|
args: []
|
|
3164
3317
|
});
|
|
3165
|
-
} catch {
|
|
3318
|
+
} catch (e) {
|
|
3319
|
+
logCatchDebug("migration", e);
|
|
3166
3320
|
}
|
|
3167
3321
|
try {
|
|
3168
3322
|
await client.execute({
|
|
3169
3323
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3170
3324
|
args: []
|
|
3171
3325
|
});
|
|
3172
|
-
} catch {
|
|
3326
|
+
} catch (e) {
|
|
3327
|
+
logCatchDebug("migration", e);
|
|
3173
3328
|
}
|
|
3174
3329
|
}
|
|
3175
3330
|
async function disposeDatabase() {
|
|
@@ -3180,7 +3335,8 @@ async function disposeDatabase() {
|
|
|
3180
3335
|
if (_client) {
|
|
3181
3336
|
try {
|
|
3182
3337
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3183
|
-
} catch {
|
|
3338
|
+
} catch (e) {
|
|
3339
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3184
3340
|
}
|
|
3185
3341
|
}
|
|
3186
3342
|
if (_daemonClient) {
|
|
@@ -3196,8 +3352,9 @@ async function disposeDatabase() {
|
|
|
3196
3352
|
_client = null;
|
|
3197
3353
|
_resilientClient = null;
|
|
3198
3354
|
}
|
|
3355
|
+
releaseDbLock();
|
|
3199
3356
|
}
|
|
3200
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3357
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3201
3358
|
var init_database = __esm({
|
|
3202
3359
|
"src/lib/database.ts"() {
|
|
3203
3360
|
"use strict";
|
|
@@ -3205,11 +3362,14 @@ var init_database = __esm({
|
|
|
3205
3362
|
init_employees();
|
|
3206
3363
|
init_database_adapter();
|
|
3207
3364
|
init_memory();
|
|
3365
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3208
3366
|
_client = null;
|
|
3209
3367
|
_resilientClient = null;
|
|
3210
3368
|
_walCheckpointTimer = null;
|
|
3211
3369
|
_daemonClient = null;
|
|
3212
3370
|
_adapterClient = null;
|
|
3371
|
+
_lockFd = null;
|
|
3372
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3213
3373
|
initTurso = initDatabase;
|
|
3214
3374
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3215
3375
|
disposeTurso = disposeDatabase;
|
|
@@ -3218,7 +3378,7 @@ var init_database = __esm({
|
|
|
3218
3378
|
|
|
3219
3379
|
// src/lib/keychain.ts
|
|
3220
3380
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3221
|
-
import { existsSync as
|
|
3381
|
+
import { existsSync as existsSync7, statSync as statSync3 } from "fs";
|
|
3222
3382
|
import { execSync as execSync3 } from "child_process";
|
|
3223
3383
|
import path6 from "path";
|
|
3224
3384
|
import os5 from "os";
|
|
@@ -3253,7 +3413,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3253
3413
|
if (process.platform !== "linux") return false;
|
|
3254
3414
|
try {
|
|
3255
3415
|
const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
|
|
3256
|
-
const st =
|
|
3416
|
+
const st = statSync3(keyPath);
|
|
3257
3417
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3258
3418
|
if (uid === 0) return true;
|
|
3259
3419
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -3454,7 +3614,7 @@ async function getMasterKey() {
|
|
|
3454
3614
|
}
|
|
3455
3615
|
}
|
|
3456
3616
|
const keyPath = getKeyPath();
|
|
3457
|
-
if (!
|
|
3617
|
+
if (!existsSync7(keyPath)) {
|
|
3458
3618
|
process.stderr.write(
|
|
3459
3619
|
`[keychain] Key not found at ${keyPath} (HOME=${os5.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3460
3620
|
`
|
|
@@ -3789,18 +3949,54 @@ __export(shard_manager_exports, {
|
|
|
3789
3949
|
shardExists: () => shardExists
|
|
3790
3950
|
});
|
|
3791
3951
|
import path7 from "path";
|
|
3792
|
-
import { existsSync as
|
|
3952
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync3, statSync as statSync4 } from "fs";
|
|
3793
3953
|
import { createClient as createClient2 } from "@libsql/client";
|
|
3794
3954
|
function initShardManager(encryptionKey) {
|
|
3795
3955
|
_encryptionKey = encryptionKey;
|
|
3796
|
-
|
|
3797
|
-
|
|
3956
|
+
_keyValidated = false;
|
|
3957
|
+
_keyValidationPromise = null;
|
|
3958
|
+
if (!existsSync8(SHARDS_DIR)) {
|
|
3959
|
+
mkdirSync3(SHARDS_DIR, { recursive: true });
|
|
3960
|
+
}
|
|
3961
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3962
|
+
if (existingShards.length === 0) {
|
|
3963
|
+
_keyValidated = true;
|
|
3798
3964
|
}
|
|
3799
3965
|
_shardingEnabled = true;
|
|
3800
3966
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
3801
3967
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
3802
3968
|
_evictionTimer.unref();
|
|
3803
3969
|
}
|
|
3970
|
+
async function validateEncryptionKey() {
|
|
3971
|
+
if (_keyValidated) return true;
|
|
3972
|
+
if (!_encryptionKey) return false;
|
|
3973
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
3974
|
+
if (existingShards.length === 0) {
|
|
3975
|
+
_keyValidated = true;
|
|
3976
|
+
return true;
|
|
3977
|
+
}
|
|
3978
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
3979
|
+
const dbPath = path7.join(SHARDS_DIR, shardFile);
|
|
3980
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
3981
|
+
try {
|
|
3982
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
3983
|
+
testClient.close();
|
|
3984
|
+
_keyValidated = true;
|
|
3985
|
+
return true;
|
|
3986
|
+
} catch {
|
|
3987
|
+
try {
|
|
3988
|
+
testClient.close();
|
|
3989
|
+
} catch {
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
process.stderr.write(
|
|
3994
|
+
`[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.
|
|
3995
|
+
`
|
|
3996
|
+
);
|
|
3997
|
+
_shardingEnabled = false;
|
|
3998
|
+
return false;
|
|
3999
|
+
}
|
|
3804
4000
|
function isShardingEnabled() {
|
|
3805
4001
|
return _shardingEnabled;
|
|
3806
4002
|
}
|
|
@@ -3834,13 +4030,13 @@ function getShardClient(projectName) {
|
|
|
3834
4030
|
}
|
|
3835
4031
|
function shardExists(projectName) {
|
|
3836
4032
|
const safeName = safeShardName(projectName);
|
|
3837
|
-
return
|
|
4033
|
+
return existsSync8(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
3838
4034
|
}
|
|
3839
4035
|
function safeShardName(projectName) {
|
|
3840
4036
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3841
4037
|
}
|
|
3842
4038
|
function listShards() {
|
|
3843
|
-
if (!
|
|
4039
|
+
if (!existsSync8(SHARDS_DIR)) return [];
|
|
3844
4040
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
3845
4041
|
}
|
|
3846
4042
|
async function auditShardHealth(options = {}) {
|
|
@@ -3853,7 +4049,7 @@ async function auditShardHealth(options = {}) {
|
|
|
3853
4049
|
const shards = [];
|
|
3854
4050
|
for (const name of names) {
|
|
3855
4051
|
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
3856
|
-
const stat =
|
|
4052
|
+
const stat = statSync4(dbPath);
|
|
3857
4053
|
const item = {
|
|
3858
4054
|
name,
|
|
3859
4055
|
path: dbPath,
|
|
@@ -4093,6 +4289,17 @@ async function ensureShardSchema(client) {
|
|
|
4093
4289
|
}
|
|
4094
4290
|
}
|
|
4095
4291
|
async function getReadyShardClient(projectName) {
|
|
4292
|
+
if (!_keyValidated) {
|
|
4293
|
+
if (!_keyValidationPromise) {
|
|
4294
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
4295
|
+
}
|
|
4296
|
+
const valid = await _keyValidationPromise;
|
|
4297
|
+
if (!valid) {
|
|
4298
|
+
throw new Error(
|
|
4299
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
4300
|
+
);
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4096
4303
|
const safeName = safeShardName(projectName);
|
|
4097
4304
|
let client = getShardClient(projectName);
|
|
4098
4305
|
try {
|
|
@@ -4105,8 +4312,8 @@ async function getReadyShardClient(projectName) {
|
|
|
4105
4312
|
_shards.delete(safeName);
|
|
4106
4313
|
_shardLastAccess.delete(safeName);
|
|
4107
4314
|
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
4108
|
-
if (
|
|
4109
|
-
const stat =
|
|
4315
|
+
if (existsSync8(dbPath)) {
|
|
4316
|
+
const stat = statSync4(dbPath);
|
|
4110
4317
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4111
4318
|
const archivedPath = path7.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4112
4319
|
renameSync3(dbPath, archivedPath);
|
|
@@ -4171,7 +4378,7 @@ function disposeShards() {
|
|
|
4171
4378
|
_shardingEnabled = false;
|
|
4172
4379
|
_encryptionKey = null;
|
|
4173
4380
|
}
|
|
4174
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
4381
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
4175
4382
|
var init_shard_manager = __esm({
|
|
4176
4383
|
"src/lib/shard-manager.ts"() {
|
|
4177
4384
|
"use strict";
|
|
@@ -4185,6 +4392,8 @@ var init_shard_manager = __esm({
|
|
|
4185
4392
|
_evictionTimer = null;
|
|
4186
4393
|
_encryptionKey = null;
|
|
4187
4394
|
_shardingEnabled = false;
|
|
4395
|
+
_keyValidated = false;
|
|
4396
|
+
_keyValidationPromise = null;
|
|
4188
4397
|
}
|
|
4189
4398
|
});
|
|
4190
4399
|
|
|
@@ -4380,6 +4589,18 @@ var init_platform_procedures = __esm({
|
|
|
4380
4589
|
priority: "p0",
|
|
4381
4590
|
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.'"
|
|
4382
4591
|
},
|
|
4592
|
+
{
|
|
4593
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
4594
|
+
domain: "workflow",
|
|
4595
|
+
priority: "p0",
|
|
4596
|
+
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."
|
|
4597
|
+
},
|
|
4598
|
+
{
|
|
4599
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
4600
|
+
domain: "workflow",
|
|
4601
|
+
priority: "p0",
|
|
4602
|
+
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."
|
|
4603
|
+
},
|
|
4383
4604
|
{
|
|
4384
4605
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
4385
4606
|
domain: "architecture",
|
|
@@ -4977,6 +5198,20 @@ __export(store_exports, {
|
|
|
4977
5198
|
vectorToBlob: () => vectorToBlob,
|
|
4978
5199
|
writeMemory: () => writeMemory
|
|
4979
5200
|
});
|
|
5201
|
+
function logStoreDebug(context, err) {
|
|
5202
|
+
if (_debugStore) {
|
|
5203
|
+
process.stderr.write(
|
|
5204
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5205
|
+
`
|
|
5206
|
+
);
|
|
5207
|
+
}
|
|
5208
|
+
}
|
|
5209
|
+
function logStoreWarn(context, err) {
|
|
5210
|
+
process.stderr.write(
|
|
5211
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5212
|
+
`
|
|
5213
|
+
);
|
|
5214
|
+
}
|
|
4980
5215
|
function isBusyError2(err) {
|
|
4981
5216
|
if (err instanceof Error) {
|
|
4982
5217
|
const msg = err.message.toLowerCase();
|
|
@@ -5031,13 +5266,15 @@ async function initStore(options) {
|
|
|
5031
5266
|
try {
|
|
5032
5267
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5033
5268
|
await initDaemonClient2();
|
|
5034
|
-
} catch {
|
|
5269
|
+
} catch (e) {
|
|
5270
|
+
logStoreWarn("catch", e);
|
|
5035
5271
|
}
|
|
5036
5272
|
if (!options?.lightweight) {
|
|
5037
5273
|
try {
|
|
5038
5274
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
5039
5275
|
initShardManager2(hexKey);
|
|
5040
|
-
} catch {
|
|
5276
|
+
} catch (e) {
|
|
5277
|
+
logStoreWarn("catch", e);
|
|
5041
5278
|
}
|
|
5042
5279
|
const client = getClient();
|
|
5043
5280
|
const vResult = await retryOnBusy2(
|
|
@@ -5048,7 +5285,8 @@ async function initStore(options) {
|
|
|
5048
5285
|
try {
|
|
5049
5286
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
5050
5287
|
await loadGlobalProcedures2();
|
|
5051
|
-
} catch {
|
|
5288
|
+
} catch (e) {
|
|
5289
|
+
logStoreWarn("catch", e);
|
|
5052
5290
|
}
|
|
5053
5291
|
}
|
|
5054
5292
|
}
|
|
@@ -5108,7 +5346,8 @@ async function writeMemory(record) {
|
|
|
5108
5346
|
memoryType
|
|
5109
5347
|
});
|
|
5110
5348
|
if (existing) return;
|
|
5111
|
-
} catch {
|
|
5349
|
+
} catch (e) {
|
|
5350
|
+
logStoreWarn("catch", e);
|
|
5112
5351
|
}
|
|
5113
5352
|
const dbRow = {
|
|
5114
5353
|
id: record.id,
|
|
@@ -5309,12 +5548,14 @@ async function flushBatch() {
|
|
|
5309
5548
|
try {
|
|
5310
5549
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5311
5550
|
await insertMemoryCardsForBatch2(batch);
|
|
5312
|
-
} catch {
|
|
5551
|
+
} catch (e) {
|
|
5552
|
+
logStoreWarn("catch", e);
|
|
5313
5553
|
}
|
|
5314
5554
|
try {
|
|
5315
5555
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
5316
5556
|
await insertOntologyForBatch2(batch);
|
|
5317
|
-
} catch {
|
|
5557
|
+
} catch (e) {
|
|
5558
|
+
logStoreWarn("catch", e);
|
|
5318
5559
|
}
|
|
5319
5560
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
5320
5561
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -5353,7 +5594,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
5353
5594
|
}
|
|
5354
5595
|
}
|
|
5355
5596
|
}
|
|
5356
|
-
} catch {
|
|
5597
|
+
} catch (e) {
|
|
5598
|
+
logStoreWarn("catch", e);
|
|
5357
5599
|
}
|
|
5358
5600
|
return batch.length;
|
|
5359
5601
|
} finally {
|
|
@@ -5395,7 +5637,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5395
5637
|
} else {
|
|
5396
5638
|
client = getClient();
|
|
5397
5639
|
}
|
|
5398
|
-
} catch {
|
|
5640
|
+
} catch (e) {
|
|
5641
|
+
logStoreDebug("shard routing fallback", e);
|
|
5399
5642
|
client = getClient();
|
|
5400
5643
|
}
|
|
5401
5644
|
const limit = options?.limit ?? 10;
|
|
@@ -5511,7 +5754,8 @@ async function attachDocumentMetadata(records) {
|
|
|
5511
5754
|
if (!record.document_id) continue;
|
|
5512
5755
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
5513
5756
|
}
|
|
5514
|
-
} catch {
|
|
5757
|
+
} catch (e) {
|
|
5758
|
+
logStoreWarn("catch", e);
|
|
5515
5759
|
}
|
|
5516
5760
|
return records;
|
|
5517
5761
|
}
|
|
@@ -5572,11 +5816,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
5572
5816
|
args: [agentId]
|
|
5573
5817
|
});
|
|
5574
5818
|
return Number(result.rows[0]?.cnt) || 0;
|
|
5575
|
-
} catch {
|
|
5819
|
+
} catch (e) {
|
|
5820
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
5576
5821
|
return 0;
|
|
5577
5822
|
}
|
|
5578
5823
|
}
|
|
5579
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5824
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
5580
5825
|
var init_store = __esm({
|
|
5581
5826
|
"src/lib/store.ts"() {
|
|
5582
5827
|
"use strict";
|
|
@@ -5586,6 +5831,7 @@ var init_store = __esm({
|
|
|
5586
5831
|
init_config();
|
|
5587
5832
|
init_state_bus();
|
|
5588
5833
|
init_memory_write_governor();
|
|
5834
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
5589
5835
|
INIT_MAX_RETRIES = 3;
|
|
5590
5836
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
5591
5837
|
_pendingRecords = [];
|
|
@@ -5625,10 +5871,10 @@ var init_runtime_table = __esm({
|
|
|
5625
5871
|
});
|
|
5626
5872
|
|
|
5627
5873
|
// src/lib/agent-config.ts
|
|
5628
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as
|
|
5874
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync10 } from "fs";
|
|
5629
5875
|
import path9 from "path";
|
|
5630
5876
|
function loadAgentConfig() {
|
|
5631
|
-
if (!
|
|
5877
|
+
if (!existsSync10(AGENT_CONFIG_PATH)) return {};
|
|
5632
5878
|
try {
|
|
5633
5879
|
return JSON.parse(readFileSync5(AGENT_CONFIG_PATH, "utf-8"));
|
|
5634
5880
|
} catch {
|
|
@@ -5750,7 +5996,7 @@ __export(active_agent_exports, {
|
|
|
5750
5996
|
resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
|
|
5751
5997
|
writeActiveAgent: () => writeActiveAgent
|
|
5752
5998
|
});
|
|
5753
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as
|
|
5999
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, unlinkSync as unlinkSync5, readdirSync as readdirSync3 } from "fs";
|
|
5754
6000
|
import { execSync as execSync6 } from "child_process";
|
|
5755
6001
|
import path10 from "path";
|
|
5756
6002
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
@@ -5800,7 +6046,7 @@ function getMarkerPath() {
|
|
|
5800
6046
|
}
|
|
5801
6047
|
function writeActiveAgent(agentId, agentRole) {
|
|
5802
6048
|
try {
|
|
5803
|
-
|
|
6049
|
+
mkdirSync5(CACHE_DIR, { recursive: true });
|
|
5804
6050
|
writeFileSync5(
|
|
5805
6051
|
getMarkerPath(),
|
|
5806
6052
|
JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
@@ -5810,7 +6056,7 @@ function writeActiveAgent(agentId, agentRole) {
|
|
|
5810
6056
|
}
|
|
5811
6057
|
function clearActiveAgent() {
|
|
5812
6058
|
try {
|
|
5813
|
-
|
|
6059
|
+
unlinkSync5(getMarkerPath());
|
|
5814
6060
|
} catch {
|
|
5815
6061
|
}
|
|
5816
6062
|
}
|
|
@@ -5826,7 +6072,7 @@ function getActiveAgent() {
|
|
|
5826
6072
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
5827
6073
|
if (age > STALE_MS) {
|
|
5828
6074
|
try {
|
|
5829
|
-
|
|
6075
|
+
unlinkSync5(markerPath);
|
|
5830
6076
|
} catch {
|
|
5831
6077
|
}
|
|
5832
6078
|
} else {
|
|
@@ -5874,7 +6120,7 @@ function getAllActiveAgents() {
|
|
|
5874
6120
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
5875
6121
|
if (age > STALE_MS) {
|
|
5876
6122
|
try {
|
|
5877
|
-
|
|
6123
|
+
unlinkSync5(path10.join(CACHE_DIR, file));
|
|
5878
6124
|
} catch {
|
|
5879
6125
|
}
|
|
5880
6126
|
continue;
|
|
@@ -5897,11 +6143,11 @@ function getAllActiveAgents() {
|
|
|
5897
6143
|
function cleanupSessionMarkers() {
|
|
5898
6144
|
const key = getSessionKey();
|
|
5899
6145
|
try {
|
|
5900
|
-
|
|
6146
|
+
unlinkSync5(path10.join(CACHE_DIR, `active-agent-${key}.json`));
|
|
5901
6147
|
} catch {
|
|
5902
6148
|
}
|
|
5903
6149
|
try {
|
|
5904
|
-
|
|
6150
|
+
unlinkSync5(path10.join(CACHE_DIR, "active-agent-undefined.json"));
|
|
5905
6151
|
} catch {
|
|
5906
6152
|
}
|
|
5907
6153
|
}
|
|
@@ -5922,7 +6168,7 @@ var init_active_agent = __esm({
|
|
|
5922
6168
|
init_store();
|
|
5923
6169
|
import os7 from "os";
|
|
5924
6170
|
import path11 from "path";
|
|
5925
|
-
import { existsSync as
|
|
6171
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync4 } from "fs";
|
|
5926
6172
|
import { spawnSync } from "child_process";
|
|
5927
6173
|
|
|
5928
6174
|
// src/bin/fast-db-init.ts
|
|
@@ -5992,11 +6238,11 @@ async function fastDbInit() {
|
|
|
5992
6238
|
import os6 from "os";
|
|
5993
6239
|
import path8 from "path";
|
|
5994
6240
|
import {
|
|
5995
|
-
existsSync as
|
|
5996
|
-
mkdirSync as
|
|
6241
|
+
existsSync as existsSync9,
|
|
6242
|
+
mkdirSync as mkdirSync4,
|
|
5997
6243
|
readdirSync as readdirSync2,
|
|
5998
|
-
statSync as
|
|
5999
|
-
unlinkSync as
|
|
6244
|
+
statSync as statSync5,
|
|
6245
|
+
unlinkSync as unlinkSync4,
|
|
6000
6246
|
writeFileSync as writeFileSync3
|
|
6001
6247
|
} from "fs";
|
|
6002
6248
|
|
|
@@ -6057,7 +6303,7 @@ function getBehaviorLimit() {
|
|
|
6057
6303
|
}
|
|
6058
6304
|
}
|
|
6059
6305
|
function sweepStaleBehaviorExports(now = Date.now()) {
|
|
6060
|
-
if (!
|
|
6306
|
+
if (!existsSync9(BEHAVIORS_EXPORT_DIR)) return;
|
|
6061
6307
|
let entries;
|
|
6062
6308
|
try {
|
|
6063
6309
|
entries = readdirSync2(BEHAVIORS_EXPORT_DIR);
|
|
@@ -6067,9 +6313,9 @@ function sweepStaleBehaviorExports(now = Date.now()) {
|
|
|
6067
6313
|
for (const entry of entries) {
|
|
6068
6314
|
const filePath = path8.join(BEHAVIORS_EXPORT_DIR, entry);
|
|
6069
6315
|
try {
|
|
6070
|
-
const stat =
|
|
6316
|
+
const stat = statSync5(filePath);
|
|
6071
6317
|
if (now - stat.mtimeMs > STALE_EXPORT_AGE_MS) {
|
|
6072
|
-
|
|
6318
|
+
unlinkSync4(filePath);
|
|
6073
6319
|
}
|
|
6074
6320
|
} catch {
|
|
6075
6321
|
}
|
|
@@ -6107,7 +6353,7 @@ function exportFilePath(agentId, projectName, sessionKey) {
|
|
|
6107
6353
|
);
|
|
6108
6354
|
}
|
|
6109
6355
|
async function exportBehaviorsForAgent(agentId, projectName, sessionKey) {
|
|
6110
|
-
|
|
6356
|
+
mkdirSync4(BEHAVIORS_EXPORT_DIR, { recursive: true });
|
|
6111
6357
|
sweepStaleBehaviorExports();
|
|
6112
6358
|
const behaviors = await listBehaviors(agentId, projectName, getBehaviorLimit());
|
|
6113
6359
|
if (behaviors.length === 0) return null;
|
|
@@ -6343,7 +6589,7 @@ async function isKnownAgent(agent) {
|
|
|
6343
6589
|
function identityPathFor(agent) {
|
|
6344
6590
|
const dir = path11.join(os7.homedir(), ".exe-os", "identity");
|
|
6345
6591
|
const exactPath = path11.join(dir, `${agent}.md`);
|
|
6346
|
-
if (
|
|
6592
|
+
if (existsSync11(exactPath)) return exactPath;
|
|
6347
6593
|
try {
|
|
6348
6594
|
const files = readdirSync4(dir);
|
|
6349
6595
|
const match = files.find((f) => f.toLowerCase() === `${agent.toLowerCase()}.md`);
|
|
@@ -6374,7 +6620,7 @@ function collectAllMcpServers() {
|
|
|
6374
6620
|
];
|
|
6375
6621
|
for (const src of sources) {
|
|
6376
6622
|
try {
|
|
6377
|
-
if (!
|
|
6623
|
+
if (!existsSync11(src)) continue;
|
|
6378
6624
|
const data = JSON.parse(readFileSync7(src, "utf-8"));
|
|
6379
6625
|
const block = data.mcpServers;
|
|
6380
6626
|
if (!block) continue;
|
|
@@ -6410,7 +6656,7 @@ function generateLeanMcpConfig(agent, role) {
|
|
|
6410
6656
|
};
|
|
6411
6657
|
}
|
|
6412
6658
|
const configDir = path11.join(os7.homedir(), ".exe-os", "mcp-configs");
|
|
6413
|
-
|
|
6659
|
+
mkdirSync6(configDir, { recursive: true });
|
|
6414
6660
|
const configPath = path11.join(configDir, `${agent}-lean.json`);
|
|
6415
6661
|
writeFileSync6(configPath, JSON.stringify({ mcpServers: leanServers }, null, 2), "utf-8");
|
|
6416
6662
|
const saved = Object.keys(allServers).length - Object.keys(leanServers).length;
|
|
@@ -6432,7 +6678,7 @@ function generateLeanMcpConfig(agent, role) {
|
|
|
6432
6678
|
function leanMcpConfigFor(agent) {
|
|
6433
6679
|
if (!leanMcpEnabled()) return null;
|
|
6434
6680
|
const p = path11.join(os7.homedir(), ".exe-os", "mcp-configs", `${agent}-lean.json`);
|
|
6435
|
-
return
|
|
6681
|
+
return existsSync11(p) ? p : null;
|
|
6436
6682
|
}
|
|
6437
6683
|
var _ccHelpOutput = null;
|
|
6438
6684
|
function getCcHelpOutput() {
|
|
@@ -6457,7 +6703,7 @@ function buildLaunchPlan(agent, behaviorsPath, passthrough, _hasAgentFlag, _prov
|
|
|
6457
6703
|
const idPath = identityPathFor(agent);
|
|
6458
6704
|
const ccAgentPath = path11.join(os7.homedir(), ".claude", "agents", `${agent}.md`);
|
|
6459
6705
|
let effectiveCcPath = null;
|
|
6460
|
-
if (
|
|
6706
|
+
if (existsSync11(ccAgentPath)) {
|
|
6461
6707
|
effectiveCcPath = ccAgentPath;
|
|
6462
6708
|
} else {
|
|
6463
6709
|
try {
|
|
@@ -6468,9 +6714,9 @@ function buildLaunchPlan(agent, behaviorsPath, passthrough, _hasAgentFlag, _prov
|
|
|
6468
6714
|
} catch {
|
|
6469
6715
|
}
|
|
6470
6716
|
}
|
|
6471
|
-
const effectiveIdPath =
|
|
6717
|
+
const effectiveIdPath = existsSync11(idPath) ? idPath : effectiveCcPath;
|
|
6472
6718
|
let identityContent = null;
|
|
6473
|
-
if (effectiveIdPath &&
|
|
6719
|
+
if (effectiveIdPath && existsSync11(effectiveIdPath)) {
|
|
6474
6720
|
try {
|
|
6475
6721
|
const content = readFileSync7(effectiveIdPath, "utf-8");
|
|
6476
6722
|
if (content.trim().length > 0) identityContent = content;
|
|
@@ -6480,14 +6726,14 @@ function buildLaunchPlan(agent, behaviorsPath, passthrough, _hasAgentFlag, _prov
|
|
|
6480
6726
|
if (!identityContent) {
|
|
6481
6727
|
try {
|
|
6482
6728
|
const rosterPath = path11.join(os7.homedir(), ".exe-os", "exe-employees.json");
|
|
6483
|
-
if (
|
|
6729
|
+
if (existsSync11(rosterPath)) {
|
|
6484
6730
|
const roster = JSON.parse(readFileSync7(rosterPath, "utf8"));
|
|
6485
6731
|
const emp = roster.find((e) => e.name.toLowerCase() === agent.toLowerCase());
|
|
6486
6732
|
if (emp?.systemPrompt && emp.systemPrompt.trim().length > 20) {
|
|
6487
6733
|
identityContent = emp.systemPrompt;
|
|
6488
6734
|
try {
|
|
6489
6735
|
const dir = path11.dirname(idPath);
|
|
6490
|
-
if (!
|
|
6736
|
+
if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
|
|
6491
6737
|
const hasFrontmatter = identityContent.trimStart().startsWith("---");
|
|
6492
6738
|
const fileContent = hasFrontmatter ? identityContent : `---
|
|
6493
6739
|
role: ${(emp.role ?? "employee").toLowerCase()}
|
|
@@ -6528,14 +6774,14 @@ ${identityContent}`;
|
|
|
6528
6774
|
} else {
|
|
6529
6775
|
try {
|
|
6530
6776
|
const tmpPath = path11.join(os7.homedir(), ".exe-os", "session-cache", `${agent}-identity.md`);
|
|
6531
|
-
|
|
6777
|
+
mkdirSync6(path11.dirname(tmpPath), { recursive: true });
|
|
6532
6778
|
writeFileSync6(tmpPath, identityContent, "utf-8");
|
|
6533
6779
|
args.push("--append-system-prompt-file", tmpPath);
|
|
6534
6780
|
} catch {
|
|
6535
6781
|
}
|
|
6536
6782
|
}
|
|
6537
6783
|
}
|
|
6538
|
-
if (behaviorsPath &&
|
|
6784
|
+
if (behaviorsPath && existsSync11(behaviorsPath)) {
|
|
6539
6785
|
args.push("--append-system-prompt-file", behaviorsPath);
|
|
6540
6786
|
}
|
|
6541
6787
|
const leanMcp = leanMcpConfigFor(agent);
|
|
@@ -6629,10 +6875,10 @@ async function main() {
|
|
|
6629
6875
|
if (hasAgentFlag) {
|
|
6630
6876
|
const ccAgentDir = path11.join(os7.homedir(), ".claude", "agents");
|
|
6631
6877
|
const ccAgentFile = path11.join(ccAgentDir, `${agent}.md`);
|
|
6632
|
-
if (!
|
|
6878
|
+
if (!existsSync11(ccAgentFile)) {
|
|
6633
6879
|
const exeIdentity = identityPathFor(agent);
|
|
6634
6880
|
let sourceFile = null;
|
|
6635
|
-
if (
|
|
6881
|
+
if (existsSync11(exeIdentity)) {
|
|
6636
6882
|
sourceFile = exeIdentity;
|
|
6637
6883
|
} else {
|
|
6638
6884
|
try {
|
|
@@ -6645,7 +6891,7 @@ async function main() {
|
|
|
6645
6891
|
}
|
|
6646
6892
|
if (sourceFile) {
|
|
6647
6893
|
try {
|
|
6648
|
-
|
|
6894
|
+
mkdirSync6(ccAgentDir, { recursive: true });
|
|
6649
6895
|
let content = readFileSync7(sourceFile, "utf-8");
|
|
6650
6896
|
content = content.replace(/\$\{agent_id\}/g, baseAgentName(agent));
|
|
6651
6897
|
writeFileSync6(ccAgentFile, content, "utf-8");
|