@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.
Files changed (110) hide show
  1. package/dist/bin/backfill-conversations.js +359 -267
  2. package/dist/bin/backfill-responses.js +357 -265
  3. package/dist/bin/backfill-vectors.js +339 -264
  4. package/dist/bin/cleanup-stale-review-tasks.js +315 -256
  5. package/dist/bin/cli.js +494 -240
  6. package/dist/bin/exe-agent.js +141 -46
  7. package/dist/bin/exe-assign.js +151 -63
  8. package/dist/bin/exe-boot.js +294 -115
  9. package/dist/bin/exe-call.js +76 -51
  10. package/dist/bin/exe-cloud.js +58 -45
  11. package/dist/bin/exe-dispatch.js +434 -277
  12. package/dist/bin/exe-doctor.js +317 -246
  13. package/dist/bin/exe-export-behaviors.js +328 -248
  14. package/dist/bin/exe-forget.js +314 -231
  15. package/dist/bin/exe-gateway.js +2676 -1402
  16. package/dist/bin/exe-heartbeat.js +329 -264
  17. package/dist/bin/exe-kill.js +324 -244
  18. package/dist/bin/exe-launch-agent.js +574 -463
  19. package/dist/bin/exe-link.js +1055 -95
  20. package/dist/bin/exe-new-employee.js +49 -54
  21. package/dist/bin/exe-pending-messages.js +310 -253
  22. package/dist/bin/exe-pending-notifications.js +299 -228
  23. package/dist/bin/exe-pending-reviews.js +314 -245
  24. package/dist/bin/exe-rename.js +259 -195
  25. package/dist/bin/exe-review.js +140 -64
  26. package/dist/bin/exe-search.js +543 -356
  27. package/dist/bin/exe-session-cleanup.js +463 -382
  28. package/dist/bin/exe-settings.js +129 -99
  29. package/dist/bin/exe-start.sh +6 -6
  30. package/dist/bin/exe-status.js +95 -36
  31. package/dist/bin/exe-team.js +116 -51
  32. package/dist/bin/git-sweep.js +482 -307
  33. package/dist/bin/graph-backfill.js +357 -245
  34. package/dist/bin/graph-export.js +324 -244
  35. package/dist/bin/install.js +33 -10
  36. package/dist/bin/scan-tasks.js +481 -307
  37. package/dist/bin/setup.js +1147 -140
  38. package/dist/bin/shard-migrate.js +321 -241
  39. package/dist/bin/update.js +1 -7
  40. package/dist/bin/wiki-sync.js +318 -238
  41. package/dist/gateway/index.js +2656 -1383
  42. package/dist/hooks/bug-report-worker.js +641 -472
  43. package/dist/hooks/commit-complete.js +482 -307
  44. package/dist/hooks/error-recall.js +363 -135
  45. package/dist/hooks/exe-heartbeat-hook.js +97 -27
  46. package/dist/hooks/ingest-worker.js +584 -397
  47. package/dist/hooks/ingest.js +123 -58
  48. package/dist/hooks/instructions-loaded.js +212 -82
  49. package/dist/hooks/notification.js +200 -70
  50. package/dist/hooks/post-compact.js +199 -81
  51. package/dist/hooks/pre-compact.js +352 -140
  52. package/dist/hooks/pre-tool-use.js +416 -278
  53. package/dist/hooks/prompt-ingest-worker.js +376 -299
  54. package/dist/hooks/prompt-submit.js +414 -188
  55. package/dist/hooks/response-ingest-worker.js +408 -338
  56. package/dist/hooks/session-end.js +209 -83
  57. package/dist/hooks/session-start.js +382 -158
  58. package/dist/hooks/stop.js +209 -83
  59. package/dist/hooks/subagent-stop.js +209 -85
  60. package/dist/hooks/summary-worker.js +606 -510
  61. package/dist/index.js +2133 -855
  62. package/dist/lib/cloud-sync.js +1175 -184
  63. package/dist/lib/config.js +1 -9
  64. package/dist/lib/consolidation.js +71 -34
  65. package/dist/lib/database.js +166 -14
  66. package/dist/lib/device-registry.js +189 -117
  67. package/dist/lib/embedder.js +6 -10
  68. package/dist/lib/employee-templates.js +134 -39
  69. package/dist/lib/employees.js +30 -7
  70. package/dist/lib/exe-daemon-client.js +5 -7
  71. package/dist/lib/exe-daemon.js +514 -152
  72. package/dist/lib/hybrid-search.js +543 -356
  73. package/dist/lib/identity-templates.js +15 -15
  74. package/dist/lib/identity.js +19 -15
  75. package/dist/lib/license.js +1 -7
  76. package/dist/lib/messaging.js +157 -135
  77. package/dist/lib/reminders.js +97 -0
  78. package/dist/lib/schedules.js +302 -231
  79. package/dist/lib/skill-learning.js +33 -27
  80. package/dist/lib/status-brief.js +11 -14
  81. package/dist/lib/store.js +326 -237
  82. package/dist/lib/task-router.js +105 -1
  83. package/dist/lib/tasks.js +233 -116
  84. package/dist/lib/tmux-routing.js +173 -56
  85. package/dist/lib/ws-client.js +13 -3
  86. package/dist/mcp/server.js +2009 -1015
  87. package/dist/mcp/tools/complete-reminder.js +97 -0
  88. package/dist/mcp/tools/create-reminder.js +97 -0
  89. package/dist/mcp/tools/create-task.js +426 -262
  90. package/dist/mcp/tools/deactivate-behavior.js +119 -44
  91. package/dist/mcp/tools/list-reminders.js +97 -0
  92. package/dist/mcp/tools/list-tasks.js +56 -57
  93. package/dist/mcp/tools/send-message.js +206 -143
  94. package/dist/mcp/tools/update-task.js +259 -85
  95. package/dist/runtime/index.js +495 -316
  96. package/dist/tui/App.js +1128 -919
  97. package/package.json +2 -10
  98. package/src/commands/exe/afk.md +8 -8
  99. package/src/commands/exe/assign.md +1 -1
  100. package/src/commands/exe/build-adv.md +1 -1
  101. package/src/commands/exe/call.md +10 -10
  102. package/src/commands/exe/employee-heartbeat.md +9 -6
  103. package/src/commands/exe/heartbeat.md +5 -5
  104. package/src/commands/exe/intercom.md +26 -15
  105. package/src/commands/exe/launch.md +2 -2
  106. package/src/commands/exe/new-employee.md +1 -1
  107. package/src/commands/exe/review.md +2 -2
  108. package/src/commands/exe/schedule.md +1 -1
  109. package/src/commands/exe/sessions.md +2 -2
  110. 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 path3 from "path";
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 readFileSync2, writeFileSync, mkdirSync, unlinkSync, readdirSync } from "fs";
8
- import { execSync as execSync2 } from "child_process";
9
- import path2 from "path";
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 = path2.join(EXE_AI_DIR, "session-cache");
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 path2.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
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 = readFileSync2(markerPath, "utf8");
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
- unlinkSync(markerPath);
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 = execSync2(
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 empMatch = sessionName.match(/^([a-zA-Z]+)\d*-exe\d+$/);
171
- if (empMatch && empMatch[1] !== "exe") {
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 !== EXE_AGENT_ID) {
271
+ if (!canCoordinate(agent.agentId, agent.agentRole)) {
202
272
  cleanExit();
203
273
  return;
204
274
  }
205
- const cliPath = path3.resolve(
206
- path3.dirname(fileURLToPath(import.meta.url)),
275
+ const cliPath = path4.resolve(
276
+ path4.dirname(fileURLToPath(import.meta.url)),
207
277
  "..",
208
278
  "bin",
209
279
  "exe-heartbeat.js"