@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
|
@@ -154,7 +154,7 @@ function baseAgentName(name, employees) {
|
|
|
154
154
|
if (getEmployee(roster, base)) return base;
|
|
155
155
|
return name;
|
|
156
156
|
}
|
|
157
|
-
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
|
|
157
|
+
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, IDENTITY_DIR;
|
|
158
158
|
var init_employees = __esm({
|
|
159
159
|
"src/lib/employees.ts"() {
|
|
160
160
|
"use strict";
|
|
@@ -162,15 +162,40 @@ var init_employees = __esm({
|
|
|
162
162
|
EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
163
163
|
DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
164
164
|
COORDINATOR_ROLE = "COO";
|
|
165
|
+
IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// src/lib/database-adapter.ts
|
|
170
|
+
import os3 from "os";
|
|
171
|
+
import path3 from "path";
|
|
172
|
+
import { createRequire } from "module";
|
|
173
|
+
import { pathToFileURL } from "url";
|
|
174
|
+
var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
|
|
175
|
+
var init_database_adapter = __esm({
|
|
176
|
+
"src/lib/database-adapter.ts"() {
|
|
177
|
+
"use strict";
|
|
178
|
+
BOOLEAN_COLUMNS_BY_TABLE = {
|
|
179
|
+
memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
|
|
180
|
+
behaviors: /* @__PURE__ */ new Set(["active"]),
|
|
181
|
+
notifications: /* @__PURE__ */ new Set(["read"]),
|
|
182
|
+
users: /* @__PURE__ */ new Set(["has_personal_memory"])
|
|
183
|
+
};
|
|
184
|
+
BOOLEAN_COLUMN_NAMES = new Set(
|
|
185
|
+
Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
|
|
186
|
+
);
|
|
165
187
|
}
|
|
166
188
|
});
|
|
167
189
|
|
|
168
190
|
// src/lib/database.ts
|
|
169
191
|
import { createClient } from "@libsql/client";
|
|
170
192
|
function getClient() {
|
|
171
|
-
if (!
|
|
193
|
+
if (!_adapterClient) {
|
|
172
194
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
173
195
|
}
|
|
196
|
+
if (process.env.DATABASE_URL) {
|
|
197
|
+
return _adapterClient;
|
|
198
|
+
}
|
|
174
199
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
175
200
|
return _resilientClient;
|
|
176
201
|
}
|
|
@@ -179,25 +204,27 @@ function getClient() {
|
|
|
179
204
|
}
|
|
180
205
|
return _resilientClient;
|
|
181
206
|
}
|
|
182
|
-
var _resilientClient, _daemonClient;
|
|
207
|
+
var _resilientClient, _daemonClient, _adapterClient;
|
|
183
208
|
var init_database = __esm({
|
|
184
209
|
"src/lib/database.ts"() {
|
|
185
210
|
"use strict";
|
|
186
211
|
init_db_retry();
|
|
187
212
|
init_employees();
|
|
213
|
+
init_database_adapter();
|
|
188
214
|
_resilientClient = null;
|
|
189
215
|
_daemonClient = null;
|
|
216
|
+
_adapterClient = null;
|
|
190
217
|
}
|
|
191
218
|
});
|
|
192
219
|
|
|
193
220
|
// src/lib/session-registry.ts
|
|
194
|
-
import
|
|
195
|
-
import
|
|
221
|
+
import path4 from "path";
|
|
222
|
+
import os4 from "os";
|
|
196
223
|
var REGISTRY_PATH;
|
|
197
224
|
var init_session_registry = __esm({
|
|
198
225
|
"src/lib/session-registry.ts"() {
|
|
199
226
|
"use strict";
|
|
200
|
-
REGISTRY_PATH =
|
|
227
|
+
REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
|
|
201
228
|
}
|
|
202
229
|
});
|
|
203
230
|
|
|
@@ -434,7 +461,7 @@ var init_runtime_table = __esm({
|
|
|
434
461
|
|
|
435
462
|
// src/lib/agent-config.ts
|
|
436
463
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
|
|
437
|
-
import
|
|
464
|
+
import path5 from "path";
|
|
438
465
|
function loadAgentConfig() {
|
|
439
466
|
if (!existsSync3(AGENT_CONFIG_PATH)) return {};
|
|
440
467
|
try {
|
|
@@ -457,7 +484,7 @@ var init_agent_config = __esm({
|
|
|
457
484
|
"use strict";
|
|
458
485
|
init_config();
|
|
459
486
|
init_runtime_table();
|
|
460
|
-
AGENT_CONFIG_PATH =
|
|
487
|
+
AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
|
|
461
488
|
DEFAULT_MODELS = {
|
|
462
489
|
claude: "claude-opus-4",
|
|
463
490
|
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
@@ -468,10 +495,10 @@ var init_agent_config = __esm({
|
|
|
468
495
|
|
|
469
496
|
// src/lib/intercom-queue.ts
|
|
470
497
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
|
|
471
|
-
import
|
|
472
|
-
import
|
|
498
|
+
import path6 from "path";
|
|
499
|
+
import os5 from "os";
|
|
473
500
|
function ensureDir() {
|
|
474
|
-
const dir =
|
|
501
|
+
const dir = path6.dirname(QUEUE_PATH);
|
|
475
502
|
if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
|
|
476
503
|
}
|
|
477
504
|
function readQueue() {
|
|
@@ -509,31 +536,31 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
509
536
|
var init_intercom_queue = __esm({
|
|
510
537
|
"src/lib/intercom-queue.ts"() {
|
|
511
538
|
"use strict";
|
|
512
|
-
QUEUE_PATH =
|
|
539
|
+
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
513
540
|
TTL_MS = 60 * 60 * 1e3;
|
|
514
|
-
INTERCOM_LOG =
|
|
541
|
+
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
515
542
|
}
|
|
516
543
|
});
|
|
517
544
|
|
|
518
545
|
// src/lib/license.ts
|
|
519
546
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
520
547
|
import { randomUUID } from "crypto";
|
|
521
|
-
import
|
|
548
|
+
import path7 from "path";
|
|
522
549
|
import { jwtVerify, importSPKI } from "jose";
|
|
523
550
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
524
551
|
var init_license = __esm({
|
|
525
552
|
"src/lib/license.ts"() {
|
|
526
553
|
"use strict";
|
|
527
554
|
init_config();
|
|
528
|
-
LICENSE_PATH =
|
|
529
|
-
CACHE_PATH =
|
|
530
|
-
DEVICE_ID_PATH =
|
|
555
|
+
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
556
|
+
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
557
|
+
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
531
558
|
}
|
|
532
559
|
});
|
|
533
560
|
|
|
534
561
|
// src/lib/plan-limits.ts
|
|
535
562
|
import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
|
|
536
|
-
import
|
|
563
|
+
import path8 from "path";
|
|
537
564
|
var CACHE_PATH2;
|
|
538
565
|
var init_plan_limits = __esm({
|
|
539
566
|
"src/lib/plan-limits.ts"() {
|
|
@@ -542,15 +569,15 @@ var init_plan_limits = __esm({
|
|
|
542
569
|
init_employees();
|
|
543
570
|
init_license();
|
|
544
571
|
init_config();
|
|
545
|
-
CACHE_PATH2 =
|
|
572
|
+
CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
|
|
546
573
|
}
|
|
547
574
|
});
|
|
548
575
|
|
|
549
576
|
// src/lib/tmux-routing.ts
|
|
550
577
|
import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
|
|
551
578
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync, readdirSync } from "fs";
|
|
552
|
-
import
|
|
553
|
-
import
|
|
579
|
+
import path9 from "path";
|
|
580
|
+
import os6 from "os";
|
|
554
581
|
import { fileURLToPath } from "url";
|
|
555
582
|
function getMySession() {
|
|
556
583
|
return getTransport().getMySession();
|
|
@@ -590,7 +617,7 @@ function extractRootExe(name) {
|
|
|
590
617
|
}
|
|
591
618
|
function getParentExe(sessionKey) {
|
|
592
619
|
try {
|
|
593
|
-
const data = JSON.parse(readFileSync7(
|
|
620
|
+
const data = JSON.parse(readFileSync7(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
594
621
|
return data.parentExe || null;
|
|
595
622
|
} catch {
|
|
596
623
|
return null;
|
|
@@ -735,7 +762,7 @@ function sendIntercom(targetSession) {
|
|
|
735
762
|
try {
|
|
736
763
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
737
764
|
const agent = baseAgentName(rawAgent);
|
|
738
|
-
const markerPath =
|
|
765
|
+
const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
739
766
|
if (existsSync7(markerPath)) {
|
|
740
767
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
|
|
741
768
|
return "debounced";
|
|
@@ -745,7 +772,7 @@ function sendIntercom(targetSession) {
|
|
|
745
772
|
try {
|
|
746
773
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
747
774
|
const agent = baseAgentName(rawAgent);
|
|
748
|
-
const taskDir =
|
|
775
|
+
const taskDir = path9.join(process.cwd(), "exe", agent);
|
|
749
776
|
if (existsSync7(taskDir)) {
|
|
750
777
|
const files = readdirSync(taskDir).filter(
|
|
751
778
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
@@ -799,13 +826,13 @@ var init_tmux_routing = __esm({
|
|
|
799
826
|
init_intercom_queue();
|
|
800
827
|
init_plan_limits();
|
|
801
828
|
init_employees();
|
|
802
|
-
SPAWN_LOCK_DIR =
|
|
803
|
-
SESSION_CACHE =
|
|
829
|
+
SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
830
|
+
SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
|
|
804
831
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
805
832
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
806
833
|
CODEX_DEBOUNCE_MS = 12e4;
|
|
807
|
-
INTERCOM_LOG2 =
|
|
808
|
-
DEBOUNCE_FILE =
|
|
834
|
+
INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
835
|
+
DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
|
|
809
836
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
810
837
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
|
|
811
838
|
}
|
|
@@ -962,8 +989,8 @@ init_session_key();
|
|
|
962
989
|
init_employees();
|
|
963
990
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, readdirSync as readdirSync2 } from "fs";
|
|
964
991
|
import { execSync as execSync5 } from "child_process";
|
|
965
|
-
import
|
|
966
|
-
var CACHE_DIR =
|
|
992
|
+
import path10 from "path";
|
|
993
|
+
var CACHE_DIR = path10.join(EXE_AI_DIR, "session-cache");
|
|
967
994
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
968
995
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
969
996
|
if (candidate === baseName) return true;
|
|
@@ -1008,7 +1035,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
|
|
|
1008
1035
|
return null;
|
|
1009
1036
|
}
|
|
1010
1037
|
function getMarkerPath() {
|
|
1011
|
-
return
|
|
1038
|
+
return path10.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
|
|
1012
1039
|
}
|
|
1013
1040
|
function getActiveAgent() {
|
|
1014
1041
|
try {
|
|
@@ -259,7 +259,7 @@ function baseAgentName(name, employees) {
|
|
|
259
259
|
if (getEmployee(roster, base)) return base;
|
|
260
260
|
return name;
|
|
261
261
|
}
|
|
262
|
-
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
|
|
262
|
+
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, IDENTITY_DIR;
|
|
263
263
|
var init_employees = __esm({
|
|
264
264
|
"src/lib/employees.ts"() {
|
|
265
265
|
"use strict";
|
|
@@ -267,15 +267,40 @@ var init_employees = __esm({
|
|
|
267
267
|
EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
268
268
|
DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
269
269
|
COORDINATOR_ROLE = "COO";
|
|
270
|
+
IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// src/lib/database-adapter.ts
|
|
275
|
+
import os3 from "os";
|
|
276
|
+
import path3 from "path";
|
|
277
|
+
import { createRequire } from "module";
|
|
278
|
+
import { pathToFileURL } from "url";
|
|
279
|
+
var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
|
|
280
|
+
var init_database_adapter = __esm({
|
|
281
|
+
"src/lib/database-adapter.ts"() {
|
|
282
|
+
"use strict";
|
|
283
|
+
BOOLEAN_COLUMNS_BY_TABLE = {
|
|
284
|
+
memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
|
|
285
|
+
behaviors: /* @__PURE__ */ new Set(["active"]),
|
|
286
|
+
notifications: /* @__PURE__ */ new Set(["read"]),
|
|
287
|
+
users: /* @__PURE__ */ new Set(["has_personal_memory"])
|
|
288
|
+
};
|
|
289
|
+
BOOLEAN_COLUMN_NAMES = new Set(
|
|
290
|
+
Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
|
|
291
|
+
);
|
|
270
292
|
}
|
|
271
293
|
});
|
|
272
294
|
|
|
273
295
|
// src/lib/database.ts
|
|
274
296
|
import { createClient } from "@libsql/client";
|
|
275
297
|
function getClient() {
|
|
276
|
-
if (!
|
|
298
|
+
if (!_adapterClient) {
|
|
277
299
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
278
300
|
}
|
|
301
|
+
if (process.env.DATABASE_URL) {
|
|
302
|
+
return _adapterClient;
|
|
303
|
+
}
|
|
279
304
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
280
305
|
return _resilientClient;
|
|
281
306
|
}
|
|
@@ -284,21 +309,23 @@ function getClient() {
|
|
|
284
309
|
}
|
|
285
310
|
return _resilientClient;
|
|
286
311
|
}
|
|
287
|
-
var _resilientClient, _daemonClient;
|
|
312
|
+
var _resilientClient, _daemonClient, _adapterClient;
|
|
288
313
|
var init_database = __esm({
|
|
289
314
|
"src/lib/database.ts"() {
|
|
290
315
|
"use strict";
|
|
291
316
|
init_db_retry();
|
|
292
317
|
init_employees();
|
|
318
|
+
init_database_adapter();
|
|
293
319
|
_resilientClient = null;
|
|
294
320
|
_daemonClient = null;
|
|
321
|
+
_adapterClient = null;
|
|
295
322
|
}
|
|
296
323
|
});
|
|
297
324
|
|
|
298
325
|
// src/lib/notifications.ts
|
|
299
326
|
import crypto from "crypto";
|
|
300
|
-
import
|
|
301
|
-
import
|
|
327
|
+
import path4 from "path";
|
|
328
|
+
import os4 from "os";
|
|
302
329
|
import {
|
|
303
330
|
readFileSync as readFileSync3,
|
|
304
331
|
readdirSync,
|
|
@@ -403,13 +430,13 @@ var init_state_bus = __esm({
|
|
|
403
430
|
});
|
|
404
431
|
|
|
405
432
|
// src/lib/session-registry.ts
|
|
406
|
-
import
|
|
407
|
-
import
|
|
433
|
+
import path5 from "path";
|
|
434
|
+
import os5 from "os";
|
|
408
435
|
var REGISTRY_PATH;
|
|
409
436
|
var init_session_registry = __esm({
|
|
410
437
|
"src/lib/session-registry.ts"() {
|
|
411
438
|
"use strict";
|
|
412
|
-
REGISTRY_PATH =
|
|
439
|
+
REGISTRY_PATH = path5.join(os5.homedir(), ".exe-os", "session-registry.json");
|
|
413
440
|
}
|
|
414
441
|
});
|
|
415
442
|
|
|
@@ -646,7 +673,7 @@ var init_runtime_table = __esm({
|
|
|
646
673
|
|
|
647
674
|
// src/lib/agent-config.ts
|
|
648
675
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync } from "fs";
|
|
649
|
-
import
|
|
676
|
+
import path6 from "path";
|
|
650
677
|
function loadAgentConfig() {
|
|
651
678
|
if (!existsSync4(AGENT_CONFIG_PATH)) return {};
|
|
652
679
|
try {
|
|
@@ -669,7 +696,7 @@ var init_agent_config = __esm({
|
|
|
669
696
|
"use strict";
|
|
670
697
|
init_config();
|
|
671
698
|
init_runtime_table();
|
|
672
|
-
AGENT_CONFIG_PATH =
|
|
699
|
+
AGENT_CONFIG_PATH = path6.join(EXE_AI_DIR, "agent-config.json");
|
|
673
700
|
DEFAULT_MODELS = {
|
|
674
701
|
claude: "claude-opus-4",
|
|
675
702
|
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
@@ -688,10 +715,10 @@ __export(intercom_queue_exports, {
|
|
|
688
715
|
readQueue: () => readQueue
|
|
689
716
|
});
|
|
690
717
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
|
|
691
|
-
import
|
|
692
|
-
import
|
|
718
|
+
import path7 from "path";
|
|
719
|
+
import os6 from "os";
|
|
693
720
|
function ensureDir() {
|
|
694
|
-
const dir =
|
|
721
|
+
const dir = path7.dirname(QUEUE_PATH);
|
|
695
722
|
if (!existsSync5(dir)) mkdirSync2(dir, { recursive: true });
|
|
696
723
|
}
|
|
697
724
|
function readQueue() {
|
|
@@ -797,32 +824,32 @@ var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
|
797
824
|
var init_intercom_queue = __esm({
|
|
798
825
|
"src/lib/intercom-queue.ts"() {
|
|
799
826
|
"use strict";
|
|
800
|
-
QUEUE_PATH =
|
|
827
|
+
QUEUE_PATH = path7.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
801
828
|
MAX_RETRIES = 5;
|
|
802
829
|
TTL_MS = 60 * 60 * 1e3;
|
|
803
|
-
INTERCOM_LOG =
|
|
830
|
+
INTERCOM_LOG = path7.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
804
831
|
}
|
|
805
832
|
});
|
|
806
833
|
|
|
807
834
|
// src/lib/license.ts
|
|
808
835
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
|
|
809
836
|
import { randomUUID } from "crypto";
|
|
810
|
-
import
|
|
837
|
+
import path8 from "path";
|
|
811
838
|
import { jwtVerify, importSPKI } from "jose";
|
|
812
839
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
813
840
|
var init_license = __esm({
|
|
814
841
|
"src/lib/license.ts"() {
|
|
815
842
|
"use strict";
|
|
816
843
|
init_config();
|
|
817
|
-
LICENSE_PATH =
|
|
818
|
-
CACHE_PATH =
|
|
819
|
-
DEVICE_ID_PATH =
|
|
844
|
+
LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
|
|
845
|
+
CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
|
|
846
|
+
DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
|
|
820
847
|
}
|
|
821
848
|
});
|
|
822
849
|
|
|
823
850
|
// src/lib/plan-limits.ts
|
|
824
851
|
import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
|
|
825
|
-
import
|
|
852
|
+
import path9 from "path";
|
|
826
853
|
var CACHE_PATH2;
|
|
827
854
|
var init_plan_limits = __esm({
|
|
828
855
|
"src/lib/plan-limits.ts"() {
|
|
@@ -831,15 +858,15 @@ var init_plan_limits = __esm({
|
|
|
831
858
|
init_employees();
|
|
832
859
|
init_license();
|
|
833
860
|
init_config();
|
|
834
|
-
CACHE_PATH2 =
|
|
861
|
+
CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
|
|
835
862
|
}
|
|
836
863
|
});
|
|
837
864
|
|
|
838
865
|
// src/lib/tmux-routing.ts
|
|
839
866
|
import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
|
|
840
867
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
841
|
-
import
|
|
842
|
-
import
|
|
868
|
+
import path10 from "path";
|
|
869
|
+
import os7 from "os";
|
|
843
870
|
import { fileURLToPath } from "url";
|
|
844
871
|
function getMySession() {
|
|
845
872
|
return getTransport().getMySession();
|
|
@@ -852,7 +879,7 @@ function extractRootExe(name) {
|
|
|
852
879
|
}
|
|
853
880
|
function getParentExe(sessionKey) {
|
|
854
881
|
try {
|
|
855
|
-
const data = JSON.parse(readFileSync8(
|
|
882
|
+
const data = JSON.parse(readFileSync8(path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
856
883
|
return data.parentExe || null;
|
|
857
884
|
} catch {
|
|
858
885
|
return null;
|
|
@@ -861,7 +888,7 @@ function getParentExe(sessionKey) {
|
|
|
861
888
|
function getDispatchedBy(sessionKey) {
|
|
862
889
|
try {
|
|
863
890
|
const data = JSON.parse(readFileSync8(
|
|
864
|
-
|
|
891
|
+
path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
|
|
865
892
|
"utf8"
|
|
866
893
|
));
|
|
867
894
|
return data.dispatchedBy ?? data.parentExe ?? null;
|
|
@@ -1005,7 +1032,7 @@ function sendIntercom(targetSession) {
|
|
|
1005
1032
|
try {
|
|
1006
1033
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
1007
1034
|
const agent = baseAgentName(rawAgent);
|
|
1008
|
-
const markerPath =
|
|
1035
|
+
const markerPath = path10.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
1009
1036
|
if (existsSync8(markerPath)) {
|
|
1010
1037
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
|
|
1011
1038
|
return "debounced";
|
|
@@ -1015,7 +1042,7 @@ function sendIntercom(targetSession) {
|
|
|
1015
1042
|
try {
|
|
1016
1043
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
1017
1044
|
const agent = baseAgentName(rawAgent);
|
|
1018
|
-
const taskDir =
|
|
1045
|
+
const taskDir = path10.join(process.cwd(), "exe", agent);
|
|
1019
1046
|
if (existsSync8(taskDir)) {
|
|
1020
1047
|
const files = readdirSync2(taskDir).filter(
|
|
1021
1048
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
@@ -1091,12 +1118,12 @@ var init_tmux_routing = __esm({
|
|
|
1091
1118
|
init_intercom_queue();
|
|
1092
1119
|
init_plan_limits();
|
|
1093
1120
|
init_employees();
|
|
1094
|
-
SPAWN_LOCK_DIR =
|
|
1095
|
-
SESSION_CACHE =
|
|
1121
|
+
SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
|
|
1122
|
+
SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
|
|
1096
1123
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
1097
1124
|
CODEX_DEBOUNCE_MS = 12e4;
|
|
1098
|
-
INTERCOM_LOG2 =
|
|
1099
|
-
DEBOUNCE_FILE =
|
|
1125
|
+
INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
1126
|
+
DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
|
|
1100
1127
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
1101
1128
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
|
|
1102
1129
|
}
|
|
@@ -1128,8 +1155,8 @@ var init_task_scope = __esm({
|
|
|
1128
1155
|
|
|
1129
1156
|
// src/lib/tasks-crud.ts
|
|
1130
1157
|
import crypto2 from "crypto";
|
|
1131
|
-
import
|
|
1132
|
-
import
|
|
1158
|
+
import path11 from "path";
|
|
1159
|
+
import os8 from "os";
|
|
1133
1160
|
import { execSync as execSync5 } from "child_process";
|
|
1134
1161
|
import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
|
|
1135
1162
|
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
|
|
@@ -1428,7 +1455,7 @@ var init_tasks_crud = __esm({
|
|
|
1428
1455
|
});
|
|
1429
1456
|
|
|
1430
1457
|
// src/lib/tasks-review.ts
|
|
1431
|
-
import
|
|
1458
|
+
import path12 from "path";
|
|
1432
1459
|
import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
|
|
1433
1460
|
async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
1434
1461
|
if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
|
|
@@ -1474,11 +1501,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
1474
1501
|
);
|
|
1475
1502
|
}
|
|
1476
1503
|
try {
|
|
1477
|
-
const cacheDir =
|
|
1504
|
+
const cacheDir = path12.join(EXE_AI_DIR, "session-cache");
|
|
1478
1505
|
if (existsSync10(cacheDir)) {
|
|
1479
1506
|
for (const f of readdirSync3(cacheDir)) {
|
|
1480
1507
|
if (f.startsWith("review-notified-")) {
|
|
1481
|
-
unlinkSync3(
|
|
1508
|
+
unlinkSync3(path12.join(cacheDir, f));
|
|
1482
1509
|
}
|
|
1483
1510
|
}
|
|
1484
1511
|
}
|
|
@@ -1499,7 +1526,7 @@ var init_tasks_review = __esm({
|
|
|
1499
1526
|
});
|
|
1500
1527
|
|
|
1501
1528
|
// src/lib/tasks-chain.ts
|
|
1502
|
-
import
|
|
1529
|
+
import path13 from "path";
|
|
1503
1530
|
import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
1504
1531
|
async function cascadeUnblock(taskId, baseDir, now) {
|
|
1505
1532
|
const client = getClient();
|
|
@@ -1516,7 +1543,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
1516
1543
|
});
|
|
1517
1544
|
for (const ur of unblockedRows.rows) {
|
|
1518
1545
|
try {
|
|
1519
|
-
const ubFile =
|
|
1546
|
+
const ubFile = path13.join(baseDir, String(ur.task_file));
|
|
1520
1547
|
let ubContent = await readFile3(ubFile, "utf-8");
|
|
1521
1548
|
ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
|
|
1522
1549
|
ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
|
|
@@ -1919,14 +1946,14 @@ var init_skill_learning = __esm({
|
|
|
1919
1946
|
});
|
|
1920
1947
|
|
|
1921
1948
|
// src/lib/tasks.ts
|
|
1922
|
-
import
|
|
1949
|
+
import path14 from "path";
|
|
1923
1950
|
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync4 } from "fs";
|
|
1924
1951
|
async function updateTask(input) {
|
|
1925
1952
|
const { row, taskFile, now, taskId } = await updateTaskStatus(input);
|
|
1926
1953
|
try {
|
|
1927
1954
|
const agent = String(row.assigned_to);
|
|
1928
|
-
const cacheDir =
|
|
1929
|
-
const cachePath =
|
|
1955
|
+
const cacheDir = path14.join(EXE_AI_DIR, "session-cache");
|
|
1956
|
+
const cachePath = path14.join(cacheDir, `current-task-${agent}.json`);
|
|
1930
1957
|
if (input.status === "in_progress") {
|
|
1931
1958
|
mkdirSync5(cacheDir, { recursive: true });
|
|
1932
1959
|
writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
@@ -2083,7 +2110,7 @@ __export(active_agent_exports, {
|
|
|
2083
2110
|
});
|
|
2084
2111
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5, readdirSync as readdirSync4 } from "fs";
|
|
2085
2112
|
import { execSync as execSync6 } from "child_process";
|
|
2086
|
-
import
|
|
2113
|
+
import path15 from "path";
|
|
2087
2114
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
2088
2115
|
if (candidate === baseName) return true;
|
|
2089
2116
|
if (!candidate.startsWith(baseName)) return false;
|
|
@@ -2127,7 +2154,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
|
|
|
2127
2154
|
return null;
|
|
2128
2155
|
}
|
|
2129
2156
|
function getMarkerPath() {
|
|
2130
|
-
return
|
|
2157
|
+
return path15.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
|
|
2131
2158
|
}
|
|
2132
2159
|
function writeActiveAgent(agentId, agentRole) {
|
|
2133
2160
|
try {
|
|
@@ -2196,14 +2223,14 @@ function getAllActiveAgents() {
|
|
|
2196
2223
|
const key = file.slice("active-agent-".length, -".json".length);
|
|
2197
2224
|
if (key === "undefined") continue;
|
|
2198
2225
|
try {
|
|
2199
|
-
const raw = readFileSync10(
|
|
2226
|
+
const raw = readFileSync10(path15.join(CACHE_DIR, file), "utf8");
|
|
2200
2227
|
const data = JSON.parse(raw);
|
|
2201
2228
|
if (!data.agentId) continue;
|
|
2202
2229
|
if (data.startedAt) {
|
|
2203
2230
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
2204
2231
|
if (age > STALE_MS) {
|
|
2205
2232
|
try {
|
|
2206
|
-
unlinkSync5(
|
|
2233
|
+
unlinkSync5(path15.join(CACHE_DIR, file));
|
|
2207
2234
|
} catch {
|
|
2208
2235
|
}
|
|
2209
2236
|
continue;
|
|
@@ -2226,11 +2253,11 @@ function getAllActiveAgents() {
|
|
|
2226
2253
|
function cleanupSessionMarkers() {
|
|
2227
2254
|
const key = getSessionKey();
|
|
2228
2255
|
try {
|
|
2229
|
-
unlinkSync5(
|
|
2256
|
+
unlinkSync5(path15.join(CACHE_DIR, `active-agent-${key}.json`));
|
|
2230
2257
|
} catch {
|
|
2231
2258
|
}
|
|
2232
2259
|
try {
|
|
2233
|
-
unlinkSync5(
|
|
2260
|
+
unlinkSync5(path15.join(CACHE_DIR, "active-agent-undefined.json"));
|
|
2234
2261
|
} catch {
|
|
2235
2262
|
}
|
|
2236
2263
|
}
|
|
@@ -2241,7 +2268,7 @@ var init_active_agent = __esm({
|
|
|
2241
2268
|
init_config();
|
|
2242
2269
|
init_session_key();
|
|
2243
2270
|
init_employees();
|
|
2244
|
-
CACHE_DIR =
|
|
2271
|
+
CACHE_DIR = path15.join(EXE_AI_DIR, "session-cache");
|
|
2245
2272
|
STALE_MS = 24 * 60 * 60 * 1e3;
|
|
2246
2273
|
}
|
|
2247
2274
|
});
|