@askexenow/exe-os 0.9.7 → 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 +953 -105
- package/dist/bin/backfill-responses.js +952 -104
- package/dist/bin/backfill-vectors.js +956 -108
- package/dist/bin/cleanup-stale-review-tasks.js +802 -58
- package/dist/bin/cli.js +2292 -1070
- package/dist/bin/exe-agent-config.js +157 -101
- package/dist/bin/exe-agent.js +55 -29
- package/dist/bin/exe-assign.js +940 -92
- package/dist/bin/exe-boot.js +1424 -442
- package/dist/bin/exe-call.js +240 -141
- package/dist/bin/exe-cloud.js +198 -70
- package/dist/bin/exe-dispatch.js +951 -192
- package/dist/bin/exe-doctor.js +791 -51
- package/dist/bin/exe-export-behaviors.js +790 -42
- package/dist/bin/exe-forget.js +771 -31
- package/dist/bin/exe-gateway.js +1592 -521
- package/dist/bin/exe-heartbeat.js +850 -109
- package/dist/bin/exe-kill.js +783 -35
- package/dist/bin/exe-launch-agent.js +1030 -107
- package/dist/bin/exe-link.js +916 -110
- package/dist/bin/exe-new-employee.js +526 -217
- package/dist/bin/exe-pending-messages.js +1046 -62
- package/dist/bin/exe-pending-notifications.js +1318 -111
- package/dist/bin/exe-pending-reviews.js +1040 -72
- package/dist/bin/exe-rename.js +772 -59
- package/dist/bin/exe-review.js +772 -32
- package/dist/bin/exe-search.js +982 -128
- package/dist/bin/exe-session-cleanup.js +1180 -306
- package/dist/bin/exe-settings.js +185 -105
- package/dist/bin/exe-start-codex.js +886 -132
- package/dist/bin/exe-start-opencode.js +873 -119
- package/dist/bin/exe-status.js +803 -59
- package/dist/bin/exe-team.js +772 -32
- package/dist/bin/git-sweep.js +1046 -223
- package/dist/bin/graph-backfill.js +779 -31
- package/dist/bin/graph-export.js +785 -37
- package/dist/bin/install.js +632 -200
- package/dist/bin/scan-tasks.js +1055 -232
- package/dist/bin/setup.js +1419 -320
- package/dist/bin/shard-migrate.js +783 -35
- package/dist/bin/update.js +138 -49
- package/dist/bin/wiki-sync.js +782 -34
- package/dist/gateway/index.js +1444 -449
- package/dist/hooks/bug-report-worker.js +1141 -269
- package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
- package/dist/hooks/commit-complete.js +1044 -221
- package/dist/hooks/error-recall.js +989 -135
- package/dist/hooks/exe-heartbeat-hook.js +99 -75
- package/dist/hooks/ingest-worker.js +4176 -3226
- package/dist/hooks/ingest.js +920 -168
- package/dist/hooks/instructions-loaded.js +874 -70
- package/dist/hooks/notification.js +860 -56
- package/dist/hooks/post-compact.js +881 -73
- package/dist/hooks/pre-compact.js +1050 -227
- package/dist/hooks/pre-tool-use.js +1084 -159
- package/dist/hooks/prompt-ingest-worker.js +1089 -164
- package/dist/hooks/prompt-submit.js +1469 -515
- package/dist/hooks/response-ingest-worker.js +1104 -179
- package/dist/hooks/session-end.js +1085 -251
- package/dist/hooks/session-start.js +1241 -231
- package/dist/hooks/stop.js +935 -109
- package/dist/hooks/subagent-stop.js +881 -73
- package/dist/hooks/summary-worker.js +1323 -307
- package/dist/index.js +1449 -452
- package/dist/lib/agent-config.js +28 -6
- package/dist/lib/cloud-sync.js +909 -115
- package/dist/lib/config.js +30 -10
- package/dist/lib/consolidation.js +42 -9
- package/dist/lib/database.js +739 -33
- package/dist/lib/db-daemon-client.js +73 -19
- package/dist/lib/db.js +2359 -0
- package/dist/lib/device-registry.js +760 -47
- package/dist/lib/embedder.js +201 -73
- package/dist/lib/employee-templates.js +30 -4
- package/dist/lib/employees.js +290 -86
- package/dist/lib/exe-daemon-client.js +187 -83
- package/dist/lib/exe-daemon.js +1696 -616
- package/dist/lib/hybrid-search.js +982 -128
- package/dist/lib/identity.js +43 -13
- package/dist/lib/license.js +133 -48
- package/dist/lib/messaging.js +167 -80
- package/dist/lib/reminders.js +35 -5
- package/dist/lib/schedules.js +772 -32
- package/dist/lib/skill-learning.js +54 -7
- package/dist/lib/store.js +779 -31
- package/dist/lib/task-router.js +94 -73
- package/dist/lib/tasks.js +298 -225
- package/dist/lib/tmux-routing.js +246 -172
- package/dist/lib/token-spend.js +52 -14
- package/dist/mcp/server.js +2893 -850
- package/dist/mcp/tools/complete-reminder.js +35 -5
- package/dist/mcp/tools/create-reminder.js +35 -5
- package/dist/mcp/tools/create-task.js +507 -323
- package/dist/mcp/tools/deactivate-behavior.js +40 -10
- package/dist/mcp/tools/list-reminders.js +35 -5
- package/dist/mcp/tools/list-tasks.js +277 -104
- package/dist/mcp/tools/send-message.js +129 -56
- package/dist/mcp/tools/update-task.js +1864 -188
- package/dist/runtime/index.js +1083 -259
- package/dist/tui/App.js +1501 -434
- package/package.json +3 -2
package/dist/bin/exe-call.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");
|
|
@@ -100,6 +126,120 @@ var init_config = __esm({
|
|
|
100
126
|
}
|
|
101
127
|
});
|
|
102
128
|
|
|
129
|
+
// src/lib/runtime-table.ts
|
|
130
|
+
var RUNTIME_TABLE, DEFAULT_RUNTIME;
|
|
131
|
+
var init_runtime_table = __esm({
|
|
132
|
+
"src/lib/runtime-table.ts"() {
|
|
133
|
+
"use strict";
|
|
134
|
+
RUNTIME_TABLE = {
|
|
135
|
+
codex: {
|
|
136
|
+
binary: "codex",
|
|
137
|
+
launchMode: "interactive",
|
|
138
|
+
autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
|
|
139
|
+
inlineFlag: "--no-alt-screen",
|
|
140
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
141
|
+
defaultModel: "gpt-5.4"
|
|
142
|
+
},
|
|
143
|
+
opencode: {
|
|
144
|
+
binary: "opencode",
|
|
145
|
+
launchMode: "exec",
|
|
146
|
+
autoApproveFlag: "--dangerously-skip-permissions",
|
|
147
|
+
inlineFlag: "",
|
|
148
|
+
apiKeyEnv: "ANTHROPIC_API_KEY",
|
|
149
|
+
defaultModel: "anthropic/claude-sonnet-4-6"
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
DEFAULT_RUNTIME = "claude";
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// src/lib/agent-config.ts
|
|
157
|
+
var agent_config_exports = {};
|
|
158
|
+
__export(agent_config_exports, {
|
|
159
|
+
AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
|
|
160
|
+
DEFAULT_MODELS: () => DEFAULT_MODELS,
|
|
161
|
+
KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
|
|
162
|
+
RUNTIME_LABELS: () => RUNTIME_LABELS,
|
|
163
|
+
clearAgentRuntime: () => clearAgentRuntime,
|
|
164
|
+
getAgentRuntime: () => getAgentRuntime,
|
|
165
|
+
loadAgentConfig: () => loadAgentConfig,
|
|
166
|
+
saveAgentConfig: () => saveAgentConfig,
|
|
167
|
+
setAgentRuntime: () => setAgentRuntime
|
|
168
|
+
});
|
|
169
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
170
|
+
import path2 from "path";
|
|
171
|
+
function loadAgentConfig() {
|
|
172
|
+
if (!existsSync3(AGENT_CONFIG_PATH)) return {};
|
|
173
|
+
try {
|
|
174
|
+
return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
|
|
175
|
+
} catch {
|
|
176
|
+
return {};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function saveAgentConfig(config) {
|
|
180
|
+
const dir = path2.dirname(AGENT_CONFIG_PATH);
|
|
181
|
+
ensurePrivateDirSync(dir);
|
|
182
|
+
writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
183
|
+
enforcePrivateFileSync(AGENT_CONFIG_PATH);
|
|
184
|
+
}
|
|
185
|
+
function getAgentRuntime(agentId) {
|
|
186
|
+
const config = loadAgentConfig();
|
|
187
|
+
const entry = config[agentId];
|
|
188
|
+
if (entry) return entry;
|
|
189
|
+
const orgDefault = config["default"];
|
|
190
|
+
if (orgDefault) return orgDefault;
|
|
191
|
+
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
192
|
+
}
|
|
193
|
+
function setAgentRuntime(agentId, runtime, model) {
|
|
194
|
+
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
195
|
+
if (!knownModels) {
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (!knownModels.includes(model)) {
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const config = loadAgentConfig();
|
|
208
|
+
config[agentId] = { runtime, model };
|
|
209
|
+
saveAgentConfig(config);
|
|
210
|
+
return { ok: true };
|
|
211
|
+
}
|
|
212
|
+
function clearAgentRuntime(agentId) {
|
|
213
|
+
const config = loadAgentConfig();
|
|
214
|
+
delete config[agentId];
|
|
215
|
+
saveAgentConfig(config);
|
|
216
|
+
}
|
|
217
|
+
var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
|
|
218
|
+
var init_agent_config = __esm({
|
|
219
|
+
"src/lib/agent-config.ts"() {
|
|
220
|
+
"use strict";
|
|
221
|
+
init_config();
|
|
222
|
+
init_runtime_table();
|
|
223
|
+
init_secure_files();
|
|
224
|
+
AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
225
|
+
KNOWN_RUNTIMES = {
|
|
226
|
+
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
227
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
228
|
+
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
229
|
+
};
|
|
230
|
+
RUNTIME_LABELS = {
|
|
231
|
+
claude: "Claude Code (Anthropic)",
|
|
232
|
+
codex: "Codex (OpenAI)",
|
|
233
|
+
opencode: "OpenCode (open source)"
|
|
234
|
+
};
|
|
235
|
+
DEFAULT_MODELS = {
|
|
236
|
+
claude: "claude-opus-4",
|
|
237
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
238
|
+
opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
103
243
|
// src/lib/employees.ts
|
|
104
244
|
var employees_exports = {};
|
|
105
245
|
__export(employees_exports, {
|
|
@@ -115,6 +255,7 @@ __export(employees_exports, {
|
|
|
115
255
|
getEmployeeByRole: () => getEmployeeByRole,
|
|
116
256
|
getEmployeeNamesByRole: () => getEmployeeNamesByRole,
|
|
117
257
|
hasRole: () => hasRole,
|
|
258
|
+
hireEmployee: () => hireEmployee,
|
|
118
259
|
isCoordinatorName: () => isCoordinatorName,
|
|
119
260
|
isCoordinatorRole: () => isCoordinatorRole,
|
|
120
261
|
isMultiInstance: () => isMultiInstance,
|
|
@@ -127,9 +268,9 @@ __export(employees_exports, {
|
|
|
127
268
|
validateEmployeeName: () => validateEmployeeName
|
|
128
269
|
});
|
|
129
270
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
130
|
-
import { existsSync as
|
|
271
|
+
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
131
272
|
import { execSync } from "child_process";
|
|
132
|
-
import
|
|
273
|
+
import path3 from "path";
|
|
133
274
|
import os2 from "os";
|
|
134
275
|
function normalizeRole(role) {
|
|
135
276
|
return (role ?? "").trim().toLowerCase();
|
|
@@ -166,7 +307,7 @@ function validateEmployeeName(name) {
|
|
|
166
307
|
return { valid: true };
|
|
167
308
|
}
|
|
168
309
|
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
169
|
-
if (!
|
|
310
|
+
if (!existsSync4(employeesPath)) {
|
|
170
311
|
return [];
|
|
171
312
|
}
|
|
172
313
|
const raw = await readFile2(employeesPath, "utf-8");
|
|
@@ -177,13 +318,13 @@ async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
|
177
318
|
}
|
|
178
319
|
}
|
|
179
320
|
async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
|
|
180
|
-
await mkdir2(
|
|
321
|
+
await mkdir2(path3.dirname(employeesPath), { recursive: true });
|
|
181
322
|
await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
182
323
|
}
|
|
183
324
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
184
|
-
if (!
|
|
325
|
+
if (!existsSync4(employeesPath)) return [];
|
|
185
326
|
try {
|
|
186
|
-
return JSON.parse(
|
|
327
|
+
return JSON.parse(readFileSync3(employeesPath, "utf-8"));
|
|
187
328
|
} catch {
|
|
188
329
|
return [];
|
|
189
330
|
}
|
|
@@ -225,6 +366,52 @@ function addEmployee(employees, employee) {
|
|
|
225
366
|
}
|
|
226
367
|
return [...employees, normalized];
|
|
227
368
|
}
|
|
369
|
+
function appendToCoordinatorTeam(employee) {
|
|
370
|
+
const coordinator = getCoordinatorEmployee(loadEmployeesSync());
|
|
371
|
+
if (!coordinator) return;
|
|
372
|
+
const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
|
|
373
|
+
if (!existsSync4(idPath)) return;
|
|
374
|
+
const content = readFileSync3(idPath, "utf-8");
|
|
375
|
+
if (content.includes(`**${capitalize(employee.name)}`)) return;
|
|
376
|
+
const teamMatch = content.match(TEAM_SECTION_RE);
|
|
377
|
+
if (!teamMatch || teamMatch.index === void 0) return;
|
|
378
|
+
const afterTeam = content.slice(teamMatch.index + teamMatch[0].length);
|
|
379
|
+
const nextHeading = afterTeam.match(/\n## /);
|
|
380
|
+
const entry = `
|
|
381
|
+
**${capitalize(employee.name)} (${employee.role}):** Newly hired. Update this description as the role develops.
|
|
382
|
+
`;
|
|
383
|
+
let updated;
|
|
384
|
+
if (nextHeading && nextHeading.index !== void 0) {
|
|
385
|
+
const insertAt = teamMatch.index + teamMatch[0].length + nextHeading.index;
|
|
386
|
+
updated = content.slice(0, insertAt) + entry + content.slice(insertAt);
|
|
387
|
+
} else {
|
|
388
|
+
updated = content.trimEnd() + "\n" + entry;
|
|
389
|
+
}
|
|
390
|
+
writeFileSync2(idPath, updated, "utf-8");
|
|
391
|
+
}
|
|
392
|
+
function capitalize(s) {
|
|
393
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
394
|
+
}
|
|
395
|
+
async function hireEmployee(employee) {
|
|
396
|
+
const employees = await loadEmployees();
|
|
397
|
+
const updated = addEmployee(employees, employee);
|
|
398
|
+
await saveEmployees(updated);
|
|
399
|
+
try {
|
|
400
|
+
appendToCoordinatorTeam(employee);
|
|
401
|
+
} catch {
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
const { loadAgentConfig: loadAgentConfig2, saveAgentConfig: saveAgentConfig2 } = await Promise.resolve().then(() => (init_agent_config(), agent_config_exports));
|
|
405
|
+
const config = loadAgentConfig2();
|
|
406
|
+
const name = employee.name.toLowerCase();
|
|
407
|
+
if (!config[name] && config["default"]) {
|
|
408
|
+
config[name] = { ...config["default"] };
|
|
409
|
+
saveAgentConfig2(config);
|
|
410
|
+
}
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
return updated;
|
|
414
|
+
}
|
|
228
415
|
async function normalizeRosterCase(rosterPath) {
|
|
229
416
|
const employees = await loadEmployees(rosterPath);
|
|
230
417
|
let changed = false;
|
|
@@ -234,14 +421,14 @@ async function normalizeRosterCase(rosterPath) {
|
|
|
234
421
|
emp.name = emp.name.toLowerCase();
|
|
235
422
|
changed = true;
|
|
236
423
|
try {
|
|
237
|
-
const identityDir =
|
|
238
|
-
const oldPath =
|
|
239
|
-
const newPath =
|
|
240
|
-
if (
|
|
424
|
+
const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
|
|
425
|
+
const oldPath = path3.join(identityDir, `${oldName}.md`);
|
|
426
|
+
const newPath = path3.join(identityDir, `${emp.name}.md`);
|
|
427
|
+
if (existsSync4(oldPath) && !existsSync4(newPath)) {
|
|
241
428
|
renameSync2(oldPath, newPath);
|
|
242
|
-
} else if (
|
|
243
|
-
const content =
|
|
244
|
-
|
|
429
|
+
} else if (existsSync4(oldPath) && oldPath !== newPath) {
|
|
430
|
+
const content = readFileSync3(oldPath, "utf-8");
|
|
431
|
+
writeFileSync2(newPath, content, "utf-8");
|
|
245
432
|
if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
|
|
246
433
|
unlinkSync(oldPath);
|
|
247
434
|
}
|
|
@@ -271,7 +458,7 @@ function registerBinSymlinks(name) {
|
|
|
271
458
|
errors.push("Could not find 'exe-os' in PATH");
|
|
272
459
|
return { created, skipped, errors };
|
|
273
460
|
}
|
|
274
|
-
const binDir =
|
|
461
|
+
const binDir = path3.dirname(exeBinPath);
|
|
275
462
|
let target;
|
|
276
463
|
try {
|
|
277
464
|
target = readlinkSync(exeBinPath);
|
|
@@ -281,8 +468,8 @@ function registerBinSymlinks(name) {
|
|
|
281
468
|
}
|
|
282
469
|
for (const suffix of ["", "-opencode"]) {
|
|
283
470
|
const linkName = `${name}${suffix}`;
|
|
284
|
-
const linkPath =
|
|
285
|
-
if (
|
|
471
|
+
const linkPath = path3.join(binDir, linkName);
|
|
472
|
+
if (existsSync4(linkPath)) {
|
|
286
473
|
skipped.push(linkName);
|
|
287
474
|
continue;
|
|
288
475
|
}
|
|
@@ -295,15 +482,17 @@ function registerBinSymlinks(name) {
|
|
|
295
482
|
}
|
|
296
483
|
return { created, skipped, errors };
|
|
297
484
|
}
|
|
298
|
-
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES;
|
|
485
|
+
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR, TEAM_SECTION_RE;
|
|
299
486
|
var init_employees = __esm({
|
|
300
487
|
"src/lib/employees.ts"() {
|
|
301
488
|
"use strict";
|
|
302
489
|
init_config();
|
|
303
|
-
EMPLOYEES_PATH =
|
|
490
|
+
EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
|
|
304
491
|
DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
305
492
|
COORDINATOR_ROLE = "COO";
|
|
306
493
|
MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
|
|
494
|
+
IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
|
|
495
|
+
TEAM_SECTION_RE = /^## Team\b.*$/m;
|
|
307
496
|
}
|
|
308
497
|
});
|
|
309
498
|
|
|
@@ -314,6 +503,27 @@ var init_db_retry = __esm({
|
|
|
314
503
|
}
|
|
315
504
|
});
|
|
316
505
|
|
|
506
|
+
// src/lib/database-adapter.ts
|
|
507
|
+
import os3 from "os";
|
|
508
|
+
import path4 from "path";
|
|
509
|
+
import { createRequire } from "module";
|
|
510
|
+
import { pathToFileURL } from "url";
|
|
511
|
+
var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
|
|
512
|
+
var init_database_adapter = __esm({
|
|
513
|
+
"src/lib/database-adapter.ts"() {
|
|
514
|
+
"use strict";
|
|
515
|
+
BOOLEAN_COLUMNS_BY_TABLE = {
|
|
516
|
+
memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
|
|
517
|
+
behaviors: /* @__PURE__ */ new Set(["active"]),
|
|
518
|
+
notifications: /* @__PURE__ */ new Set(["read"]),
|
|
519
|
+
users: /* @__PURE__ */ new Set(["has_personal_memory"])
|
|
520
|
+
};
|
|
521
|
+
BOOLEAN_COLUMN_NAMES = new Set(
|
|
522
|
+
Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
|
|
317
527
|
// src/lib/database.ts
|
|
318
528
|
import { createClient } from "@libsql/client";
|
|
319
529
|
var init_database = __esm({
|
|
@@ -321,6 +531,7 @@ var init_database = __esm({
|
|
|
321
531
|
"use strict";
|
|
322
532
|
init_db_retry();
|
|
323
533
|
init_employees();
|
|
534
|
+
init_database_adapter();
|
|
324
535
|
}
|
|
325
536
|
});
|
|
326
537
|
|
|
@@ -1082,122 +1293,10 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
|
|
|
1082
1293
|
}
|
|
1083
1294
|
});
|
|
1084
1295
|
|
|
1085
|
-
// src/lib/runtime-table.ts
|
|
1086
|
-
var RUNTIME_TABLE, DEFAULT_RUNTIME;
|
|
1087
|
-
var init_runtime_table = __esm({
|
|
1088
|
-
"src/lib/runtime-table.ts"() {
|
|
1089
|
-
"use strict";
|
|
1090
|
-
RUNTIME_TABLE = {
|
|
1091
|
-
codex: {
|
|
1092
|
-
binary: "codex",
|
|
1093
|
-
launchMode: "interactive",
|
|
1094
|
-
autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
|
|
1095
|
-
inlineFlag: "--no-alt-screen",
|
|
1096
|
-
apiKeyEnv: "OPENAI_API_KEY",
|
|
1097
|
-
defaultModel: "gpt-5.4"
|
|
1098
|
-
},
|
|
1099
|
-
opencode: {
|
|
1100
|
-
binary: "opencode",
|
|
1101
|
-
launchMode: "exec",
|
|
1102
|
-
autoApproveFlag: "--dangerously-skip-permissions",
|
|
1103
|
-
inlineFlag: "",
|
|
1104
|
-
apiKeyEnv: "ANTHROPIC_API_KEY",
|
|
1105
|
-
defaultModel: "anthropic/claude-sonnet-4-6"
|
|
1106
|
-
}
|
|
1107
|
-
};
|
|
1108
|
-
DEFAULT_RUNTIME = "claude";
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
|
|
1112
|
-
// src/lib/agent-config.ts
|
|
1113
|
-
var agent_config_exports = {};
|
|
1114
|
-
__export(agent_config_exports, {
|
|
1115
|
-
AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
|
|
1116
|
-
DEFAULT_MODELS: () => DEFAULT_MODELS,
|
|
1117
|
-
KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
|
|
1118
|
-
RUNTIME_LABELS: () => RUNTIME_LABELS,
|
|
1119
|
-
clearAgentRuntime: () => clearAgentRuntime,
|
|
1120
|
-
getAgentRuntime: () => getAgentRuntime,
|
|
1121
|
-
loadAgentConfig: () => loadAgentConfig,
|
|
1122
|
-
saveAgentConfig: () => saveAgentConfig,
|
|
1123
|
-
setAgentRuntime: () => setAgentRuntime
|
|
1124
|
-
});
|
|
1125
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
|
|
1126
|
-
import path3 from "path";
|
|
1127
|
-
function loadAgentConfig() {
|
|
1128
|
-
if (!existsSync3(AGENT_CONFIG_PATH)) return {};
|
|
1129
|
-
try {
|
|
1130
|
-
return JSON.parse(readFileSync3(AGENT_CONFIG_PATH, "utf-8"));
|
|
1131
|
-
} catch {
|
|
1132
|
-
return {};
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
function saveAgentConfig(config) {
|
|
1136
|
-
const dir = path3.dirname(AGENT_CONFIG_PATH);
|
|
1137
|
-
if (!existsSync3(dir)) mkdirSync(dir, { recursive: true });
|
|
1138
|
-
writeFileSync2(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
1139
|
-
}
|
|
1140
|
-
function getAgentRuntime(agentId) {
|
|
1141
|
-
const config = loadAgentConfig();
|
|
1142
|
-
const entry = config[agentId];
|
|
1143
|
-
if (entry) return entry;
|
|
1144
|
-
const orgDefault = config["default"];
|
|
1145
|
-
if (orgDefault) return orgDefault;
|
|
1146
|
-
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
1147
|
-
}
|
|
1148
|
-
function setAgentRuntime(agentId, runtime, model) {
|
|
1149
|
-
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
1150
|
-
if (!knownModels) {
|
|
1151
|
-
return {
|
|
1152
|
-
ok: false,
|
|
1153
|
-
error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
if (!knownModels.includes(model)) {
|
|
1157
|
-
return {
|
|
1158
|
-
ok: false,
|
|
1159
|
-
error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
|
|
1160
|
-
};
|
|
1161
|
-
}
|
|
1162
|
-
const config = loadAgentConfig();
|
|
1163
|
-
config[agentId] = { runtime, model };
|
|
1164
|
-
saveAgentConfig(config);
|
|
1165
|
-
return { ok: true };
|
|
1166
|
-
}
|
|
1167
|
-
function clearAgentRuntime(agentId) {
|
|
1168
|
-
const config = loadAgentConfig();
|
|
1169
|
-
delete config[agentId];
|
|
1170
|
-
saveAgentConfig(config);
|
|
1171
|
-
}
|
|
1172
|
-
var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
|
|
1173
|
-
var init_agent_config = __esm({
|
|
1174
|
-
"src/lib/agent-config.ts"() {
|
|
1175
|
-
"use strict";
|
|
1176
|
-
init_config();
|
|
1177
|
-
init_runtime_table();
|
|
1178
|
-
AGENT_CONFIG_PATH = path3.join(EXE_AI_DIR, "agent-config.json");
|
|
1179
|
-
KNOWN_RUNTIMES = {
|
|
1180
|
-
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
1181
|
-
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
1182
|
-
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
1183
|
-
};
|
|
1184
|
-
RUNTIME_LABELS = {
|
|
1185
|
-
claude: "Claude Code (Anthropic)",
|
|
1186
|
-
codex: "Codex (OpenAI)",
|
|
1187
|
-
opencode: "OpenCode (open source)"
|
|
1188
|
-
};
|
|
1189
|
-
DEFAULT_MODELS = {
|
|
1190
|
-
claude: "claude-opus-4",
|
|
1191
|
-
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
1192
|
-
opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
|
|
1193
|
-
};
|
|
1194
|
-
}
|
|
1195
|
-
});
|
|
1196
|
-
|
|
1197
1296
|
// src/bin/exe-call.ts
|
|
1198
1297
|
init_employees();
|
|
1199
1298
|
init_config();
|
|
1200
|
-
import
|
|
1299
|
+
import path5 from "path";
|
|
1201
1300
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1202
1301
|
import { execSync as execSync2 } from "child_process";
|
|
1203
1302
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -1241,10 +1340,10 @@ function buildSessionEnv(employee, sessionDir) {
|
|
|
1241
1340
|
env["AGENT_ROLE"] = employee.role;
|
|
1242
1341
|
return env;
|
|
1243
1342
|
}
|
|
1244
|
-
async function prepareSessionDir(name, systemPrompt, sessionsBase =
|
|
1245
|
-
const sessionDir =
|
|
1343
|
+
async function prepareSessionDir(name, systemPrompt, sessionsBase = path5.join(EXE_AI_DIR, "sessions")) {
|
|
1344
|
+
const sessionDir = path5.join(sessionsBase, name);
|
|
1246
1345
|
await mkdir3(sessionDir, { recursive: true });
|
|
1247
|
-
await writeFile3(
|
|
1346
|
+
await writeFile3(path5.join(sessionDir, "CLAUDE.md"), systemPrompt, "utf-8");
|
|
1248
1347
|
return sessionDir;
|
|
1249
1348
|
}
|
|
1250
1349
|
if (isMainModule(import.meta.url)) {
|
|
@@ -1252,8 +1351,8 @@ if (isMainModule(import.meta.url)) {
|
|
|
1252
1351
|
const employees = await loadEmployees();
|
|
1253
1352
|
const coordinatorName = getCoordinatorName(employees);
|
|
1254
1353
|
if (!name || name === coordinatorName) {
|
|
1255
|
-
const __dirname =
|
|
1256
|
-
const bootPath =
|
|
1354
|
+
const __dirname = path5.dirname(fileURLToPath2(import.meta.url));
|
|
1355
|
+
const bootPath = path5.join(__dirname, "exe-boot.js");
|
|
1257
1356
|
try {
|
|
1258
1357
|
execSync2(`node "${bootPath}"`, { stdio: "inherit" });
|
|
1259
1358
|
} catch (err) {
|
|
@@ -1298,13 +1397,13 @@ if (isMainModule(import.meta.url)) {
|
|
|
1298
1397
|
console.log(
|
|
1299
1398
|
`Launching ${employee.name} (${employee.role}) on Codex (${rtConfig.model})...`
|
|
1300
1399
|
);
|
|
1301
|
-
const codexLauncher =
|
|
1400
|
+
const codexLauncher = path5.join(path5.dirname(fileURLToPath2(import.meta.url)), "exe-start-codex.js");
|
|
1302
1401
|
execSync2(`node "${codexLauncher}" --agent ${employee.name}`, { stdio: "inherit", env });
|
|
1303
1402
|
} else if (rtConfig.runtime === "opencode") {
|
|
1304
1403
|
console.log(
|
|
1305
1404
|
`Launching ${employee.name} (${employee.role}) on OpenCode (${rtConfig.model})...`
|
|
1306
1405
|
);
|
|
1307
|
-
const opencodeLauncher =
|
|
1406
|
+
const opencodeLauncher = path5.join(path5.dirname(fileURLToPath2(import.meta.url)), "exe-start-opencode.js");
|
|
1308
1407
|
execSync2(`node "${opencodeLauncher}" --agent ${employee.name}`, { stdio: "inherit", env });
|
|
1309
1408
|
} else {
|
|
1310
1409
|
console.log(
|