@askexenow/exe-os 0.8.80 → 0.8.82
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 +359 -267
- package/dist/bin/backfill-responses.js +357 -265
- package/dist/bin/backfill-vectors.js +339 -264
- package/dist/bin/cleanup-stale-review-tasks.js +315 -256
- package/dist/bin/cli.js +494 -240
- package/dist/bin/exe-agent.js +141 -46
- package/dist/bin/exe-assign.js +151 -63
- package/dist/bin/exe-boot.js +294 -115
- package/dist/bin/exe-call.js +76 -51
- package/dist/bin/exe-cloud.js +58 -45
- package/dist/bin/exe-dispatch.js +434 -277
- package/dist/bin/exe-doctor.js +317 -246
- package/dist/bin/exe-export-behaviors.js +328 -248
- package/dist/bin/exe-forget.js +314 -231
- package/dist/bin/exe-gateway.js +2676 -1402
- package/dist/bin/exe-heartbeat.js +329 -264
- package/dist/bin/exe-kill.js +324 -244
- package/dist/bin/exe-launch-agent.js +574 -463
- package/dist/bin/exe-link.js +1055 -95
- package/dist/bin/exe-new-employee.js +49 -54
- package/dist/bin/exe-pending-messages.js +310 -253
- package/dist/bin/exe-pending-notifications.js +299 -228
- package/dist/bin/exe-pending-reviews.js +314 -245
- package/dist/bin/exe-rename.js +259 -195
- package/dist/bin/exe-review.js +140 -64
- package/dist/bin/exe-search.js +543 -356
- package/dist/bin/exe-session-cleanup.js +463 -382
- package/dist/bin/exe-settings.js +129 -99
- package/dist/bin/exe-start.sh +6 -6
- package/dist/bin/exe-status.js +95 -36
- package/dist/bin/exe-team.js +116 -51
- package/dist/bin/git-sweep.js +482 -307
- package/dist/bin/graph-backfill.js +357 -245
- package/dist/bin/graph-export.js +324 -244
- package/dist/bin/install.js +33 -10
- package/dist/bin/scan-tasks.js +481 -307
- package/dist/bin/setup.js +1147 -140
- package/dist/bin/shard-migrate.js +321 -241
- package/dist/bin/update.js +1 -7
- package/dist/bin/wiki-sync.js +318 -238
- package/dist/gateway/index.js +2656 -1383
- package/dist/hooks/bug-report-worker.js +641 -472
- package/dist/hooks/commit-complete.js +482 -307
- package/dist/hooks/error-recall.js +363 -135
- package/dist/hooks/exe-heartbeat-hook.js +97 -27
- package/dist/hooks/ingest-worker.js +584 -397
- package/dist/hooks/ingest.js +123 -58
- package/dist/hooks/instructions-loaded.js +212 -82
- package/dist/hooks/notification.js +200 -70
- package/dist/hooks/post-compact.js +199 -81
- package/dist/hooks/pre-compact.js +352 -140
- package/dist/hooks/pre-tool-use.js +416 -278
- package/dist/hooks/prompt-ingest-worker.js +376 -299
- package/dist/hooks/prompt-submit.js +414 -188
- package/dist/hooks/response-ingest-worker.js +408 -338
- package/dist/hooks/session-end.js +209 -83
- package/dist/hooks/session-start.js +382 -158
- package/dist/hooks/stop.js +209 -83
- package/dist/hooks/subagent-stop.js +209 -85
- package/dist/hooks/summary-worker.js +606 -510
- package/dist/index.js +2133 -855
- package/dist/lib/cloud-sync.js +1175 -184
- package/dist/lib/config.js +1 -9
- package/dist/lib/consolidation.js +71 -34
- package/dist/lib/database.js +166 -14
- package/dist/lib/device-registry.js +189 -117
- package/dist/lib/embedder.js +6 -10
- package/dist/lib/employee-templates.js +134 -39
- package/dist/lib/employees.js +30 -7
- package/dist/lib/exe-daemon-client.js +5 -7
- package/dist/lib/exe-daemon.js +514 -152
- package/dist/lib/hybrid-search.js +543 -356
- package/dist/lib/identity-templates.js +15 -15
- package/dist/lib/identity.js +19 -15
- package/dist/lib/license.js +1 -7
- package/dist/lib/messaging.js +157 -135
- package/dist/lib/reminders.js +97 -0
- package/dist/lib/schedules.js +302 -231
- package/dist/lib/skill-learning.js +33 -27
- package/dist/lib/status-brief.js +11 -14
- package/dist/lib/store.js +326 -237
- package/dist/lib/task-router.js +105 -1
- package/dist/lib/tasks.js +233 -116
- package/dist/lib/tmux-routing.js +173 -56
- package/dist/lib/ws-client.js +13 -3
- package/dist/mcp/server.js +2009 -1015
- package/dist/mcp/tools/complete-reminder.js +97 -0
- package/dist/mcp/tools/create-reminder.js +97 -0
- package/dist/mcp/tools/create-task.js +426 -262
- package/dist/mcp/tools/deactivate-behavior.js +119 -44
- package/dist/mcp/tools/list-reminders.js +97 -0
- package/dist/mcp/tools/list-tasks.js +56 -57
- package/dist/mcp/tools/send-message.js +206 -143
- package/dist/mcp/tools/update-task.js +259 -85
- package/dist/runtime/index.js +495 -316
- package/dist/tui/App.js +1128 -919
- package/package.json +2 -10
- package/src/commands/exe/afk.md +8 -8
- package/src/commands/exe/assign.md +1 -1
- package/src/commands/exe/build-adv.md +1 -1
- package/src/commands/exe/call.md +10 -10
- package/src/commands/exe/employee-heartbeat.md +9 -6
- package/src/commands/exe/heartbeat.md +5 -5
- package/src/commands/exe/intercom.md +26 -15
- package/src/commands/exe/launch.md +2 -2
- package/src/commands/exe/new-employee.md +1 -1
- package/src/commands/exe/review.md +2 -2
- package/src/commands/exe/schedule.md +1 -1
- package/src/commands/exe/sessions.md +2 -2
- package/src/commands/exe.md +22 -20
|
@@ -6,28 +6,13 @@ import crypto from "crypto";
|
|
|
6
6
|
|
|
7
7
|
// src/lib/database.ts
|
|
8
8
|
import { createClient } from "@libsql/client";
|
|
9
|
-
var _resilientClient = null;
|
|
10
|
-
function getClient() {
|
|
11
|
-
if (!_resilientClient) {
|
|
12
|
-
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
13
|
-
}
|
|
14
|
-
return _resilientClient;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// src/lib/behaviors.ts
|
|
18
|
-
async function deactivateBehavior(id) {
|
|
19
|
-
const client = getClient();
|
|
20
|
-
const result = await client.execute({
|
|
21
|
-
sql: `UPDATE behaviors SET active = 0, updated_at = ? WHERE id = ? AND active = 1`,
|
|
22
|
-
args: [(/* @__PURE__ */ new Date()).toISOString(), id]
|
|
23
|
-
});
|
|
24
|
-
return (result.rowsAffected ?? 0) > 0;
|
|
25
|
-
}
|
|
26
9
|
|
|
27
|
-
// src/
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
10
|
+
// src/lib/employees.ts
|
|
11
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
12
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
13
|
+
import { execSync } from "child_process";
|
|
30
14
|
import path2 from "path";
|
|
15
|
+
import os2 from "os";
|
|
31
16
|
|
|
32
17
|
// src/lib/config.ts
|
|
33
18
|
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
@@ -89,13 +74,7 @@ var DEFAULT_CONFIG = {
|
|
|
89
74
|
wikiUrl: "",
|
|
90
75
|
wikiApiKey: "",
|
|
91
76
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
92
|
-
wikiWorkspaceMapping: {
|
|
93
|
-
exe: "Executive",
|
|
94
|
-
yoshi: "Engineering",
|
|
95
|
-
mari: "Marketing",
|
|
96
|
-
tom: "Engineering",
|
|
97
|
-
sasha: "Production"
|
|
98
|
-
},
|
|
77
|
+
wikiWorkspaceMapping: {},
|
|
99
78
|
wikiAutoUpdate: true,
|
|
100
79
|
wikiAutoUpdateThreshold: 0.5,
|
|
101
80
|
wikiAutoUpdateCreateNew: true,
|
|
@@ -120,15 +99,74 @@ var DEFAULT_CONFIG = {
|
|
|
120
99
|
}
|
|
121
100
|
};
|
|
122
101
|
|
|
102
|
+
// src/lib/employees.ts
|
|
103
|
+
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
104
|
+
var DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
105
|
+
var COORDINATOR_ROLE = "COO";
|
|
106
|
+
function normalizeRole(role) {
|
|
107
|
+
return (role ?? "").trim().toLowerCase();
|
|
108
|
+
}
|
|
109
|
+
function isCoordinatorRole(role) {
|
|
110
|
+
return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
|
|
111
|
+
}
|
|
112
|
+
function getCoordinatorEmployee(employees) {
|
|
113
|
+
return employees.find((e) => isCoordinatorRole(e.role));
|
|
114
|
+
}
|
|
115
|
+
function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
116
|
+
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
117
|
+
}
|
|
118
|
+
function isCoordinatorName(agentName, employees = loadEmployeesSync()) {
|
|
119
|
+
if (!agentName) return false;
|
|
120
|
+
return agentName.toLowerCase() === getCoordinatorName(employees).toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
function canCoordinate(agentName, agentRole, employees = loadEmployeesSync()) {
|
|
123
|
+
return agentName === "default" || isCoordinatorRole(agentRole) || isCoordinatorName(agentName, employees);
|
|
124
|
+
}
|
|
125
|
+
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
126
|
+
if (!existsSync2(employeesPath)) return [];
|
|
127
|
+
try {
|
|
128
|
+
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
129
|
+
} catch {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function getEmployee(employees, name) {
|
|
134
|
+
return employees.find((e) => e.name.toLowerCase() === name.toLowerCase());
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/lib/database.ts
|
|
138
|
+
var _resilientClient = null;
|
|
139
|
+
function getClient() {
|
|
140
|
+
if (!_resilientClient) {
|
|
141
|
+
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
142
|
+
}
|
|
143
|
+
return _resilientClient;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/lib/behaviors.ts
|
|
147
|
+
async function deactivateBehavior(id) {
|
|
148
|
+
const client = getClient();
|
|
149
|
+
const result = await client.execute({
|
|
150
|
+
sql: `UPDATE behaviors SET active = 0, updated_at = ? WHERE id = ? AND active = 1`,
|
|
151
|
+
args: [(/* @__PURE__ */ new Date()).toISOString(), id]
|
|
152
|
+
});
|
|
153
|
+
return (result.rowsAffected ?? 0) > 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/adapters/claude/active-agent.ts
|
|
157
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, unlinkSync as unlinkSync2, readdirSync } from "fs";
|
|
158
|
+
import { execSync as execSync3 } from "child_process";
|
|
159
|
+
import path3 from "path";
|
|
160
|
+
|
|
123
161
|
// src/lib/session-key.ts
|
|
124
|
-
import { execSync } from "child_process";
|
|
162
|
+
import { execSync as execSync2 } from "child_process";
|
|
125
163
|
var _cached = null;
|
|
126
164
|
function getSessionKey() {
|
|
127
165
|
if (_cached) return _cached;
|
|
128
166
|
let pid = process.ppid;
|
|
129
167
|
for (let i = 0; i < 10; i++) {
|
|
130
168
|
try {
|
|
131
|
-
const info =
|
|
169
|
+
const info = execSync2(`ps -p ${pid} -o ppid=,comm=`, {
|
|
132
170
|
encoding: "utf8",
|
|
133
171
|
timeout: 2e3
|
|
134
172
|
}).trim();
|
|
@@ -150,22 +188,64 @@ function getSessionKey() {
|
|
|
150
188
|
}
|
|
151
189
|
|
|
152
190
|
// src/adapters/claude/active-agent.ts
|
|
153
|
-
var CACHE_DIR =
|
|
191
|
+
var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
|
|
154
192
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
193
|
+
function isNameWithOptionalInstance(candidate, baseName) {
|
|
194
|
+
if (candidate === baseName) return true;
|
|
195
|
+
if (!candidate.startsWith(baseName)) return false;
|
|
196
|
+
return /^\d+$/.test(candidate.slice(baseName.length));
|
|
197
|
+
}
|
|
198
|
+
function resolveEmployeeFromSessionPrefix(prefix, employees) {
|
|
199
|
+
const sorted = [...employees].sort((a, b) => b.name.length - a.name.length);
|
|
200
|
+
for (const employee of sorted) {
|
|
201
|
+
if (isNameWithOptionalInstance(prefix, employee.name)) {
|
|
202
|
+
return { agentId: employee.name, agentRole: employee.role };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
function resolveActiveAgentFromTmuxSession(sessionName) {
|
|
208
|
+
const employees = loadEmployeesSync();
|
|
209
|
+
const coordinator = getCoordinatorEmployee(employees);
|
|
210
|
+
const coordinatorName = coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
211
|
+
if (isNameWithOptionalInstance(sessionName, coordinatorName)) {
|
|
212
|
+
return {
|
|
213
|
+
agentId: coordinatorName,
|
|
214
|
+
agentRole: coordinator?.role ?? "COO"
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
if (isNameWithOptionalInstance(sessionName, DEFAULT_COORDINATOR_TEMPLATE_NAME)) {
|
|
218
|
+
return {
|
|
219
|
+
agentId: coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME,
|
|
220
|
+
agentRole: coordinator?.role ?? "COO"
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (sessionName.includes("-")) {
|
|
224
|
+
const prefix = sessionName.split("-")[0] ?? "";
|
|
225
|
+
const employee = resolveEmployeeFromSessionPrefix(prefix, employees);
|
|
226
|
+
if (employee) return employee;
|
|
227
|
+
const legacy = prefix.match(/^([a-zA-Z]+)\d*$/);
|
|
228
|
+
if (legacy?.[1] && legacy[1] !== DEFAULT_COORDINATOR_TEMPLATE_NAME) {
|
|
229
|
+
const emp = getEmployee(employees, legacy[1]);
|
|
230
|
+
return { agentId: emp?.name ?? legacy[1], agentRole: emp?.role ?? "employee" };
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
155
235
|
function getMarkerPath() {
|
|
156
|
-
return
|
|
236
|
+
return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
|
|
157
237
|
}
|
|
158
238
|
function getActiveAgent() {
|
|
159
239
|
try {
|
|
160
240
|
const markerPath = getMarkerPath();
|
|
161
|
-
const raw =
|
|
241
|
+
const raw = readFileSync3(markerPath, "utf8");
|
|
162
242
|
const data = JSON.parse(raw);
|
|
163
243
|
if (data.agentId) {
|
|
164
244
|
if (data.startedAt) {
|
|
165
245
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
166
246
|
if (age > STALE_MS) {
|
|
167
247
|
try {
|
|
168
|
-
|
|
248
|
+
unlinkSync2(markerPath);
|
|
169
249
|
} catch {
|
|
170
250
|
}
|
|
171
251
|
} else {
|
|
@@ -184,17 +264,12 @@ function getActiveAgent() {
|
|
|
184
264
|
} catch {
|
|
185
265
|
}
|
|
186
266
|
try {
|
|
187
|
-
const sessionName =
|
|
267
|
+
const sessionName = execSync3(
|
|
188
268
|
"tmux display-message -p '#{session_name}' 2>/dev/null",
|
|
189
269
|
{ encoding: "utf8", timeout: 2e3 }
|
|
190
270
|
).trim();
|
|
191
|
-
const
|
|
192
|
-
if (
|
|
193
|
-
return { agentId: empMatch[1], agentRole: "employee" };
|
|
194
|
-
}
|
|
195
|
-
if (/^exe\d+$/.test(sessionName)) {
|
|
196
|
-
return { agentId: "exe", agentRole: "COO" };
|
|
197
|
-
}
|
|
271
|
+
const resolved = resolveActiveAgentFromTmuxSession(sessionName);
|
|
272
|
+
if (resolved) return resolved;
|
|
198
273
|
} catch {
|
|
199
274
|
}
|
|
200
275
|
return {
|
|
@@ -209,19 +284,19 @@ function registerDeactivateBehavior(server) {
|
|
|
209
284
|
"deactivate_behavior",
|
|
210
285
|
{
|
|
211
286
|
title: "Deactivate Behavior",
|
|
212
|
-
description: "Soft-delete a behavior by setting active = 0. RESTRICTED: only
|
|
287
|
+
description: "Soft-delete a behavior by setting active = 0. RESTRICTED: only coordinator or founder sessions can use this. Use list_behaviors to find the behavior ID first.",
|
|
213
288
|
inputSchema: {
|
|
214
289
|
behavior_id: z.string().describe("UUID of the behavior to deactivate")
|
|
215
290
|
}
|
|
216
291
|
},
|
|
217
292
|
async ({ behavior_id }) => {
|
|
218
293
|
const caller = getActiveAgent();
|
|
219
|
-
const allowed = caller.agentId
|
|
294
|
+
const allowed = canCoordinate(caller.agentId, caller.agentRole);
|
|
220
295
|
if (!allowed) {
|
|
221
296
|
return {
|
|
222
297
|
content: [{
|
|
223
298
|
type: "text",
|
|
224
|
-
text: `Permission denied. Only
|
|
299
|
+
text: `Permission denied. Only the coordinator or founder sessions can deactivate behaviors. You are "${caller.agentId}".`
|
|
225
300
|
}],
|
|
226
301
|
isError: true
|
|
227
302
|
};
|
|
@@ -6,6 +6,103 @@ import crypto from "crypto";
|
|
|
6
6
|
|
|
7
7
|
// src/lib/database.ts
|
|
8
8
|
import { createClient } from "@libsql/client";
|
|
9
|
+
|
|
10
|
+
// src/lib/employees.ts
|
|
11
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
12
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
13
|
+
import { execSync } from "child_process";
|
|
14
|
+
import path2 from "path";
|
|
15
|
+
import os2 from "os";
|
|
16
|
+
|
|
17
|
+
// src/lib/config.ts
|
|
18
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
19
|
+
import { readFileSync, existsSync, renameSync } from "fs";
|
|
20
|
+
import path from "path";
|
|
21
|
+
import os from "os";
|
|
22
|
+
function resolveDataDir() {
|
|
23
|
+
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
24
|
+
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
25
|
+
const newDir = path.join(os.homedir(), ".exe-os");
|
|
26
|
+
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
27
|
+
if (!existsSync(newDir) && existsSync(legacyDir)) {
|
|
28
|
+
try {
|
|
29
|
+
renameSync(legacyDir, newDir);
|
|
30
|
+
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
31
|
+
`);
|
|
32
|
+
} catch {
|
|
33
|
+
return legacyDir;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return newDir;
|
|
37
|
+
}
|
|
38
|
+
var EXE_AI_DIR = resolveDataDir();
|
|
39
|
+
var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
40
|
+
var MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
41
|
+
var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
42
|
+
var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
43
|
+
var CURRENT_CONFIG_VERSION = 1;
|
|
44
|
+
var DEFAULT_CONFIG = {
|
|
45
|
+
config_version: CURRENT_CONFIG_VERSION,
|
|
46
|
+
dbPath: DB_PATH,
|
|
47
|
+
modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
|
|
48
|
+
embeddingDim: 1024,
|
|
49
|
+
batchSize: 20,
|
|
50
|
+
flushIntervalMs: 1e4,
|
|
51
|
+
autoIngestion: true,
|
|
52
|
+
autoRetrieval: true,
|
|
53
|
+
searchMode: "hybrid",
|
|
54
|
+
hookSearchMode: "hybrid",
|
|
55
|
+
fileGrepEnabled: true,
|
|
56
|
+
splashEffect: true,
|
|
57
|
+
consolidationEnabled: true,
|
|
58
|
+
consolidationIntervalMs: 6 * 60 * 60 * 1e3,
|
|
59
|
+
consolidationModel: "claude-haiku-4-5-20251001",
|
|
60
|
+
consolidationMaxCallsPerRun: 20,
|
|
61
|
+
selfQueryRouter: true,
|
|
62
|
+
selfQueryModel: "claude-haiku-4-5-20251001",
|
|
63
|
+
rerankerEnabled: true,
|
|
64
|
+
scalingRoadmap: {
|
|
65
|
+
rerankerAutoTrigger: {
|
|
66
|
+
enabled: true,
|
|
67
|
+
broadQueryMinCardinality: 5e4,
|
|
68
|
+
fetchTopK: 150,
|
|
69
|
+
returnTopK: 5
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
graphRagEnabled: true,
|
|
73
|
+
wikiEnabled: false,
|
|
74
|
+
wikiUrl: "",
|
|
75
|
+
wikiApiKey: "",
|
|
76
|
+
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
77
|
+
wikiWorkspaceMapping: {},
|
|
78
|
+
wikiAutoUpdate: true,
|
|
79
|
+
wikiAutoUpdateThreshold: 0.5,
|
|
80
|
+
wikiAutoUpdateCreateNew: true,
|
|
81
|
+
skillLearning: true,
|
|
82
|
+
skillThreshold: 3,
|
|
83
|
+
skillModel: "claude-haiku-4-5-20251001",
|
|
84
|
+
exeHeartbeat: {
|
|
85
|
+
enabled: true,
|
|
86
|
+
intervalSeconds: 60,
|
|
87
|
+
staleInProgressThresholdHours: 2
|
|
88
|
+
},
|
|
89
|
+
sessionLifecycle: {
|
|
90
|
+
idleKillEnabled: true,
|
|
91
|
+
idleKillTicksRequired: 3,
|
|
92
|
+
idleKillIntercomAckWindowMs: 1e4,
|
|
93
|
+
maxAutoInstances: 10
|
|
94
|
+
},
|
|
95
|
+
autoUpdate: {
|
|
96
|
+
checkOnBoot: true,
|
|
97
|
+
autoInstall: false,
|
|
98
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// src/lib/employees.ts
|
|
103
|
+
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
104
|
+
|
|
105
|
+
// src/lib/database.ts
|
|
9
106
|
var _resilientClient = null;
|
|
10
107
|
function getClient() {
|
|
11
108
|
if (!_resilientClient) {
|
|
@@ -26,23 +26,6 @@ var init_db_retry = __esm({
|
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
// src/lib/database.ts
|
|
30
|
-
import { createClient } from "@libsql/client";
|
|
31
|
-
function getClient() {
|
|
32
|
-
if (!_resilientClient) {
|
|
33
|
-
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
34
|
-
}
|
|
35
|
-
return _resilientClient;
|
|
36
|
-
}
|
|
37
|
-
var _resilientClient;
|
|
38
|
-
var init_database = __esm({
|
|
39
|
-
"src/lib/database.ts"() {
|
|
40
|
-
"use strict";
|
|
41
|
-
init_db_retry();
|
|
42
|
-
_resilientClient = null;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
29
|
// src/lib/config.ts
|
|
47
30
|
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
48
31
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
@@ -107,13 +90,7 @@ var init_config = __esm({
|
|
|
107
90
|
wikiUrl: "",
|
|
108
91
|
wikiApiKey: "",
|
|
109
92
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
110
|
-
wikiWorkspaceMapping: {
|
|
111
|
-
exe: "Executive",
|
|
112
|
-
yoshi: "Engineering",
|
|
113
|
-
mari: "Marketing",
|
|
114
|
-
tom: "Engineering",
|
|
115
|
-
sasha: "Production"
|
|
116
|
-
},
|
|
93
|
+
wikiWorkspaceMapping: {},
|
|
117
94
|
wikiAutoUpdate: true,
|
|
118
95
|
wikiAutoUpdateThreshold: 0.5,
|
|
119
96
|
wikiAutoUpdateCreateNew: true,
|
|
@@ -140,15 +117,48 @@ var init_config = __esm({
|
|
|
140
117
|
}
|
|
141
118
|
});
|
|
142
119
|
|
|
143
|
-
// src/lib/
|
|
144
|
-
import
|
|
120
|
+
// src/lib/employees.ts
|
|
121
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
122
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
123
|
+
import { execSync } from "child_process";
|
|
145
124
|
import path2 from "path";
|
|
146
125
|
import os2 from "os";
|
|
126
|
+
var EMPLOYEES_PATH;
|
|
127
|
+
var init_employees = __esm({
|
|
128
|
+
"src/lib/employees.ts"() {
|
|
129
|
+
"use strict";
|
|
130
|
+
init_config();
|
|
131
|
+
EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// src/lib/database.ts
|
|
136
|
+
import { createClient } from "@libsql/client";
|
|
137
|
+
function getClient() {
|
|
138
|
+
if (!_resilientClient) {
|
|
139
|
+
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
140
|
+
}
|
|
141
|
+
return _resilientClient;
|
|
142
|
+
}
|
|
143
|
+
var _resilientClient;
|
|
144
|
+
var init_database = __esm({
|
|
145
|
+
"src/lib/database.ts"() {
|
|
146
|
+
"use strict";
|
|
147
|
+
init_db_retry();
|
|
148
|
+
init_employees();
|
|
149
|
+
_resilientClient = null;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// src/lib/notifications.ts
|
|
154
|
+
import crypto from "crypto";
|
|
155
|
+
import path3 from "path";
|
|
156
|
+
import os3 from "os";
|
|
147
157
|
import {
|
|
148
|
-
readFileSync as
|
|
158
|
+
readFileSync as readFileSync3,
|
|
149
159
|
readdirSync,
|
|
150
|
-
unlinkSync,
|
|
151
|
-
existsSync as
|
|
160
|
+
unlinkSync as unlinkSync2,
|
|
161
|
+
existsSync as existsSync3,
|
|
152
162
|
rmdirSync
|
|
153
163
|
} from "fs";
|
|
154
164
|
var init_notifications = __esm({
|
|
@@ -214,24 +224,24 @@ var init_state_bus = __esm({
|
|
|
214
224
|
});
|
|
215
225
|
|
|
216
226
|
// src/lib/session-registry.ts
|
|
217
|
-
import
|
|
218
|
-
import
|
|
227
|
+
import path4 from "path";
|
|
228
|
+
import os4 from "os";
|
|
219
229
|
var REGISTRY_PATH;
|
|
220
230
|
var init_session_registry = __esm({
|
|
221
231
|
"src/lib/session-registry.ts"() {
|
|
222
232
|
"use strict";
|
|
223
|
-
REGISTRY_PATH =
|
|
233
|
+
REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
|
|
224
234
|
}
|
|
225
235
|
});
|
|
226
236
|
|
|
227
237
|
// src/lib/session-key.ts
|
|
228
|
-
import { execSync } from "child_process";
|
|
238
|
+
import { execSync as execSync2 } from "child_process";
|
|
229
239
|
function getSessionKey() {
|
|
230
240
|
if (_cached) return _cached;
|
|
231
241
|
let pid = process.ppid;
|
|
232
242
|
for (let i = 0; i < 10; i++) {
|
|
233
243
|
try {
|
|
234
|
-
const info =
|
|
244
|
+
const info = execSync2(`ps -p ${pid} -o ppid=,comm=`, {
|
|
235
245
|
encoding: "utf8",
|
|
236
246
|
timeout: 2e3
|
|
237
247
|
}).trim();
|
|
@@ -367,7 +377,7 @@ var init_transport = __esm({
|
|
|
367
377
|
});
|
|
368
378
|
|
|
369
379
|
// src/lib/cc-agent-support.ts
|
|
370
|
-
import { execSync as
|
|
380
|
+
import { execSync as execSync3 } from "child_process";
|
|
371
381
|
var init_cc_agent_support = __esm({
|
|
372
382
|
"src/lib/cc-agent-support.ts"() {
|
|
373
383
|
"use strict";
|
|
@@ -396,31 +406,16 @@ var init_provider_table = __esm({
|
|
|
396
406
|
});
|
|
397
407
|
|
|
398
408
|
// src/lib/intercom-queue.ts
|
|
399
|
-
import { readFileSync as
|
|
400
|
-
import
|
|
401
|
-
import
|
|
409
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync as renameSync3, existsSync as existsSync4, mkdirSync } from "fs";
|
|
410
|
+
import path5 from "path";
|
|
411
|
+
import os5 from "os";
|
|
402
412
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
403
413
|
var init_intercom_queue = __esm({
|
|
404
414
|
"src/lib/intercom-queue.ts"() {
|
|
405
415
|
"use strict";
|
|
406
|
-
QUEUE_PATH =
|
|
416
|
+
QUEUE_PATH = path5.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
407
417
|
TTL_MS = 60 * 60 * 1e3;
|
|
408
|
-
INTERCOM_LOG =
|
|
409
|
-
}
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
// src/lib/employees.ts
|
|
413
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
414
|
-
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
415
|
-
import { execSync as execSync3 } from "child_process";
|
|
416
|
-
import path5 from "path";
|
|
417
|
-
import os5 from "os";
|
|
418
|
-
var EMPLOYEES_PATH;
|
|
419
|
-
var init_employees = __esm({
|
|
420
|
-
"src/lib/employees.ts"() {
|
|
421
|
-
"use strict";
|
|
422
|
-
init_config();
|
|
423
|
-
EMPLOYEES_PATH = path5.join(EXE_AI_DIR, "exe-employees.json");
|
|
418
|
+
INTERCOM_LOG = path5.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
424
419
|
}
|
|
425
420
|
});
|
|
426
421
|
|
|
@@ -464,8 +459,10 @@ function getMySession() {
|
|
|
464
459
|
return getTransport().getMySession();
|
|
465
460
|
}
|
|
466
461
|
function extractRootExe(name) {
|
|
467
|
-
|
|
468
|
-
|
|
462
|
+
if (!name) return null;
|
|
463
|
+
if (!name.includes("-")) return name;
|
|
464
|
+
const parts = name.split("-").filter(Boolean);
|
|
465
|
+
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
469
466
|
}
|
|
470
467
|
function getParentExe(sessionKey) {
|
|
471
468
|
try {
|
|
@@ -500,6 +497,7 @@ var init_tmux_routing = __esm({
|
|
|
500
497
|
init_provider_table();
|
|
501
498
|
init_intercom_queue();
|
|
502
499
|
init_plan_limits();
|
|
500
|
+
init_employees();
|
|
503
501
|
SPAWN_LOCK_DIR = path8.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
504
502
|
SESSION_CACHE = path8.join(os6.homedir(), ".exe-os", "session-cache");
|
|
505
503
|
INTERCOM_LOG2 = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
@@ -646,6 +644,7 @@ var init_tasks = __esm({
|
|
|
646
644
|
init_config();
|
|
647
645
|
init_notifications();
|
|
648
646
|
init_state_bus();
|
|
647
|
+
init_employees();
|
|
649
648
|
init_tasks_crud();
|
|
650
649
|
init_tasks_review();
|
|
651
650
|
init_tasks_crud();
|