@askexenow/exe-os 0.9.16 → 0.9.18
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/backfill-conversations.js +1242 -909
- package/dist/bin/backfill-responses.js +1245 -912
- package/dist/bin/backfill-vectors.js +1244 -906
- package/dist/bin/cleanup-stale-review-tasks.js +1870 -417
- package/dist/bin/cli.js +217 -107
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +62 -0
- package/dist/bin/exe-assign.js +346 -10
- package/dist/bin/exe-boot.js +387 -32
- package/dist/bin/exe-call.js +72 -2
- package/dist/bin/exe-cloud.js +8 -0
- package/dist/bin/exe-dispatch.js +1821 -225
- package/dist/bin/exe-doctor.js +720 -52
- package/dist/bin/exe-export-behaviors.js +1429 -148
- package/dist/bin/exe-forget.js +1408 -34
- package/dist/bin/exe-gateway.js +1629 -1295
- package/dist/bin/exe-heartbeat.js +1899 -448
- package/dist/bin/exe-kill.js +1624 -346
- package/dist/bin/exe-launch-agent.js +726 -90
- package/dist/bin/exe-link.js +27 -8
- package/dist/bin/exe-new-employee.js +75 -9
- package/dist/bin/exe-pending-messages.js +2769 -1316
- package/dist/bin/exe-pending-notifications.js +2829 -1376
- package/dist/bin/exe-pending-reviews.js +2847 -1392
- package/dist/bin/exe-rename.js +89 -8
- package/dist/bin/exe-review.js +1494 -312
- package/dist/bin/exe-search.js +1608 -1300
- package/dist/bin/exe-session-cleanup.js +194 -91
- package/dist/bin/exe-settings.js +10 -2
- package/dist/bin/exe-start-codex.js +769 -120
- package/dist/bin/exe-start-opencode.js +763 -108
- package/dist/bin/exe-status.js +1887 -434
- package/dist/bin/exe-team.js +1782 -324
- package/dist/bin/git-sweep.js +408 -33
- package/dist/bin/graph-backfill.js +681 -27
- package/dist/bin/graph-export.js +1419 -141
- package/dist/bin/install.js +4 -8
- package/dist/bin/intercom-check.js +8641 -0
- package/dist/bin/scan-tasks.js +553 -38
- package/dist/bin/setup.js +82 -10
- package/dist/bin/shard-migrate.js +682 -28
- package/dist/gateway/index.js +1629 -1295
- package/dist/hooks/bug-report-worker.js +1136 -183
- package/dist/hooks/codex-stop-task-finalizer.js +1060 -107
- package/dist/hooks/commit-complete.js +408 -33
- package/dist/hooks/error-recall.js +1608 -1300
- package/dist/hooks/ingest-worker.js +250 -7966
- package/dist/hooks/ingest.js +707 -119
- package/dist/hooks/instructions-loaded.js +383 -20
- package/dist/hooks/notification.js +383 -20
- package/dist/hooks/post-compact.js +384 -21
- package/dist/hooks/{response-ingest-worker.js → post-tool-combined.js} +4157 -1716
- package/dist/hooks/pre-compact.js +486 -45
- package/dist/hooks/pre-tool-use.js +385 -22
- package/dist/hooks/prompt-submit.js +291 -96
- package/dist/hooks/session-end.js +490 -48
- package/dist/hooks/session-start.js +236 -22
- package/dist/hooks/stop.js +192 -50
- package/dist/hooks/subagent-stop.js +95 -18
- package/dist/hooks/summary-worker.js +205 -361
- package/dist/index.js +221 -105
- package/dist/lib/agent-config.js +2 -2
- package/dist/lib/cloud-sync.js +27 -8
- package/dist/lib/consolidation.js +437 -41
- package/dist/lib/database.js +20 -8
- package/dist/lib/db-daemon-client.js +2 -2
- package/dist/lib/db.js +20 -8
- package/dist/lib/device-registry.js +27 -8
- package/dist/lib/employee-templates.js +62 -0
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon.js +6703 -6259
- package/dist/lib/hybrid-search.js +1608 -1300
- package/dist/lib/identity.js +1 -1
- package/dist/lib/messaging.js +11 -3
- package/dist/lib/reminders.js +1 -1
- package/dist/lib/schedules.js +718 -26
- package/dist/lib/session-registry.js +11 -0
- package/dist/lib/skill-learning.js +639 -9
- package/dist/lib/store.js +676 -27
- package/dist/lib/tasks.js +665 -27
- package/dist/lib/tmux-routing.js +732 -94
- package/dist/lib/token-spend.js +1 -1
- package/dist/mcp/server.js +856 -383
- package/dist/mcp/tools/complete-reminder.js +1 -1
- package/dist/mcp/tools/create-reminder.js +1 -1
- package/dist/mcp/tools/create-task.js +616 -46
- package/dist/mcp/tools/deactivate-behavior.js +9 -1
- package/dist/mcp/tools/list-reminders.js +1 -1
- package/dist/mcp/tools/list-tasks.js +10 -2
- package/dist/mcp/tools/send-message.js +11 -3
- package/dist/mcp/tools/update-task.js +677 -39
- package/dist/runtime/index.js +425 -37
- package/dist/tui/App.js +365 -34
- package/package.json +5 -2
- package/src/commands/exe/intercom.md +6 -17
- package/dist/bin/wiki-sync.js +0 -2991
- package/dist/hooks/prompt-ingest-worker.js +0 -3979
package/dist/runtime/index.js
CHANGED
|
@@ -64,6 +64,21 @@ var init_secure_files = __esm({
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
// src/lib/config.ts
|
|
67
|
+
var config_exports = {};
|
|
68
|
+
__export(config_exports, {
|
|
69
|
+
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
70
|
+
CONFIG_PATH: () => CONFIG_PATH,
|
|
71
|
+
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
72
|
+
DB_PATH: () => DB_PATH,
|
|
73
|
+
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
74
|
+
LEGACY_LANCE_PATH: () => LEGACY_LANCE_PATH,
|
|
75
|
+
MODELS_DIR: () => MODELS_DIR,
|
|
76
|
+
loadConfig: () => loadConfig,
|
|
77
|
+
loadConfigFrom: () => loadConfigFrom,
|
|
78
|
+
loadConfigSync: () => loadConfigSync,
|
|
79
|
+
migrateConfig: () => migrateConfig,
|
|
80
|
+
saveConfig: () => saveConfig
|
|
81
|
+
});
|
|
67
82
|
import { readFile, writeFile } from "fs/promises";
|
|
68
83
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
69
84
|
import path2 from "path";
|
|
@@ -167,6 +182,46 @@ async function loadConfig() {
|
|
|
167
182
|
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db") };
|
|
168
183
|
}
|
|
169
184
|
}
|
|
185
|
+
function loadConfigSync() {
|
|
186
|
+
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
187
|
+
const configPath = path2.join(dir, "config.json");
|
|
188
|
+
if (!existsSync2(configPath)) {
|
|
189
|
+
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db") };
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
193
|
+
let parsed = JSON.parse(raw);
|
|
194
|
+
parsed = migrateLegacyConfig(parsed);
|
|
195
|
+
const { config: migratedCfg } = migrateConfig(parsed);
|
|
196
|
+
normalizeScalingRoadmap(migratedCfg);
|
|
197
|
+
normalizeSessionLifecycle(migratedCfg);
|
|
198
|
+
normalizeAutoUpdate(migratedCfg);
|
|
199
|
+
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
200
|
+
} catch {
|
|
201
|
+
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db") };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function saveConfig(config) {
|
|
205
|
+
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
206
|
+
await ensurePrivateDir(dir);
|
|
207
|
+
const configPath = path2.join(dir, "config.json");
|
|
208
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
209
|
+
await enforcePrivateFile(configPath);
|
|
210
|
+
}
|
|
211
|
+
async function loadConfigFrom(configPath) {
|
|
212
|
+
const raw = await readFile(configPath, "utf-8");
|
|
213
|
+
try {
|
|
214
|
+
let parsed = JSON.parse(raw);
|
|
215
|
+
parsed = migrateLegacyConfig(parsed);
|
|
216
|
+
const { config: migratedCfg } = migrateConfig(parsed);
|
|
217
|
+
normalizeScalingRoadmap(migratedCfg);
|
|
218
|
+
normalizeSessionLifecycle(migratedCfg);
|
|
219
|
+
normalizeAutoUpdate(migratedCfg);
|
|
220
|
+
return { ...DEFAULT_CONFIG, ...migratedCfg };
|
|
221
|
+
} catch {
|
|
222
|
+
return { ...DEFAULT_CONFIG };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
170
225
|
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
171
226
|
var init_config = __esm({
|
|
172
227
|
"src/lib/config.ts"() {
|
|
@@ -324,6 +379,7 @@ var session_registry_exports = {};
|
|
|
324
379
|
__export(session_registry_exports, {
|
|
325
380
|
listSessions: () => listSessions,
|
|
326
381
|
pruneStaleSessions: () => pruneStaleSessions,
|
|
382
|
+
refreshSessionProject: () => refreshSessionProject,
|
|
327
383
|
registerSession: () => registerSession
|
|
328
384
|
});
|
|
329
385
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
|
|
@@ -344,6 +400,16 @@ function registerSession(entry) {
|
|
|
344
400
|
}
|
|
345
401
|
writeFileSync2(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
|
|
346
402
|
}
|
|
403
|
+
function refreshSessionProject(windowName, projectDir) {
|
|
404
|
+
const sessions = listSessions();
|
|
405
|
+
const entry = sessions.find((s) => s.windowName === windowName);
|
|
406
|
+
if (!entry || entry.projectDir === projectDir) return;
|
|
407
|
+
entry.projectDir = projectDir;
|
|
408
|
+
try {
|
|
409
|
+
writeFileSync2(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
|
|
410
|
+
} catch {
|
|
411
|
+
}
|
|
412
|
+
}
|
|
347
413
|
function listSessions() {
|
|
348
414
|
try {
|
|
349
415
|
const raw = readFileSync3(REGISTRY_PATH, "utf8");
|
|
@@ -702,7 +768,7 @@ var init_agent_config = __esm({
|
|
|
702
768
|
init_secure_files();
|
|
703
769
|
AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
|
|
704
770
|
DEFAULT_MODELS = {
|
|
705
|
-
claude: "claude-opus-4",
|
|
771
|
+
claude: "claude-opus-4.6",
|
|
706
772
|
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
707
773
|
opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
|
|
708
774
|
};
|
|
@@ -884,9 +950,9 @@ var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
|
884
950
|
var init_db_retry = __esm({
|
|
885
951
|
"src/lib/db-retry.ts"() {
|
|
886
952
|
"use strict";
|
|
887
|
-
MAX_RETRIES2 =
|
|
888
|
-
BASE_DELAY_MS =
|
|
889
|
-
MAX_JITTER_MS =
|
|
953
|
+
MAX_RETRIES2 = 5;
|
|
954
|
+
BASE_DELAY_MS = 250;
|
|
955
|
+
MAX_JITTER_MS = 400;
|
|
890
956
|
}
|
|
891
957
|
});
|
|
892
958
|
|
|
@@ -1474,6 +1540,15 @@ var init_database_adapter = __esm({
|
|
|
1474
1540
|
}
|
|
1475
1541
|
});
|
|
1476
1542
|
|
|
1543
|
+
// src/types/memory.ts
|
|
1544
|
+
var EMBEDDING_DIM;
|
|
1545
|
+
var init_memory = __esm({
|
|
1546
|
+
"src/types/memory.ts"() {
|
|
1547
|
+
"use strict";
|
|
1548
|
+
EMBEDDING_DIM = 1024;
|
|
1549
|
+
}
|
|
1550
|
+
});
|
|
1551
|
+
|
|
1477
1552
|
// src/lib/daemon-auth.ts
|
|
1478
1553
|
import crypto from "crypto";
|
|
1479
1554
|
import path8 from "path";
|
|
@@ -1748,6 +1823,9 @@ async function connectEmbedDaemon() {
|
|
|
1748
1823
|
}
|
|
1749
1824
|
return false;
|
|
1750
1825
|
}
|
|
1826
|
+
function sendRequest(texts, priority) {
|
|
1827
|
+
return sendDaemonRequest({ texts, priority });
|
|
1828
|
+
}
|
|
1751
1829
|
function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
1752
1830
|
return new Promise((resolve) => {
|
|
1753
1831
|
if (!_socket || !_connected) {
|
|
@@ -1770,10 +1848,150 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1770
1848
|
}
|
|
1771
1849
|
});
|
|
1772
1850
|
}
|
|
1851
|
+
async function pingDaemon() {
|
|
1852
|
+
if (!_socket || !_connected) return null;
|
|
1853
|
+
const response = await sendDaemonRequest({ type: "health" }, 5e3);
|
|
1854
|
+
if (response.health) {
|
|
1855
|
+
return response.health;
|
|
1856
|
+
}
|
|
1857
|
+
return null;
|
|
1858
|
+
}
|
|
1859
|
+
function killAndRespawnDaemon() {
|
|
1860
|
+
if (!acquireSpawnLock()) {
|
|
1861
|
+
process.stderr.write("[exed-client] Another process is already restarting daemon \u2014 skipping\n");
|
|
1862
|
+
if (_socket) {
|
|
1863
|
+
_socket.destroy();
|
|
1864
|
+
_socket = null;
|
|
1865
|
+
}
|
|
1866
|
+
_connected = false;
|
|
1867
|
+
_buffer = "";
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
try {
|
|
1871
|
+
process.stderr.write("[exed-client] Killing daemon for restart...\n");
|
|
1872
|
+
if (existsSync8(PID_PATH)) {
|
|
1873
|
+
try {
|
|
1874
|
+
const pid = parseInt(readFileSync7(PID_PATH, "utf8").trim(), 10);
|
|
1875
|
+
if (pid > 0) {
|
|
1876
|
+
try {
|
|
1877
|
+
process.kill(pid, "SIGKILL");
|
|
1878
|
+
} catch {
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
} catch {
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
if (_socket) {
|
|
1885
|
+
_socket.destroy();
|
|
1886
|
+
_socket = null;
|
|
1887
|
+
}
|
|
1888
|
+
_connected = false;
|
|
1889
|
+
_buffer = "";
|
|
1890
|
+
try {
|
|
1891
|
+
unlinkSync2(PID_PATH);
|
|
1892
|
+
} catch {
|
|
1893
|
+
}
|
|
1894
|
+
try {
|
|
1895
|
+
unlinkSync2(SOCKET_PATH);
|
|
1896
|
+
} catch {
|
|
1897
|
+
}
|
|
1898
|
+
spawnDaemon();
|
|
1899
|
+
} finally {
|
|
1900
|
+
releaseSpawnLock();
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
function isDaemonTooYoung() {
|
|
1904
|
+
try {
|
|
1905
|
+
const stat = statSync(PID_PATH);
|
|
1906
|
+
return Date.now() - stat.mtimeMs < MIN_DAEMON_AGE_MS;
|
|
1907
|
+
} catch {
|
|
1908
|
+
return false;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
async function retryThenRestart(doRequest, label) {
|
|
1912
|
+
const result = await doRequest();
|
|
1913
|
+
if (!result.error) {
|
|
1914
|
+
_consecutiveFailures = 0;
|
|
1915
|
+
return result;
|
|
1916
|
+
}
|
|
1917
|
+
_consecutiveFailures++;
|
|
1918
|
+
for (let i = 0; i < MAX_RETRIES_BEFORE_RESTART; i++) {
|
|
1919
|
+
const delayMs = RETRY_DELAYS_MS[i] ?? 5e3;
|
|
1920
|
+
process.stderr.write(`[exed-client] ${label} failed (${result.error}), retry ${i + 1}/${MAX_RETRIES_BEFORE_RESTART} in ${delayMs}ms
|
|
1921
|
+
`);
|
|
1922
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
1923
|
+
if (!_connected) {
|
|
1924
|
+
if (!await connectToSocket()) continue;
|
|
1925
|
+
}
|
|
1926
|
+
const retry = await doRequest();
|
|
1927
|
+
if (!retry.error) {
|
|
1928
|
+
_consecutiveFailures = 0;
|
|
1929
|
+
return retry;
|
|
1930
|
+
}
|
|
1931
|
+
_consecutiveFailures++;
|
|
1932
|
+
}
|
|
1933
|
+
if (isDaemonTooYoung()) {
|
|
1934
|
+
process.stderr.write(`[exed-client] ${label}: daemon too young (< ${MIN_DAEMON_AGE_MS / 1e3}s) \u2014 skipping restart
|
|
1935
|
+
`);
|
|
1936
|
+
return { error: result.error };
|
|
1937
|
+
}
|
|
1938
|
+
process.stderr.write(`[exed-client] ${label}: ${_consecutiveFailures} consecutive failures \u2014 restarting daemon
|
|
1939
|
+
`);
|
|
1940
|
+
killAndRespawnDaemon();
|
|
1941
|
+
const start = Date.now();
|
|
1942
|
+
let delay2 = 200;
|
|
1943
|
+
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1944
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
1945
|
+
if (await connectToSocket()) break;
|
|
1946
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
1947
|
+
}
|
|
1948
|
+
if (!_connected) return { error: "Daemon restart failed" };
|
|
1949
|
+
const final = await doRequest();
|
|
1950
|
+
if (!final.error) _consecutiveFailures = 0;
|
|
1951
|
+
return final;
|
|
1952
|
+
}
|
|
1953
|
+
async function embedViaClient(text, priority = "high") {
|
|
1954
|
+
if (!_connected && !await connectEmbedDaemon()) return null;
|
|
1955
|
+
_requestCount++;
|
|
1956
|
+
if (_requestCount % HEALTH_CHECK_INTERVAL === 0) {
|
|
1957
|
+
const health = await pingDaemon();
|
|
1958
|
+
if (!health && !isDaemonTooYoung()) {
|
|
1959
|
+
process.stderr.write(`[exed-client] Periodic health check failed at request ${_requestCount} \u2014 restarting daemon
|
|
1960
|
+
`);
|
|
1961
|
+
killAndRespawnDaemon();
|
|
1962
|
+
const start = Date.now();
|
|
1963
|
+
let d = 200;
|
|
1964
|
+
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1965
|
+
await new Promise((r) => setTimeout(r, d));
|
|
1966
|
+
if (await connectToSocket()) break;
|
|
1967
|
+
d = Math.min(d * 2, 3e3);
|
|
1968
|
+
}
|
|
1969
|
+
if (!_connected) return null;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
const result = await retryThenRestart(
|
|
1973
|
+
() => sendRequest([text], priority),
|
|
1974
|
+
"Embed"
|
|
1975
|
+
);
|
|
1976
|
+
return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
|
|
1977
|
+
}
|
|
1978
|
+
function disconnectClient() {
|
|
1979
|
+
if (_socket) {
|
|
1980
|
+
_socket.destroy();
|
|
1981
|
+
_socket = null;
|
|
1982
|
+
}
|
|
1983
|
+
_connected = false;
|
|
1984
|
+
_buffer = "";
|
|
1985
|
+
for (const [id, entry] of _pending) {
|
|
1986
|
+
clearTimeout(entry.timer);
|
|
1987
|
+
_pending.delete(id);
|
|
1988
|
+
entry.resolve({ error: "Client disconnected" });
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1773
1991
|
function isClientConnected() {
|
|
1774
1992
|
return _connected;
|
|
1775
1993
|
}
|
|
1776
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _pending, MAX_BUFFER;
|
|
1994
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
|
|
1777
1995
|
var init_exe_daemon_client = __esm({
|
|
1778
1996
|
"src/lib/exe-daemon-client.ts"() {
|
|
1779
1997
|
"use strict";
|
|
@@ -1789,6 +2007,12 @@ var init_exe_daemon_client = __esm({
|
|
|
1789
2007
|
_socket = null;
|
|
1790
2008
|
_connected = false;
|
|
1791
2009
|
_buffer = "";
|
|
2010
|
+
_requestCount = 0;
|
|
2011
|
+
_consecutiveFailures = 0;
|
|
2012
|
+
HEALTH_CHECK_INTERVAL = 100;
|
|
2013
|
+
MAX_RETRIES_BEFORE_RESTART = 3;
|
|
2014
|
+
RETRY_DELAYS_MS = [1e3, 3e3, 5e3];
|
|
2015
|
+
MIN_DAEMON_AGE_MS = 3e4;
|
|
1792
2016
|
_pending = /* @__PURE__ */ new Map();
|
|
1793
2017
|
MAX_BUFFER = 1e7;
|
|
1794
2018
|
}
|
|
@@ -1896,7 +2120,7 @@ function createDaemonDbClient(fallbackClient) {
|
|
|
1896
2120
|
});
|
|
1897
2121
|
if (response.error) {
|
|
1898
2122
|
const errMsg = String(response.error);
|
|
1899
|
-
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
2123
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed" || errMsg === "DB not initialized") {
|
|
1900
2124
|
process.stderr.write(`[db-daemon] Transport error (${errMsg}), falling back to direct
|
|
1901
2125
|
`);
|
|
1902
2126
|
return fallbackClient.execute(stmt);
|
|
@@ -1921,7 +2145,7 @@ function createDaemonDbClient(fallbackClient) {
|
|
|
1921
2145
|
});
|
|
1922
2146
|
if (response.error) {
|
|
1923
2147
|
const errMsg = String(response.error);
|
|
1924
|
-
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
2148
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed" || errMsg === "DB not initialized") {
|
|
1925
2149
|
process.stderr.write(`[db-daemon] Batch transport error (${errMsg}), falling back to direct
|
|
1926
2150
|
`);
|
|
1927
2151
|
return fallbackClient.batch(stmts, mode);
|
|
@@ -2044,7 +2268,7 @@ async function initDatabase(config) {
|
|
|
2044
2268
|
});
|
|
2045
2269
|
}, 3e4);
|
|
2046
2270
|
_walCheckpointTimer.unref();
|
|
2047
|
-
if (process.env.DATABASE_URL) {
|
|
2271
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2048
2272
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2049
2273
|
}
|
|
2050
2274
|
}
|
|
@@ -2055,7 +2279,7 @@ function getClient() {
|
|
|
2055
2279
|
if (!_adapterClient) {
|
|
2056
2280
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
2057
2281
|
}
|
|
2058
|
-
if (process.env.DATABASE_URL) {
|
|
2282
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2059
2283
|
return _adapterClient;
|
|
2060
2284
|
}
|
|
2061
2285
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
@@ -2067,9 +2291,11 @@ function getClient() {
|
|
|
2067
2291
|
return _resilientClient;
|
|
2068
2292
|
}
|
|
2069
2293
|
async function initDaemonClient() {
|
|
2070
|
-
if (process.env.DATABASE_URL) return;
|
|
2294
|
+
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
|
|
2071
2295
|
if (process.env.EXE_IS_DAEMON === "1") return;
|
|
2296
|
+
if (process.env.VITEST) return;
|
|
2072
2297
|
if (!_resilientClient) return;
|
|
2298
|
+
if (_daemonClient) return;
|
|
2073
2299
|
try {
|
|
2074
2300
|
const { initDaemonDbClient: initDaemonDbClient2 } = await Promise.resolve().then(() => (init_db_daemon_client(), db_daemon_client_exports));
|
|
2075
2301
|
_daemonClient = await initDaemonDbClient2(_resilientClient);
|
|
@@ -2218,6 +2444,13 @@ async function ensureSchema() {
|
|
|
2218
2444
|
});
|
|
2219
2445
|
} catch {
|
|
2220
2446
|
}
|
|
2447
|
+
try {
|
|
2448
|
+
await client.execute({
|
|
2449
|
+
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2450
|
+
args: []
|
|
2451
|
+
});
|
|
2452
|
+
} catch {
|
|
2453
|
+
}
|
|
2221
2454
|
try {
|
|
2222
2455
|
await client.execute({
|
|
2223
2456
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3088,6 +3321,7 @@ var init_database = __esm({
|
|
|
3088
3321
|
init_db_retry();
|
|
3089
3322
|
init_employees();
|
|
3090
3323
|
init_database_adapter();
|
|
3324
|
+
init_memory();
|
|
3091
3325
|
_client = null;
|
|
3092
3326
|
_resilientClient = null;
|
|
3093
3327
|
_walCheckpointTimer = null;
|
|
@@ -3622,15 +3856,20 @@ async function createTaskCore(input) {
|
|
|
3622
3856
|
const { resolveExeSession: resolveExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
|
|
3623
3857
|
const resolved = resolveExeSession2();
|
|
3624
3858
|
if (resolved && input.projectName) {
|
|
3625
|
-
const
|
|
3626
|
-
|
|
3627
|
-
if (sessionProject && sessionProject !== input.projectName) {
|
|
3628
|
-
scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
|
|
3629
|
-
process.stderr.write(`[create_task] ${scopeMismatchWarning}
|
|
3630
|
-
`);
|
|
3631
|
-
earlySessionScope = null;
|
|
3632
|
-
} else {
|
|
3859
|
+
const isCoordinatorSession = !resolved.includes("-");
|
|
3860
|
+
if (isCoordinatorSession) {
|
|
3633
3861
|
earlySessionScope = resolved;
|
|
3862
|
+
} else {
|
|
3863
|
+
const { getSessionProject: getSessionProject2 } = await Promise.resolve().then(() => (init_session_scope(), session_scope_exports));
|
|
3864
|
+
const sessionProject = getSessionProject2(resolved);
|
|
3865
|
+
if (sessionProject && sessionProject !== input.projectName) {
|
|
3866
|
+
scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
|
|
3867
|
+
process.stderr.write(`[create_task] ${scopeMismatchWarning}
|
|
3868
|
+
`);
|
|
3869
|
+
earlySessionScope = null;
|
|
3870
|
+
} else {
|
|
3871
|
+
earlySessionScope = resolved;
|
|
3872
|
+
}
|
|
3634
3873
|
}
|
|
3635
3874
|
} else {
|
|
3636
3875
|
earlySessionScope = resolved;
|
|
@@ -4515,6 +4754,10 @@ async function dispatchTaskToEmployee(input) {
|
|
|
4515
4754
|
if (transport.isAlive(sessionName)) {
|
|
4516
4755
|
const result = sendIntercom(sessionName);
|
|
4517
4756
|
const dispatched = result === "acknowledged" || result === "debounced" || result === "queued" ? "verified" : result === "delivered" ? "sent_unverified" : "session_dead";
|
|
4757
|
+
process.stderr.write(
|
|
4758
|
+
`[dispatch-audit] intercom \u2192 ${sessionName} | task="${input.title}" [${input.priority}] | result=${dispatched} (sendIntercom=${result})
|
|
4759
|
+
`
|
|
4760
|
+
);
|
|
4518
4761
|
return { dispatched, session: sessionName, crossProject };
|
|
4519
4762
|
} else {
|
|
4520
4763
|
const projectDir = input.projectDir ?? process.cwd();
|
|
@@ -4523,11 +4766,15 @@ async function dispatchTaskToEmployee(input) {
|
|
|
4523
4766
|
});
|
|
4524
4767
|
if (result.status === "failed") {
|
|
4525
4768
|
process.stderr.write(
|
|
4526
|
-
`[dispatch]
|
|
4769
|
+
`[dispatch-audit] SPAWN FAILED \u2192 ${input.assignedTo} | task="${input.title}" [${input.priority}] | error=${result.error}
|
|
4527
4770
|
`
|
|
4528
4771
|
);
|
|
4529
4772
|
return { dispatched: "session_missing" };
|
|
4530
4773
|
}
|
|
4774
|
+
process.stderr.write(
|
|
4775
|
+
`[dispatch-audit] SPAWNED \u2192 ${result.sessionName} | task="${input.title}" [${input.priority}]
|
|
4776
|
+
`
|
|
4777
|
+
);
|
|
4531
4778
|
return { dispatched: "spawned", session: result.sessionName, crossProject };
|
|
4532
4779
|
}
|
|
4533
4780
|
} catch {
|
|
@@ -4537,7 +4784,13 @@ async function dispatchTaskToEmployee(input) {
|
|
|
4537
4784
|
function notifyTaskDone() {
|
|
4538
4785
|
try {
|
|
4539
4786
|
const key = getSessionKey();
|
|
4540
|
-
if (key && !process.env.VITEST)
|
|
4787
|
+
if (key && !process.env.VITEST) {
|
|
4788
|
+
notifyParentExe(key);
|
|
4789
|
+
process.stderr.write(
|
|
4790
|
+
`[dispatch-audit] notifyTaskDone \u2192 parent coordinator (session=${key})
|
|
4791
|
+
`
|
|
4792
|
+
);
|
|
4793
|
+
}
|
|
4541
4794
|
} catch {
|
|
4542
4795
|
}
|
|
4543
4796
|
}
|
|
@@ -4558,6 +4811,74 @@ var init_tasks_notify = __esm({
|
|
|
4558
4811
|
}
|
|
4559
4812
|
});
|
|
4560
4813
|
|
|
4814
|
+
// src/lib/embedder.ts
|
|
4815
|
+
var embedder_exports = {};
|
|
4816
|
+
__export(embedder_exports, {
|
|
4817
|
+
disposeEmbedder: () => disposeEmbedder,
|
|
4818
|
+
embed: () => embed,
|
|
4819
|
+
embedDirect: () => embedDirect,
|
|
4820
|
+
getEmbedder: () => getEmbedder
|
|
4821
|
+
});
|
|
4822
|
+
async function getEmbedder() {
|
|
4823
|
+
const ok = await connectEmbedDaemon();
|
|
4824
|
+
if (!ok) {
|
|
4825
|
+
throw new Error(
|
|
4826
|
+
"Could not connect to embedding daemon. Ensure the model is installed (run /exe-setup)."
|
|
4827
|
+
);
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
async function embed(text) {
|
|
4831
|
+
const priority = process.env.EXE_EMBED_PRIORITY === "low" ? "low" : "high";
|
|
4832
|
+
const vector = await embedViaClient(text, priority);
|
|
4833
|
+
if (!vector) {
|
|
4834
|
+
throw new Error(
|
|
4835
|
+
"Embedding failed: daemon unavailable. Run /exe-setup to verify model installation."
|
|
4836
|
+
);
|
|
4837
|
+
}
|
|
4838
|
+
if (vector.length !== EMBEDDING_DIM) {
|
|
4839
|
+
throw new Error(
|
|
4840
|
+
`Embedding dimension mismatch: expected ${EMBEDDING_DIM}, got ${vector.length}. Ensure the correct Jina v5-small Q4_K_M GGUF model is installed.`
|
|
4841
|
+
);
|
|
4842
|
+
}
|
|
4843
|
+
return vector;
|
|
4844
|
+
}
|
|
4845
|
+
async function disposeEmbedder() {
|
|
4846
|
+
disconnectClient();
|
|
4847
|
+
}
|
|
4848
|
+
async function embedDirect(text) {
|
|
4849
|
+
const llamaCpp = await import("node-llama-cpp");
|
|
4850
|
+
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
4851
|
+
const { existsSync: existsSync17 } = await import("fs");
|
|
4852
|
+
const path21 = await import("path");
|
|
4853
|
+
const modelPath = path21.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
4854
|
+
if (!existsSync17(modelPath)) {
|
|
4855
|
+
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
4856
|
+
}
|
|
4857
|
+
const llama = await llamaCpp.getLlama();
|
|
4858
|
+
const model = await llama.loadModel({ modelPath });
|
|
4859
|
+
const context = await model.createEmbeddingContext();
|
|
4860
|
+
try {
|
|
4861
|
+
const embedding = await context.getEmbeddingFor(text);
|
|
4862
|
+
const vector = Array.from(embedding.vector);
|
|
4863
|
+
if (vector.length !== EMBEDDING_DIM) {
|
|
4864
|
+
throw new Error(
|
|
4865
|
+
`Embedding dimension mismatch: expected ${EMBEDDING_DIM}, got ${vector.length}.`
|
|
4866
|
+
);
|
|
4867
|
+
}
|
|
4868
|
+
return vector;
|
|
4869
|
+
} finally {
|
|
4870
|
+
await context.dispose();
|
|
4871
|
+
await model.dispose();
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
var init_embedder = __esm({
|
|
4875
|
+
"src/lib/embedder.ts"() {
|
|
4876
|
+
"use strict";
|
|
4877
|
+
init_memory();
|
|
4878
|
+
init_exe_daemon_client();
|
|
4879
|
+
}
|
|
4880
|
+
});
|
|
4881
|
+
|
|
4561
4882
|
// src/lib/behaviors.ts
|
|
4562
4883
|
var behaviors_exports = {};
|
|
4563
4884
|
__export(behaviors_exports, {
|
|
@@ -4571,17 +4892,24 @@ async function storeBehavior(opts) {
|
|
|
4571
4892
|
const client = getClient();
|
|
4572
4893
|
const id = crypto5.randomUUID();
|
|
4573
4894
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4895
|
+
let vector = null;
|
|
4896
|
+
try {
|
|
4897
|
+
const { embed: embed2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
4898
|
+
const vec = await embed2(opts.content);
|
|
4899
|
+
vector = new Float32Array(vec);
|
|
4900
|
+
} catch {
|
|
4901
|
+
}
|
|
4574
4902
|
await client.execute({
|
|
4575
|
-
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
|
|
4576
|
-
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
4577
|
-
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now, now]
|
|
4903
|
+
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector)
|
|
4904
|
+
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?)`,
|
|
4905
|
+
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now, now, vector ? vector.buffer : null]
|
|
4578
4906
|
});
|
|
4579
4907
|
return id;
|
|
4580
4908
|
}
|
|
4581
4909
|
async function listBehaviors(agentId, projectName, limit = 30) {
|
|
4582
4910
|
const client = getClient();
|
|
4583
4911
|
const result = await client.execute({
|
|
4584
|
-
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at
|
|
4912
|
+
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector
|
|
4585
4913
|
FROM behaviors
|
|
4586
4914
|
WHERE agent_id = ? AND active = 1
|
|
4587
4915
|
AND (project_name IS NULL OR project_name = ?)
|
|
@@ -4602,13 +4930,14 @@ async function listBehaviors(agentId, projectName, limit = 30) {
|
|
|
4602
4930
|
content: String(r.content),
|
|
4603
4931
|
active: Number(r.active),
|
|
4604
4932
|
created_at: String(r.created_at),
|
|
4605
|
-
updated_at: String(r.updated_at)
|
|
4933
|
+
updated_at: String(r.updated_at),
|
|
4934
|
+
vector: r.vector ? Array.from(new Float32Array(r.vector)) : null
|
|
4606
4935
|
}));
|
|
4607
4936
|
}
|
|
4608
4937
|
async function listBehaviorsByDomain(agentId, domain) {
|
|
4609
4938
|
const client = getClient();
|
|
4610
4939
|
const result = await client.execute({
|
|
4611
|
-
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at
|
|
4940
|
+
sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector
|
|
4612
4941
|
FROM behaviors
|
|
4613
4942
|
WHERE agent_id = ? AND domain = ? AND active = 1`,
|
|
4614
4943
|
args: [agentId, domain]
|
|
@@ -4622,7 +4951,8 @@ async function listBehaviorsByDomain(agentId, domain) {
|
|
|
4622
4951
|
content: String(r.content),
|
|
4623
4952
|
active: Number(r.active),
|
|
4624
4953
|
created_at: String(r.created_at),
|
|
4625
|
-
updated_at: String(r.updated_at)
|
|
4954
|
+
updated_at: String(r.updated_at),
|
|
4955
|
+
vector: r.vector ? Array.from(new Float32Array(r.vector)) : null
|
|
4626
4956
|
}));
|
|
4627
4957
|
}
|
|
4628
4958
|
async function deactivateBehavior(id) {
|
|
@@ -5732,7 +6062,7 @@ function isSessionBusy(sessionName) {
|
|
|
5732
6062
|
function isExeSession(sessionName) {
|
|
5733
6063
|
const matchesBaseWithInstance = (baseName) => sessionName === baseName || sessionName.startsWith(baseName) && /^\d+$/.test(sessionName.slice(baseName.length));
|
|
5734
6064
|
const coordinatorName = getCoordinatorName();
|
|
5735
|
-
return matchesBaseWithInstance(coordinatorName)
|
|
6065
|
+
return matchesBaseWithInstance(coordinatorName);
|
|
5736
6066
|
}
|
|
5737
6067
|
function sendIntercom(targetSession) {
|
|
5738
6068
|
const transport = getTransport();
|
|
@@ -6236,15 +6566,6 @@ var init_tmux_routing = __esm({
|
|
|
6236
6566
|
}
|
|
6237
6567
|
});
|
|
6238
6568
|
|
|
6239
|
-
// src/types/memory.ts
|
|
6240
|
-
var EMBEDDING_DIM;
|
|
6241
|
-
var init_memory = __esm({
|
|
6242
|
-
"src/types/memory.ts"() {
|
|
6243
|
-
"use strict";
|
|
6244
|
-
EMBEDDING_DIM = 1024;
|
|
6245
|
-
}
|
|
6246
|
-
});
|
|
6247
|
-
|
|
6248
6569
|
// src/lib/keychain.ts
|
|
6249
6570
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
6250
6571
|
import { existsSync as existsSync15 } from "fs";
|
|
@@ -6732,6 +7053,68 @@ var init_platform_procedures = __esm({
|
|
|
6732
7053
|
domain: "architecture",
|
|
6733
7054
|
priority: "p0",
|
|
6734
7055
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
7056
|
+
},
|
|
7057
|
+
// --- MCP is the ONLY data interface ---
|
|
7058
|
+
{
|
|
7059
|
+
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
7060
|
+
domain: "workflow",
|
|
7061
|
+
priority: "p0",
|
|
7062
|
+
content: "If MCP tools are unavailable, disconnected, or returning connection errors: STOP. Tell the user clearly: 'MCP server is disconnected. Please run /mcp to reconnect.' Do NOT attempt workarounds \u2014 no raw Node imports, no direct DB access, no CLI hacks, no daemon socket calls. MCP is the ONLY data interface. Working around it wastes time, hits bundling issues, and bypasses the contract boundary. Ask once, wait, proceed when reconnected."
|
|
7063
|
+
},
|
|
7064
|
+
// --- MCP Tool Catalog (Layer 0 — every agent knows what tools exist) ---
|
|
7065
|
+
{
|
|
7066
|
+
title: "MCP tools \u2014 memory and search",
|
|
7067
|
+
domain: "tool-use",
|
|
7068
|
+
priority: "p1",
|
|
7069
|
+
content: "recall_my_memory: search your own memories (semantic + FTS). ask_team_memory: search a colleague's memories by agent name. store_memory: persist a memory (decisions, summaries, context). commit_memory: high-importance memory that survives consolidation. search_everything: unified search across memories, tasks, entities, conversations. get_session_context: temporal window of memories around a timestamp. consolidate_memories: merge duplicate/related memories into insights. get_memory_cardinality: count memories per agent (health check)."
|
|
7070
|
+
},
|
|
7071
|
+
{
|
|
7072
|
+
title: "MCP tools \u2014 task orchestration",
|
|
7073
|
+
domain: "tool-use",
|
|
7074
|
+
priority: "p1",
|
|
7075
|
+
content: "create_task: dispatch work to an employee (auto-spawns session). The ONLY dispatch path. list_tasks: query tasks by status, assignee, project. get_task: fetch full task details by ID. update_task: change status (in_progress, done, blocked, cancelled) + add result summary. close_task: finalize a reviewed task (COO only). checkpoint_task: save progress state for crash recovery. resume_employee: re-spawn an employee session for an existing task."
|
|
7076
|
+
},
|
|
7077
|
+
{
|
|
7078
|
+
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
7079
|
+
domain: "tool-use",
|
|
7080
|
+
priority: "p1",
|
|
7081
|
+
content: "query_relationships: find connections between entities in the knowledge graph. get_entity_neighbors: explore an entity's direct connections. get_hot_entities: find most-referenced entities (trending topics). get_graph_stats: graph health \u2014 entity/relationship counts, density. export_graph: export graph data for visualization. merge_entities: deduplicate entities (alias resolution). find_similar_trajectories: match tool-call patterns to past task solutions."
|
|
7082
|
+
},
|
|
7083
|
+
{
|
|
7084
|
+
title: "MCP tools \u2014 identity, behavior, and decisions",
|
|
7085
|
+
domain: "tool-use",
|
|
7086
|
+
priority: "p1",
|
|
7087
|
+
content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query."
|
|
7088
|
+
},
|
|
7089
|
+
{
|
|
7090
|
+
title: "MCP tools \u2014 communication and messaging",
|
|
7091
|
+
domain: "tool-use",
|
|
7092
|
+
priority: "p1",
|
|
7093
|
+
content: "send_message: send supplementary context to another agent (NOT for actionable work \u2014 use create_task). acknowledge_messages: mark messages as read. send_whatsapp: send WhatsApp message via gateway (customer-facing alerts). query_conversations: search ingested conversations across all channels (WhatsApp, email, etc.)."
|
|
7094
|
+
},
|
|
7095
|
+
{
|
|
7096
|
+
title: "MCP tools \u2014 wiki, documents, and content",
|
|
7097
|
+
domain: "tool-use",
|
|
7098
|
+
priority: "p1",
|
|
7099
|
+
content: "create_wiki_page: create a wiki page in exe-wiki. list_wiki_pages: browse wiki pages. get_wiki_page: read a wiki page. update_wiki_page: edit a wiki page. ingest_document: import a file (PDF, MD, etc.) into memory as chunks. list_documents: browse ingested documents by workspace. purge_document: remove a document and its memory chunks. set_document_importance: adjust chunk importance scores. rerank_documents: re-score document relevance for a query."
|
|
7100
|
+
},
|
|
7101
|
+
{
|
|
7102
|
+
title: "MCP tools \u2014 system, operations, and admin",
|
|
7103
|
+
domain: "tool-use",
|
|
7104
|
+
priority: "p1",
|
|
7105
|
+
content: "get_agent_spend: token usage per agent/session (cost tracking). list_agent_sessions: view agent session history. get_session_kills: audit log of killed sessions. get_daemon_health: check exed daemon status. get_auto_wake_status: daemon auto-wake configuration. get_worker_gate: check worker deployment gates. run_memory_audit: health check \u2014 duplicates, null vectors, orphaned rows. run_consolidation: trigger sleep-time memory consolidation. cloud_sync: force a cloud sync cycle. backup_vps: trigger VPS backup."
|
|
7106
|
+
},
|
|
7107
|
+
{
|
|
7108
|
+
title: "MCP tools \u2014 config, licensing, and team",
|
|
7109
|
+
domain: "tool-use",
|
|
7110
|
+
priority: "p1",
|
|
7111
|
+
content: "set_agent_config: view/change per-agent runtime and model settings. list_employees: view the employee roster. add_person: add a person to the CRM contacts roster. list_people: browse CRM contacts. get_person: fetch contact details. get_license_status: check license validity. create_license: generate a new license key (admin). list_licenses: view all issued licenses. activate_license: activate a license on a device."
|
|
7112
|
+
},
|
|
7113
|
+
{
|
|
7114
|
+
title: "MCP tools \u2014 advanced (triggers, skills, orchestration)",
|
|
7115
|
+
domain: "tool-use",
|
|
7116
|
+
priority: "p1",
|
|
7117
|
+
content: "create_trigger: set up a scheduled recurring agent job (cron). list_triggers: view active triggers. load_skill: load a slash-command skill dynamically. apply_starter_pack: import a pre-built behavior + identity pack for a role. export_orchestration: export full org state (tasks, behaviors, identities) as portable JSON. import_orchestration: import org state into a new instance. deploy_client: deploy a customer client instance. query_company_brain: unified RAG query across all company knowledge. create_reminder: set a text reminder (shown in boot brief). list_reminders: view pending reminders. complete_reminder: mark a reminder done. global_procedure: manage Layer 0 procedures (actions: store, list, deactivate). Legacy aliases: store_global_procedure, list_global_procedures, deactivate_global_procedure."
|
|
6735
7118
|
}
|
|
6736
7119
|
];
|
|
6737
7120
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -6881,6 +7264,11 @@ async function initStore(options) {
|
|
|
6881
7264
|
encryptionKey: hexKey
|
|
6882
7265
|
});
|
|
6883
7266
|
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
7267
|
+
try {
|
|
7268
|
+
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
7269
|
+
await initDaemonClient2();
|
|
7270
|
+
} catch {
|
|
7271
|
+
}
|
|
6884
7272
|
if (!options?.lightweight) {
|
|
6885
7273
|
try {
|
|
6886
7274
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|