@askexenow/exe-os 0.9.7 → 0.9.8
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 +754 -79
- package/dist/bin/backfill-responses.js +752 -77
- package/dist/bin/backfill-vectors.js +752 -77
- package/dist/bin/cleanup-stale-review-tasks.js +657 -35
- package/dist/bin/cli.js +1388 -605
- package/dist/bin/exe-agent-config.js +123 -95
- package/dist/bin/exe-agent.js +41 -25
- package/dist/bin/exe-assign.js +732 -57
- package/dist/bin/exe-boot.js +784 -153
- package/dist/bin/exe-call.js +209 -138
- package/dist/bin/exe-cloud.js +35 -12
- package/dist/bin/exe-dispatch.js +692 -70
- package/dist/bin/exe-doctor.js +648 -26
- package/dist/bin/exe-export-behaviors.js +650 -20
- package/dist/bin/exe-forget.js +635 -13
- package/dist/bin/exe-gateway.js +1053 -271
- package/dist/bin/exe-heartbeat.js +665 -43
- package/dist/bin/exe-kill.js +646 -16
- package/dist/bin/exe-launch-agent.js +887 -97
- package/dist/bin/exe-link.js +658 -43
- package/dist/bin/exe-new-employee.js +378 -177
- package/dist/bin/exe-pending-messages.js +656 -34
- package/dist/bin/exe-pending-notifications.js +635 -13
- package/dist/bin/exe-pending-reviews.js +659 -37
- package/dist/bin/exe-rename.js +645 -30
- package/dist/bin/exe-review.js +635 -13
- package/dist/bin/exe-search.js +771 -88
- package/dist/bin/exe-session-cleanup.js +834 -150
- package/dist/bin/exe-settings.js +127 -91
- package/dist/bin/exe-start-codex.js +729 -94
- package/dist/bin/exe-start-opencode.js +717 -82
- package/dist/bin/exe-status.js +657 -35
- package/dist/bin/exe-team.js +635 -13
- package/dist/bin/git-sweep.js +720 -89
- package/dist/bin/graph-backfill.js +643 -13
- package/dist/bin/graph-export.js +646 -16
- package/dist/bin/install.js +596 -193
- package/dist/bin/scan-tasks.js +724 -93
- package/dist/bin/setup.js +1038 -210
- package/dist/bin/shard-migrate.js +645 -15
- package/dist/bin/wiki-sync.js +646 -16
- package/dist/gateway/index.js +1027 -245
- package/dist/hooks/bug-report-worker.js +891 -170
- package/dist/hooks/commit-complete.js +718 -87
- package/dist/hooks/error-recall.js +776 -93
- package/dist/hooks/exe-heartbeat-hook.js +85 -71
- package/dist/hooks/ingest-worker.js +840 -156
- package/dist/hooks/ingest.js +90 -73
- package/dist/hooks/instructions-loaded.js +669 -38
- package/dist/hooks/notification.js +661 -30
- package/dist/hooks/post-compact.js +674 -43
- package/dist/hooks/pre-compact.js +718 -87
- package/dist/hooks/pre-tool-use.js +872 -125
- package/dist/hooks/prompt-ingest-worker.js +758 -83
- package/dist/hooks/prompt-submit.js +1060 -319
- package/dist/hooks/response-ingest-worker.js +758 -83
- package/dist/hooks/session-end.js +721 -90
- package/dist/hooks/session-start.js +1031 -207
- package/dist/hooks/stop.js +680 -49
- package/dist/hooks/subagent-stop.js +674 -43
- package/dist/hooks/summary-worker.js +816 -132
- package/dist/index.js +1015 -232
- package/dist/lib/cloud-sync.js +663 -48
- package/dist/lib/consolidation.js +26 -3
- package/dist/lib/database.js +626 -18
- package/dist/lib/db.js +2261 -0
- package/dist/lib/device-registry.js +640 -25
- package/dist/lib/embedder.js +96 -43
- package/dist/lib/employee-templates.js +16 -0
- package/dist/lib/employees.js +259 -83
- package/dist/lib/exe-daemon-client.js +101 -63
- package/dist/lib/exe-daemon.js +894 -162
- package/dist/lib/hybrid-search.js +771 -88
- package/dist/lib/identity.js +27 -7
- package/dist/lib/messaging.js +55 -28
- package/dist/lib/reminders.js +21 -1
- package/dist/lib/schedules.js +636 -14
- package/dist/lib/skill-learning.js +21 -1
- package/dist/lib/store.js +643 -13
- package/dist/lib/task-router.js +82 -71
- package/dist/lib/tasks.js +98 -71
- package/dist/lib/tmux-routing.js +87 -60
- package/dist/lib/token-spend.js +26 -6
- package/dist/mcp/server.js +1784 -458
- package/dist/mcp/tools/complete-reminder.js +21 -1
- package/dist/mcp/tools/create-reminder.js +21 -1
- package/dist/mcp/tools/create-task.js +290 -164
- package/dist/mcp/tools/deactivate-behavior.js +24 -4
- package/dist/mcp/tools/list-reminders.js +21 -1
- package/dist/mcp/tools/list-tasks.js +195 -38
- package/dist/mcp/tools/send-message.js +58 -31
- package/dist/mcp/tools/update-task.js +75 -48
- package/dist/runtime/index.js +720 -89
- package/dist/tui/App.js +853 -123
- package/package.json +3 -2
package/dist/bin/exe-call.js
CHANGED
|
@@ -100,6 +100,118 @@ var init_config = __esm({
|
|
|
100
100
|
}
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
// src/lib/runtime-table.ts
|
|
104
|
+
var RUNTIME_TABLE, DEFAULT_RUNTIME;
|
|
105
|
+
var init_runtime_table = __esm({
|
|
106
|
+
"src/lib/runtime-table.ts"() {
|
|
107
|
+
"use strict";
|
|
108
|
+
RUNTIME_TABLE = {
|
|
109
|
+
codex: {
|
|
110
|
+
binary: "codex",
|
|
111
|
+
launchMode: "interactive",
|
|
112
|
+
autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
|
|
113
|
+
inlineFlag: "--no-alt-screen",
|
|
114
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
115
|
+
defaultModel: "gpt-5.4"
|
|
116
|
+
},
|
|
117
|
+
opencode: {
|
|
118
|
+
binary: "opencode",
|
|
119
|
+
launchMode: "exec",
|
|
120
|
+
autoApproveFlag: "--dangerously-skip-permissions",
|
|
121
|
+
inlineFlag: "",
|
|
122
|
+
apiKeyEnv: "ANTHROPIC_API_KEY",
|
|
123
|
+
defaultModel: "anthropic/claude-sonnet-4-6"
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
DEFAULT_RUNTIME = "claude";
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// src/lib/agent-config.ts
|
|
131
|
+
var agent_config_exports = {};
|
|
132
|
+
__export(agent_config_exports, {
|
|
133
|
+
AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
|
|
134
|
+
DEFAULT_MODELS: () => DEFAULT_MODELS,
|
|
135
|
+
KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
|
|
136
|
+
RUNTIME_LABELS: () => RUNTIME_LABELS,
|
|
137
|
+
clearAgentRuntime: () => clearAgentRuntime,
|
|
138
|
+
getAgentRuntime: () => getAgentRuntime,
|
|
139
|
+
loadAgentConfig: () => loadAgentConfig,
|
|
140
|
+
saveAgentConfig: () => saveAgentConfig,
|
|
141
|
+
setAgentRuntime: () => setAgentRuntime
|
|
142
|
+
});
|
|
143
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
|
|
144
|
+
import path2 from "path";
|
|
145
|
+
function loadAgentConfig() {
|
|
146
|
+
if (!existsSync2(AGENT_CONFIG_PATH)) return {};
|
|
147
|
+
try {
|
|
148
|
+
return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
|
|
149
|
+
} catch {
|
|
150
|
+
return {};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function saveAgentConfig(config) {
|
|
154
|
+
const dir = path2.dirname(AGENT_CONFIG_PATH);
|
|
155
|
+
if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
|
|
156
|
+
writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
157
|
+
}
|
|
158
|
+
function getAgentRuntime(agentId) {
|
|
159
|
+
const config = loadAgentConfig();
|
|
160
|
+
const entry = config[agentId];
|
|
161
|
+
if (entry) return entry;
|
|
162
|
+
const orgDefault = config["default"];
|
|
163
|
+
if (orgDefault) return orgDefault;
|
|
164
|
+
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
165
|
+
}
|
|
166
|
+
function setAgentRuntime(agentId, runtime, model) {
|
|
167
|
+
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
168
|
+
if (!knownModels) {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (!knownModels.includes(model)) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const config = loadAgentConfig();
|
|
181
|
+
config[agentId] = { runtime, model };
|
|
182
|
+
saveAgentConfig(config);
|
|
183
|
+
return { ok: true };
|
|
184
|
+
}
|
|
185
|
+
function clearAgentRuntime(agentId) {
|
|
186
|
+
const config = loadAgentConfig();
|
|
187
|
+
delete config[agentId];
|
|
188
|
+
saveAgentConfig(config);
|
|
189
|
+
}
|
|
190
|
+
var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
|
|
191
|
+
var init_agent_config = __esm({
|
|
192
|
+
"src/lib/agent-config.ts"() {
|
|
193
|
+
"use strict";
|
|
194
|
+
init_config();
|
|
195
|
+
init_runtime_table();
|
|
196
|
+
AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
197
|
+
KNOWN_RUNTIMES = {
|
|
198
|
+
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
199
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
200
|
+
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
201
|
+
};
|
|
202
|
+
RUNTIME_LABELS = {
|
|
203
|
+
claude: "Claude Code (Anthropic)",
|
|
204
|
+
codex: "Codex (OpenAI)",
|
|
205
|
+
opencode: "OpenCode (open source)"
|
|
206
|
+
};
|
|
207
|
+
DEFAULT_MODELS = {
|
|
208
|
+
claude: "claude-opus-4",
|
|
209
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
210
|
+
opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
103
215
|
// src/lib/employees.ts
|
|
104
216
|
var employees_exports = {};
|
|
105
217
|
__export(employees_exports, {
|
|
@@ -115,6 +227,7 @@ __export(employees_exports, {
|
|
|
115
227
|
getEmployeeByRole: () => getEmployeeByRole,
|
|
116
228
|
getEmployeeNamesByRole: () => getEmployeeNamesByRole,
|
|
117
229
|
hasRole: () => hasRole,
|
|
230
|
+
hireEmployee: () => hireEmployee,
|
|
118
231
|
isCoordinatorName: () => isCoordinatorName,
|
|
119
232
|
isCoordinatorRole: () => isCoordinatorRole,
|
|
120
233
|
isMultiInstance: () => isMultiInstance,
|
|
@@ -127,9 +240,9 @@ __export(employees_exports, {
|
|
|
127
240
|
validateEmployeeName: () => validateEmployeeName
|
|
128
241
|
});
|
|
129
242
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
130
|
-
import { existsSync as
|
|
243
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
131
244
|
import { execSync } from "child_process";
|
|
132
|
-
import
|
|
245
|
+
import path3 from "path";
|
|
133
246
|
import os2 from "os";
|
|
134
247
|
function normalizeRole(role) {
|
|
135
248
|
return (role ?? "").trim().toLowerCase();
|
|
@@ -166,7 +279,7 @@ function validateEmployeeName(name) {
|
|
|
166
279
|
return { valid: true };
|
|
167
280
|
}
|
|
168
281
|
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
169
|
-
if (!
|
|
282
|
+
if (!existsSync3(employeesPath)) {
|
|
170
283
|
return [];
|
|
171
284
|
}
|
|
172
285
|
const raw = await readFile2(employeesPath, "utf-8");
|
|
@@ -177,13 +290,13 @@ async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
|
177
290
|
}
|
|
178
291
|
}
|
|
179
292
|
async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
|
|
180
|
-
await mkdir2(
|
|
293
|
+
await mkdir2(path3.dirname(employeesPath), { recursive: true });
|
|
181
294
|
await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
|
|
182
295
|
}
|
|
183
296
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
184
|
-
if (!
|
|
297
|
+
if (!existsSync3(employeesPath)) return [];
|
|
185
298
|
try {
|
|
186
|
-
return JSON.parse(
|
|
299
|
+
return JSON.parse(readFileSync3(employeesPath, "utf-8"));
|
|
187
300
|
} catch {
|
|
188
301
|
return [];
|
|
189
302
|
}
|
|
@@ -225,6 +338,52 @@ function addEmployee(employees, employee) {
|
|
|
225
338
|
}
|
|
226
339
|
return [...employees, normalized];
|
|
227
340
|
}
|
|
341
|
+
function appendToCoordinatorTeam(employee) {
|
|
342
|
+
const coordinator = getCoordinatorEmployee(loadEmployeesSync());
|
|
343
|
+
if (!coordinator) return;
|
|
344
|
+
const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
|
|
345
|
+
if (!existsSync3(idPath)) return;
|
|
346
|
+
const content = readFileSync3(idPath, "utf-8");
|
|
347
|
+
if (content.includes(`**${capitalize(employee.name)}`)) return;
|
|
348
|
+
const teamMatch = content.match(TEAM_SECTION_RE);
|
|
349
|
+
if (!teamMatch || teamMatch.index === void 0) return;
|
|
350
|
+
const afterTeam = content.slice(teamMatch.index + teamMatch[0].length);
|
|
351
|
+
const nextHeading = afterTeam.match(/\n## /);
|
|
352
|
+
const entry = `
|
|
353
|
+
**${capitalize(employee.name)} (${employee.role}):** Newly hired. Update this description as the role develops.
|
|
354
|
+
`;
|
|
355
|
+
let updated;
|
|
356
|
+
if (nextHeading && nextHeading.index !== void 0) {
|
|
357
|
+
const insertAt = teamMatch.index + teamMatch[0].length + nextHeading.index;
|
|
358
|
+
updated = content.slice(0, insertAt) + entry + content.slice(insertAt);
|
|
359
|
+
} else {
|
|
360
|
+
updated = content.trimEnd() + "\n" + entry;
|
|
361
|
+
}
|
|
362
|
+
writeFileSync2(idPath, updated, "utf-8");
|
|
363
|
+
}
|
|
364
|
+
function capitalize(s) {
|
|
365
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
366
|
+
}
|
|
367
|
+
async function hireEmployee(employee) {
|
|
368
|
+
const employees = await loadEmployees();
|
|
369
|
+
const updated = addEmployee(employees, employee);
|
|
370
|
+
await saveEmployees(updated);
|
|
371
|
+
try {
|
|
372
|
+
appendToCoordinatorTeam(employee);
|
|
373
|
+
} catch {
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
const { loadAgentConfig: loadAgentConfig2, saveAgentConfig: saveAgentConfig2 } = await Promise.resolve().then(() => (init_agent_config(), agent_config_exports));
|
|
377
|
+
const config = loadAgentConfig2();
|
|
378
|
+
const name = employee.name.toLowerCase();
|
|
379
|
+
if (!config[name] && config["default"]) {
|
|
380
|
+
config[name] = { ...config["default"] };
|
|
381
|
+
saveAgentConfig2(config);
|
|
382
|
+
}
|
|
383
|
+
} catch {
|
|
384
|
+
}
|
|
385
|
+
return updated;
|
|
386
|
+
}
|
|
228
387
|
async function normalizeRosterCase(rosterPath) {
|
|
229
388
|
const employees = await loadEmployees(rosterPath);
|
|
230
389
|
let changed = false;
|
|
@@ -234,14 +393,14 @@ async function normalizeRosterCase(rosterPath) {
|
|
|
234
393
|
emp.name = emp.name.toLowerCase();
|
|
235
394
|
changed = true;
|
|
236
395
|
try {
|
|
237
|
-
const identityDir =
|
|
238
|
-
const oldPath =
|
|
239
|
-
const newPath =
|
|
240
|
-
if (
|
|
396
|
+
const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
|
|
397
|
+
const oldPath = path3.join(identityDir, `${oldName}.md`);
|
|
398
|
+
const newPath = path3.join(identityDir, `${emp.name}.md`);
|
|
399
|
+
if (existsSync3(oldPath) && !existsSync3(newPath)) {
|
|
241
400
|
renameSync2(oldPath, newPath);
|
|
242
|
-
} else if (
|
|
243
|
-
const content =
|
|
244
|
-
|
|
401
|
+
} else if (existsSync3(oldPath) && oldPath !== newPath) {
|
|
402
|
+
const content = readFileSync3(oldPath, "utf-8");
|
|
403
|
+
writeFileSync2(newPath, content, "utf-8");
|
|
245
404
|
if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
|
|
246
405
|
unlinkSync(oldPath);
|
|
247
406
|
}
|
|
@@ -271,7 +430,7 @@ function registerBinSymlinks(name) {
|
|
|
271
430
|
errors.push("Could not find 'exe-os' in PATH");
|
|
272
431
|
return { created, skipped, errors };
|
|
273
432
|
}
|
|
274
|
-
const binDir =
|
|
433
|
+
const binDir = path3.dirname(exeBinPath);
|
|
275
434
|
let target;
|
|
276
435
|
try {
|
|
277
436
|
target = readlinkSync(exeBinPath);
|
|
@@ -281,8 +440,8 @@ function registerBinSymlinks(name) {
|
|
|
281
440
|
}
|
|
282
441
|
for (const suffix of ["", "-opencode"]) {
|
|
283
442
|
const linkName = `${name}${suffix}`;
|
|
284
|
-
const linkPath =
|
|
285
|
-
if (
|
|
443
|
+
const linkPath = path3.join(binDir, linkName);
|
|
444
|
+
if (existsSync3(linkPath)) {
|
|
286
445
|
skipped.push(linkName);
|
|
287
446
|
continue;
|
|
288
447
|
}
|
|
@@ -295,15 +454,17 @@ function registerBinSymlinks(name) {
|
|
|
295
454
|
}
|
|
296
455
|
return { created, skipped, errors };
|
|
297
456
|
}
|
|
298
|
-
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES;
|
|
457
|
+
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR, TEAM_SECTION_RE;
|
|
299
458
|
var init_employees = __esm({
|
|
300
459
|
"src/lib/employees.ts"() {
|
|
301
460
|
"use strict";
|
|
302
461
|
init_config();
|
|
303
|
-
EMPLOYEES_PATH =
|
|
462
|
+
EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
|
|
304
463
|
DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
305
464
|
COORDINATOR_ROLE = "COO";
|
|
306
465
|
MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
|
|
466
|
+
IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
|
|
467
|
+
TEAM_SECTION_RE = /^## Team\b.*$/m;
|
|
307
468
|
}
|
|
308
469
|
});
|
|
309
470
|
|
|
@@ -314,6 +475,27 @@ var init_db_retry = __esm({
|
|
|
314
475
|
}
|
|
315
476
|
});
|
|
316
477
|
|
|
478
|
+
// src/lib/database-adapter.ts
|
|
479
|
+
import os3 from "os";
|
|
480
|
+
import path4 from "path";
|
|
481
|
+
import { createRequire } from "module";
|
|
482
|
+
import { pathToFileURL } from "url";
|
|
483
|
+
var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
|
|
484
|
+
var init_database_adapter = __esm({
|
|
485
|
+
"src/lib/database-adapter.ts"() {
|
|
486
|
+
"use strict";
|
|
487
|
+
BOOLEAN_COLUMNS_BY_TABLE = {
|
|
488
|
+
memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
|
|
489
|
+
behaviors: /* @__PURE__ */ new Set(["active"]),
|
|
490
|
+
notifications: /* @__PURE__ */ new Set(["read"]),
|
|
491
|
+
users: /* @__PURE__ */ new Set(["has_personal_memory"])
|
|
492
|
+
};
|
|
493
|
+
BOOLEAN_COLUMN_NAMES = new Set(
|
|
494
|
+
Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
|
|
317
499
|
// src/lib/database.ts
|
|
318
500
|
import { createClient } from "@libsql/client";
|
|
319
501
|
var init_database = __esm({
|
|
@@ -321,6 +503,7 @@ var init_database = __esm({
|
|
|
321
503
|
"use strict";
|
|
322
504
|
init_db_retry();
|
|
323
505
|
init_employees();
|
|
506
|
+
init_database_adapter();
|
|
324
507
|
}
|
|
325
508
|
});
|
|
326
509
|
|
|
@@ -1082,122 +1265,10 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
|
|
|
1082
1265
|
}
|
|
1083
1266
|
});
|
|
1084
1267
|
|
|
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
1268
|
// src/bin/exe-call.ts
|
|
1198
1269
|
init_employees();
|
|
1199
1270
|
init_config();
|
|
1200
|
-
import
|
|
1271
|
+
import path5 from "path";
|
|
1201
1272
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1202
1273
|
import { execSync as execSync2 } from "child_process";
|
|
1203
1274
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -1241,10 +1312,10 @@ function buildSessionEnv(employee, sessionDir) {
|
|
|
1241
1312
|
env["AGENT_ROLE"] = employee.role;
|
|
1242
1313
|
return env;
|
|
1243
1314
|
}
|
|
1244
|
-
async function prepareSessionDir(name, systemPrompt, sessionsBase =
|
|
1245
|
-
const sessionDir =
|
|
1315
|
+
async function prepareSessionDir(name, systemPrompt, sessionsBase = path5.join(EXE_AI_DIR, "sessions")) {
|
|
1316
|
+
const sessionDir = path5.join(sessionsBase, name);
|
|
1246
1317
|
await mkdir3(sessionDir, { recursive: true });
|
|
1247
|
-
await writeFile3(
|
|
1318
|
+
await writeFile3(path5.join(sessionDir, "CLAUDE.md"), systemPrompt, "utf-8");
|
|
1248
1319
|
return sessionDir;
|
|
1249
1320
|
}
|
|
1250
1321
|
if (isMainModule(import.meta.url)) {
|
|
@@ -1252,8 +1323,8 @@ if (isMainModule(import.meta.url)) {
|
|
|
1252
1323
|
const employees = await loadEmployees();
|
|
1253
1324
|
const coordinatorName = getCoordinatorName(employees);
|
|
1254
1325
|
if (!name || name === coordinatorName) {
|
|
1255
|
-
const __dirname =
|
|
1256
|
-
const bootPath =
|
|
1326
|
+
const __dirname = path5.dirname(fileURLToPath2(import.meta.url));
|
|
1327
|
+
const bootPath = path5.join(__dirname, "exe-boot.js");
|
|
1257
1328
|
try {
|
|
1258
1329
|
execSync2(`node "${bootPath}"`, { stdio: "inherit" });
|
|
1259
1330
|
} catch (err) {
|
|
@@ -1298,13 +1369,13 @@ if (isMainModule(import.meta.url)) {
|
|
|
1298
1369
|
console.log(
|
|
1299
1370
|
`Launching ${employee.name} (${employee.role}) on Codex (${rtConfig.model})...`
|
|
1300
1371
|
);
|
|
1301
|
-
const codexLauncher =
|
|
1372
|
+
const codexLauncher = path5.join(path5.dirname(fileURLToPath2(import.meta.url)), "exe-start-codex.js");
|
|
1302
1373
|
execSync2(`node "${codexLauncher}" --agent ${employee.name}`, { stdio: "inherit", env });
|
|
1303
1374
|
} else if (rtConfig.runtime === "opencode") {
|
|
1304
1375
|
console.log(
|
|
1305
1376
|
`Launching ${employee.name} (${employee.role}) on OpenCode (${rtConfig.model})...`
|
|
1306
1377
|
);
|
|
1307
|
-
const opencodeLauncher =
|
|
1378
|
+
const opencodeLauncher = path5.join(path5.dirname(fileURLToPath2(import.meta.url)), "exe-start-opencode.js");
|
|
1308
1379
|
execSync2(`node "${opencodeLauncher}" --agent ${employee.name}`, { stdio: "inherit", env });
|
|
1309
1380
|
} else {
|
|
1310
1381
|
console.log(
|
package/dist/bin/exe-cloud.js
CHANGED
|
@@ -322,12 +322,34 @@ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as r
|
|
|
322
322
|
import { execSync } from "child_process";
|
|
323
323
|
import path3 from "path";
|
|
324
324
|
import os3 from "os";
|
|
325
|
-
var EMPLOYEES_PATH;
|
|
325
|
+
var EMPLOYEES_PATH, IDENTITY_DIR;
|
|
326
326
|
var init_employees = __esm({
|
|
327
327
|
"src/lib/employees.ts"() {
|
|
328
328
|
"use strict";
|
|
329
329
|
init_config();
|
|
330
330
|
EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
|
|
331
|
+
IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// src/lib/database-adapter.ts
|
|
336
|
+
import os4 from "os";
|
|
337
|
+
import path4 from "path";
|
|
338
|
+
import { createRequire } from "module";
|
|
339
|
+
import { pathToFileURL } from "url";
|
|
340
|
+
var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
|
|
341
|
+
var init_database_adapter = __esm({
|
|
342
|
+
"src/lib/database-adapter.ts"() {
|
|
343
|
+
"use strict";
|
|
344
|
+
BOOLEAN_COLUMNS_BY_TABLE = {
|
|
345
|
+
memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
|
|
346
|
+
behaviors: /* @__PURE__ */ new Set(["active"]),
|
|
347
|
+
notifications: /* @__PURE__ */ new Set(["read"]),
|
|
348
|
+
users: /* @__PURE__ */ new Set(["has_personal_memory"])
|
|
349
|
+
};
|
|
350
|
+
BOOLEAN_COLUMN_NAMES = new Set(
|
|
351
|
+
Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
|
|
352
|
+
);
|
|
331
353
|
}
|
|
332
354
|
});
|
|
333
355
|
|
|
@@ -338,6 +360,7 @@ var init_database = __esm({
|
|
|
338
360
|
"use strict";
|
|
339
361
|
init_db_retry();
|
|
340
362
|
init_employees();
|
|
363
|
+
init_database_adapter();
|
|
341
364
|
}
|
|
342
365
|
});
|
|
343
366
|
|
|
@@ -360,7 +383,7 @@ __export(license_exports, {
|
|
|
360
383
|
});
|
|
361
384
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync } from "fs";
|
|
362
385
|
import { randomUUID } from "crypto";
|
|
363
|
-
import
|
|
386
|
+
import path5 from "path";
|
|
364
387
|
import { jwtVerify, importSPKI } from "jose";
|
|
365
388
|
async function fetchRetry(url, init) {
|
|
366
389
|
try {
|
|
@@ -371,7 +394,7 @@ async function fetchRetry(url, init) {
|
|
|
371
394
|
}
|
|
372
395
|
}
|
|
373
396
|
function loadDeviceId() {
|
|
374
|
-
const deviceJsonPath =
|
|
397
|
+
const deviceJsonPath = path5.join(EXE_AI_DIR, "device.json");
|
|
375
398
|
try {
|
|
376
399
|
if (existsSync4(deviceJsonPath)) {
|
|
377
400
|
const data = JSON.parse(readFileSync3(deviceJsonPath, "utf8"));
|
|
@@ -536,7 +559,7 @@ async function checkLicense() {
|
|
|
536
559
|
let key = loadLicense();
|
|
537
560
|
if (!key) {
|
|
538
561
|
try {
|
|
539
|
-
const configPath =
|
|
562
|
+
const configPath = path5.join(EXE_AI_DIR, "config.json");
|
|
540
563
|
if (existsSync4(configPath)) {
|
|
541
564
|
const raw = JSON.parse(readFileSync3(configPath, "utf8"));
|
|
542
565
|
const cloud = raw.cloud;
|
|
@@ -697,9 +720,9 @@ var init_license = __esm({
|
|
|
697
720
|
"src/lib/license.ts"() {
|
|
698
721
|
"use strict";
|
|
699
722
|
init_config();
|
|
700
|
-
LICENSE_PATH =
|
|
701
|
-
CACHE_PATH =
|
|
702
|
-
DEVICE_ID_PATH =
|
|
723
|
+
LICENSE_PATH = path5.join(EXE_AI_DIR, "license.key");
|
|
724
|
+
CACHE_PATH = path5.join(EXE_AI_DIR, "license-cache.json");
|
|
725
|
+
DEVICE_ID_PATH = path5.join(EXE_AI_DIR, "device-id");
|
|
703
726
|
API_BASE = "https://askexe.com/cloud";
|
|
704
727
|
RETRY_DELAY_MS = 500;
|
|
705
728
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
@@ -731,13 +754,13 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
|
731
754
|
// src/lib/crdt-sync.ts
|
|
732
755
|
import * as Y from "yjs";
|
|
733
756
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
734
|
-
import
|
|
757
|
+
import path6 from "path";
|
|
735
758
|
import { homedir } from "os";
|
|
736
759
|
var DEFAULT_STATE_PATH;
|
|
737
760
|
var init_crdt_sync = __esm({
|
|
738
761
|
"src/lib/crdt-sync.ts"() {
|
|
739
762
|
"use strict";
|
|
740
|
-
DEFAULT_STATE_PATH =
|
|
763
|
+
DEFAULT_STATE_PATH = path6.join(homedir(), ".exe-os", "crdt-state.bin");
|
|
741
764
|
}
|
|
742
765
|
});
|
|
743
766
|
|
|
@@ -780,7 +803,7 @@ function isMainModule(importMetaUrl) {
|
|
|
780
803
|
init_database();
|
|
781
804
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6, readdirSync, mkdirSync as mkdirSync3, appendFileSync, unlinkSync as unlinkSync3, openSync, closeSync } from "fs";
|
|
782
805
|
import crypto3 from "crypto";
|
|
783
|
-
import
|
|
806
|
+
import path7 from "path";
|
|
784
807
|
import { homedir as homedir2 } from "os";
|
|
785
808
|
|
|
786
809
|
// src/lib/crypto.ts
|
|
@@ -795,7 +818,7 @@ init_config();
|
|
|
795
818
|
init_crdt_sync();
|
|
796
819
|
init_employees();
|
|
797
820
|
var LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
|
|
798
|
-
var ROSTER_LOCK_PATH =
|
|
821
|
+
var ROSTER_LOCK_PATH = path7.join(EXE_AI_DIR, "roster-merge.lock");
|
|
799
822
|
function assertSecureEndpoint(endpoint) {
|
|
800
823
|
if (endpoint.startsWith("https://")) return;
|
|
801
824
|
if (endpoint.startsWith("http://")) {
|
|
@@ -810,7 +833,7 @@ function assertSecureEndpoint(endpoint) {
|
|
|
810
833
|
);
|
|
811
834
|
}
|
|
812
835
|
}
|
|
813
|
-
var ROSTER_DELETIONS_PATH =
|
|
836
|
+
var ROSTER_DELETIONS_PATH = path7.join(EXE_AI_DIR, "roster-deletions.json");
|
|
814
837
|
|
|
815
838
|
// src/bin/exe-cloud.ts
|
|
816
839
|
var BAR = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
|