@askexenow/exe-os 0.9.8 → 0.9.9
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 +222 -49
- package/dist/bin/backfill-responses.js +221 -48
- package/dist/bin/backfill-vectors.js +225 -52
- package/dist/bin/cleanup-stale-review-tasks.js +150 -28
- package/dist/bin/cli.js +1295 -856
- package/dist/bin/exe-agent-config.js +36 -8
- package/dist/bin/exe-agent.js +14 -4
- package/dist/bin/exe-assign.js +221 -48
- package/dist/bin/exe-boot.js +778 -427
- package/dist/bin/exe-call.js +41 -13
- package/dist/bin/exe-cloud.js +163 -58
- package/dist/bin/exe-dispatch.js +276 -139
- package/dist/bin/exe-doctor.js +145 -27
- package/dist/bin/exe-export-behaviors.js +141 -23
- package/dist/bin/exe-forget.js +137 -19
- package/dist/bin/exe-gateway.js +677 -388
- package/dist/bin/exe-heartbeat.js +227 -108
- package/dist/bin/exe-kill.js +138 -20
- package/dist/bin/exe-launch-agent.js +172 -39
- package/dist/bin/exe-link.js +291 -100
- package/dist/bin/exe-new-employee.js +214 -106
- package/dist/bin/exe-pending-messages.js +395 -33
- package/dist/bin/exe-pending-notifications.js +684 -99
- package/dist/bin/exe-pending-reviews.js +420 -74
- package/dist/bin/exe-rename.js +147 -49
- package/dist/bin/exe-review.js +138 -20
- package/dist/bin/exe-search.js +240 -69
- package/dist/bin/exe-session-cleanup.js +440 -250
- package/dist/bin/exe-settings.js +61 -17
- package/dist/bin/exe-start-codex.js +158 -39
- package/dist/bin/exe-start-opencode.js +157 -38
- package/dist/bin/exe-status.js +151 -29
- package/dist/bin/exe-team.js +138 -20
- package/dist/bin/git-sweep.js +404 -212
- package/dist/bin/graph-backfill.js +137 -19
- package/dist/bin/graph-export.js +140 -22
- package/dist/bin/install.js +90 -61
- package/dist/bin/scan-tasks.js +412 -220
- package/dist/bin/setup.js +564 -293
- package/dist/bin/shard-migrate.js +139 -21
- package/dist/bin/update.js +138 -49
- package/dist/bin/wiki-sync.js +137 -19
- package/dist/gateway/index.js +533 -320
- package/dist/hooks/bug-report-worker.js +344 -193
- package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
- package/dist/hooks/commit-complete.js +402 -210
- package/dist/hooks/error-recall.js +245 -74
- package/dist/hooks/exe-heartbeat-hook.js +16 -6
- package/dist/hooks/ingest-worker.js +3423 -3157
- package/dist/hooks/ingest.js +832 -97
- package/dist/hooks/instructions-loaded.js +227 -54
- package/dist/hooks/notification.js +216 -43
- package/dist/hooks/post-compact.js +239 -62
- package/dist/hooks/pre-compact.js +408 -216
- package/dist/hooks/pre-tool-use.js +268 -90
- package/dist/hooks/prompt-ingest-worker.js +352 -102
- package/dist/hooks/prompt-submit.js +541 -328
- package/dist/hooks/response-ingest-worker.js +372 -122
- package/dist/hooks/session-end.js +443 -240
- package/dist/hooks/session-start.js +313 -127
- package/dist/hooks/stop.js +293 -98
- package/dist/hooks/subagent-stop.js +239 -62
- package/dist/hooks/summary-worker.js +568 -236
- package/dist/index.js +538 -324
- package/dist/lib/agent-config.js +28 -6
- package/dist/lib/cloud-sync.js +284 -105
- package/dist/lib/config.js +30 -10
- package/dist/lib/consolidation.js +16 -6
- package/dist/lib/database.js +123 -25
- package/dist/lib/db-daemon-client.js +73 -19
- package/dist/lib/db.js +123 -25
- package/dist/lib/device-registry.js +133 -35
- package/dist/lib/embedder.js +107 -32
- package/dist/lib/employee-templates.js +14 -4
- package/dist/lib/employees.js +41 -13
- package/dist/lib/exe-daemon-client.js +88 -22
- package/dist/lib/exe-daemon.js +935 -587
- package/dist/lib/hybrid-search.js +240 -69
- package/dist/lib/identity.js +18 -8
- package/dist/lib/license.js +133 -48
- package/dist/lib/messaging.js +116 -56
- package/dist/lib/reminders.js +14 -4
- package/dist/lib/schedules.js +137 -19
- package/dist/lib/skill-learning.js +33 -6
- package/dist/lib/store.js +137 -19
- package/dist/lib/task-router.js +14 -4
- package/dist/lib/tasks.js +280 -234
- package/dist/lib/tmux-routing.js +172 -125
- package/dist/lib/token-spend.js +26 -8
- package/dist/mcp/server.js +1326 -609
- package/dist/mcp/tools/complete-reminder.js +14 -4
- package/dist/mcp/tools/create-reminder.js +14 -4
- package/dist/mcp/tools/create-task.js +306 -248
- package/dist/mcp/tools/deactivate-behavior.js +16 -6
- package/dist/mcp/tools/list-reminders.js +14 -4
- package/dist/mcp/tools/list-tasks.js +123 -107
- package/dist/mcp/tools/send-message.js +75 -29
- package/dist/mcp/tools/update-task.js +1848 -199
- package/dist/runtime/index.js +441 -248
- package/dist/tui/App.js +761 -424
- package/package.json +1 -1
package/dist/bin/exe-rename.js
CHANGED
|
@@ -9,9 +9,34 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/lib/secure-files.ts
|
|
13
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
14
|
+
import { chmod, mkdir } from "fs/promises";
|
|
15
|
+
function ensurePrivateDirSync(dirPath) {
|
|
16
|
+
mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
17
|
+
try {
|
|
18
|
+
chmodSync(dirPath, PRIVATE_DIR_MODE);
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function enforcePrivateFileSync(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
25
|
+
} catch {
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
29
|
+
var init_secure_files = __esm({
|
|
30
|
+
"src/lib/secure-files.ts"() {
|
|
31
|
+
"use strict";
|
|
32
|
+
PRIVATE_DIR_MODE = 448;
|
|
33
|
+
PRIVATE_FILE_MODE = 384;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
12
37
|
// src/lib/config.ts
|
|
13
|
-
import { readFile, writeFile
|
|
14
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
38
|
+
import { readFile, writeFile } from "fs/promises";
|
|
39
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
15
40
|
import path from "path";
|
|
16
41
|
import os from "os";
|
|
17
42
|
function resolveDataDir() {
|
|
@@ -19,7 +44,7 @@ function resolveDataDir() {
|
|
|
19
44
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
20
45
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
21
46
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
22
|
-
if (!
|
|
47
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
23
48
|
try {
|
|
24
49
|
renameSync(legacyDir, newDir);
|
|
25
50
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -34,6 +59,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
34
59
|
var init_config = __esm({
|
|
35
60
|
"src/lib/config.ts"() {
|
|
36
61
|
"use strict";
|
|
62
|
+
init_secure_files();
|
|
37
63
|
EXE_AI_DIR = resolveDataDir();
|
|
38
64
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
39
65
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -102,7 +128,7 @@ var init_config = __esm({
|
|
|
102
128
|
|
|
103
129
|
// src/lib/employees.ts
|
|
104
130
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
105
|
-
import { existsSync as
|
|
131
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
106
132
|
import { execSync } from "child_process";
|
|
107
133
|
import path2 from "path";
|
|
108
134
|
import os2 from "os";
|
|
@@ -134,7 +160,7 @@ function validateEmployeeName(name) {
|
|
|
134
160
|
return { valid: true };
|
|
135
161
|
}
|
|
136
162
|
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
137
|
-
if (!
|
|
163
|
+
if (!existsSync3(employeesPath)) {
|
|
138
164
|
return [];
|
|
139
165
|
}
|
|
140
166
|
const raw = await readFile2(employeesPath, "utf-8");
|
|
@@ -149,7 +175,7 @@ async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
|
|
|
149
175
|
await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
150
176
|
}
|
|
151
177
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
152
|
-
if (!
|
|
178
|
+
if (!existsSync3(employeesPath)) return [];
|
|
153
179
|
try {
|
|
154
180
|
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
155
181
|
} catch {
|
|
@@ -183,7 +209,7 @@ function registerBinSymlinks(name) {
|
|
|
183
209
|
for (const suffix of ["", "-opencode"]) {
|
|
184
210
|
const linkName = `${name}${suffix}`;
|
|
185
211
|
const linkPath = path2.join(binDir, linkName);
|
|
186
|
-
if (
|
|
212
|
+
if (existsSync3(linkPath)) {
|
|
187
213
|
skipped.push(linkName);
|
|
188
214
|
continue;
|
|
189
215
|
}
|
|
@@ -847,13 +873,50 @@ var init_database_adapter = __esm({
|
|
|
847
873
|
}
|
|
848
874
|
});
|
|
849
875
|
|
|
876
|
+
// src/lib/daemon-auth.ts
|
|
877
|
+
import crypto from "crypto";
|
|
878
|
+
import path4 from "path";
|
|
879
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
880
|
+
function normalizeToken(token) {
|
|
881
|
+
if (!token) return null;
|
|
882
|
+
const trimmed = token.trim();
|
|
883
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
884
|
+
}
|
|
885
|
+
function readDaemonToken() {
|
|
886
|
+
try {
|
|
887
|
+
if (!existsSync4(DAEMON_TOKEN_PATH)) return null;
|
|
888
|
+
return normalizeToken(readFileSync3(DAEMON_TOKEN_PATH, "utf8"));
|
|
889
|
+
} catch {
|
|
890
|
+
return null;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
function ensureDaemonToken(seed) {
|
|
894
|
+
const existing = readDaemonToken();
|
|
895
|
+
if (existing) return existing;
|
|
896
|
+
const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
|
|
897
|
+
ensurePrivateDirSync(EXE_AI_DIR);
|
|
898
|
+
writeFileSync2(DAEMON_TOKEN_PATH, `${token}
|
|
899
|
+
`, "utf8");
|
|
900
|
+
enforcePrivateFileSync(DAEMON_TOKEN_PATH);
|
|
901
|
+
return token;
|
|
902
|
+
}
|
|
903
|
+
var DAEMON_TOKEN_PATH;
|
|
904
|
+
var init_daemon_auth = __esm({
|
|
905
|
+
"src/lib/daemon-auth.ts"() {
|
|
906
|
+
"use strict";
|
|
907
|
+
init_config();
|
|
908
|
+
init_secure_files();
|
|
909
|
+
DAEMON_TOKEN_PATH = path4.join(EXE_AI_DIR, "exed.token");
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
|
|
850
913
|
// src/lib/exe-daemon-client.ts
|
|
851
914
|
import net from "net";
|
|
852
915
|
import os4 from "os";
|
|
853
916
|
import { spawn } from "child_process";
|
|
854
917
|
import { randomUUID } from "crypto";
|
|
855
|
-
import { existsSync as
|
|
856
|
-
import
|
|
918
|
+
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
919
|
+
import path5 from "path";
|
|
857
920
|
import { fileURLToPath } from "url";
|
|
858
921
|
function handleData(chunk) {
|
|
859
922
|
_buffer += chunk.toString();
|
|
@@ -881,9 +944,9 @@ function handleData(chunk) {
|
|
|
881
944
|
}
|
|
882
945
|
}
|
|
883
946
|
function cleanupStaleFiles() {
|
|
884
|
-
if (
|
|
947
|
+
if (existsSync5(PID_PATH)) {
|
|
885
948
|
try {
|
|
886
|
-
const pid = parseInt(
|
|
949
|
+
const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
|
|
887
950
|
if (pid > 0) {
|
|
888
951
|
try {
|
|
889
952
|
process.kill(pid, 0);
|
|
@@ -904,11 +967,11 @@ function cleanupStaleFiles() {
|
|
|
904
967
|
}
|
|
905
968
|
}
|
|
906
969
|
function findPackageRoot() {
|
|
907
|
-
let dir =
|
|
908
|
-
const { root } =
|
|
970
|
+
let dir = path5.dirname(fileURLToPath(import.meta.url));
|
|
971
|
+
const { root } = path5.parse(dir);
|
|
909
972
|
while (dir !== root) {
|
|
910
|
-
if (
|
|
911
|
-
dir =
|
|
973
|
+
if (existsSync5(path5.join(dir, "package.json"))) return dir;
|
|
974
|
+
dir = path5.dirname(dir);
|
|
912
975
|
}
|
|
913
976
|
return null;
|
|
914
977
|
}
|
|
@@ -934,16 +997,17 @@ function spawnDaemon() {
|
|
|
934
997
|
process.stderr.write("[exed-client] WARN: cannot find package root\n");
|
|
935
998
|
return;
|
|
936
999
|
}
|
|
937
|
-
const daemonPath =
|
|
938
|
-
if (!
|
|
1000
|
+
const daemonPath = path5.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
1001
|
+
if (!existsSync5(daemonPath)) {
|
|
939
1002
|
process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
|
|
940
1003
|
`);
|
|
941
1004
|
return;
|
|
942
1005
|
}
|
|
943
1006
|
const resolvedPath = daemonPath;
|
|
1007
|
+
const daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV] ?? null);
|
|
944
1008
|
process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
|
|
945
1009
|
`);
|
|
946
|
-
const logPath =
|
|
1010
|
+
const logPath = path5.join(path5.dirname(SOCKET_PATH), "exed.log");
|
|
947
1011
|
let stderrFd = "ignore";
|
|
948
1012
|
try {
|
|
949
1013
|
stderrFd = openSync(logPath, "a");
|
|
@@ -961,7 +1025,8 @@ function spawnDaemon() {
|
|
|
961
1025
|
TMUX_PANE: void 0,
|
|
962
1026
|
// Prevents resolveExeSession() from scoping to one session
|
|
963
1027
|
EXE_DAEMON_SOCK: SOCKET_PATH,
|
|
964
|
-
EXE_DAEMON_PID: PID_PATH
|
|
1028
|
+
EXE_DAEMON_PID: PID_PATH,
|
|
1029
|
+
[DAEMON_TOKEN_ENV]: daemonToken
|
|
965
1030
|
}
|
|
966
1031
|
});
|
|
967
1032
|
child.unref();
|
|
@@ -1068,13 +1133,14 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1068
1133
|
return;
|
|
1069
1134
|
}
|
|
1070
1135
|
const id = randomUUID();
|
|
1136
|
+
const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
|
|
1071
1137
|
const timer = setTimeout(() => {
|
|
1072
1138
|
_pending.delete(id);
|
|
1073
1139
|
resolve({ error: "Request timeout" });
|
|
1074
1140
|
}, timeoutMs);
|
|
1075
1141
|
_pending.set(id, { resolve, timer });
|
|
1076
1142
|
try {
|
|
1077
|
-
_socket.write(JSON.stringify({ id, ...payload }) + "\n");
|
|
1143
|
+
_socket.write(JSON.stringify({ id, token, ...payload }) + "\n");
|
|
1078
1144
|
} catch {
|
|
1079
1145
|
clearTimeout(timer);
|
|
1080
1146
|
_pending.delete(id);
|
|
@@ -1085,17 +1151,19 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1085
1151
|
function isClientConnected() {
|
|
1086
1152
|
return _connected;
|
|
1087
1153
|
}
|
|
1088
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _pending, MAX_BUFFER;
|
|
1154
|
+
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;
|
|
1089
1155
|
var init_exe_daemon_client = __esm({
|
|
1090
1156
|
"src/lib/exe-daemon-client.ts"() {
|
|
1091
1157
|
"use strict";
|
|
1092
1158
|
init_config();
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1159
|
+
init_daemon_auth();
|
|
1160
|
+
SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path5.join(EXE_AI_DIR, "exed.sock");
|
|
1161
|
+
PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path5.join(EXE_AI_DIR, "exed.pid");
|
|
1162
|
+
SPAWN_LOCK_PATH = path5.join(EXE_AI_DIR, "exed-spawn.lock");
|
|
1096
1163
|
SPAWN_LOCK_STALE_MS = 3e4;
|
|
1097
1164
|
CONNECT_TIMEOUT_MS = 15e3;
|
|
1098
1165
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
1166
|
+
DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
|
|
1099
1167
|
_socket = null;
|
|
1100
1168
|
_connected = false;
|
|
1101
1169
|
_buffer = "";
|
|
@@ -1674,6 +1742,7 @@ async function ensureSchema() {
|
|
|
1674
1742
|
project TEXT NOT NULL,
|
|
1675
1743
|
summary TEXT NOT NULL,
|
|
1676
1744
|
task_file TEXT,
|
|
1745
|
+
session_scope TEXT,
|
|
1677
1746
|
read INTEGER NOT NULL DEFAULT 0,
|
|
1678
1747
|
created_at TEXT NOT NULL
|
|
1679
1748
|
);
|
|
@@ -1682,7 +1751,7 @@ async function ensureSchema() {
|
|
|
1682
1751
|
ON notifications(read);
|
|
1683
1752
|
|
|
1684
1753
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent
|
|
1685
|
-
ON notifications(agent_id);
|
|
1754
|
+
ON notifications(agent_id, session_scope);
|
|
1686
1755
|
|
|
1687
1756
|
CREATE INDEX IF NOT EXISTS idx_notifications_task_file
|
|
1688
1757
|
ON notifications(task_file);
|
|
@@ -1720,6 +1789,7 @@ async function ensureSchema() {
|
|
|
1720
1789
|
target_agent TEXT NOT NULL,
|
|
1721
1790
|
target_project TEXT,
|
|
1722
1791
|
target_device TEXT NOT NULL DEFAULT 'local',
|
|
1792
|
+
session_scope TEXT,
|
|
1723
1793
|
content TEXT NOT NULL,
|
|
1724
1794
|
priority TEXT DEFAULT 'normal',
|
|
1725
1795
|
status TEXT DEFAULT 'pending',
|
|
@@ -1733,10 +1803,31 @@ async function ensureSchema() {
|
|
|
1733
1803
|
);
|
|
1734
1804
|
|
|
1735
1805
|
CREATE INDEX IF NOT EXISTS idx_messages_target
|
|
1736
|
-
ON messages(target_agent, status);
|
|
1806
|
+
ON messages(target_agent, session_scope, status);
|
|
1737
1807
|
|
|
1738
1808
|
CREATE INDEX IF NOT EXISTS idx_messages_conversation_order
|
|
1739
|
-
ON messages(target_agent, from_agent, server_seq);
|
|
1809
|
+
ON messages(target_agent, session_scope, from_agent, server_seq);
|
|
1810
|
+
`);
|
|
1811
|
+
try {
|
|
1812
|
+
await client.execute({
|
|
1813
|
+
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
1814
|
+
args: []
|
|
1815
|
+
});
|
|
1816
|
+
} catch {
|
|
1817
|
+
}
|
|
1818
|
+
try {
|
|
1819
|
+
await client.execute({
|
|
1820
|
+
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
1821
|
+
args: []
|
|
1822
|
+
});
|
|
1823
|
+
} catch {
|
|
1824
|
+
}
|
|
1825
|
+
await client.executeMultiple(`
|
|
1826
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
1827
|
+
ON notifications(agent_id, session_scope, read, created_at);
|
|
1828
|
+
|
|
1829
|
+
CREATE INDEX IF NOT EXISTS idx_messages_target_scope_status
|
|
1830
|
+
ON messages(target_agent, session_scope, status, created_at);
|
|
1740
1831
|
`);
|
|
1741
1832
|
try {
|
|
1742
1833
|
await client.execute({
|
|
@@ -2320,6 +2411,13 @@ async function ensureSchema() {
|
|
|
2320
2411
|
} catch {
|
|
2321
2412
|
}
|
|
2322
2413
|
}
|
|
2414
|
+
try {
|
|
2415
|
+
await client.execute({
|
|
2416
|
+
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
2417
|
+
args: []
|
|
2418
|
+
});
|
|
2419
|
+
} catch {
|
|
2420
|
+
}
|
|
2323
2421
|
}
|
|
2324
2422
|
async function disposeDatabase() {
|
|
2325
2423
|
if (_walCheckpointTimer) {
|
|
@@ -2359,9 +2457,9 @@ var init_database = __esm({
|
|
|
2359
2457
|
|
|
2360
2458
|
// src/bin/exe-rename.ts
|
|
2361
2459
|
init_employees();
|
|
2362
|
-
import { readFileSync as
|
|
2460
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync3, existsSync as existsSync6 } from "fs";
|
|
2363
2461
|
import { execSync as execSync2 } from "child_process";
|
|
2364
|
-
import
|
|
2462
|
+
import path6 from "path";
|
|
2365
2463
|
import { homedir } from "os";
|
|
2366
2464
|
|
|
2367
2465
|
// src/lib/global-procedures.ts
|
|
@@ -2506,9 +2604,9 @@ function isMainModule(importMetaUrl) {
|
|
|
2506
2604
|
|
|
2507
2605
|
// src/bin/exe-rename.ts
|
|
2508
2606
|
async function renameEmployee(oldName, newName, opts = {}) {
|
|
2509
|
-
const rosterPath = opts.rosterPath ??
|
|
2510
|
-
const identityDir = opts.identityDir ??
|
|
2511
|
-
const agentsDir = opts.agentsDir ??
|
|
2607
|
+
const rosterPath = opts.rosterPath ?? path6.join(homedir(), ".exe-os", "exe-employees.json");
|
|
2608
|
+
const identityDir = opts.identityDir ?? path6.join(homedir(), ".exe-os", "identity");
|
|
2609
|
+
const agentsDir = opts.agentsDir ?? path6.join(homedir(), ".claude", "agents");
|
|
2512
2610
|
const validation = validateEmployeeName(newName);
|
|
2513
2611
|
if (!validation.valid) {
|
|
2514
2612
|
return { success: false, error: validation.error };
|
|
@@ -2537,40 +2635,40 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
2537
2635
|
undo: () => {
|
|
2538
2636
|
employee.name = originalName;
|
|
2539
2637
|
employee.systemPrompt = originalPrompt;
|
|
2540
|
-
|
|
2638
|
+
writeFileSync3(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
2541
2639
|
}
|
|
2542
2640
|
});
|
|
2543
|
-
const oldIdentityPath =
|
|
2544
|
-
const newIdentityPath =
|
|
2545
|
-
if (
|
|
2546
|
-
const content =
|
|
2641
|
+
const oldIdentityPath = path6.join(identityDir, `${rosterOldName}.md`);
|
|
2642
|
+
const newIdentityPath = path6.join(identityDir, `${newName}.md`);
|
|
2643
|
+
if (existsSync6(oldIdentityPath)) {
|
|
2644
|
+
const content = readFileSync5(oldIdentityPath, "utf-8");
|
|
2547
2645
|
const updatedContent = content.replace(
|
|
2548
2646
|
/^(agent_id:\s*)\S+/m,
|
|
2549
2647
|
`$1${newName}`
|
|
2550
2648
|
);
|
|
2551
2649
|
renameSync3(oldIdentityPath, newIdentityPath);
|
|
2552
|
-
|
|
2650
|
+
writeFileSync3(newIdentityPath, updatedContent, "utf-8");
|
|
2553
2651
|
rollbackStack.push({
|
|
2554
2652
|
description: "restore identity file",
|
|
2555
2653
|
undo: () => {
|
|
2556
|
-
if (
|
|
2557
|
-
|
|
2654
|
+
if (existsSync6(newIdentityPath)) {
|
|
2655
|
+
writeFileSync3(newIdentityPath, content, "utf-8");
|
|
2558
2656
|
renameSync3(newIdentityPath, oldIdentityPath);
|
|
2559
2657
|
}
|
|
2560
2658
|
}
|
|
2561
2659
|
});
|
|
2562
2660
|
}
|
|
2563
|
-
const oldAgentPath =
|
|
2564
|
-
const newAgentPath =
|
|
2565
|
-
if (
|
|
2566
|
-
const agentContent =
|
|
2661
|
+
const oldAgentPath = path6.join(agentsDir, `${rosterOldName}.md`);
|
|
2662
|
+
const newAgentPath = path6.join(agentsDir, `${newName}.md`);
|
|
2663
|
+
if (existsSync6(oldAgentPath)) {
|
|
2664
|
+
const agentContent = readFileSync5(oldAgentPath, "utf-8");
|
|
2567
2665
|
renameSync3(oldAgentPath, newAgentPath);
|
|
2568
2666
|
rollbackStack.push({
|
|
2569
2667
|
description: "restore agent file",
|
|
2570
2668
|
undo: () => {
|
|
2571
|
-
if (
|
|
2669
|
+
if (existsSync6(newAgentPath)) {
|
|
2572
2670
|
renameSync3(newAgentPath, oldAgentPath);
|
|
2573
|
-
|
|
2671
|
+
writeFileSync3(oldAgentPath, agentContent, "utf-8");
|
|
2574
2672
|
}
|
|
2575
2673
|
}
|
|
2576
2674
|
});
|
|
@@ -2648,10 +2746,10 @@ function removeOldSymlinks(name) {
|
|
|
2648
2746
|
try {
|
|
2649
2747
|
const exeBinPath = findExeBin2();
|
|
2650
2748
|
if (!exeBinPath) return;
|
|
2651
|
-
const binDir =
|
|
2749
|
+
const binDir = path6.dirname(exeBinPath);
|
|
2652
2750
|
for (const suffix of ["", "-opencode"]) {
|
|
2653
|
-
const linkPath =
|
|
2654
|
-
if (
|
|
2751
|
+
const linkPath = path6.join(binDir, `${name}${suffix}`);
|
|
2752
|
+
if (existsSync6(linkPath)) {
|
|
2655
2753
|
try {
|
|
2656
2754
|
unlinkSync3(linkPath);
|
|
2657
2755
|
} catch {
|