@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
@@ -326,7 +326,7 @@ function isMultiInstance(agentName, employees) {
326
326
  if (!emp) return false;
327
327
  return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
328
328
  }
329
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES;
329
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, MULTI_INSTANCE_ROLES, IDENTITY_DIR;
330
330
  var init_employees = __esm({
331
331
  "src/lib/employees.ts"() {
332
332
  "use strict";
@@ -335,6 +335,7 @@ var init_employees = __esm({
335
335
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
336
336
  COORDINATOR_ROLE = "COO";
337
337
  MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
338
+ IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
338
339
  }
339
340
  });
340
341
 
@@ -794,13 +795,597 @@ var init_db_retry = __esm({
794
795
  }
795
796
  });
796
797
 
798
+ // src/lib/database-adapter.ts
799
+ import os5 from "os";
800
+ import path7 from "path";
801
+ import { createRequire } from "module";
802
+ import { pathToFileURL } from "url";
803
+ function quotedIdentifier(identifier) {
804
+ return `"${identifier.replace(/"/g, '""')}"`;
805
+ }
806
+ function unqualifiedTableName(name) {
807
+ const raw = name.trim().replace(/^"|"$/g, "");
808
+ const parts = raw.split(".");
809
+ return parts[parts.length - 1].replace(/^"|"$/g, "").toLowerCase();
810
+ }
811
+ function stripTrailingSemicolon(sql) {
812
+ return sql.trim().replace(/;+\s*$/u, "");
813
+ }
814
+ function appendClause(sql, clause) {
815
+ const trimmed = stripTrailingSemicolon(sql);
816
+ const returningMatch = /\sRETURNING\b[\s\S]*$/iu.exec(trimmed);
817
+ if (!returningMatch) {
818
+ return `${trimmed}${clause}`;
819
+ }
820
+ const idx = returningMatch.index;
821
+ return `${trimmed.slice(0, idx)}${clause}${trimmed.slice(idx)}`;
822
+ }
823
+ function normalizeStatement(stmt) {
824
+ if (typeof stmt === "string") {
825
+ return { kind: "positional", sql: stmt, args: [] };
826
+ }
827
+ const sql = stmt.sql;
828
+ if (Array.isArray(stmt.args) || stmt.args === void 0) {
829
+ return { kind: "positional", sql, args: stmt.args ?? [] };
830
+ }
831
+ return { kind: "named", sql, args: stmt.args };
832
+ }
833
+ function rewriteBooleanLiterals(sql) {
834
+ let out = sql;
835
+ for (const column of BOOLEAN_COLUMN_NAMES) {
836
+ const scoped = `((?:\\b[a-z_][a-z0-9_]*\\.)?${column})`;
837
+ out = out.replace(new RegExp(`${scoped}\\s*=\\s*0\\b`, "giu"), "$1 = FALSE");
838
+ out = out.replace(new RegExp(`${scoped}\\s*=\\s*1\\b`, "giu"), "$1 = TRUE");
839
+ out = out.replace(new RegExp(`${scoped}\\s*!=\\s*0\\b`, "giu"), "$1 != FALSE");
840
+ out = out.replace(new RegExp(`${scoped}\\s*!=\\s*1\\b`, "giu"), "$1 != TRUE");
841
+ out = out.replace(new RegExp(`${scoped}\\s*<>\\s*0\\b`, "giu"), "$1 <> FALSE");
842
+ out = out.replace(new RegExp(`${scoped}\\s*<>\\s*1\\b`, "giu"), "$1 <> TRUE");
843
+ }
844
+ return out;
845
+ }
846
+ function rewriteInsertOrIgnore(sql) {
847
+ if (!/^\s*INSERT\s+OR\s+IGNORE\s+INTO\b/iu.test(sql)) {
848
+ return sql;
849
+ }
850
+ const replaced = sql.replace(/^\s*INSERT\s+OR\s+IGNORE\s+INTO\b/iu, "INSERT INTO");
851
+ return /\bON\s+CONFLICT\b/iu.test(replaced) ? replaced : appendClause(replaced, " ON CONFLICT DO NOTHING");
852
+ }
853
+ function rewriteInsertOrReplace(sql) {
854
+ const match = /^\s*INSERT\s+OR\s+REPLACE\s+INTO\s+([A-Za-z0-9_."]+)\s*\(([^)]+)\)([\s\S]*)$/iu.exec(sql);
855
+ if (!match) {
856
+ return sql;
857
+ }
858
+ const rawTable = match[1];
859
+ const rawColumns = match[2];
860
+ const remainder = match[3];
861
+ const tableName = unqualifiedTableName(rawTable);
862
+ const conflictKeys = UPSERT_KEYS[tableName];
863
+ if (!conflictKeys?.length) {
864
+ return sql;
865
+ }
866
+ const columns = rawColumns.split(",").map((col) => col.trim().replace(/^"|"$/g, ""));
867
+ const updateColumns = columns.filter((col) => !conflictKeys.includes(col));
868
+ const conflictTarget = conflictKeys.map(quotedIdentifier).join(", ");
869
+ const updateClause = updateColumns.length === 0 ? " DO NOTHING" : ` DO UPDATE SET ${updateColumns.map((col) => `${quotedIdentifier(col)} = EXCLUDED.${quotedIdentifier(col)}`).join(", ")}`;
870
+ return `INSERT INTO ${rawTable} (${rawColumns})${appendClause(remainder, ` ON CONFLICT (${conflictTarget})${updateClause}`)}`;
871
+ }
872
+ function rewriteSql(sql) {
873
+ let out = sql;
874
+ out = out.replace(/\bdatetime\(\s*['"]now['"]\s*\)/giu, "CURRENT_TIMESTAMP");
875
+ out = out.replace(/\bvector32\s*\(\s*\?\s*\)/giu, "?");
876
+ out = rewriteBooleanLiterals(out);
877
+ out = rewriteInsertOrReplace(out);
878
+ out = rewriteInsertOrIgnore(out);
879
+ return stripTrailingSemicolon(out);
880
+ }
881
+ function toBoolean(value) {
882
+ if (value === null || value === void 0) return value;
883
+ if (typeof value === "boolean") return value;
884
+ if (typeof value === "number") return value !== 0;
885
+ if (typeof value === "bigint") return value !== 0n;
886
+ if (typeof value === "string") {
887
+ const normalized = value.trim().toLowerCase();
888
+ if (normalized === "0" || normalized === "false") return false;
889
+ if (normalized === "1" || normalized === "true") return true;
890
+ }
891
+ return Boolean(value);
892
+ }
893
+ function countQuestionMarks(sql, end) {
894
+ let count = 0;
895
+ let inSingle = false;
896
+ let inDouble = false;
897
+ let inLineComment = false;
898
+ let inBlockComment = false;
899
+ for (let i = 0; i < end; i++) {
900
+ const ch = sql[i];
901
+ const next = sql[i + 1];
902
+ if (inLineComment) {
903
+ if (ch === "\n") inLineComment = false;
904
+ continue;
905
+ }
906
+ if (inBlockComment) {
907
+ if (ch === "*" && next === "/") {
908
+ inBlockComment = false;
909
+ i += 1;
910
+ }
911
+ continue;
912
+ }
913
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
914
+ inLineComment = true;
915
+ i += 1;
916
+ continue;
917
+ }
918
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
919
+ inBlockComment = true;
920
+ i += 1;
921
+ continue;
922
+ }
923
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
924
+ inSingle = !inSingle;
925
+ continue;
926
+ }
927
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
928
+ inDouble = !inDouble;
929
+ continue;
930
+ }
931
+ if (!inSingle && !inDouble && ch === "?") {
932
+ count += 1;
933
+ }
934
+ }
935
+ return count;
936
+ }
937
+ function findBooleanPlaceholderIndexes(sql) {
938
+ const indexes = /* @__PURE__ */ new Set();
939
+ for (const column of BOOLEAN_COLUMN_NAMES) {
940
+ const pattern = new RegExp(`(?:\\b[a-z_][a-z0-9_]*\\.)?${column}\\s*=\\s*\\?`, "giu");
941
+ for (const match of sql.matchAll(pattern)) {
942
+ const matchText = match[0];
943
+ const qIndex = match.index + matchText.lastIndexOf("?");
944
+ indexes.add(countQuestionMarks(sql, qIndex + 1));
945
+ }
946
+ }
947
+ return indexes;
948
+ }
949
+ function coerceInsertBooleanArgs(sql, args) {
950
+ const match = /^\s*INSERT(?:\s+OR\s+(?:IGNORE|REPLACE))?\s+INTO\s+([A-Za-z0-9_."]+)\s*\(([^)]+)\)/iu.exec(sql);
951
+ if (!match) return;
952
+ const rawTable = match[1];
953
+ const rawColumns = match[2];
954
+ const boolColumns = BOOLEAN_COLUMNS_BY_TABLE[unqualifiedTableName(rawTable)];
955
+ if (!boolColumns?.size) return;
956
+ const columns = rawColumns.split(",").map((col) => col.trim().replace(/^"|"$/g, ""));
957
+ for (const [index, column] of columns.entries()) {
958
+ if (boolColumns.has(column) && index < args.length) {
959
+ args[index] = toBoolean(args[index]);
960
+ }
961
+ }
962
+ }
963
+ function coerceUpdateBooleanArgs(sql, args) {
964
+ const match = /^\s*UPDATE\s+([A-Za-z0-9_."]+)\s+SET\s+([\s\S]+?)(?:\s+WHERE\b|$)/iu.exec(sql);
965
+ if (!match) return;
966
+ const rawTable = match[1];
967
+ const setClause = match[2];
968
+ const boolColumns = BOOLEAN_COLUMNS_BY_TABLE[unqualifiedTableName(rawTable)];
969
+ if (!boolColumns?.size) return;
970
+ const assignments = setClause.split(",");
971
+ let placeholderIndex = 0;
972
+ for (const assignment of assignments) {
973
+ if (!assignment.includes("?")) continue;
974
+ placeholderIndex += 1;
975
+ const colMatch = /^\s*(?:[A-Za-z_][A-Za-z0-9_]*\.)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*\?/iu.exec(assignment);
976
+ if (colMatch && boolColumns.has(colMatch[1])) {
977
+ args[placeholderIndex - 1] = toBoolean(args[placeholderIndex - 1]);
978
+ }
979
+ }
980
+ }
981
+ function coerceBooleanArgs(sql, args) {
982
+ const nextArgs = [...args];
983
+ coerceInsertBooleanArgs(sql, nextArgs);
984
+ coerceUpdateBooleanArgs(sql, nextArgs);
985
+ const placeholderIndexes = findBooleanPlaceholderIndexes(sql);
986
+ for (const index of placeholderIndexes) {
987
+ if (index > 0 && index <= nextArgs.length) {
988
+ nextArgs[index - 1] = toBoolean(nextArgs[index - 1]);
989
+ }
990
+ }
991
+ return nextArgs;
992
+ }
993
+ function convertQuestionMarksToDollarParams(sql) {
994
+ let out = "";
995
+ let placeholder = 0;
996
+ let inSingle = false;
997
+ let inDouble = false;
998
+ let inLineComment = false;
999
+ let inBlockComment = false;
1000
+ for (let i = 0; i < sql.length; i++) {
1001
+ const ch = sql[i];
1002
+ const next = sql[i + 1];
1003
+ if (inLineComment) {
1004
+ out += ch;
1005
+ if (ch === "\n") inLineComment = false;
1006
+ continue;
1007
+ }
1008
+ if (inBlockComment) {
1009
+ out += ch;
1010
+ if (ch === "*" && next === "/") {
1011
+ out += next;
1012
+ inBlockComment = false;
1013
+ i += 1;
1014
+ }
1015
+ continue;
1016
+ }
1017
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
1018
+ out += ch + next;
1019
+ inLineComment = true;
1020
+ i += 1;
1021
+ continue;
1022
+ }
1023
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
1024
+ out += ch + next;
1025
+ inBlockComment = true;
1026
+ i += 1;
1027
+ continue;
1028
+ }
1029
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
1030
+ inSingle = !inSingle;
1031
+ out += ch;
1032
+ continue;
1033
+ }
1034
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
1035
+ inDouble = !inDouble;
1036
+ out += ch;
1037
+ continue;
1038
+ }
1039
+ if (!inSingle && !inDouble && ch === "?") {
1040
+ placeholder += 1;
1041
+ out += `$${placeholder}`;
1042
+ continue;
1043
+ }
1044
+ out += ch;
1045
+ }
1046
+ return out;
1047
+ }
1048
+ function translateStatementForPostgres(stmt) {
1049
+ const normalized = normalizeStatement(stmt);
1050
+ if (normalized.kind === "named") {
1051
+ throw new Error("Named SQL parameters are not supported by the Prisma adapter.");
1052
+ }
1053
+ const rewrittenSql = rewriteSql(normalized.sql);
1054
+ const coercedArgs = coerceBooleanArgs(rewrittenSql, normalized.args);
1055
+ return {
1056
+ sql: convertQuestionMarksToDollarParams(rewrittenSql),
1057
+ args: coercedArgs
1058
+ };
1059
+ }
1060
+ function shouldBypassPostgres(stmt) {
1061
+ const normalized = normalizeStatement(stmt);
1062
+ if (normalized.kind === "named") {
1063
+ return true;
1064
+ }
1065
+ return IMMEDIATE_FALLBACK_PATTERNS.some((pattern) => pattern.test(normalized.sql));
1066
+ }
1067
+ function shouldFallbackOnError(error) {
1068
+ const message = error instanceof Error ? error.message : String(error);
1069
+ return /42P01|42883|42601|does not exist|syntax error|not supported|Named SQL parameters are not supported/iu.test(message);
1070
+ }
1071
+ function isReadQuery(sql) {
1072
+ const trimmed = sql.trimStart();
1073
+ return /^(SELECT|WITH|SHOW|EXPLAIN|VALUES)\b/iu.test(trimmed) || /\bRETURNING\b/iu.test(trimmed);
1074
+ }
1075
+ function buildRow(row, columns) {
1076
+ const values = columns.map((column) => row[column]);
1077
+ return Object.assign(values, row);
1078
+ }
1079
+ function buildResultSet(rows, rowsAffected = 0) {
1080
+ const columns = rows[0] ? Object.keys(rows[0]) : [];
1081
+ const resultRows = rows.map((row) => buildRow(row, columns));
1082
+ return {
1083
+ columns,
1084
+ columnTypes: columns.map(() => ""),
1085
+ rows: resultRows,
1086
+ rowsAffected,
1087
+ lastInsertRowid: void 0,
1088
+ toJSON() {
1089
+ return {
1090
+ columns,
1091
+ columnTypes: columns.map(() => ""),
1092
+ rows,
1093
+ rowsAffected,
1094
+ lastInsertRowid: void 0
1095
+ };
1096
+ }
1097
+ };
1098
+ }
1099
+ async function loadPrismaClient() {
1100
+ if (!prismaClientPromise) {
1101
+ prismaClientPromise = (async () => {
1102
+ const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
1103
+ if (explicitPath) {
1104
+ const module2 = await import(pathToFileURL(explicitPath).href);
1105
+ const PrismaClient2 = module2.PrismaClient ?? module2.default?.PrismaClient;
1106
+ if (!PrismaClient2) {
1107
+ throw new Error(`No PrismaClient export found at ${explicitPath}`);
1108
+ }
1109
+ return new PrismaClient2();
1110
+ }
1111
+ const exeDbRoot = process.env.EXE_DB_ROOT ?? path7.join(os5.homedir(), "exe-db");
1112
+ const requireFromExeDb = createRequire(path7.join(exeDbRoot, "package.json"));
1113
+ const prismaEntry = requireFromExeDb.resolve("@prisma/client");
1114
+ const module = await import(pathToFileURL(prismaEntry).href);
1115
+ const PrismaClient = module.PrismaClient ?? module.default?.PrismaClient;
1116
+ if (!PrismaClient) {
1117
+ throw new Error(`No PrismaClient export found in ${prismaEntry}`);
1118
+ }
1119
+ return new PrismaClient();
1120
+ })();
1121
+ }
1122
+ return prismaClientPromise;
1123
+ }
1124
+ async function ensureCompatibilityViews(prisma) {
1125
+ if (!compatibilityBootstrapPromise) {
1126
+ compatibilityBootstrapPromise = (async () => {
1127
+ for (const mapping of VIEW_MAPPINGS) {
1128
+ const relation = mapping.source.replace(/"/g, "");
1129
+ const rows = await prisma.$queryRawUnsafe(
1130
+ "SELECT to_regclass($1) AS regclass",
1131
+ relation
1132
+ );
1133
+ if (!rows[0]?.regclass) {
1134
+ continue;
1135
+ }
1136
+ await prisma.$executeRawUnsafe(
1137
+ `CREATE OR REPLACE VIEW public.${quotedIdentifier(mapping.view)} AS SELECT * FROM ${mapping.source}`
1138
+ );
1139
+ }
1140
+ })();
1141
+ }
1142
+ return compatibilityBootstrapPromise;
1143
+ }
1144
+ async function executeOnPrisma(executor, stmt) {
1145
+ const translated = translateStatementForPostgres(stmt);
1146
+ if (isReadQuery(translated.sql)) {
1147
+ const rows = await executor.$queryRawUnsafe(
1148
+ translated.sql,
1149
+ ...translated.args
1150
+ );
1151
+ return buildResultSet(rows, /\bRETURNING\b/iu.test(translated.sql) ? rows.length : 0);
1152
+ }
1153
+ const rowsAffected = await executor.$executeRawUnsafe(translated.sql, ...translated.args);
1154
+ return buildResultSet([], rowsAffected);
1155
+ }
1156
+ function splitSqlStatements(sql) {
1157
+ const parts = [];
1158
+ let current = "";
1159
+ let inSingle = false;
1160
+ let inDouble = false;
1161
+ let inLineComment = false;
1162
+ let inBlockComment = false;
1163
+ for (let i = 0; i < sql.length; i++) {
1164
+ const ch = sql[i];
1165
+ const next = sql[i + 1];
1166
+ if (inLineComment) {
1167
+ current += ch;
1168
+ if (ch === "\n") inLineComment = false;
1169
+ continue;
1170
+ }
1171
+ if (inBlockComment) {
1172
+ current += ch;
1173
+ if (ch === "*" && next === "/") {
1174
+ current += next;
1175
+ inBlockComment = false;
1176
+ i += 1;
1177
+ }
1178
+ continue;
1179
+ }
1180
+ if (!inSingle && !inDouble && ch === "-" && next === "-") {
1181
+ current += ch + next;
1182
+ inLineComment = true;
1183
+ i += 1;
1184
+ continue;
1185
+ }
1186
+ if (!inSingle && !inDouble && ch === "/" && next === "*") {
1187
+ current += ch + next;
1188
+ inBlockComment = true;
1189
+ i += 1;
1190
+ continue;
1191
+ }
1192
+ if (!inDouble && ch === "'" && sql[i - 1] !== "\\") {
1193
+ inSingle = !inSingle;
1194
+ current += ch;
1195
+ continue;
1196
+ }
1197
+ if (!inSingle && ch === '"' && sql[i - 1] !== "\\") {
1198
+ inDouble = !inDouble;
1199
+ current += ch;
1200
+ continue;
1201
+ }
1202
+ if (!inSingle && !inDouble && ch === ";") {
1203
+ if (current.trim()) {
1204
+ parts.push(current.trim());
1205
+ }
1206
+ current = "";
1207
+ continue;
1208
+ }
1209
+ current += ch;
1210
+ }
1211
+ if (current.trim()) {
1212
+ parts.push(current.trim());
1213
+ }
1214
+ return parts;
1215
+ }
1216
+ async function createPrismaDbAdapter(fallbackClient) {
1217
+ const prisma = await loadPrismaClient();
1218
+ await ensureCompatibilityViews(prisma);
1219
+ let closed = false;
1220
+ let adapter;
1221
+ const fallbackExecute = async (stmt, error) => {
1222
+ if (!fallbackClient) {
1223
+ if (error) throw error;
1224
+ throw new Error("No fallback SQLite client is available for this Prisma-routed query.");
1225
+ }
1226
+ if (error) {
1227
+ process.stderr.write(
1228
+ `[database-adapter] Falling back to SQLite: ${error instanceof Error ? error.message : String(error)}
1229
+ `
1230
+ );
1231
+ }
1232
+ return fallbackClient.execute(stmt);
1233
+ };
1234
+ adapter = {
1235
+ async execute(stmt) {
1236
+ if (shouldBypassPostgres(stmt)) {
1237
+ return fallbackExecute(stmt);
1238
+ }
1239
+ try {
1240
+ return await executeOnPrisma(prisma, stmt);
1241
+ } catch (error) {
1242
+ if (shouldFallbackOnError(error)) {
1243
+ return fallbackExecute(stmt, error);
1244
+ }
1245
+ throw error;
1246
+ }
1247
+ },
1248
+ async batch(stmts, mode) {
1249
+ if (stmts.some((stmt) => shouldBypassPostgres(stmt))) {
1250
+ if (!fallbackClient) {
1251
+ throw new Error("Cannot batch unsupported SQLite-only statements without a fallback client.");
1252
+ }
1253
+ return fallbackClient.batch(stmts, mode);
1254
+ }
1255
+ try {
1256
+ if (prisma.$transaction) {
1257
+ return await prisma.$transaction(async (tx) => {
1258
+ const results2 = [];
1259
+ for (const stmt of stmts) {
1260
+ results2.push(await executeOnPrisma(tx, stmt));
1261
+ }
1262
+ return results2;
1263
+ });
1264
+ }
1265
+ const results = [];
1266
+ for (const stmt of stmts) {
1267
+ results.push(await executeOnPrisma(prisma, stmt));
1268
+ }
1269
+ return results;
1270
+ } catch (error) {
1271
+ if (fallbackClient && shouldFallbackOnError(error)) {
1272
+ process.stderr.write(
1273
+ `[database-adapter] Falling back batch to SQLite: ${error instanceof Error ? error.message : String(error)}
1274
+ `
1275
+ );
1276
+ return fallbackClient.batch(stmts, mode);
1277
+ }
1278
+ throw error;
1279
+ }
1280
+ },
1281
+ async migrate(stmts) {
1282
+ if (fallbackClient) {
1283
+ return fallbackClient.migrate(stmts);
1284
+ }
1285
+ return adapter.batch(stmts, "deferred");
1286
+ },
1287
+ async transaction(mode) {
1288
+ if (!fallbackClient) {
1289
+ throw new Error("Interactive transactions are only supported on the SQLite fallback client.");
1290
+ }
1291
+ return fallbackClient.transaction(mode);
1292
+ },
1293
+ async executeMultiple(sql) {
1294
+ if (fallbackClient && shouldBypassPostgres(sql)) {
1295
+ return fallbackClient.executeMultiple(sql);
1296
+ }
1297
+ for (const statement of splitSqlStatements(sql)) {
1298
+ await adapter.execute(statement);
1299
+ }
1300
+ },
1301
+ async sync() {
1302
+ if (fallbackClient) {
1303
+ return fallbackClient.sync();
1304
+ }
1305
+ return { frame_no: 0, frames_synced: 0 };
1306
+ },
1307
+ close() {
1308
+ closed = true;
1309
+ prismaClientPromise = null;
1310
+ compatibilityBootstrapPromise = null;
1311
+ void prisma.$disconnect?.();
1312
+ },
1313
+ get closed() {
1314
+ return closed;
1315
+ },
1316
+ get protocol() {
1317
+ return "prisma-postgres";
1318
+ }
1319
+ };
1320
+ return adapter;
1321
+ }
1322
+ var VIEW_MAPPINGS, UPSERT_KEYS, BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES, IMMEDIATE_FALLBACK_PATTERNS, prismaClientPromise, compatibilityBootstrapPromise;
1323
+ var init_database_adapter = __esm({
1324
+ "src/lib/database-adapter.ts"() {
1325
+ "use strict";
1326
+ VIEW_MAPPINGS = [
1327
+ { view: "memories", source: "memory.memory_records" },
1328
+ { view: "tasks", source: "memory.tasks" },
1329
+ { view: "behaviors", source: "memory.behaviors" },
1330
+ { view: "entities", source: "memory.entities" },
1331
+ { view: "relationships", source: "memory.relationships" },
1332
+ { view: "entity_memories", source: "memory.entity_memories" },
1333
+ { view: "entity_aliases", source: "memory.entity_aliases" },
1334
+ { view: "notifications", source: "memory.notifications" },
1335
+ { view: "messages", source: "memory.messages" },
1336
+ { view: "users", source: "wiki.users" },
1337
+ { view: "workspaces", source: "wiki.workspaces" },
1338
+ { view: "workspace_users", source: "wiki.workspace_users" },
1339
+ { view: "documents", source: "wiki.workspace_documents" },
1340
+ { view: "chats", source: "wiki.workspace_chats" }
1341
+ ];
1342
+ UPSERT_KEYS = {
1343
+ memories: ["id"],
1344
+ tasks: ["id"],
1345
+ behaviors: ["id"],
1346
+ entities: ["id"],
1347
+ relationships: ["id"],
1348
+ entity_aliases: ["alias"],
1349
+ notifications: ["id"],
1350
+ messages: ["id"],
1351
+ users: ["id"],
1352
+ workspaces: ["id"],
1353
+ workspace_users: ["id"],
1354
+ documents: ["id"],
1355
+ chats: ["id"]
1356
+ };
1357
+ BOOLEAN_COLUMNS_BY_TABLE = {
1358
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
1359
+ behaviors: /* @__PURE__ */ new Set(["active"]),
1360
+ notifications: /* @__PURE__ */ new Set(["read"]),
1361
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
1362
+ };
1363
+ BOOLEAN_COLUMN_NAMES = new Set(
1364
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
1365
+ );
1366
+ IMMEDIATE_FALLBACK_PATTERNS = [
1367
+ /\bPRAGMA\b/i,
1368
+ /\bsqlite_master\b/i,
1369
+ /(?:^|[.\s])(?:memories|conversations|entities)_fts\b/i,
1370
+ /\bMATCH\b/i,
1371
+ /\bvector_distance_cos\s*\(/i,
1372
+ /\bjson_extract\s*\(/i,
1373
+ /\bjulianday\s*\(/i,
1374
+ /\bstrftime\s*\(/i,
1375
+ /\blast_insert_rowid\s*\(/i
1376
+ ];
1377
+ prismaClientPromise = null;
1378
+ compatibilityBootstrapPromise = null;
1379
+ }
1380
+ });
1381
+
797
1382
  // src/lib/exe-daemon-client.ts
798
1383
  import net from "net";
799
- import os5 from "os";
1384
+ import os6 from "os";
800
1385
  import { spawn } from "child_process";
801
1386
  import { randomUUID } from "crypto";
802
1387
  import { existsSync as existsSync6, unlinkSync as unlinkSync3, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
803
- import path7 from "path";
1388
+ import path8 from "path";
804
1389
  import { fileURLToPath } from "url";
805
1390
  function handleData(chunk) {
806
1391
  _buffer += chunk.toString();
@@ -851,17 +1436,17 @@ function cleanupStaleFiles() {
851
1436
  }
852
1437
  }
853
1438
  function findPackageRoot() {
854
- let dir = path7.dirname(fileURLToPath(import.meta.url));
855
- const { root } = path7.parse(dir);
1439
+ let dir = path8.dirname(fileURLToPath(import.meta.url));
1440
+ const { root } = path8.parse(dir);
856
1441
  while (dir !== root) {
857
- if (existsSync6(path7.join(dir, "package.json"))) return dir;
858
- dir = path7.dirname(dir);
1442
+ if (existsSync6(path8.join(dir, "package.json"))) return dir;
1443
+ dir = path8.dirname(dir);
859
1444
  }
860
1445
  return null;
861
1446
  }
862
1447
  function spawnDaemon() {
863
- const freeGB = os5.freemem() / (1024 * 1024 * 1024);
864
- const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
1448
+ const freeGB = os6.freemem() / (1024 * 1024 * 1024);
1449
+ const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
865
1450
  if (totalGB <= 8) {
866
1451
  process.stderr.write(
867
1452
  `[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
@@ -881,7 +1466,7 @@ function spawnDaemon() {
881
1466
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
882
1467
  return;
883
1468
  }
884
- const daemonPath = path7.join(pkgRoot, "dist", "lib", "exe-daemon.js");
1469
+ const daemonPath = path8.join(pkgRoot, "dist", "lib", "exe-daemon.js");
885
1470
  if (!existsSync6(daemonPath)) {
886
1471
  process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
887
1472
  `);
@@ -890,7 +1475,7 @@ function spawnDaemon() {
890
1475
  const resolvedPath = daemonPath;
891
1476
  process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
892
1477
  `);
893
- const logPath = path7.join(path7.dirname(SOCKET_PATH), "exed.log");
1478
+ const logPath = path8.join(path8.dirname(SOCKET_PATH), "exed.log");
894
1479
  let stderrFd = "ignore";
895
1480
  try {
896
1481
  stderrFd = openSync(logPath, "a");
@@ -1037,9 +1622,9 @@ var init_exe_daemon_client = __esm({
1037
1622
  "src/lib/exe-daemon-client.ts"() {
1038
1623
  "use strict";
1039
1624
  init_config();
1040
- SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path7.join(EXE_AI_DIR, "exed.sock");
1041
- PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path7.join(EXE_AI_DIR, "exed.pid");
1042
- SPAWN_LOCK_PATH = path7.join(EXE_AI_DIR, "exed-spawn.lock");
1625
+ SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path8.join(EXE_AI_DIR, "exed.sock");
1626
+ PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path8.join(EXE_AI_DIR, "exed.pid");
1627
+ SPAWN_LOCK_PATH = path8.join(EXE_AI_DIR, "exed-spawn.lock");
1043
1628
  SPAWN_LOCK_STALE_MS = 3e4;
1044
1629
  CONNECT_TIMEOUT_MS = 15e3;
1045
1630
  REQUEST_TIMEOUT_MS = 3e4;
@@ -1121,7 +1706,7 @@ __export(db_daemon_client_exports, {
1121
1706
  createDaemonDbClient: () => createDaemonDbClient,
1122
1707
  initDaemonDbClient: () => initDaemonDbClient
1123
1708
  });
1124
- function normalizeStatement(stmt) {
1709
+ function normalizeStatement2(stmt) {
1125
1710
  if (typeof stmt === "string") {
1126
1711
  return { sql: stmt, args: [] };
1127
1712
  }
@@ -1145,7 +1730,7 @@ function createDaemonDbClient(fallbackClient) {
1145
1730
  if (!_useDaemon || !isClientConnected()) {
1146
1731
  return fallbackClient.execute(stmt);
1147
1732
  }
1148
- const { sql, args } = normalizeStatement(stmt);
1733
+ const { sql, args } = normalizeStatement2(stmt);
1149
1734
  const response = await sendDaemonRequest({
1150
1735
  type: "db-execute",
1151
1736
  sql,
@@ -1170,7 +1755,7 @@ function createDaemonDbClient(fallbackClient) {
1170
1755
  if (!_useDaemon || !isClientConnected()) {
1171
1756
  return fallbackClient.batch(stmts, mode);
1172
1757
  }
1173
- const statements = stmts.map(normalizeStatement);
1758
+ const statements = stmts.map(normalizeStatement2);
1174
1759
  const response = await sendDaemonRequest({
1175
1760
  type: "db-batch",
1176
1761
  statements,
@@ -1265,6 +1850,18 @@ __export(database_exports, {
1265
1850
  });
1266
1851
  import { createClient } from "@libsql/client";
1267
1852
  async function initDatabase(config) {
1853
+ if (_walCheckpointTimer) {
1854
+ clearInterval(_walCheckpointTimer);
1855
+ _walCheckpointTimer = null;
1856
+ }
1857
+ if (_daemonClient) {
1858
+ _daemonClient.close();
1859
+ _daemonClient = null;
1860
+ }
1861
+ if (_adapterClient && _adapterClient !== _resilientClient) {
1862
+ _adapterClient.close();
1863
+ }
1864
+ _adapterClient = null;
1268
1865
  if (_client) {
1269
1866
  _client.close();
1270
1867
  _client = null;
@@ -1278,6 +1875,7 @@ async function initDatabase(config) {
1278
1875
  }
1279
1876
  _client = createClient(opts);
1280
1877
  _resilientClient = wrapWithRetry(_client);
1878
+ _adapterClient = _resilientClient;
1281
1879
  _client.execute("PRAGMA busy_timeout = 30000").catch(() => {
1282
1880
  });
1283
1881
  _client.execute("PRAGMA journal_mode = WAL").catch(() => {
@@ -1288,14 +1886,20 @@ async function initDatabase(config) {
1288
1886
  });
1289
1887
  }, 3e4);
1290
1888
  _walCheckpointTimer.unref();
1889
+ if (process.env.DATABASE_URL) {
1890
+ _adapterClient = await createPrismaDbAdapter(_resilientClient);
1891
+ }
1291
1892
  }
1292
1893
  function isInitialized() {
1293
- return _client !== null;
1894
+ return _adapterClient !== null || _client !== null;
1294
1895
  }
1295
1896
  function getClient() {
1296
- if (!_resilientClient) {
1897
+ if (!_adapterClient) {
1297
1898
  throw new Error("Database client not initialized. Call initDatabase() first.");
1298
1899
  }
1900
+ if (process.env.DATABASE_URL) {
1901
+ return _adapterClient;
1902
+ }
1299
1903
  if (process.env.EXE_IS_DAEMON === "1") {
1300
1904
  return _resilientClient;
1301
1905
  }
@@ -1305,6 +1909,7 @@ function getClient() {
1305
1909
  return _resilientClient;
1306
1910
  }
1307
1911
  async function initDaemonClient() {
1912
+ if (process.env.DATABASE_URL) return;
1308
1913
  if (process.env.EXE_IS_DAEMON === "1") return;
1309
1914
  if (!_resilientClient) return;
1310
1915
  try {
@@ -2249,26 +2854,36 @@ async function ensureSchema() {
2249
2854
  }
2250
2855
  }
2251
2856
  async function disposeDatabase() {
2857
+ if (_walCheckpointTimer) {
2858
+ clearInterval(_walCheckpointTimer);
2859
+ _walCheckpointTimer = null;
2860
+ }
2252
2861
  if (_daemonClient) {
2253
2862
  _daemonClient.close();
2254
2863
  _daemonClient = null;
2255
2864
  }
2865
+ if (_adapterClient && _adapterClient !== _resilientClient) {
2866
+ _adapterClient.close();
2867
+ }
2868
+ _adapterClient = null;
2256
2869
  if (_client) {
2257
2870
  _client.close();
2258
2871
  _client = null;
2259
2872
  _resilientClient = null;
2260
2873
  }
2261
2874
  }
2262
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, initTurso, disposeTurso;
2875
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2263
2876
  var init_database = __esm({
2264
2877
  "src/lib/database.ts"() {
2265
2878
  "use strict";
2266
2879
  init_db_retry();
2267
2880
  init_employees();
2881
+ init_database_adapter();
2268
2882
  _client = null;
2269
2883
  _resilientClient = null;
2270
2884
  _walCheckpointTimer = null;
2271
2885
  _daemonClient = null;
2886
+ _adapterClient = null;
2272
2887
  initTurso = initDatabase;
2273
2888
  disposeTurso = disposeDatabase;
2274
2889
  }
@@ -2277,16 +2892,16 @@ var init_database = __esm({
2277
2892
  // src/lib/license.ts
2278
2893
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
2279
2894
  import { randomUUID as randomUUID2 } from "crypto";
2280
- import path8 from "path";
2895
+ import path9 from "path";
2281
2896
  import { jwtVerify, importSPKI } from "jose";
2282
2897
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
2283
2898
  var init_license = __esm({
2284
2899
  "src/lib/license.ts"() {
2285
2900
  "use strict";
2286
2901
  init_config();
2287
- LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
2288
- CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
2289
- DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
2902
+ LICENSE_PATH = path9.join(EXE_AI_DIR, "license.key");
2903
+ CACHE_PATH = path9.join(EXE_AI_DIR, "license-cache.json");
2904
+ DEVICE_ID_PATH = path9.join(EXE_AI_DIR, "device-id");
2290
2905
  PLAN_LIMITS = {
2291
2906
  free: { devices: 1, employees: 1, memories: 5e3 },
2292
2907
  pro: { devices: 3, employees: 5, memories: 1e5 },
@@ -2299,7 +2914,7 @@ var init_license = __esm({
2299
2914
 
2300
2915
  // src/lib/plan-limits.ts
2301
2916
  import { readFileSync as readFileSync9, existsSync as existsSync8 } from "fs";
2302
- import path9 from "path";
2917
+ import path10 from "path";
2303
2918
  function getLicenseSync() {
2304
2919
  try {
2305
2920
  if (!existsSync8(CACHE_PATH2)) return freeLicense();
@@ -2371,7 +2986,7 @@ var init_plan_limits = __esm({
2371
2986
  this.name = "PlanLimitError";
2372
2987
  }
2373
2988
  };
2374
- CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
2989
+ CACHE_PATH2 = path10.join(EXE_AI_DIR, "license-cache.json");
2375
2990
  }
2376
2991
  });
2377
2992
 
@@ -2388,8 +3003,8 @@ __export(notifications_exports, {
2388
3003
  writeNotification: () => writeNotification
2389
3004
  });
2390
3005
  import crypto from "crypto";
2391
- import path10 from "path";
2392
- import os6 from "os";
3006
+ import path11 from "path";
3007
+ import os7 from "os";
2393
3008
  import {
2394
3009
  readFileSync as readFileSync10,
2395
3010
  readdirSync as readdirSync2,
@@ -2530,8 +3145,8 @@ function formatNotifications(notifications) {
2530
3145
  return lines.join("\n");
2531
3146
  }
2532
3147
  async function migrateJsonNotifications() {
2533
- const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path10.join(os6.homedir(), ".exe-os");
2534
- const notifDir = path10.join(base, "notifications");
3148
+ const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path11.join(os7.homedir(), ".exe-os");
3149
+ const notifDir = path11.join(base, "notifications");
2535
3150
  if (!existsSync9(notifDir)) return 0;
2536
3151
  let migrated = 0;
2537
3152
  try {
@@ -2540,7 +3155,7 @@ async function migrateJsonNotifications() {
2540
3155
  const client = getClient();
2541
3156
  for (const file of files) {
2542
3157
  try {
2543
- const filePath = path10.join(notifDir, file);
3158
+ const filePath = path11.join(notifDir, file);
2544
3159
  const data = JSON.parse(readFileSync10(filePath, "utf8"));
2545
3160
  await client.execute({
2546
3161
  sql: `INSERT OR IGNORE INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, read, created_at)
@@ -2717,8 +3332,8 @@ __export(tasks_crud_exports, {
2717
3332
  writeCheckpoint: () => writeCheckpoint
2718
3333
  });
2719
3334
  import crypto3 from "crypto";
2720
- import path11 from "path";
2721
- import os7 from "os";
3335
+ import path12 from "path";
3336
+ import os8 from "os";
2722
3337
  import { execSync as execSync5 } from "child_process";
2723
3338
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
2724
3339
  import { existsSync as existsSync10, readFileSync as readFileSync11 } from "fs";
@@ -2896,8 +3511,8 @@ ${laneWarning}` : laneWarning;
2896
3511
  }
2897
3512
  if (input2.baseDir) {
2898
3513
  try {
2899
- await mkdir3(path11.join(input2.baseDir, "exe", "output"), { recursive: true });
2900
- await mkdir3(path11.join(input2.baseDir, "exe", "research"), { recursive: true });
3514
+ await mkdir3(path12.join(input2.baseDir, "exe", "output"), { recursive: true });
3515
+ await mkdir3(path12.join(input2.baseDir, "exe", "research"), { recursive: true });
2901
3516
  await ensureArchitectureDoc(input2.baseDir, input2.projectName);
2902
3517
  await ensureGitignoreExe(input2.baseDir);
2903
3518
  } catch {
@@ -2933,9 +3548,9 @@ ${laneWarning}` : laneWarning;
2933
3548
  });
2934
3549
  if (input2.baseDir) {
2935
3550
  try {
2936
- const EXE_OS_DIR = path11.join(os7.homedir(), ".exe-os");
2937
- const mdPath = path11.join(EXE_OS_DIR, taskFile);
2938
- const mdDir = path11.dirname(mdPath);
3551
+ const EXE_OS_DIR = path12.join(os8.homedir(), ".exe-os");
3552
+ const mdPath = path12.join(EXE_OS_DIR, taskFile);
3553
+ const mdDir = path12.dirname(mdPath);
2939
3554
  if (!existsSync10(mdDir)) await mkdir3(mdDir, { recursive: true });
2940
3555
  const reviewer = input2.reviewer ?? input2.assignedBy;
2941
3556
  const mdContent = `# ${input2.title}
@@ -3236,7 +3851,7 @@ async function deleteTaskCore(taskId, _baseDir) {
3236
3851
  return { taskFile, assignedTo, assignedBy, taskSlug };
3237
3852
  }
3238
3853
  async function ensureArchitectureDoc(baseDir, projectName) {
3239
- const archPath = path11.join(baseDir, "exe", "ARCHITECTURE.md");
3854
+ const archPath = path12.join(baseDir, "exe", "ARCHITECTURE.md");
3240
3855
  try {
3241
3856
  if (existsSync10(archPath)) return;
3242
3857
  const template = [
@@ -3271,7 +3886,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
3271
3886
  }
3272
3887
  }
3273
3888
  async function ensureGitignoreExe(baseDir) {
3274
- const gitignorePath = path11.join(baseDir, ".gitignore");
3889
+ const gitignorePath = path12.join(baseDir, ".gitignore");
3275
3890
  try {
3276
3891
  if (existsSync10(gitignorePath)) {
3277
3892
  const content = readFileSync11(gitignorePath, "utf-8");
@@ -3305,13 +3920,13 @@ var init_tasks_crud = __esm({
3305
3920
  });
3306
3921
 
3307
3922
  // src/lib/tasks-review.ts
3308
- import path12 from "path";
3923
+ import path13 from "path";
3309
3924
  import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync5 } from "fs";
3310
3925
  async function countPendingReviews(sessionScope) {
3311
3926
  const client = getClient();
3312
3927
  if (sessionScope) {
3313
3928
  const result2 = await client.execute({
3314
- sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND (session_scope = ? OR session_scope IS NULL)",
3929
+ sql: "SELECT COUNT(*) as cnt FROM tasks WHERE status = 'needs_review' AND session_scope = ?",
3315
3930
  args: [sessionScope]
3316
3931
  });
3317
3932
  return Number(result2.rows[0]?.cnt) || 0;
@@ -3487,11 +4102,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
3487
4102
  );
3488
4103
  }
3489
4104
  try {
3490
- const cacheDir = path12.join(EXE_AI_DIR, "session-cache");
4105
+ const cacheDir = path13.join(EXE_AI_DIR, "session-cache");
3491
4106
  if (existsSync11(cacheDir)) {
3492
4107
  for (const f of readdirSync3(cacheDir)) {
3493
4108
  if (f.startsWith("review-notified-")) {
3494
- unlinkSync5(path12.join(cacheDir, f));
4109
+ unlinkSync5(path13.join(cacheDir, f));
3495
4110
  }
3496
4111
  }
3497
4112
  }
@@ -3512,7 +4127,7 @@ var init_tasks_review = __esm({
3512
4127
  });
3513
4128
 
3514
4129
  // src/lib/tasks-chain.ts
3515
- import path13 from "path";
4130
+ import path14 from "path";
3516
4131
  import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
3517
4132
  async function cascadeUnblock(taskId, baseDir, now) {
3518
4133
  const client = getClient();
@@ -3529,7 +4144,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
3529
4144
  });
3530
4145
  for (const ur of unblockedRows.rows) {
3531
4146
  try {
3532
- const ubFile = path13.join(baseDir, String(ur.task_file));
4147
+ const ubFile = path14.join(baseDir, String(ur.task_file));
3533
4148
  let ubContent = await readFile3(ubFile, "utf-8");
3534
4149
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
3535
4150
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -3598,7 +4213,7 @@ var init_tasks_chain = __esm({
3598
4213
 
3599
4214
  // src/lib/project-name.ts
3600
4215
  import { execSync as execSync6 } from "child_process";
3601
- import path14 from "path";
4216
+ import path15 from "path";
3602
4217
  function getProjectName(cwd) {
3603
4218
  const dir = cwd ?? process.cwd();
3604
4219
  if (_cached2 && _cachedCwd === dir) return _cached2;
@@ -3611,7 +4226,7 @@ function getProjectName(cwd) {
3611
4226
  timeout: 2e3,
3612
4227
  stdio: ["pipe", "pipe", "pipe"]
3613
4228
  }).trim();
3614
- repoRoot = path14.dirname(gitCommonDir);
4229
+ repoRoot = path15.dirname(gitCommonDir);
3615
4230
  } catch {
3616
4231
  repoRoot = execSync6("git rev-parse --show-toplevel", {
3617
4232
  cwd: dir,
@@ -3620,11 +4235,11 @@ function getProjectName(cwd) {
3620
4235
  stdio: ["pipe", "pipe", "pipe"]
3621
4236
  }).trim();
3622
4237
  }
3623
- _cached2 = path14.basename(repoRoot);
4238
+ _cached2 = path15.basename(repoRoot);
3624
4239
  _cachedCwd = dir;
3625
4240
  return _cached2;
3626
4241
  } catch {
3627
- _cached2 = path14.basename(dir);
4242
+ _cached2 = path15.basename(dir);
3628
4243
  _cachedCwd = dir;
3629
4244
  return _cached2;
3630
4245
  }
@@ -4097,7 +4712,7 @@ __export(tasks_exports, {
4097
4712
  updateTaskStatus: () => updateTaskStatus,
4098
4713
  writeCheckpoint: () => writeCheckpoint
4099
4714
  });
4100
- import path15 from "path";
4715
+ import path16 from "path";
4101
4716
  import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync6 } from "fs";
4102
4717
  async function createTask(input2) {
4103
4718
  const result = await createTaskCore(input2);
@@ -4117,8 +4732,8 @@ async function updateTask(input2) {
4117
4732
  const { row, taskFile, now, taskId } = await updateTaskStatus(input2);
4118
4733
  try {
4119
4734
  const agent = String(row.assigned_to);
4120
- const cacheDir = path15.join(EXE_AI_DIR, "session-cache");
4121
- const cachePath = path15.join(cacheDir, `current-task-${agent}.json`);
4735
+ const cacheDir = path16.join(EXE_AI_DIR, "session-cache");
4736
+ const cachePath = path16.join(cacheDir, `current-task-${agent}.json`);
4122
4737
  if (input2.status === "in_progress") {
4123
4738
  mkdirSync6(cacheDir, { recursive: true });
4124
4739
  writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
@@ -4589,12 +5204,12 @@ __export(tmux_routing_exports, {
4589
5204
  });
4590
5205
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
4591
5206
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync12, appendFileSync, readdirSync as readdirSync4 } from "fs";
4592
- import path16 from "path";
4593
- import os8 from "os";
5207
+ import path17 from "path";
5208
+ import os9 from "os";
4594
5209
  import { fileURLToPath as fileURLToPath2 } from "url";
4595
5210
  import { unlinkSync as unlinkSync7 } from "fs";
4596
5211
  function spawnLockPath(sessionName) {
4597
- return path16.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
5212
+ return path17.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
4598
5213
  }
4599
5214
  function isProcessAlive(pid) {
4600
5215
  try {
@@ -4631,8 +5246,8 @@ function releaseSpawnLock2(sessionName) {
4631
5246
  function resolveBehaviorsExporterScript() {
4632
5247
  try {
4633
5248
  const thisFile = fileURLToPath2(import.meta.url);
4634
- const scriptPath = path16.join(
4635
- path16.dirname(thisFile),
5249
+ const scriptPath = path17.join(
5250
+ path17.dirname(thisFile),
4636
5251
  "..",
4637
5252
  "bin",
4638
5253
  "exe-export-behaviors.js"
@@ -4707,7 +5322,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
4707
5322
  mkdirSync7(SESSION_CACHE, { recursive: true });
4708
5323
  }
4709
5324
  const rootExe = extractRootExe(parentExe) ?? parentExe;
4710
- const filePath = path16.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
5325
+ const filePath = path17.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
4711
5326
  writeFileSync8(filePath, JSON.stringify({
4712
5327
  parentExe: rootExe,
4713
5328
  dispatchedBy: dispatchedBy || rootExe,
@@ -4716,7 +5331,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
4716
5331
  }
4717
5332
  function getParentExe(sessionKey) {
4718
5333
  try {
4719
- const data = JSON.parse(readFileSync12(path16.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
5334
+ const data = JSON.parse(readFileSync12(path17.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
4720
5335
  return data.parentExe || null;
4721
5336
  } catch {
4722
5337
  return null;
@@ -4725,7 +5340,7 @@ function getParentExe(sessionKey) {
4725
5340
  function getDispatchedBy(sessionKey) {
4726
5341
  try {
4727
5342
  const data = JSON.parse(readFileSync12(
4728
- path16.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
5343
+ path17.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
4729
5344
  "utf8"
4730
5345
  ));
4731
5346
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -4911,7 +5526,7 @@ function sendIntercom(targetSession) {
4911
5526
  try {
4912
5527
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
4913
5528
  const agent = baseAgentName(rawAgent);
4914
- const markerPath = path16.join(SESSION_CACHE, `current-task-${agent}.json`);
5529
+ const markerPath = path17.join(SESSION_CACHE, `current-task-${agent}.json`);
4915
5530
  if (existsSync12(markerPath)) {
4916
5531
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
4917
5532
  return "debounced";
@@ -4921,7 +5536,7 @@ function sendIntercom(targetSession) {
4921
5536
  try {
4922
5537
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
4923
5538
  const agent = baseAgentName(rawAgent);
4924
- const taskDir = path16.join(process.cwd(), "exe", agent);
5539
+ const taskDir = path17.join(process.cwd(), "exe", agent);
4925
5540
  if (existsSync12(taskDir)) {
4926
5541
  const files = readdirSync4(taskDir).filter(
4927
5542
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -5055,8 +5670,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5055
5670
  const transport = getTransport();
5056
5671
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
5057
5672
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
5058
- const logDir = path16.join(os8.homedir(), ".exe-os", "session-logs");
5059
- const logFile = path16.join(logDir, `${instanceLabel}-${Date.now()}.log`);
5673
+ const logDir = path17.join(os9.homedir(), ".exe-os", "session-logs");
5674
+ const logFile = path17.join(logDir, `${instanceLabel}-${Date.now()}.log`);
5060
5675
  if (!existsSync12(logDir)) {
5061
5676
  mkdirSync7(logDir, { recursive: true });
5062
5677
  }
@@ -5064,14 +5679,14 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5064
5679
  let cleanupSuffix = "";
5065
5680
  try {
5066
5681
  const thisFile = fileURLToPath2(import.meta.url);
5067
- const cleanupScript = path16.join(path16.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
5682
+ const cleanupScript = path17.join(path17.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
5068
5683
  if (existsSync12(cleanupScript)) {
5069
5684
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
5070
5685
  }
5071
5686
  } catch {
5072
5687
  }
5073
5688
  try {
5074
- const claudeJsonPath = path16.join(os8.homedir(), ".claude.json");
5689
+ const claudeJsonPath = path17.join(os9.homedir(), ".claude.json");
5075
5690
  let claudeJson = {};
5076
5691
  try {
5077
5692
  claudeJson = JSON.parse(readFileSync12(claudeJsonPath, "utf8"));
@@ -5086,10 +5701,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5086
5701
  } catch {
5087
5702
  }
5088
5703
  try {
5089
- const settingsDir = path16.join(os8.homedir(), ".claude", "projects");
5704
+ const settingsDir = path17.join(os9.homedir(), ".claude", "projects");
5090
5705
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
5091
- const projSettingsDir = path16.join(settingsDir, normalizedKey);
5092
- const settingsPath = path16.join(projSettingsDir, "settings.json");
5706
+ const projSettingsDir = path17.join(settingsDir, normalizedKey);
5707
+ const settingsPath = path17.join(projSettingsDir, "settings.json");
5093
5708
  let settings = {};
5094
5709
  try {
5095
5710
  settings = JSON.parse(readFileSync12(settingsPath, "utf8"));
@@ -5136,8 +5751,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5136
5751
  let behaviorsFlag = "";
5137
5752
  let legacyFallbackWarned = false;
5138
5753
  if (!useExeAgent && !useBinSymlink) {
5139
- const identityPath = path16.join(
5140
- os8.homedir(),
5754
+ const identityPath = path17.join(
5755
+ os9.homedir(),
5141
5756
  ".exe-os",
5142
5757
  "identity",
5143
5758
  `${employeeName}.md`
@@ -5152,7 +5767,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5152
5767
  }
5153
5768
  const behaviorsFile = exportBehaviorsSync(
5154
5769
  employeeName,
5155
- path16.basename(spawnCwd),
5770
+ path17.basename(spawnCwd),
5156
5771
  sessionName
5157
5772
  );
5158
5773
  if (behaviorsFile) {
@@ -5167,9 +5782,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5167
5782
  }
5168
5783
  let sessionContextFlag = "";
5169
5784
  try {
5170
- const ctxDir = path16.join(os8.homedir(), ".exe-os", "session-cache");
5785
+ const ctxDir = path17.join(os9.homedir(), ".exe-os", "session-cache");
5171
5786
  mkdirSync7(ctxDir, { recursive: true });
5172
- const ctxFile = path16.join(ctxDir, `session-context-${sessionName}.md`);
5787
+ const ctxFile = path17.join(ctxDir, `session-context-${sessionName}.md`);
5173
5788
  const ctxContent = [
5174
5789
  `## Session Context`,
5175
5790
  `You are running in tmux session: ${sessionName}.`,
@@ -5253,7 +5868,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
5253
5868
  transport.pipeLog(sessionName, logFile);
5254
5869
  try {
5255
5870
  const mySession = getMySession();
5256
- const dispatchInfo = path16.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
5871
+ const dispatchInfo = path17.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
5257
5872
  writeFileSync8(dispatchInfo, JSON.stringify({
5258
5873
  dispatchedBy: mySession,
5259
5874
  rootExe: exeSession,
@@ -5328,15 +5943,15 @@ var init_tmux_routing = __esm({
5328
5943
  init_intercom_queue();
5329
5944
  init_plan_limits();
5330
5945
  init_employees();
5331
- SPAWN_LOCK_DIR = path16.join(os8.homedir(), ".exe-os", "spawn-locks");
5332
- SESSION_CACHE = path16.join(os8.homedir(), ".exe-os", "session-cache");
5946
+ SPAWN_LOCK_DIR = path17.join(os9.homedir(), ".exe-os", "spawn-locks");
5947
+ SESSION_CACHE = path17.join(os9.homedir(), ".exe-os", "session-cache");
5333
5948
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
5334
5949
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
5335
5950
  VERIFY_PANE_LINES = 200;
5336
5951
  INTERCOM_DEBOUNCE_MS = 3e4;
5337
5952
  CODEX_DEBOUNCE_MS = 12e4;
5338
- INTERCOM_LOG2 = path16.join(os8.homedir(), ".exe-os", "intercom.log");
5339
- DEBOUNCE_FILE = path16.join(SESSION_CACHE, "intercom-debounce.json");
5953
+ INTERCOM_LOG2 = path17.join(os9.homedir(), ".exe-os", "intercom.log");
5954
+ DEBOUNCE_FILE = path17.join(SESSION_CACHE, "intercom-debounce.json");
5340
5955
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
5341
5956
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
5342
5957
  }
@@ -5378,13 +5993,13 @@ var init_memory = __esm({
5378
5993
  // src/lib/keychain.ts
5379
5994
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
5380
5995
  import { existsSync as existsSync13 } from "fs";
5381
- import path17 from "path";
5382
- import os9 from "os";
5996
+ import path18 from "path";
5997
+ import os10 from "os";
5383
5998
  function getKeyDir() {
5384
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path17.join(os9.homedir(), ".exe-os");
5999
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path18.join(os10.homedir(), ".exe-os");
5385
6000
  }
5386
6001
  function getKeyPath() {
5387
- return path17.join(getKeyDir(), "master.key");
6002
+ return path18.join(getKeyDir(), "master.key");
5388
6003
  }
5389
6004
  async function tryKeytar() {
5390
6005
  try {
@@ -5407,7 +6022,7 @@ async function getMasterKey() {
5407
6022
  const keyPath = getKeyPath();
5408
6023
  if (!existsSync13(keyPath)) {
5409
6024
  process.stderr.write(
5410
- `[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
6025
+ `[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
5411
6026
  `
5412
6027
  );
5413
6028
  return null;
@@ -5445,7 +6060,7 @@ __export(shard_manager_exports, {
5445
6060
  listShards: () => listShards,
5446
6061
  shardExists: () => shardExists
5447
6062
  });
5448
- import path18 from "path";
6063
+ import path19 from "path";
5449
6064
  import { existsSync as existsSync14, mkdirSync as mkdirSync8, readdirSync as readdirSync5 } from "fs";
5450
6065
  import { createClient as createClient2 } from "@libsql/client";
5451
6066
  function initShardManager(encryptionKey) {
@@ -5471,7 +6086,7 @@ function getShardClient(projectName) {
5471
6086
  }
5472
6087
  const cached = _shards.get(safeName);
5473
6088
  if (cached) return cached;
5474
- const dbPath = path18.join(SHARDS_DIR, `${safeName}.db`);
6089
+ const dbPath = path19.join(SHARDS_DIR, `${safeName}.db`);
5475
6090
  const client = createClient2({
5476
6091
  url: `file:${dbPath}`,
5477
6092
  encryptionKey: _encryptionKey
@@ -5481,7 +6096,7 @@ function getShardClient(projectName) {
5481
6096
  }
5482
6097
  function shardExists(projectName) {
5483
6098
  const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
5484
- return existsSync14(path18.join(SHARDS_DIR, `${safeName}.db`));
6099
+ return existsSync14(path19.join(SHARDS_DIR, `${safeName}.db`));
5485
6100
  }
5486
6101
  function listShards() {
5487
6102
  if (!existsSync14(SHARDS_DIR)) return [];
@@ -5558,7 +6173,23 @@ async function ensureShardSchema(client) {
5558
6173
  // MS-11: draft staging, MS-6a: memory_type, MS-7: trajectory
5559
6174
  "ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0",
5560
6175
  "ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'",
5561
- "ALTER TABLE memories ADD COLUMN trajectory TEXT"
6176
+ "ALTER TABLE memories ADD COLUMN trajectory TEXT",
6177
+ // Metadata enrichment columns (must match database.ts)
6178
+ "ALTER TABLE memories ADD COLUMN intent TEXT",
6179
+ "ALTER TABLE memories ADD COLUMN outcome TEXT",
6180
+ "ALTER TABLE memories ADD COLUMN domain TEXT",
6181
+ "ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
6182
+ "ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
6183
+ "ALTER TABLE memories ADD COLUMN chain_position TEXT",
6184
+ "ALTER TABLE memories ADD COLUMN review_status TEXT",
6185
+ "ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
6186
+ "ALTER TABLE memories ADD COLUMN file_paths TEXT",
6187
+ "ALTER TABLE memories ADD COLUMN commit_hash TEXT",
6188
+ "ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
6189
+ "ALTER TABLE memories ADD COLUMN token_cost REAL",
6190
+ "ALTER TABLE memories ADD COLUMN audience TEXT",
6191
+ "ALTER TABLE memories ADD COLUMN language_type TEXT",
6192
+ "ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
5562
6193
  ]) {
5563
6194
  try {
5564
6195
  await client.execute(col);
@@ -5670,7 +6301,7 @@ var init_shard_manager = __esm({
5670
6301
  "src/lib/shard-manager.ts"() {
5671
6302
  "use strict";
5672
6303
  init_config();
5673
- SHARDS_DIR = path18.join(EXE_AI_DIR, "shards");
6304
+ SHARDS_DIR = path19.join(EXE_AI_DIR, "shards");
5674
6305
  _shards = /* @__PURE__ */ new Map();
5675
6306
  _encryptionKey = null;
5676
6307
  _shardingEnabled = false;