@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.
Files changed (95) hide show
  1. package/dist/bin/backfill-conversations.js +754 -79
  2. package/dist/bin/backfill-responses.js +752 -77
  3. package/dist/bin/backfill-vectors.js +752 -77
  4. package/dist/bin/cleanup-stale-review-tasks.js +657 -35
  5. package/dist/bin/cli.js +1388 -605
  6. package/dist/bin/exe-agent-config.js +123 -95
  7. package/dist/bin/exe-agent.js +41 -25
  8. package/dist/bin/exe-assign.js +732 -57
  9. package/dist/bin/exe-boot.js +784 -153
  10. package/dist/bin/exe-call.js +209 -138
  11. package/dist/bin/exe-cloud.js +35 -12
  12. package/dist/bin/exe-dispatch.js +692 -70
  13. package/dist/bin/exe-doctor.js +648 -26
  14. package/dist/bin/exe-export-behaviors.js +650 -20
  15. package/dist/bin/exe-forget.js +635 -13
  16. package/dist/bin/exe-gateway.js +1053 -271
  17. package/dist/bin/exe-heartbeat.js +665 -43
  18. package/dist/bin/exe-kill.js +646 -16
  19. package/dist/bin/exe-launch-agent.js +887 -97
  20. package/dist/bin/exe-link.js +658 -43
  21. package/dist/bin/exe-new-employee.js +378 -177
  22. package/dist/bin/exe-pending-messages.js +656 -34
  23. package/dist/bin/exe-pending-notifications.js +635 -13
  24. package/dist/bin/exe-pending-reviews.js +659 -37
  25. package/dist/bin/exe-rename.js +645 -30
  26. package/dist/bin/exe-review.js +635 -13
  27. package/dist/bin/exe-search.js +771 -88
  28. package/dist/bin/exe-session-cleanup.js +834 -150
  29. package/dist/bin/exe-settings.js +127 -91
  30. package/dist/bin/exe-start-codex.js +729 -94
  31. package/dist/bin/exe-start-opencode.js +717 -82
  32. package/dist/bin/exe-status.js +657 -35
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +720 -89
  35. package/dist/bin/graph-backfill.js +643 -13
  36. package/dist/bin/graph-export.js +646 -16
  37. package/dist/bin/install.js +596 -193
  38. package/dist/bin/scan-tasks.js +724 -93
  39. package/dist/bin/setup.js +1038 -210
  40. package/dist/bin/shard-migrate.js +645 -15
  41. package/dist/bin/wiki-sync.js +646 -16
  42. package/dist/gateway/index.js +1027 -245
  43. package/dist/hooks/bug-report-worker.js +891 -170
  44. package/dist/hooks/commit-complete.js +718 -87
  45. package/dist/hooks/error-recall.js +776 -93
  46. package/dist/hooks/exe-heartbeat-hook.js +85 -71
  47. package/dist/hooks/ingest-worker.js +840 -156
  48. package/dist/hooks/ingest.js +90 -73
  49. package/dist/hooks/instructions-loaded.js +669 -38
  50. package/dist/hooks/notification.js +661 -30
  51. package/dist/hooks/post-compact.js +674 -43
  52. package/dist/hooks/pre-compact.js +718 -87
  53. package/dist/hooks/pre-tool-use.js +872 -125
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1060 -319
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +721 -90
  58. package/dist/hooks/session-start.js +1031 -207
  59. package/dist/hooks/stop.js +680 -49
  60. package/dist/hooks/subagent-stop.js +674 -43
  61. package/dist/hooks/summary-worker.js +816 -132
  62. package/dist/index.js +1015 -232
  63. package/dist/lib/cloud-sync.js +663 -48
  64. package/dist/lib/consolidation.js +26 -3
  65. package/dist/lib/database.js +626 -18
  66. package/dist/lib/db.js +2261 -0
  67. package/dist/lib/device-registry.js +640 -25
  68. package/dist/lib/embedder.js +96 -43
  69. package/dist/lib/employee-templates.js +16 -0
  70. package/dist/lib/employees.js +259 -83
  71. package/dist/lib/exe-daemon-client.js +101 -63
  72. package/dist/lib/exe-daemon.js +894 -162
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +55 -28
  76. package/dist/lib/reminders.js +21 -1
  77. package/dist/lib/schedules.js +636 -14
  78. package/dist/lib/skill-learning.js +21 -1
  79. package/dist/lib/store.js +643 -13
  80. package/dist/lib/task-router.js +82 -71
  81. package/dist/lib/tasks.js +98 -71
  82. package/dist/lib/tmux-routing.js +87 -60
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1784 -458
  85. package/dist/mcp/tools/complete-reminder.js +21 -1
  86. package/dist/mcp/tools/create-reminder.js +21 -1
  87. package/dist/mcp/tools/create-task.js +290 -164
  88. package/dist/mcp/tools/deactivate-behavior.js +24 -4
  89. package/dist/mcp/tools/list-reminders.js +21 -1
  90. package/dist/mcp/tools/list-tasks.js +195 -38
  91. package/dist/mcp/tools/send-message.js +58 -31
  92. package/dist/mcp/tools/update-task.js +75 -48
  93. package/dist/runtime/index.js +720 -89
  94. package/dist/tui/App.js +853 -123
  95. package/package.json +3 -2
@@ -272,6 +272,118 @@ var init_config = __esm({
272
272
  }
273
273
  });
274
274
 
275
+ // src/lib/runtime-table.ts
276
+ var RUNTIME_TABLE, DEFAULT_RUNTIME;
277
+ var init_runtime_table = __esm({
278
+ "src/lib/runtime-table.ts"() {
279
+ "use strict";
280
+ RUNTIME_TABLE = {
281
+ codex: {
282
+ binary: "codex",
283
+ launchMode: "interactive",
284
+ autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
285
+ inlineFlag: "--no-alt-screen",
286
+ apiKeyEnv: "OPENAI_API_KEY",
287
+ defaultModel: "gpt-5.4"
288
+ },
289
+ opencode: {
290
+ binary: "opencode",
291
+ launchMode: "exec",
292
+ autoApproveFlag: "--dangerously-skip-permissions",
293
+ inlineFlag: "",
294
+ apiKeyEnv: "ANTHROPIC_API_KEY",
295
+ defaultModel: "anthropic/claude-sonnet-4-6"
296
+ }
297
+ };
298
+ DEFAULT_RUNTIME = "claude";
299
+ }
300
+ });
301
+
302
+ // src/lib/agent-config.ts
303
+ var agent_config_exports = {};
304
+ __export(agent_config_exports, {
305
+ AGENT_CONFIG_PATH: () => AGENT_CONFIG_PATH,
306
+ DEFAULT_MODELS: () => DEFAULT_MODELS,
307
+ KNOWN_RUNTIMES: () => KNOWN_RUNTIMES,
308
+ RUNTIME_LABELS: () => RUNTIME_LABELS,
309
+ clearAgentRuntime: () => clearAgentRuntime,
310
+ getAgentRuntime: () => getAgentRuntime,
311
+ loadAgentConfig: () => loadAgentConfig,
312
+ saveAgentConfig: () => saveAgentConfig,
313
+ setAgentRuntime: () => setAgentRuntime
314
+ });
315
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
316
+ import path2 from "path";
317
+ function loadAgentConfig() {
318
+ if (!existsSync2(AGENT_CONFIG_PATH)) return {};
319
+ try {
320
+ return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
321
+ } catch {
322
+ return {};
323
+ }
324
+ }
325
+ function saveAgentConfig(config) {
326
+ const dir = path2.dirname(AGENT_CONFIG_PATH);
327
+ if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
328
+ writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
329
+ }
330
+ function getAgentRuntime(agentId) {
331
+ const config = loadAgentConfig();
332
+ const entry = config[agentId];
333
+ if (entry) return entry;
334
+ const orgDefault = config["default"];
335
+ if (orgDefault) return orgDefault;
336
+ return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
337
+ }
338
+ function setAgentRuntime(agentId, runtime, model) {
339
+ const knownModels = KNOWN_RUNTIMES[runtime];
340
+ if (!knownModels) {
341
+ return {
342
+ ok: false,
343
+ error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
344
+ };
345
+ }
346
+ if (!knownModels.includes(model)) {
347
+ return {
348
+ ok: false,
349
+ error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
350
+ };
351
+ }
352
+ const config = loadAgentConfig();
353
+ config[agentId] = { runtime, model };
354
+ saveAgentConfig(config);
355
+ return { ok: true };
356
+ }
357
+ function clearAgentRuntime(agentId) {
358
+ const config = loadAgentConfig();
359
+ delete config[agentId];
360
+ saveAgentConfig(config);
361
+ }
362
+ var AGENT_CONFIG_PATH, KNOWN_RUNTIMES, RUNTIME_LABELS, DEFAULT_MODELS;
363
+ var init_agent_config = __esm({
364
+ "src/lib/agent-config.ts"() {
365
+ "use strict";
366
+ init_config();
367
+ init_runtime_table();
368
+ AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
369
+ KNOWN_RUNTIMES = {
370
+ claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
371
+ codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
372
+ opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
373
+ };
374
+ RUNTIME_LABELS = {
375
+ claude: "Claude Code (Anthropic)",
376
+ codex: "Codex (OpenAI)",
377
+ opencode: "OpenCode (open source)"
378
+ };
379
+ DEFAULT_MODELS = {
380
+ claude: "claude-opus-4",
381
+ codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
382
+ opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
383
+ };
384
+ }
385
+ });
386
+
275
387
  // src/lib/employees.ts
276
388
  var employees_exports = {};
277
389
  __export(employees_exports, {
@@ -287,6 +399,7 @@ __export(employees_exports, {
287
399
  getEmployeeByRole: () => getEmployeeByRole,
288
400
  getEmployeeNamesByRole: () => getEmployeeNamesByRole,
289
401
  hasRole: () => hasRole,
402
+ hireEmployee: () => hireEmployee,
290
403
  isCoordinatorName: () => isCoordinatorName,
291
404
  isCoordinatorRole: () => isCoordinatorRole,
292
405
  isMultiInstance: () => isMultiInstance,
@@ -299,9 +412,9 @@ __export(employees_exports, {
299
412
  validateEmployeeName: () => validateEmployeeName
300
413
  });
301
414
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
302
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
415
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
303
416
  import { execSync } from "child_process";
304
- import path2 from "path";
417
+ import path3 from "path";
305
418
  import os2 from "os";
306
419
  function normalizeRole(role) {
307
420
  return (role ?? "").trim().toLowerCase();
@@ -338,7 +451,7 @@ function validateEmployeeName(name) {
338
451
  return { valid: true };
339
452
  }
340
453
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
341
- if (!existsSync2(employeesPath)) {
454
+ if (!existsSync3(employeesPath)) {
342
455
  return [];
343
456
  }
344
457
  const raw = await readFile2(employeesPath, "utf-8");
@@ -349,13 +462,13 @@ async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
349
462
  }
350
463
  }
351
464
  async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
352
- await mkdir2(path2.dirname(employeesPath), { recursive: true });
465
+ await mkdir2(path3.dirname(employeesPath), { recursive: true });
353
466
  await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
354
467
  }
355
468
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
356
- if (!existsSync2(employeesPath)) return [];
469
+ if (!existsSync3(employeesPath)) return [];
357
470
  try {
358
- return JSON.parse(readFileSync2(employeesPath, "utf-8"));
471
+ return JSON.parse(readFileSync3(employeesPath, "utf-8"));
359
472
  } catch {
360
473
  return [];
361
474
  }
@@ -397,6 +510,52 @@ function addEmployee(employees, employee) {
397
510
  }
398
511
  return [...employees, normalized];
399
512
  }
513
+ function appendToCoordinatorTeam(employee) {
514
+ const coordinator = getCoordinatorEmployee(loadEmployeesSync());
515
+ if (!coordinator) return;
516
+ const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
517
+ if (!existsSync3(idPath)) return;
518
+ const content = readFileSync3(idPath, "utf-8");
519
+ if (content.includes(`**${capitalize(employee.name)}`)) return;
520
+ const teamMatch = content.match(TEAM_SECTION_RE);
521
+ if (!teamMatch || teamMatch.index === void 0) return;
522
+ const afterTeam = content.slice(teamMatch.index + teamMatch[0].length);
523
+ const nextHeading = afterTeam.match(/\n## /);
524
+ const entry = `
525
+ **${capitalize(employee.name)} (${employee.role}):** Newly hired. Update this description as the role develops.
526
+ `;
527
+ let updated;
528
+ if (nextHeading && nextHeading.index !== void 0) {
529
+ const insertAt = teamMatch.index + teamMatch[0].length + nextHeading.index;
530
+ updated = content.slice(0, insertAt) + entry + content.slice(insertAt);
531
+ } else {
532
+ updated = content.trimEnd() + "\n" + entry;
533
+ }
534
+ writeFileSync2(idPath, updated, "utf-8");
535
+ }
536
+ function capitalize(s) {
537
+ return s.charAt(0).toUpperCase() + s.slice(1);
538
+ }
539
+ async function hireEmployee(employee) {
540
+ const employees = await loadEmployees();
541
+ const updated = addEmployee(employees, employee);
542
+ await saveEmployees(updated);
543
+ try {
544
+ appendToCoordinatorTeam(employee);
545
+ } catch {
546
+ }
547
+ try {
548
+ const { loadAgentConfig: loadAgentConfig2, saveAgentConfig: saveAgentConfig2 } = await Promise.resolve().then(() => (init_agent_config(), agent_config_exports));
549
+ const config = loadAgentConfig2();
550
+ const name = employee.name.toLowerCase();
551
+ if (!config[name] && config["default"]) {
552
+ config[name] = { ...config["default"] };
553
+ saveAgentConfig2(config);
554
+ }
555
+ } catch {
556
+ }
557
+ return updated;
558
+ }
400
559
  async function normalizeRosterCase(rosterPath) {
401
560
  const employees = await loadEmployees(rosterPath);
402
561
  let changed = false;
@@ -406,14 +565,14 @@ async function normalizeRosterCase(rosterPath) {
406
565
  emp.name = emp.name.toLowerCase();
407
566
  changed = true;
408
567
  try {
409
- const identityDir = path2.join(os2.homedir(), ".exe-os", "identity");
410
- const oldPath = path2.join(identityDir, `${oldName}.md`);
411
- const newPath = path2.join(identityDir, `${emp.name}.md`);
412
- if (existsSync2(oldPath) && !existsSync2(newPath)) {
568
+ const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
569
+ const oldPath = path3.join(identityDir, `${oldName}.md`);
570
+ const newPath = path3.join(identityDir, `${emp.name}.md`);
571
+ if (existsSync3(oldPath) && !existsSync3(newPath)) {
413
572
  renameSync2(oldPath, newPath);
414
- } else if (existsSync2(oldPath) && oldPath !== newPath) {
415
- const content = readFileSync2(oldPath, "utf-8");
416
- writeFileSync(newPath, content, "utf-8");
573
+ } else if (existsSync3(oldPath) && oldPath !== newPath) {
574
+ const content = readFileSync3(oldPath, "utf-8");
575
+ writeFileSync2(newPath, content, "utf-8");
417
576
  if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
418
577
  unlinkSync(oldPath);
419
578
  }
@@ -443,7 +602,7 @@ function registerBinSymlinks(name) {
443
602
  errors.push("Could not find 'exe-os' in PATH");
444
603
  return { created, skipped, errors };
445
604
  }
446
- const binDir = path2.dirname(exeBinPath);
605
+ const binDir = path3.dirname(exeBinPath);
447
606
  let target;
448
607
  try {
449
608
  target = readlinkSync(exeBinPath);
@@ -453,8 +612,8 @@ function registerBinSymlinks(name) {
453
612
  }
454
613
  for (const suffix of ["", "-opencode"]) {
455
614
  const linkName = `${name}${suffix}`;
456
- const linkPath = path2.join(binDir, linkName);
457
- if (existsSync2(linkPath)) {
615
+ const linkPath = path3.join(binDir, linkName);
616
+ if (existsSync3(linkPath)) {
458
617
  skipped.push(linkName);
459
618
  continue;
460
619
  }
@@ -467,24 +626,50 @@ function registerBinSymlinks(name) {
467
626
  }
468
627
  return { created, skipped, errors };
469
628
  }
470
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES;
629
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR, TEAM_SECTION_RE;
471
630
  var init_employees = __esm({
472
631
  "src/lib/employees.ts"() {
473
632
  "use strict";
474
633
  init_config();
475
- EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
634
+ EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
476
635
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
477
636
  COORDINATOR_ROLE = "COO";
478
637
  MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
638
+ IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
639
+ TEAM_SECTION_RE = /^## Team\b.*$/m;
640
+ }
641
+ });
642
+
643
+ // src/lib/database-adapter.ts
644
+ import os3 from "os";
645
+ import path4 from "path";
646
+ import { createRequire } from "module";
647
+ import { pathToFileURL } from "url";
648
+ var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
649
+ var init_database_adapter = __esm({
650
+ "src/lib/database-adapter.ts"() {
651
+ "use strict";
652
+ BOOLEAN_COLUMNS_BY_TABLE = {
653
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
654
+ behaviors: /* @__PURE__ */ new Set(["active"]),
655
+ notifications: /* @__PURE__ */ new Set(["read"]),
656
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
657
+ };
658
+ BOOLEAN_COLUMN_NAMES = new Set(
659
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
660
+ );
479
661
  }
480
662
  });
481
663
 
482
664
  // src/lib/database.ts
483
665
  import { createClient } from "@libsql/client";
484
666
  function getClient() {
485
- if (!_resilientClient) {
667
+ if (!_adapterClient) {
486
668
  throw new Error("Database client not initialized. Call initDatabase() first.");
487
669
  }
670
+ if (process.env.DATABASE_URL) {
671
+ return _adapterClient;
672
+ }
488
673
  if (process.env.EXE_IS_DAEMON === "1") {
489
674
  return _resilientClient;
490
675
  }
@@ -493,26 +678,28 @@ function getClient() {
493
678
  }
494
679
  return _resilientClient;
495
680
  }
496
- var _resilientClient, _daemonClient;
681
+ var _resilientClient, _daemonClient, _adapterClient;
497
682
  var init_database = __esm({
498
683
  "src/lib/database.ts"() {
499
684
  "use strict";
500
685
  init_db_retry();
501
686
  init_employees();
687
+ init_database_adapter();
502
688
  _resilientClient = null;
503
689
  _daemonClient = null;
690
+ _adapterClient = null;
504
691
  }
505
692
  });
506
693
 
507
694
  // src/lib/notifications.ts
508
695
  import crypto from "crypto";
509
- import path3 from "path";
510
- import os3 from "os";
696
+ import path5 from "path";
697
+ import os4 from "os";
511
698
  import {
512
- readFileSync as readFileSync3,
699
+ readFileSync as readFileSync4,
513
700
  readdirSync,
514
701
  unlinkSync as unlinkSync2,
515
- existsSync as existsSync3,
702
+ existsSync as existsSync4,
516
703
  rmdirSync
517
704
  } from "fs";
518
705
  async function writeNotification(notification) {
@@ -612,13 +799,13 @@ var init_state_bus = __esm({
612
799
  });
613
800
 
614
801
  // src/lib/session-registry.ts
615
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync, existsSync as existsSync4 } from "fs";
616
- import path4 from "path";
617
- import os4 from "os";
802
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync5 } from "fs";
803
+ import path6 from "path";
804
+ import os5 from "os";
618
805
  function registerSession(entry) {
619
- const dir = path4.dirname(REGISTRY_PATH);
620
- if (!existsSync4(dir)) {
621
- mkdirSync(dir, { recursive: true });
806
+ const dir = path6.dirname(REGISTRY_PATH);
807
+ if (!existsSync5(dir)) {
808
+ mkdirSync2(dir, { recursive: true });
622
809
  }
623
810
  const sessions = listSessions();
624
811
  const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
@@ -627,11 +814,11 @@ function registerSession(entry) {
627
814
  } else {
628
815
  sessions.push(entry);
629
816
  }
630
- writeFileSync2(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
817
+ writeFileSync3(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
631
818
  }
632
819
  function listSessions() {
633
820
  try {
634
- const raw = readFileSync4(REGISTRY_PATH, "utf8");
821
+ const raw = readFileSync5(REGISTRY_PATH, "utf8");
635
822
  return JSON.parse(raw);
636
823
  } catch {
637
824
  return [];
@@ -641,7 +828,7 @@ var REGISTRY_PATH;
641
828
  var init_session_registry = __esm({
642
829
  "src/lib/session-registry.ts"() {
643
830
  "use strict";
644
- REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
831
+ REGISTRY_PATH = path6.join(os5.homedir(), ".exe-os", "session-registry.json");
645
832
  }
646
833
  });
647
834
 
@@ -893,67 +1080,6 @@ var init_provider_table = __esm({
893
1080
  }
894
1081
  });
895
1082
 
896
- // src/lib/runtime-table.ts
897
- var RUNTIME_TABLE, DEFAULT_RUNTIME;
898
- var init_runtime_table = __esm({
899
- "src/lib/runtime-table.ts"() {
900
- "use strict";
901
- RUNTIME_TABLE = {
902
- codex: {
903
- binary: "codex",
904
- launchMode: "interactive",
905
- autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
906
- inlineFlag: "--no-alt-screen",
907
- apiKeyEnv: "OPENAI_API_KEY",
908
- defaultModel: "gpt-5.4"
909
- },
910
- opencode: {
911
- binary: "opencode",
912
- launchMode: "exec",
913
- autoApproveFlag: "--dangerously-skip-permissions",
914
- inlineFlag: "",
915
- apiKeyEnv: "ANTHROPIC_API_KEY",
916
- defaultModel: "anthropic/claude-sonnet-4-6"
917
- }
918
- };
919
- DEFAULT_RUNTIME = "claude";
920
- }
921
- });
922
-
923
- // src/lib/agent-config.ts
924
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
925
- import path5 from "path";
926
- function loadAgentConfig() {
927
- if (!existsSync5(AGENT_CONFIG_PATH)) return {};
928
- try {
929
- return JSON.parse(readFileSync5(AGENT_CONFIG_PATH, "utf-8"));
930
- } catch {
931
- return {};
932
- }
933
- }
934
- function getAgentRuntime(agentId) {
935
- const config = loadAgentConfig();
936
- const entry = config[agentId];
937
- if (entry) return entry;
938
- const orgDefault = config["default"];
939
- if (orgDefault) return orgDefault;
940
- return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
941
- }
942
- var AGENT_CONFIG_PATH, DEFAULT_MODELS;
943
- var init_agent_config = __esm({
944
- "src/lib/agent-config.ts"() {
945
- "use strict";
946
- init_config();
947
- init_runtime_table();
948
- AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
949
- DEFAULT_MODELS = {
950
- claude: "claude-opus-4",
951
- codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
952
- opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
953
- };
954
- }
955
- });
956
-
957
1083
  // src/lib/intercom-queue.ts
958
1084
  var intercom_queue_exports = {};
959
1085
  __export(intercom_queue_exports, {
@@ -964,10 +1090,10 @@ __export(intercom_queue_exports, {
964
1090
  readQueue: () => readQueue
965
1091
  });
966
1092
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
967
- import path6 from "path";
968
- import os5 from "os";
1093
+ import path7 from "path";
1094
+ import os6 from "os";
969
1095
  function ensureDir() {
970
- const dir = path6.dirname(QUEUE_PATH);
1096
+ const dir = path7.dirname(QUEUE_PATH);
971
1097
  if (!existsSync6(dir)) mkdirSync3(dir, { recursive: true });
972
1098
  }
973
1099
  function readQueue() {
@@ -1073,26 +1199,26 @@ var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
1073
1199
  var init_intercom_queue = __esm({
1074
1200
  "src/lib/intercom-queue.ts"() {
1075
1201
  "use strict";
1076
- QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
1202
+ QUEUE_PATH = path7.join(os6.homedir(), ".exe-os", "intercom-queue.json");
1077
1203
  MAX_RETRIES = 5;
1078
1204
  TTL_MS = 60 * 60 * 1e3;
1079
- INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
1205
+ INTERCOM_LOG = path7.join(os6.homedir(), ".exe-os", "intercom.log");
1080
1206
  }
1081
1207
  });
1082
1208
 
1083
1209
  // src/lib/license.ts
1084
1210
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
1085
1211
  import { randomUUID } from "crypto";
1086
- import path7 from "path";
1212
+ import path8 from "path";
1087
1213
  import { jwtVerify, importSPKI } from "jose";
1088
1214
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
1089
1215
  var init_license = __esm({
1090
1216
  "src/lib/license.ts"() {
1091
1217
  "use strict";
1092
1218
  init_config();
1093
- LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
1094
- CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
1095
- DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
1219
+ LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
1220
+ CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
1221
+ DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
1096
1222
  PLAN_LIMITS = {
1097
1223
  free: { devices: 1, employees: 1, memories: 5e3 },
1098
1224
  pro: { devices: 3, employees: 5, memories: 1e5 },
@@ -1105,7 +1231,7 @@ var init_license = __esm({
1105
1231
 
1106
1232
  // src/lib/plan-limits.ts
1107
1233
  import { readFileSync as readFileSync8, existsSync as existsSync8 } from "fs";
1108
- import path8 from "path";
1234
+ import path9 from "path";
1109
1235
  function getLicenseSync() {
1110
1236
  try {
1111
1237
  if (!existsSync8(CACHE_PATH2)) return freeLicense();
@@ -1177,7 +1303,7 @@ var init_plan_limits = __esm({
1177
1303
  this.name = "PlanLimitError";
1178
1304
  }
1179
1305
  };
1180
- CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
1306
+ CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
1181
1307
  }
1182
1308
  });
1183
1309
 
@@ -1526,12 +1652,12 @@ __export(tmux_routing_exports, {
1526
1652
  });
1527
1653
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
1528
1654
  import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync9, appendFileSync, readdirSync as readdirSync2 } from "fs";
1529
- import path9 from "path";
1530
- import os6 from "os";
1655
+ import path10 from "path";
1656
+ import os7 from "os";
1531
1657
  import { fileURLToPath } from "url";
1532
1658
  import { unlinkSync as unlinkSync3 } from "fs";
1533
1659
  function spawnLockPath(sessionName) {
1534
- return path9.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
1660
+ return path10.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
1535
1661
  }
1536
1662
  function isProcessAlive(pid) {
1537
1663
  try {
@@ -1568,8 +1694,8 @@ function releaseSpawnLock(sessionName) {
1568
1694
  function resolveBehaviorsExporterScript() {
1569
1695
  try {
1570
1696
  const thisFile = fileURLToPath(import.meta.url);
1571
- const scriptPath = path9.join(
1572
- path9.dirname(thisFile),
1697
+ const scriptPath = path10.join(
1698
+ path10.dirname(thisFile),
1573
1699
  "..",
1574
1700
  "bin",
1575
1701
  "exe-export-behaviors.js"
@@ -1644,7 +1770,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
1644
1770
  mkdirSync5(SESSION_CACHE, { recursive: true });
1645
1771
  }
1646
1772
  const rootExe = extractRootExe(parentExe) ?? parentExe;
1647
- const filePath = path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
1773
+ const filePath = path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
1648
1774
  writeFileSync6(filePath, JSON.stringify({
1649
1775
  parentExe: rootExe,
1650
1776
  dispatchedBy: dispatchedBy || rootExe,
@@ -1653,7 +1779,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
1653
1779
  }
1654
1780
  function getParentExe(sessionKey) {
1655
1781
  try {
1656
- const data = JSON.parse(readFileSync9(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
1782
+ const data = JSON.parse(readFileSync9(path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
1657
1783
  return data.parentExe || null;
1658
1784
  } catch {
1659
1785
  return null;
@@ -1662,7 +1788,7 @@ function getParentExe(sessionKey) {
1662
1788
  function getDispatchedBy(sessionKey) {
1663
1789
  try {
1664
1790
  const data = JSON.parse(readFileSync9(
1665
- path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
1791
+ path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
1666
1792
  "utf8"
1667
1793
  ));
1668
1794
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -1848,7 +1974,7 @@ function sendIntercom(targetSession) {
1848
1974
  try {
1849
1975
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
1850
1976
  const agent = baseAgentName(rawAgent);
1851
- const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
1977
+ const markerPath = path10.join(SESSION_CACHE, `current-task-${agent}.json`);
1852
1978
  if (existsSync9(markerPath)) {
1853
1979
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
1854
1980
  return "debounced";
@@ -1858,7 +1984,7 @@ function sendIntercom(targetSession) {
1858
1984
  try {
1859
1985
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
1860
1986
  const agent = baseAgentName(rawAgent);
1861
- const taskDir = path9.join(process.cwd(), "exe", agent);
1987
+ const taskDir = path10.join(process.cwd(), "exe", agent);
1862
1988
  if (existsSync9(taskDir)) {
1863
1989
  const files = readdirSync2(taskDir).filter(
1864
1990
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -1992,8 +2118,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1992
2118
  const transport = getTransport();
1993
2119
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
1994
2120
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
1995
- const logDir = path9.join(os6.homedir(), ".exe-os", "session-logs");
1996
- const logFile = path9.join(logDir, `${instanceLabel}-${Date.now()}.log`);
2121
+ const logDir = path10.join(os7.homedir(), ".exe-os", "session-logs");
2122
+ const logFile = path10.join(logDir, `${instanceLabel}-${Date.now()}.log`);
1997
2123
  if (!existsSync9(logDir)) {
1998
2124
  mkdirSync5(logDir, { recursive: true });
1999
2125
  }
@@ -2001,14 +2127,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2001
2127
  let cleanupSuffix = "";
2002
2128
  try {
2003
2129
  const thisFile = fileURLToPath(import.meta.url);
2004
- const cleanupScript = path9.join(path9.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
2130
+ const cleanupScript = path10.join(path10.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
2005
2131
  if (existsSync9(cleanupScript)) {
2006
2132
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
2007
2133
  }
2008
2134
  } catch {
2009
2135
  }
2010
2136
  try {
2011
- const claudeJsonPath = path9.join(os6.homedir(), ".claude.json");
2137
+ const claudeJsonPath = path10.join(os7.homedir(), ".claude.json");
2012
2138
  let claudeJson = {};
2013
2139
  try {
2014
2140
  claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
@@ -2023,10 +2149,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2023
2149
  } catch {
2024
2150
  }
2025
2151
  try {
2026
- const settingsDir = path9.join(os6.homedir(), ".claude", "projects");
2152
+ const settingsDir = path10.join(os7.homedir(), ".claude", "projects");
2027
2153
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
2028
- const projSettingsDir = path9.join(settingsDir, normalizedKey);
2029
- const settingsPath = path9.join(projSettingsDir, "settings.json");
2154
+ const projSettingsDir = path10.join(settingsDir, normalizedKey);
2155
+ const settingsPath = path10.join(projSettingsDir, "settings.json");
2030
2156
  let settings = {};
2031
2157
  try {
2032
2158
  settings = JSON.parse(readFileSync9(settingsPath, "utf8"));
@@ -2073,8 +2199,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2073
2199
  let behaviorsFlag = "";
2074
2200
  let legacyFallbackWarned = false;
2075
2201
  if (!useExeAgent && !useBinSymlink) {
2076
- const identityPath2 = path9.join(
2077
- os6.homedir(),
2202
+ const identityPath2 = path10.join(
2203
+ os7.homedir(),
2078
2204
  ".exe-os",
2079
2205
  "identity",
2080
2206
  `${employeeName}.md`
@@ -2089,7 +2215,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2089
2215
  }
2090
2216
  const behaviorsFile = exportBehaviorsSync(
2091
2217
  employeeName,
2092
- path9.basename(spawnCwd),
2218
+ path10.basename(spawnCwd),
2093
2219
  sessionName
2094
2220
  );
2095
2221
  if (behaviorsFile) {
@@ -2104,9 +2230,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2104
2230
  }
2105
2231
  let sessionContextFlag = "";
2106
2232
  try {
2107
- const ctxDir = path9.join(os6.homedir(), ".exe-os", "session-cache");
2233
+ const ctxDir = path10.join(os7.homedir(), ".exe-os", "session-cache");
2108
2234
  mkdirSync5(ctxDir, { recursive: true });
2109
- const ctxFile = path9.join(ctxDir, `session-context-${sessionName}.md`);
2235
+ const ctxFile = path10.join(ctxDir, `session-context-${sessionName}.md`);
2110
2236
  const ctxContent = [
2111
2237
  `## Session Context`,
2112
2238
  `You are running in tmux session: ${sessionName}.`,
@@ -2190,7 +2316,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2190
2316
  transport.pipeLog(sessionName, logFile);
2191
2317
  try {
2192
2318
  const mySession = getMySession();
2193
- const dispatchInfo = path9.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
2319
+ const dispatchInfo = path10.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
2194
2320
  writeFileSync6(dispatchInfo, JSON.stringify({
2195
2321
  dispatchedBy: mySession,
2196
2322
  rootExe: exeSession,
@@ -2265,15 +2391,15 @@ var init_tmux_routing = __esm({
2265
2391
  init_intercom_queue();
2266
2392
  init_plan_limits();
2267
2393
  init_employees();
2268
- SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
2269
- SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
2394
+ SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
2395
+ SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
2270
2396
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
2271
2397
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
2272
2398
  VERIFY_PANE_LINES = 200;
2273
2399
  INTERCOM_DEBOUNCE_MS = 3e4;
2274
2400
  CODEX_DEBOUNCE_MS = 12e4;
2275
- INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
2276
- DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
2401
+ INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
2402
+ DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
2277
2403
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
2278
2404
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
2279
2405
  }
@@ -2305,8 +2431,8 @@ var init_task_scope = __esm({
2305
2431
 
2306
2432
  // src/lib/tasks-crud.ts
2307
2433
  import crypto3 from "crypto";
2308
- import path10 from "path";
2309
- import os7 from "os";
2434
+ import path11 from "path";
2435
+ import os8 from "os";
2310
2436
  import { execSync as execSync5 } from "child_process";
2311
2437
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
2312
2438
  import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
@@ -2484,8 +2610,8 @@ ${laneWarning}` : laneWarning;
2484
2610
  }
2485
2611
  if (input.baseDir) {
2486
2612
  try {
2487
- await mkdir3(path10.join(input.baseDir, "exe", "output"), { recursive: true });
2488
- await mkdir3(path10.join(input.baseDir, "exe", "research"), { recursive: true });
2613
+ await mkdir3(path11.join(input.baseDir, "exe", "output"), { recursive: true });
2614
+ await mkdir3(path11.join(input.baseDir, "exe", "research"), { recursive: true });
2489
2615
  await ensureArchitectureDoc(input.baseDir, input.projectName);
2490
2616
  await ensureGitignoreExe(input.baseDir);
2491
2617
  } catch {
@@ -2521,9 +2647,9 @@ ${laneWarning}` : laneWarning;
2521
2647
  });
2522
2648
  if (input.baseDir) {
2523
2649
  try {
2524
- const EXE_OS_DIR = path10.join(os7.homedir(), ".exe-os");
2525
- const mdPath = path10.join(EXE_OS_DIR, taskFile);
2526
- const mdDir = path10.dirname(mdPath);
2650
+ const EXE_OS_DIR = path11.join(os8.homedir(), ".exe-os");
2651
+ const mdPath = path11.join(EXE_OS_DIR, taskFile);
2652
+ const mdDir = path11.dirname(mdPath);
2527
2653
  if (!existsSync10(mdDir)) await mkdir3(mdDir, { recursive: true });
2528
2654
  const reviewer = input.reviewer ?? input.assignedBy;
2529
2655
  const mdContent = `# ${input.title}
@@ -2824,7 +2950,7 @@ async function deleteTaskCore(taskId, _baseDir) {
2824
2950
  return { taskFile, assignedTo, assignedBy, taskSlug };
2825
2951
  }
2826
2952
  async function ensureArchitectureDoc(baseDir, projectName) {
2827
- const archPath = path10.join(baseDir, "exe", "ARCHITECTURE.md");
2953
+ const archPath = path11.join(baseDir, "exe", "ARCHITECTURE.md");
2828
2954
  try {
2829
2955
  if (existsSync10(archPath)) return;
2830
2956
  const template = [
@@ -2859,7 +2985,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
2859
2985
  }
2860
2986
  }
2861
2987
  async function ensureGitignoreExe(baseDir) {
2862
- const gitignorePath = path10.join(baseDir, ".gitignore");
2988
+ const gitignorePath = path11.join(baseDir, ".gitignore");
2863
2989
  try {
2864
2990
  if (existsSync10(gitignorePath)) {
2865
2991
  const content = readFileSync10(gitignorePath, "utf-8");
@@ -2893,13 +3019,13 @@ var init_tasks_crud = __esm({
2893
3019
  });
2894
3020
 
2895
3021
  // src/lib/tasks-review.ts
2896
- import path11 from "path";
3022
+ import path12 from "path";
2897
3023
  import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync4 } from "fs";
2898
3024
  async function countPendingReviews(sessionScope) {
2899
3025
  const client = getClient();
2900
3026
  if (sessionScope) {
2901
3027
  const result2 = await client.execute({
2902
- sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND (session_scope = ? OR session_scope IS NULL)",
3028
+ sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND session_scope = ?",
2903
3029
  args: [sessionScope]
2904
3030
  });
2905
3031
  return Number(result2.rows[0]?.cnt) || 0;
@@ -3075,11 +3201,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
3075
3201
  );
3076
3202
  }
3077
3203
  try {
3078
- const cacheDir = path11.join(EXE_AI_DIR, "session-cache");
3204
+ const cacheDir = path12.join(EXE_AI_DIR, "session-cache");
3079
3205
  if (existsSync11(cacheDir)) {
3080
3206
  for (const f of readdirSync3(cacheDir)) {
3081
3207
  if (f.startsWith("review-notified-")) {
3082
- unlinkSync4(path11.join(cacheDir, f));
3208
+ unlinkSync4(path12.join(cacheDir, f));
3083
3209
  }
3084
3210
  }
3085
3211
  }
@@ -3100,7 +3226,7 @@ var init_tasks_review = __esm({
3100
3226
  });
3101
3227
 
3102
3228
  // src/lib/tasks-chain.ts
3103
- import path12 from "path";
3229
+ import path13 from "path";
3104
3230
  import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
3105
3231
  async function cascadeUnblock(taskId, baseDir, now) {
3106
3232
  const client = getClient();
@@ -3117,7 +3243,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
3117
3243
  });
3118
3244
  for (const ur of unblockedRows.rows) {
3119
3245
  try {
3120
- const ubFile = path12.join(baseDir, String(ur.task_file));
3246
+ const ubFile = path13.join(baseDir, String(ur.task_file));
3121
3247
  let ubContent = await readFile3(ubFile, "utf-8");
3122
3248
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
3123
3249
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -3186,7 +3312,7 @@ var init_tasks_chain = __esm({
3186
3312
 
3187
3313
  // src/lib/project-name.ts
3188
3314
  import { execSync as execSync6 } from "child_process";
3189
- import path13 from "path";
3315
+ import path14 from "path";
3190
3316
  function getProjectName(cwd) {
3191
3317
  const dir = cwd ?? process.cwd();
3192
3318
  if (_cached2 && _cachedCwd === dir) return _cached2;
@@ -3199,7 +3325,7 @@ function getProjectName(cwd) {
3199
3325
  timeout: 2e3,
3200
3326
  stdio: ["pipe", "pipe", "pipe"]
3201
3327
  }).trim();
3202
- repoRoot = path13.dirname(gitCommonDir);
3328
+ repoRoot = path14.dirname(gitCommonDir);
3203
3329
  } catch {
3204
3330
  repoRoot = execSync6("git rev-parse --show-toplevel", {
3205
3331
  cwd: dir,
@@ -3208,11 +3334,11 @@ function getProjectName(cwd) {
3208
3334
  stdio: ["pipe", "pipe", "pipe"]
3209
3335
  }).trim();
3210
3336
  }
3211
- _cached2 = path13.basename(repoRoot);
3337
+ _cached2 = path14.basename(repoRoot);
3212
3338
  _cachedCwd = dir;
3213
3339
  return _cached2;
3214
3340
  } catch {
3215
- _cached2 = path13.basename(dir);
3341
+ _cached2 = path14.basename(dir);
3216
3342
  _cachedCwd = dir;
3217
3343
  return _cached2;
3218
3344
  }
@@ -3685,7 +3811,7 @@ __export(tasks_exports, {
3685
3811
  updateTaskStatus: () => updateTaskStatus,
3686
3812
  writeCheckpoint: () => writeCheckpoint
3687
3813
  });
3688
- import path14 from "path";
3814
+ import path15 from "path";
3689
3815
  import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5 } from "fs";
3690
3816
  async function createTask(input) {
3691
3817
  const result = await createTaskCore(input);
@@ -3705,8 +3831,8 @@ async function updateTask(input) {
3705
3831
  const { row, taskFile, now, taskId } = await updateTaskStatus(input);
3706
3832
  try {
3707
3833
  const agent = String(row.assigned_to);
3708
- const cacheDir = path14.join(EXE_AI_DIR, "session-cache");
3709
- const cachePath = path14.join(cacheDir, `current-task-${agent}.json`);
3834
+ const cacheDir = path15.join(EXE_AI_DIR, "session-cache");
3835
+ const cachePath = path15.join(cacheDir, `current-task-${agent}.json`);
3710
3836
  if (input.status === "in_progress") {
3711
3837
  mkdirSync6(cacheDir, { recursive: true });
3712
3838
  writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
@@ -3877,15 +4003,15 @@ __export(identity_exports, {
3877
4003
  });
3878
4004
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
3879
4005
  import { readdirSync as readdirSync5 } from "fs";
3880
- import path16 from "path";
4006
+ import path17 from "path";
3881
4007
  import { createHash } from "crypto";
3882
4008
  function ensureDir2() {
3883
- if (!existsSync12(IDENTITY_DIR)) {
3884
- mkdirSync8(IDENTITY_DIR, { recursive: true });
4009
+ if (!existsSync12(IDENTITY_DIR2)) {
4010
+ mkdirSync8(IDENTITY_DIR2, { recursive: true });
3885
4011
  }
3886
4012
  }
3887
4013
  function identityPath(agentId) {
3888
- return path16.join(IDENTITY_DIR, `${agentId}.md`);
4014
+ return path17.join(IDENTITY_DIR2, `${agentId}.md`);
3889
4015
  }
3890
4016
  function parseFrontmatter(raw) {
3891
4017
  const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -3958,7 +4084,7 @@ async function updateIdentity(agentId, content, updatedBy) {
3958
4084
  }
3959
4085
  function listIdentities() {
3960
4086
  ensureDir2();
3961
- const files = readdirSync5(IDENTITY_DIR).filter((f) => f.endsWith(".md"));
4087
+ const files = readdirSync5(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
3962
4088
  const results = [];
3963
4089
  for (const file of files) {
3964
4090
  const agentId = file.replace(".md", "");
@@ -3991,13 +4117,13 @@ ${teamLines.join("\n")}`);
3991
4117
  }
3992
4118
  return parts.join("\n\n");
3993
4119
  }
3994
- var IDENTITY_DIR;
4120
+ var IDENTITY_DIR2;
3995
4121
  var init_identity = __esm({
3996
4122
  "src/lib/identity.ts"() {
3997
4123
  "use strict";
3998
4124
  init_config();
3999
4125
  init_database();
4000
- IDENTITY_DIR = path16.join(EXE_AI_DIR, "identity");
4126
+ IDENTITY_DIR2 = path17.join(EXE_AI_DIR, "identity");
4001
4127
  }
4002
4128
  });
4003
4129
 
@@ -4552,8 +4678,8 @@ init_session_key();
4552
4678
  init_employees();
4553
4679
  import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6, readdirSync as readdirSync4 } from "fs";
4554
4680
  import { execSync as execSync7 } from "child_process";
4555
- import path15 from "path";
4556
- var CACHE_DIR = path15.join(EXE_AI_DIR, "session-cache");
4681
+ import path16 from "path";
4682
+ var CACHE_DIR = path16.join(EXE_AI_DIR, "session-cache");
4557
4683
  var STALE_MS = 24 * 60 * 60 * 1e3;
4558
4684
  function isNameWithOptionalInstance(candidate, baseName) {
4559
4685
  if (candidate === baseName) return true;
@@ -4598,7 +4724,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
4598
4724
  return null;
4599
4725
  }
4600
4726
  function getMarkerPath() {
4601
- return path15.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
4727
+ return path16.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
4602
4728
  }
4603
4729
  function getActiveAgent() {
4604
4730
  try {