@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
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/adapters/claude/hooks/exe-heartbeat-hook.ts
|
|
2
2
|
import { execFileSync } from "child_process";
|
|
3
|
-
import
|
|
3
|
+
import path4 from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
|
|
6
6
|
// src/adapters/claude/active-agent.ts
|
|
7
|
-
import { readFileSync as
|
|
8
|
-
import { execSync as
|
|
9
|
-
import
|
|
7
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, unlinkSync as unlinkSync2, readdirSync } from "fs";
|
|
8
|
+
import { execSync as execSync3 } from "child_process";
|
|
9
|
+
import path3 from "path";
|
|
10
10
|
|
|
11
11
|
// src/lib/config.ts
|
|
12
12
|
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
@@ -68,13 +68,7 @@ var DEFAULT_CONFIG = {
|
|
|
68
68
|
wikiUrl: "",
|
|
69
69
|
wikiApiKey: "",
|
|
70
70
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
71
|
-
wikiWorkspaceMapping: {
|
|
72
|
-
exe: "Executive",
|
|
73
|
-
yoshi: "Engineering",
|
|
74
|
-
mari: "Marketing",
|
|
75
|
-
tom: "Engineering",
|
|
76
|
-
sasha: "Production"
|
|
77
|
-
},
|
|
71
|
+
wikiWorkspaceMapping: {},
|
|
78
72
|
wikiAutoUpdate: true,
|
|
79
73
|
wikiAutoUpdateThreshold: 0.5,
|
|
80
74
|
wikiAutoUpdateCreateNew: true,
|
|
@@ -128,23 +122,105 @@ function getSessionKey() {
|
|
|
128
122
|
return _cached;
|
|
129
123
|
}
|
|
130
124
|
|
|
125
|
+
// src/lib/employees.ts
|
|
126
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
127
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
128
|
+
import { execSync as execSync2 } from "child_process";
|
|
129
|
+
import path2 from "path";
|
|
130
|
+
import os2 from "os";
|
|
131
|
+
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
132
|
+
var DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
133
|
+
var COORDINATOR_ROLE = "COO";
|
|
134
|
+
function normalizeRole(role) {
|
|
135
|
+
return (role ?? "").trim().toLowerCase();
|
|
136
|
+
}
|
|
137
|
+
function isCoordinatorRole(role) {
|
|
138
|
+
return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
|
|
139
|
+
}
|
|
140
|
+
function getCoordinatorEmployee(employees) {
|
|
141
|
+
return employees.find((e) => isCoordinatorRole(e.role));
|
|
142
|
+
}
|
|
143
|
+
function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
144
|
+
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
145
|
+
}
|
|
146
|
+
function isCoordinatorName(agentName, employees = loadEmployeesSync()) {
|
|
147
|
+
if (!agentName) return false;
|
|
148
|
+
return agentName.toLowerCase() === getCoordinatorName(employees).toLowerCase();
|
|
149
|
+
}
|
|
150
|
+
function canCoordinate(agentName, agentRole, employees = loadEmployeesSync()) {
|
|
151
|
+
return agentName === "default" || isCoordinatorRole(agentRole) || isCoordinatorName(agentName, employees);
|
|
152
|
+
}
|
|
153
|
+
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
154
|
+
if (!existsSync2(employeesPath)) return [];
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
157
|
+
} catch {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function getEmployee(employees, name) {
|
|
162
|
+
return employees.find((e) => e.name.toLowerCase() === name.toLowerCase());
|
|
163
|
+
}
|
|
164
|
+
|
|
131
165
|
// src/adapters/claude/active-agent.ts
|
|
132
|
-
var CACHE_DIR =
|
|
166
|
+
var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
|
|
133
167
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
168
|
+
function isNameWithOptionalInstance(candidate, baseName) {
|
|
169
|
+
if (candidate === baseName) return true;
|
|
170
|
+
if (!candidate.startsWith(baseName)) return false;
|
|
171
|
+
return /^\d+$/.test(candidate.slice(baseName.length));
|
|
172
|
+
}
|
|
173
|
+
function resolveEmployeeFromSessionPrefix(prefix, employees) {
|
|
174
|
+
const sorted = [...employees].sort((a, b) => b.name.length - a.name.length);
|
|
175
|
+
for (const employee of sorted) {
|
|
176
|
+
if (isNameWithOptionalInstance(prefix, employee.name)) {
|
|
177
|
+
return { agentId: employee.name, agentRole: employee.role };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
function resolveActiveAgentFromTmuxSession(sessionName) {
|
|
183
|
+
const employees = loadEmployeesSync();
|
|
184
|
+
const coordinator = getCoordinatorEmployee(employees);
|
|
185
|
+
const coordinatorName = coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
186
|
+
if (isNameWithOptionalInstance(sessionName, coordinatorName)) {
|
|
187
|
+
return {
|
|
188
|
+
agentId: coordinatorName,
|
|
189
|
+
agentRole: coordinator?.role ?? "COO"
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (isNameWithOptionalInstance(sessionName, DEFAULT_COORDINATOR_TEMPLATE_NAME)) {
|
|
193
|
+
return {
|
|
194
|
+
agentId: coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME,
|
|
195
|
+
agentRole: coordinator?.role ?? "COO"
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (sessionName.includes("-")) {
|
|
199
|
+
const prefix = sessionName.split("-")[0] ?? "";
|
|
200
|
+
const employee = resolveEmployeeFromSessionPrefix(prefix, employees);
|
|
201
|
+
if (employee) return employee;
|
|
202
|
+
const legacy = prefix.match(/^([a-zA-Z]+)\d*$/);
|
|
203
|
+
if (legacy?.[1] && legacy[1] !== DEFAULT_COORDINATOR_TEMPLATE_NAME) {
|
|
204
|
+
const emp = getEmployee(employees, legacy[1]);
|
|
205
|
+
return { agentId: emp?.name ?? legacy[1], agentRole: emp?.role ?? "employee" };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
134
210
|
function getMarkerPath() {
|
|
135
|
-
return
|
|
211
|
+
return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
|
|
136
212
|
}
|
|
137
213
|
function getActiveAgent() {
|
|
138
214
|
try {
|
|
139
215
|
const markerPath = getMarkerPath();
|
|
140
|
-
const raw =
|
|
216
|
+
const raw = readFileSync3(markerPath, "utf8");
|
|
141
217
|
const data = JSON.parse(raw);
|
|
142
218
|
if (data.agentId) {
|
|
143
219
|
if (data.startedAt) {
|
|
144
220
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
145
221
|
if (age > STALE_MS) {
|
|
146
222
|
try {
|
|
147
|
-
|
|
223
|
+
unlinkSync2(markerPath);
|
|
148
224
|
} catch {
|
|
149
225
|
}
|
|
150
226
|
} else {
|
|
@@ -163,17 +239,12 @@ function getActiveAgent() {
|
|
|
163
239
|
} catch {
|
|
164
240
|
}
|
|
165
241
|
try {
|
|
166
|
-
const sessionName =
|
|
242
|
+
const sessionName = execSync3(
|
|
167
243
|
"tmux display-message -p '#{session_name}' 2>/dev/null",
|
|
168
244
|
{ encoding: "utf8", timeout: 2e3 }
|
|
169
245
|
).trim();
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
return { agentId: empMatch[1], agentRole: "employee" };
|
|
173
|
-
}
|
|
174
|
-
if (/^exe\d+$/.test(sessionName)) {
|
|
175
|
-
return { agentId: "exe", agentRole: "COO" };
|
|
176
|
-
}
|
|
246
|
+
const resolved = resolveActiveAgentFromTmuxSession(sessionName);
|
|
247
|
+
if (resolved) return resolved;
|
|
177
248
|
} catch {
|
|
178
249
|
}
|
|
179
250
|
return {
|
|
@@ -185,7 +256,6 @@ function getActiveAgent() {
|
|
|
185
256
|
// src/adapters/claude/hooks/exe-heartbeat-hook.ts
|
|
186
257
|
var HOOK_TIMEOUT_MS = 5e3;
|
|
187
258
|
var CLI_TIMEOUT_MS = 4e3;
|
|
188
|
-
var EXE_AGENT_ID = "exe";
|
|
189
259
|
var watchdog = setTimeout(() => process.exit(0), HOOK_TIMEOUT_MS);
|
|
190
260
|
watchdog.unref();
|
|
191
261
|
var MAX_INPUT_SIZE = 1e6;
|
|
@@ -198,12 +268,12 @@ process.stdin.on("end", () => {
|
|
|
198
268
|
void input;
|
|
199
269
|
try {
|
|
200
270
|
const agent = getActiveAgent();
|
|
201
|
-
if (agent.agentId
|
|
271
|
+
if (!canCoordinate(agent.agentId, agent.agentRole)) {
|
|
202
272
|
cleanExit();
|
|
203
273
|
return;
|
|
204
274
|
}
|
|
205
|
-
const cliPath =
|
|
206
|
-
|
|
275
|
+
const cliPath = path4.resolve(
|
|
276
|
+
path4.dirname(fileURLToPath(import.meta.url)),
|
|
207
277
|
"..",
|
|
208
278
|
"bin",
|
|
209
279
|
"exe-heartbeat.js"
|