@askexenow/exe-os 0.8.83 → 0.8.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/backfill-conversations.js +746 -595
- package/dist/bin/backfill-responses.js +745 -594
- package/dist/bin/backfill-vectors.js +312 -226
- package/dist/bin/cleanup-stale-review-tasks.js +154 -21
- package/dist/bin/cli.js +14678 -12676
- package/dist/bin/exe-agent-config.js +242 -0
- package/dist/bin/exe-agent.js +100 -91
- package/dist/bin/exe-assign.js +1003 -854
- package/dist/bin/exe-boot.js +1420 -485
- package/dist/bin/exe-call.js +10 -0
- package/dist/bin/exe-cloud.js +29 -6
- package/dist/bin/exe-dispatch.js +572 -271
- package/dist/bin/exe-doctor.js +403 -6
- package/dist/bin/exe-export-behaviors.js +175 -72
- package/dist/bin/exe-forget.js +102 -3
- package/dist/bin/exe-gateway.js +796 -292
- package/dist/bin/exe-healthcheck.js +134 -1
- package/dist/bin/exe-heartbeat.js +172 -36
- package/dist/bin/exe-kill.js +175 -72
- package/dist/bin/exe-launch-agent.js +189 -76
- package/dist/bin/exe-link.js +927 -82
- package/dist/bin/exe-new-employee.js +60 -8
- package/dist/bin/exe-pending-messages.js +151 -19
- package/dist/bin/exe-pending-notifications.js +97 -2
- package/dist/bin/exe-pending-reviews.js +155 -22
- package/dist/bin/exe-rename.js +564 -23
- package/dist/bin/exe-review.js +231 -73
- package/dist/bin/exe-search.js +995 -228
- package/dist/bin/exe-session-cleanup.js +4930 -1664
- package/dist/bin/exe-settings.js +20 -5
- package/dist/bin/exe-start-codex.js +2598 -0
- package/dist/bin/exe-start.sh +15 -3
- package/dist/bin/exe-status.js +154 -21
- package/dist/bin/exe-team.js +97 -2
- package/dist/bin/git-sweep.js +1180 -363
- package/dist/bin/graph-backfill.js +175 -72
- package/dist/bin/graph-export.js +175 -72
- package/dist/bin/install.js +60 -7
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/scan-tasks.js +1185 -367
- package/dist/bin/setup.js +914 -270
- package/dist/bin/shard-migrate.js +175 -72
- package/dist/bin/update.js +1 -0
- package/dist/bin/wiki-sync.js +175 -72
- package/dist/gateway/index.js +792 -285
- package/dist/hooks/bug-report-worker.js +445 -135
- package/dist/hooks/commit-complete.js +1178 -361
- package/dist/hooks/error-recall.js +994 -228
- package/dist/hooks/ingest-worker.js +1799 -1234
- package/dist/hooks/ingest.js +3 -0
- package/dist/hooks/instructions-loaded.js +707 -97
- package/dist/hooks/notification.js +699 -89
- package/dist/hooks/post-compact.js +757 -109
- package/dist/hooks/pre-compact.js +1061 -244
- package/dist/hooks/pre-tool-use.js +787 -130
- package/dist/hooks/prompt-ingest-worker.js +242 -101
- package/dist/hooks/prompt-submit.js +1121 -299
- package/dist/hooks/response-ingest-worker.js +242 -101
- package/dist/hooks/session-end.js +4063 -397
- package/dist/hooks/session-start.js +1071 -254
- package/dist/hooks/stop.js +768 -120
- package/dist/hooks/subagent-stop.js +757 -109
- package/dist/hooks/summary-worker.js +1706 -1011
- package/dist/index.js +1821 -1098
- package/dist/lib/agent-config.js +167 -0
- package/dist/lib/cloud-sync.js +932 -88
- package/dist/lib/consolidation.js +2 -1
- package/dist/lib/database.js +642 -87
- package/dist/lib/db-daemon-client.js +503 -0
- package/dist/lib/device-registry.js +547 -7
- package/dist/lib/embedder.js +14 -28
- package/dist/lib/employee-templates.js +84 -74
- package/dist/lib/employees.js +9 -0
- package/dist/lib/exe-daemon-client.js +16 -29
- package/dist/lib/exe-daemon.js +2733 -1575
- package/dist/lib/hybrid-search.js +995 -228
- package/dist/lib/identity.js +87 -67
- package/dist/lib/keychain.js +9 -1
- package/dist/lib/messaging.js +103 -40
- package/dist/lib/reminders.js +91 -74
- package/dist/lib/runtime-table.js +16 -0
- package/dist/lib/schedules.js +96 -2
- package/dist/lib/session-wrappers.js +22 -0
- package/dist/lib/skill-learning.js +103 -85
- package/dist/lib/store.js +234 -73
- package/dist/lib/tasks.js +348 -134
- package/dist/lib/tmux-routing.js +422 -208
- package/dist/lib/token-spend.js +273 -0
- package/dist/lib/ws-client.js +11 -0
- package/dist/mcp/server.js +5742 -696
- package/dist/mcp/tools/complete-reminder.js +94 -77
- package/dist/mcp/tools/create-reminder.js +94 -77
- package/dist/mcp/tools/create-task.js +375 -152
- package/dist/mcp/tools/deactivate-behavior.js +95 -77
- package/dist/mcp/tools/list-reminders.js +94 -77
- package/dist/mcp/tools/list-tasks.js +99 -31
- package/dist/mcp/tools/send-message.js +108 -45
- package/dist/mcp/tools/update-task.js +162 -77
- package/dist/runtime/index.js +1075 -258
- package/dist/tui/App.js +1333 -506
- package/package.json +6 -1
- package/src/commands/exe/agent-config.md +27 -0
- package/src/commands/exe/cc-doctor.md +10 -0
|
@@ -244,6 +244,7 @@ __export(employees_exports, {
|
|
|
244
244
|
DEFAULT_COORDINATOR_TEMPLATE_NAME: () => DEFAULT_COORDINATOR_TEMPLATE_NAME,
|
|
245
245
|
EMPLOYEES_PATH: () => EMPLOYEES_PATH,
|
|
246
246
|
addEmployee: () => addEmployee,
|
|
247
|
+
baseAgentName: () => baseAgentName,
|
|
247
248
|
canCoordinate: () => canCoordinate,
|
|
248
249
|
getCoordinatorEmployee: () => getCoordinatorEmployee,
|
|
249
250
|
getCoordinatorName: () => getCoordinatorName,
|
|
@@ -340,6 +341,14 @@ function hasRole(agentName, role) {
|
|
|
340
341
|
const emp = getEmployee(employees, agentName);
|
|
341
342
|
return emp ? emp.role.toLowerCase() === role.toLowerCase() : false;
|
|
342
343
|
}
|
|
344
|
+
function baseAgentName(name, employees) {
|
|
345
|
+
const match = name.match(/^([a-zA-Z]+)\d+$/);
|
|
346
|
+
if (!match) return name;
|
|
347
|
+
const base = match[1];
|
|
348
|
+
const roster = employees ?? loadEmployeesSync();
|
|
349
|
+
if (getEmployee(roster, base)) return base;
|
|
350
|
+
return name;
|
|
351
|
+
}
|
|
343
352
|
function isMultiInstance(agentName, employees) {
|
|
344
353
|
const roster = employees ?? loadEmployeesSync();
|
|
345
354
|
const emp = getEmployee(roster, agentName);
|
|
@@ -582,17 +591,53 @@ var init_provider_table = __esm({
|
|
|
582
591
|
}
|
|
583
592
|
});
|
|
584
593
|
|
|
585
|
-
// src/lib/
|
|
586
|
-
|
|
594
|
+
// src/lib/runtime-table.ts
|
|
595
|
+
var RUNTIME_TABLE;
|
|
596
|
+
var init_runtime_table = __esm({
|
|
597
|
+
"src/lib/runtime-table.ts"() {
|
|
598
|
+
"use strict";
|
|
599
|
+
RUNTIME_TABLE = {
|
|
600
|
+
codex: {
|
|
601
|
+
binary: "codex",
|
|
602
|
+
launchMode: "exec",
|
|
603
|
+
autoApproveFlag: "--full-auto",
|
|
604
|
+
inlineFlag: "--no-alt-screen",
|
|
605
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
606
|
+
defaultModel: "gpt-5.4"
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
// src/lib/agent-config.ts
|
|
613
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
|
|
587
614
|
import path5 from "path";
|
|
615
|
+
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
616
|
+
var init_agent_config = __esm({
|
|
617
|
+
"src/lib/agent-config.ts"() {
|
|
618
|
+
"use strict";
|
|
619
|
+
init_config();
|
|
620
|
+
init_runtime_table();
|
|
621
|
+
AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
|
|
622
|
+
DEFAULT_MODELS = {
|
|
623
|
+
claude: "claude-opus-4",
|
|
624
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
625
|
+
opencode: "minimax-m2.7"
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
// src/lib/intercom-queue.ts
|
|
631
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
632
|
+
import path6 from "path";
|
|
588
633
|
import os4 from "os";
|
|
589
634
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
590
635
|
var init_intercom_queue = __esm({
|
|
591
636
|
"src/lib/intercom-queue.ts"() {
|
|
592
637
|
"use strict";
|
|
593
|
-
QUEUE_PATH =
|
|
638
|
+
QUEUE_PATH = path6.join(os4.homedir(), ".exe-os", "intercom-queue.json");
|
|
594
639
|
TTL_MS = 60 * 60 * 1e3;
|
|
595
|
-
INTERCOM_LOG =
|
|
640
|
+
INTERCOM_LOG = path6.join(os4.homedir(), ".exe-os", "intercom.log");
|
|
596
641
|
}
|
|
597
642
|
});
|
|
598
643
|
|
|
@@ -651,6 +696,443 @@ var init_db_retry = __esm({
|
|
|
651
696
|
}
|
|
652
697
|
});
|
|
653
698
|
|
|
699
|
+
// src/lib/exe-daemon-client.ts
|
|
700
|
+
import net from "net";
|
|
701
|
+
import { spawn } from "child_process";
|
|
702
|
+
import { randomUUID } from "crypto";
|
|
703
|
+
import { existsSync as existsSync5, unlinkSync as unlinkSync3, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
|
|
704
|
+
import path7 from "path";
|
|
705
|
+
import { fileURLToPath } from "url";
|
|
706
|
+
function handleData(chunk) {
|
|
707
|
+
_buffer += chunk.toString();
|
|
708
|
+
if (_buffer.length > MAX_BUFFER) {
|
|
709
|
+
_buffer = "";
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
let newlineIdx;
|
|
713
|
+
while ((newlineIdx = _buffer.indexOf("\n")) !== -1) {
|
|
714
|
+
const line = _buffer.slice(0, newlineIdx).trim();
|
|
715
|
+
_buffer = _buffer.slice(newlineIdx + 1);
|
|
716
|
+
if (!line) continue;
|
|
717
|
+
try {
|
|
718
|
+
const response = JSON.parse(line);
|
|
719
|
+
const id = response.id;
|
|
720
|
+
if (!id) continue;
|
|
721
|
+
const entry = _pending.get(id);
|
|
722
|
+
if (entry) {
|
|
723
|
+
clearTimeout(entry.timer);
|
|
724
|
+
_pending.delete(id);
|
|
725
|
+
entry.resolve(response);
|
|
726
|
+
}
|
|
727
|
+
} catch {
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
function cleanupStaleFiles() {
|
|
732
|
+
if (existsSync5(PID_PATH)) {
|
|
733
|
+
try {
|
|
734
|
+
const pid = parseInt(readFileSync6(PID_PATH, "utf8").trim(), 10);
|
|
735
|
+
if (pid > 0) {
|
|
736
|
+
try {
|
|
737
|
+
process.kill(pid, 0);
|
|
738
|
+
return;
|
|
739
|
+
} catch {
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
} catch {
|
|
743
|
+
}
|
|
744
|
+
try {
|
|
745
|
+
unlinkSync3(PID_PATH);
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
try {
|
|
749
|
+
unlinkSync3(SOCKET_PATH);
|
|
750
|
+
} catch {
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function findPackageRoot() {
|
|
755
|
+
let dir = path7.dirname(fileURLToPath(import.meta.url));
|
|
756
|
+
const { root } = path7.parse(dir);
|
|
757
|
+
while (dir !== root) {
|
|
758
|
+
if (existsSync5(path7.join(dir, "package.json"))) return dir;
|
|
759
|
+
dir = path7.dirname(dir);
|
|
760
|
+
}
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
function spawnDaemon() {
|
|
764
|
+
const pkgRoot = findPackageRoot();
|
|
765
|
+
if (!pkgRoot) {
|
|
766
|
+
process.stderr.write("[exed-client] WARN: cannot find package root\n");
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
const daemonPath = path7.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
770
|
+
if (!existsSync5(daemonPath)) {
|
|
771
|
+
process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
|
|
772
|
+
`);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
const resolvedPath = daemonPath;
|
|
776
|
+
process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
|
|
777
|
+
`);
|
|
778
|
+
const logPath = path7.join(path7.dirname(SOCKET_PATH), "exed.log");
|
|
779
|
+
let stderrFd = "ignore";
|
|
780
|
+
try {
|
|
781
|
+
stderrFd = openSync(logPath, "a");
|
|
782
|
+
} catch {
|
|
783
|
+
}
|
|
784
|
+
const child = spawn(process.execPath, [resolvedPath], {
|
|
785
|
+
detached: true,
|
|
786
|
+
stdio: ["ignore", "ignore", stderrFd],
|
|
787
|
+
env: {
|
|
788
|
+
...process.env,
|
|
789
|
+
TMUX: void 0,
|
|
790
|
+
// Daemon is global — must not inherit session scope
|
|
791
|
+
TMUX_PANE: void 0,
|
|
792
|
+
// Prevents resolveExeSession() from scoping to one session
|
|
793
|
+
EXE_DAEMON_SOCK: SOCKET_PATH,
|
|
794
|
+
EXE_DAEMON_PID: PID_PATH
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
child.unref();
|
|
798
|
+
if (typeof stderrFd === "number") {
|
|
799
|
+
try {
|
|
800
|
+
closeSync(stderrFd);
|
|
801
|
+
} catch {
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
function acquireSpawnLock() {
|
|
806
|
+
try {
|
|
807
|
+
const fd = openSync(SPAWN_LOCK_PATH, "wx");
|
|
808
|
+
closeSync(fd);
|
|
809
|
+
return true;
|
|
810
|
+
} catch {
|
|
811
|
+
try {
|
|
812
|
+
const stat = statSync(SPAWN_LOCK_PATH);
|
|
813
|
+
if (Date.now() - stat.mtimeMs > SPAWN_LOCK_STALE_MS) {
|
|
814
|
+
try {
|
|
815
|
+
unlinkSync3(SPAWN_LOCK_PATH);
|
|
816
|
+
} catch {
|
|
817
|
+
}
|
|
818
|
+
try {
|
|
819
|
+
const fd = openSync(SPAWN_LOCK_PATH, "wx");
|
|
820
|
+
closeSync(fd);
|
|
821
|
+
return true;
|
|
822
|
+
} catch {
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
} catch {
|
|
826
|
+
}
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
function releaseSpawnLock() {
|
|
831
|
+
try {
|
|
832
|
+
unlinkSync3(SPAWN_LOCK_PATH);
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function connectToSocket() {
|
|
837
|
+
return new Promise((resolve) => {
|
|
838
|
+
if (_socket && _connected) {
|
|
839
|
+
resolve(true);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const socket = net.createConnection({ path: SOCKET_PATH });
|
|
843
|
+
const connectTimeout = setTimeout(() => {
|
|
844
|
+
socket.destroy();
|
|
845
|
+
resolve(false);
|
|
846
|
+
}, 2e3);
|
|
847
|
+
socket.on("connect", () => {
|
|
848
|
+
clearTimeout(connectTimeout);
|
|
849
|
+
_socket = socket;
|
|
850
|
+
_connected = true;
|
|
851
|
+
_buffer = "";
|
|
852
|
+
socket.on("data", handleData);
|
|
853
|
+
socket.on("close", () => {
|
|
854
|
+
_connected = false;
|
|
855
|
+
_socket = null;
|
|
856
|
+
for (const [id, entry] of _pending) {
|
|
857
|
+
clearTimeout(entry.timer);
|
|
858
|
+
_pending.delete(id);
|
|
859
|
+
entry.resolve({ error: "Connection closed" });
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
socket.on("error", () => {
|
|
863
|
+
_connected = false;
|
|
864
|
+
_socket = null;
|
|
865
|
+
});
|
|
866
|
+
resolve(true);
|
|
867
|
+
});
|
|
868
|
+
socket.on("error", () => {
|
|
869
|
+
clearTimeout(connectTimeout);
|
|
870
|
+
resolve(false);
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
async function connectEmbedDaemon() {
|
|
875
|
+
if (_socket && _connected) return true;
|
|
876
|
+
if (await connectToSocket()) return true;
|
|
877
|
+
if (acquireSpawnLock()) {
|
|
878
|
+
try {
|
|
879
|
+
cleanupStaleFiles();
|
|
880
|
+
spawnDaemon();
|
|
881
|
+
} finally {
|
|
882
|
+
releaseSpawnLock();
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const start = Date.now();
|
|
886
|
+
let delay2 = 100;
|
|
887
|
+
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
888
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
889
|
+
if (await connectToSocket()) return true;
|
|
890
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
891
|
+
}
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
894
|
+
function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
895
|
+
return new Promise((resolve) => {
|
|
896
|
+
if (!_socket || !_connected) {
|
|
897
|
+
resolve({ error: "Not connected" });
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
const id = randomUUID();
|
|
901
|
+
const timer = setTimeout(() => {
|
|
902
|
+
_pending.delete(id);
|
|
903
|
+
resolve({ error: "Request timeout" });
|
|
904
|
+
}, timeoutMs);
|
|
905
|
+
_pending.set(id, { resolve, timer });
|
|
906
|
+
try {
|
|
907
|
+
_socket.write(JSON.stringify({ id, ...payload }) + "\n");
|
|
908
|
+
} catch {
|
|
909
|
+
clearTimeout(timer);
|
|
910
|
+
_pending.delete(id);
|
|
911
|
+
resolve({ error: "Write failed" });
|
|
912
|
+
}
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
function isClientConnected() {
|
|
916
|
+
return _connected;
|
|
917
|
+
}
|
|
918
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _pending, MAX_BUFFER;
|
|
919
|
+
var init_exe_daemon_client = __esm({
|
|
920
|
+
"src/lib/exe-daemon-client.ts"() {
|
|
921
|
+
"use strict";
|
|
922
|
+
init_config();
|
|
923
|
+
SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path7.join(EXE_AI_DIR, "exed.sock");
|
|
924
|
+
PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path7.join(EXE_AI_DIR, "exed.pid");
|
|
925
|
+
SPAWN_LOCK_PATH = path7.join(EXE_AI_DIR, "exed-spawn.lock");
|
|
926
|
+
SPAWN_LOCK_STALE_MS = 3e4;
|
|
927
|
+
CONNECT_TIMEOUT_MS = 15e3;
|
|
928
|
+
REQUEST_TIMEOUT_MS = 3e4;
|
|
929
|
+
_socket = null;
|
|
930
|
+
_connected = false;
|
|
931
|
+
_buffer = "";
|
|
932
|
+
_pending = /* @__PURE__ */ new Map();
|
|
933
|
+
MAX_BUFFER = 1e7;
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
// src/lib/daemon-protocol.ts
|
|
938
|
+
function serializeValue(v) {
|
|
939
|
+
if (v === null || v === void 0) return null;
|
|
940
|
+
if (typeof v === "bigint") return Number(v);
|
|
941
|
+
if (typeof v === "boolean") return v ? 1 : 0;
|
|
942
|
+
if (v instanceof Uint8Array) {
|
|
943
|
+
return { __blob: Buffer.from(v).toString("base64") };
|
|
944
|
+
}
|
|
945
|
+
if (ArrayBuffer.isView(v)) {
|
|
946
|
+
return { __blob: Buffer.from(v.buffer, v.byteOffset, v.byteLength).toString("base64") };
|
|
947
|
+
}
|
|
948
|
+
if (v instanceof ArrayBuffer) {
|
|
949
|
+
return { __blob: Buffer.from(v).toString("base64") };
|
|
950
|
+
}
|
|
951
|
+
if (typeof v === "string" || typeof v === "number") return v;
|
|
952
|
+
return String(v);
|
|
953
|
+
}
|
|
954
|
+
function deserializeValue(v) {
|
|
955
|
+
if (v === null) return null;
|
|
956
|
+
if (typeof v === "object" && v !== null && "__blob" in v) {
|
|
957
|
+
const buf = Buffer.from(v.__blob, "base64");
|
|
958
|
+
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
959
|
+
}
|
|
960
|
+
return v;
|
|
961
|
+
}
|
|
962
|
+
function deserializeResultSet(srs) {
|
|
963
|
+
const rows = srs.rows.map((obj) => {
|
|
964
|
+
const values = srs.columns.map(
|
|
965
|
+
(col) => deserializeValue(obj[col] ?? null)
|
|
966
|
+
);
|
|
967
|
+
const row = values;
|
|
968
|
+
for (let i = 0; i < srs.columns.length; i++) {
|
|
969
|
+
const col = srs.columns[i];
|
|
970
|
+
if (col !== void 0) {
|
|
971
|
+
row[col] = values[i] ?? null;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
Object.defineProperty(row, "length", {
|
|
975
|
+
value: values.length,
|
|
976
|
+
enumerable: false
|
|
977
|
+
});
|
|
978
|
+
return row;
|
|
979
|
+
});
|
|
980
|
+
return {
|
|
981
|
+
columns: srs.columns,
|
|
982
|
+
columnTypes: srs.columnTypes ?? [],
|
|
983
|
+
rows,
|
|
984
|
+
rowsAffected: srs.rowsAffected,
|
|
985
|
+
lastInsertRowid: srs.lastInsertRowid != null ? BigInt(srs.lastInsertRowid) : void 0,
|
|
986
|
+
toJSON: () => ({
|
|
987
|
+
columns: srs.columns,
|
|
988
|
+
columnTypes: srs.columnTypes ?? [],
|
|
989
|
+
rows: srs.rows,
|
|
990
|
+
rowsAffected: srs.rowsAffected,
|
|
991
|
+
lastInsertRowid: srs.lastInsertRowid
|
|
992
|
+
})
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
var init_daemon_protocol = __esm({
|
|
996
|
+
"src/lib/daemon-protocol.ts"() {
|
|
997
|
+
"use strict";
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
// src/lib/db-daemon-client.ts
|
|
1002
|
+
var db_daemon_client_exports = {};
|
|
1003
|
+
__export(db_daemon_client_exports, {
|
|
1004
|
+
createDaemonDbClient: () => createDaemonDbClient,
|
|
1005
|
+
initDaemonDbClient: () => initDaemonDbClient
|
|
1006
|
+
});
|
|
1007
|
+
function normalizeStatement(stmt) {
|
|
1008
|
+
if (typeof stmt === "string") {
|
|
1009
|
+
return { sql: stmt, args: [] };
|
|
1010
|
+
}
|
|
1011
|
+
const sql = stmt.sql;
|
|
1012
|
+
let args = [];
|
|
1013
|
+
if (Array.isArray(stmt.args)) {
|
|
1014
|
+
args = stmt.args.map((v) => serializeValue(v));
|
|
1015
|
+
} else if (stmt.args && typeof stmt.args === "object") {
|
|
1016
|
+
const named = {};
|
|
1017
|
+
for (const [key, val] of Object.entries(stmt.args)) {
|
|
1018
|
+
named[key] = serializeValue(val);
|
|
1019
|
+
}
|
|
1020
|
+
return { sql, args: named };
|
|
1021
|
+
}
|
|
1022
|
+
return { sql, args };
|
|
1023
|
+
}
|
|
1024
|
+
function createDaemonDbClient(fallbackClient) {
|
|
1025
|
+
let _useDaemon = false;
|
|
1026
|
+
const client = {
|
|
1027
|
+
async execute(stmt) {
|
|
1028
|
+
if (!_useDaemon || !isClientConnected()) {
|
|
1029
|
+
return fallbackClient.execute(stmt);
|
|
1030
|
+
}
|
|
1031
|
+
const { sql, args } = normalizeStatement(stmt);
|
|
1032
|
+
const response = await sendDaemonRequest({
|
|
1033
|
+
type: "db-execute",
|
|
1034
|
+
sql,
|
|
1035
|
+
args
|
|
1036
|
+
});
|
|
1037
|
+
if (response.error) {
|
|
1038
|
+
const errMsg = String(response.error);
|
|
1039
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
1040
|
+
process.stderr.write(`[db-daemon] Transport error (${errMsg}), falling back to direct
|
|
1041
|
+
`);
|
|
1042
|
+
return fallbackClient.execute(stmt);
|
|
1043
|
+
}
|
|
1044
|
+
throw new Error(errMsg);
|
|
1045
|
+
}
|
|
1046
|
+
if (response.db) {
|
|
1047
|
+
return deserializeResultSet(response.db);
|
|
1048
|
+
}
|
|
1049
|
+
process.stderr.write("[db-daemon] Unexpected response shape, falling back to direct\n");
|
|
1050
|
+
return fallbackClient.execute(stmt);
|
|
1051
|
+
},
|
|
1052
|
+
async batch(stmts, mode) {
|
|
1053
|
+
if (!_useDaemon || !isClientConnected()) {
|
|
1054
|
+
return fallbackClient.batch(stmts, mode);
|
|
1055
|
+
}
|
|
1056
|
+
const statements = stmts.map(normalizeStatement);
|
|
1057
|
+
const response = await sendDaemonRequest({
|
|
1058
|
+
type: "db-batch",
|
|
1059
|
+
statements,
|
|
1060
|
+
mode: mode ?? "deferred"
|
|
1061
|
+
});
|
|
1062
|
+
if (response.error) {
|
|
1063
|
+
const errMsg = String(response.error);
|
|
1064
|
+
if (errMsg === "Not connected" || errMsg === "Request timeout" || errMsg === "Write failed") {
|
|
1065
|
+
process.stderr.write(`[db-daemon] Batch transport error (${errMsg}), falling back to direct
|
|
1066
|
+
`);
|
|
1067
|
+
return fallbackClient.batch(stmts, mode);
|
|
1068
|
+
}
|
|
1069
|
+
throw new Error(errMsg);
|
|
1070
|
+
}
|
|
1071
|
+
const batchResults = response["db-batch"];
|
|
1072
|
+
if (batchResults) {
|
|
1073
|
+
return batchResults.map(deserializeResultSet);
|
|
1074
|
+
}
|
|
1075
|
+
process.stderr.write("[db-daemon] Unexpected batch response shape, falling back to direct\n");
|
|
1076
|
+
return fallbackClient.batch(stmts, mode);
|
|
1077
|
+
},
|
|
1078
|
+
// Transaction support — delegate to fallback (transactions need direct connection)
|
|
1079
|
+
async transaction(mode) {
|
|
1080
|
+
return fallbackClient.transaction(mode);
|
|
1081
|
+
},
|
|
1082
|
+
// executeMultiple — delegate to fallback (used only for schema migrations)
|
|
1083
|
+
async executeMultiple(sql) {
|
|
1084
|
+
return fallbackClient.executeMultiple(sql);
|
|
1085
|
+
},
|
|
1086
|
+
// migrate — delegate to fallback
|
|
1087
|
+
async migrate(stmts) {
|
|
1088
|
+
return fallbackClient.migrate(stmts);
|
|
1089
|
+
},
|
|
1090
|
+
// Sync mode — delegate to fallback
|
|
1091
|
+
sync() {
|
|
1092
|
+
return fallbackClient.sync();
|
|
1093
|
+
},
|
|
1094
|
+
close() {
|
|
1095
|
+
_useDaemon = false;
|
|
1096
|
+
},
|
|
1097
|
+
get closed() {
|
|
1098
|
+
return fallbackClient.closed;
|
|
1099
|
+
},
|
|
1100
|
+
get protocol() {
|
|
1101
|
+
return fallbackClient.protocol;
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
return {
|
|
1105
|
+
...client,
|
|
1106
|
+
/** Enable daemon routing (call after confirming daemon is connected) */
|
|
1107
|
+
_enableDaemon() {
|
|
1108
|
+
_useDaemon = true;
|
|
1109
|
+
},
|
|
1110
|
+
/** Check if daemon routing is active */
|
|
1111
|
+
_isDaemonActive() {
|
|
1112
|
+
return _useDaemon && isClientConnected();
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
async function initDaemonDbClient(fallbackClient) {
|
|
1117
|
+
if (process.env.EXE_IS_DAEMON === "1") return null;
|
|
1118
|
+
const connected = await connectEmbedDaemon();
|
|
1119
|
+
if (!connected) {
|
|
1120
|
+
process.stderr.write("[db-daemon] Daemon unavailable \u2014 using direct SQLite\n");
|
|
1121
|
+
return null;
|
|
1122
|
+
}
|
|
1123
|
+
const client = createDaemonDbClient(fallbackClient);
|
|
1124
|
+
client._enableDaemon();
|
|
1125
|
+
process.stderr.write("[db-daemon] DB routing through daemon (single-writer)\n");
|
|
1126
|
+
return client;
|
|
1127
|
+
}
|
|
1128
|
+
var init_db_daemon_client = __esm({
|
|
1129
|
+
"src/lib/db-daemon-client.ts"() {
|
|
1130
|
+
"use strict";
|
|
1131
|
+
init_exe_daemon_client();
|
|
1132
|
+
init_daemon_protocol();
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
|
|
654
1136
|
// src/lib/database.ts
|
|
655
1137
|
var database_exports = {};
|
|
656
1138
|
__export(database_exports, {
|
|
@@ -659,6 +1141,7 @@ __export(database_exports, {
|
|
|
659
1141
|
ensureSchema: () => ensureSchema,
|
|
660
1142
|
getClient: () => getClient,
|
|
661
1143
|
getRawClient: () => getRawClient,
|
|
1144
|
+
initDaemonClient: () => initDaemonClient,
|
|
662
1145
|
initDatabase: () => initDatabase,
|
|
663
1146
|
initTurso: () => initTurso,
|
|
664
1147
|
isInitialized: () => isInitialized
|
|
@@ -686,8 +1169,27 @@ function getClient() {
|
|
|
686
1169
|
if (!_resilientClient) {
|
|
687
1170
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
688
1171
|
}
|
|
1172
|
+
if (process.env.EXE_IS_DAEMON === "1") {
|
|
1173
|
+
return _resilientClient;
|
|
1174
|
+
}
|
|
1175
|
+
if (_daemonClient && _daemonClient._isDaemonActive()) {
|
|
1176
|
+
return _daemonClient;
|
|
1177
|
+
}
|
|
689
1178
|
return _resilientClient;
|
|
690
1179
|
}
|
|
1180
|
+
async function initDaemonClient() {
|
|
1181
|
+
if (process.env.EXE_IS_DAEMON === "1") return;
|
|
1182
|
+
if (!_resilientClient) return;
|
|
1183
|
+
try {
|
|
1184
|
+
const { initDaemonDbClient: initDaemonDbClient2 } = await Promise.resolve().then(() => (init_db_daemon_client(), db_daemon_client_exports));
|
|
1185
|
+
_daemonClient = await initDaemonDbClient2(_resilientClient);
|
|
1186
|
+
} catch (err) {
|
|
1187
|
+
process.stderr.write(
|
|
1188
|
+
`[database] Daemon client init failed (non-fatal): ${err instanceof Error ? err.message : String(err)}
|
|
1189
|
+
`
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
691
1193
|
function getRawClient() {
|
|
692
1194
|
if (!_client) {
|
|
693
1195
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
@@ -1174,6 +1676,12 @@ async function ensureSchema() {
|
|
|
1174
1676
|
} catch {
|
|
1175
1677
|
}
|
|
1176
1678
|
}
|
|
1679
|
+
try {
|
|
1680
|
+
await client.execute(
|
|
1681
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
1682
|
+
);
|
|
1683
|
+
} catch {
|
|
1684
|
+
}
|
|
1177
1685
|
await client.executeMultiple(`
|
|
1178
1686
|
CREATE TABLE IF NOT EXISTS entities (
|
|
1179
1687
|
id TEXT PRIMARY KEY,
|
|
@@ -1226,7 +1734,30 @@ async function ensureSchema() {
|
|
|
1226
1734
|
entity_id TEXT NOT NULL,
|
|
1227
1735
|
PRIMARY KEY (hyperedge_id, entity_id)
|
|
1228
1736
|
);
|
|
1737
|
+
|
|
1738
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
|
|
1739
|
+
name,
|
|
1740
|
+
content=entities,
|
|
1741
|
+
content_rowid=rowid
|
|
1742
|
+
);
|
|
1743
|
+
|
|
1744
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_ai AFTER INSERT ON entities BEGIN
|
|
1745
|
+
INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
|
|
1746
|
+
END;
|
|
1747
|
+
|
|
1748
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_ad AFTER DELETE ON entities BEGIN
|
|
1749
|
+
INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
|
|
1750
|
+
END;
|
|
1751
|
+
|
|
1752
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_au AFTER UPDATE ON entities BEGIN
|
|
1753
|
+
INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
|
|
1754
|
+
INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
|
|
1755
|
+
END;
|
|
1229
1756
|
`);
|
|
1757
|
+
try {
|
|
1758
|
+
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
1759
|
+
} catch {
|
|
1760
|
+
}
|
|
1230
1761
|
await client.executeMultiple(`
|
|
1231
1762
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
1232
1763
|
alias TEXT NOT NULL PRIMARY KEY,
|
|
@@ -1407,6 +1938,33 @@ async function ensureSchema() {
|
|
|
1407
1938
|
CREATE INDEX IF NOT EXISTS idx_conversations_channel
|
|
1408
1939
|
ON conversations(channel_id);
|
|
1409
1940
|
`);
|
|
1941
|
+
await client.executeMultiple(`
|
|
1942
|
+
CREATE TABLE IF NOT EXISTS session_agent_map (
|
|
1943
|
+
session_uuid TEXT PRIMARY KEY,
|
|
1944
|
+
agent_id TEXT NOT NULL,
|
|
1945
|
+
session_name TEXT,
|
|
1946
|
+
task_id TEXT,
|
|
1947
|
+
project_name TEXT,
|
|
1948
|
+
started_at TEXT NOT NULL
|
|
1949
|
+
);
|
|
1950
|
+
|
|
1951
|
+
CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
|
|
1952
|
+
ON session_agent_map(agent_id);
|
|
1953
|
+
`);
|
|
1954
|
+
try {
|
|
1955
|
+
const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
|
|
1956
|
+
if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
|
|
1957
|
+
await client.execute({
|
|
1958
|
+
sql: `INSERT OR IGNORE INTO session_agent_map (session_uuid, agent_id, session_name, started_at)
|
|
1959
|
+
SELECT session_id, agent_id, '', MIN(timestamp)
|
|
1960
|
+
FROM memories
|
|
1961
|
+
WHERE session_id IS NOT NULL AND session_id != '' AND agent_id IS NOT NULL AND agent_id != ''
|
|
1962
|
+
GROUP BY session_id, agent_id`,
|
|
1963
|
+
args: []
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
} catch {
|
|
1967
|
+
}
|
|
1410
1968
|
try {
|
|
1411
1969
|
await client.execute({
|
|
1412
1970
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
@@ -1540,15 +2098,41 @@ async function ensureSchema() {
|
|
|
1540
2098
|
});
|
|
1541
2099
|
} catch {
|
|
1542
2100
|
}
|
|
2101
|
+
for (const col of [
|
|
2102
|
+
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
2103
|
+
"ALTER TABLE memories ADD COLUMN outcome TEXT",
|
|
2104
|
+
"ALTER TABLE memories ADD COLUMN domain TEXT",
|
|
2105
|
+
"ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
|
|
2106
|
+
"ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
|
|
2107
|
+
"ALTER TABLE memories ADD COLUMN chain_position TEXT",
|
|
2108
|
+
"ALTER TABLE memories ADD COLUMN review_status TEXT",
|
|
2109
|
+
"ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
|
|
2110
|
+
"ALTER TABLE memories ADD COLUMN file_paths TEXT",
|
|
2111
|
+
"ALTER TABLE memories ADD COLUMN commit_hash TEXT",
|
|
2112
|
+
"ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
|
|
2113
|
+
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
2114
|
+
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
2115
|
+
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
2116
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
2117
|
+
]) {
|
|
2118
|
+
try {
|
|
2119
|
+
await client.execute(col);
|
|
2120
|
+
} catch {
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
1543
2123
|
}
|
|
1544
2124
|
async function disposeDatabase() {
|
|
2125
|
+
if (_daemonClient) {
|
|
2126
|
+
_daemonClient.close();
|
|
2127
|
+
_daemonClient = null;
|
|
2128
|
+
}
|
|
1545
2129
|
if (_client) {
|
|
1546
2130
|
_client.close();
|
|
1547
2131
|
_client = null;
|
|
1548
2132
|
_resilientClient = null;
|
|
1549
2133
|
}
|
|
1550
2134
|
}
|
|
1551
|
-
var _client, _resilientClient, initTurso, disposeTurso;
|
|
2135
|
+
var _client, _resilientClient, _daemonClient, initTurso, disposeTurso;
|
|
1552
2136
|
var init_database = __esm({
|
|
1553
2137
|
"src/lib/database.ts"() {
|
|
1554
2138
|
"use strict";
|
|
@@ -1556,30 +2140,31 @@ var init_database = __esm({
|
|
|
1556
2140
|
init_employees();
|
|
1557
2141
|
_client = null;
|
|
1558
2142
|
_resilientClient = null;
|
|
2143
|
+
_daemonClient = null;
|
|
1559
2144
|
initTurso = initDatabase;
|
|
1560
2145
|
disposeTurso = disposeDatabase;
|
|
1561
2146
|
}
|
|
1562
2147
|
});
|
|
1563
2148
|
|
|
1564
2149
|
// src/lib/license.ts
|
|
1565
|
-
import { readFileSync as
|
|
1566
|
-
import { randomUUID } from "crypto";
|
|
1567
|
-
import
|
|
2150
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
|
|
2151
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2152
|
+
import path8 from "path";
|
|
1568
2153
|
import { jwtVerify, importSPKI } from "jose";
|
|
1569
2154
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
1570
2155
|
var init_license = __esm({
|
|
1571
2156
|
"src/lib/license.ts"() {
|
|
1572
2157
|
"use strict";
|
|
1573
2158
|
init_config();
|
|
1574
|
-
LICENSE_PATH =
|
|
1575
|
-
CACHE_PATH =
|
|
1576
|
-
DEVICE_ID_PATH =
|
|
2159
|
+
LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
|
|
2160
|
+
CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
|
|
2161
|
+
DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
|
|
1577
2162
|
}
|
|
1578
2163
|
});
|
|
1579
2164
|
|
|
1580
2165
|
// src/lib/plan-limits.ts
|
|
1581
|
-
import { readFileSync as
|
|
1582
|
-
import
|
|
2166
|
+
import { readFileSync as readFileSync8, existsSync as existsSync7 } from "fs";
|
|
2167
|
+
import path9 from "path";
|
|
1583
2168
|
var CACHE_PATH2;
|
|
1584
2169
|
var init_plan_limits = __esm({
|
|
1585
2170
|
"src/lib/plan-limits.ts"() {
|
|
@@ -1588,15 +2173,15 @@ var init_plan_limits = __esm({
|
|
|
1588
2173
|
init_employees();
|
|
1589
2174
|
init_license();
|
|
1590
2175
|
init_config();
|
|
1591
|
-
CACHE_PATH2 =
|
|
2176
|
+
CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
|
|
1592
2177
|
}
|
|
1593
2178
|
});
|
|
1594
2179
|
|
|
1595
2180
|
// src/lib/tmux-routing.ts
|
|
1596
|
-
import { readFileSync as
|
|
1597
|
-
import
|
|
2181
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync8, appendFileSync } from "fs";
|
|
2182
|
+
import path10 from "path";
|
|
1598
2183
|
import os5 from "os";
|
|
1599
|
-
import { fileURLToPath } from "url";
|
|
2184
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1600
2185
|
function getMySession() {
|
|
1601
2186
|
return getTransport().getMySession();
|
|
1602
2187
|
}
|
|
@@ -1608,7 +2193,7 @@ function extractRootExe(name) {
|
|
|
1608
2193
|
}
|
|
1609
2194
|
function getParentExe(sessionKey) {
|
|
1610
2195
|
try {
|
|
1611
|
-
const data = JSON.parse(
|
|
2196
|
+
const data = JSON.parse(readFileSync9(path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
1612
2197
|
return data.parentExe || null;
|
|
1613
2198
|
} catch {
|
|
1614
2199
|
return null;
|
|
@@ -1637,13 +2222,15 @@ var init_tmux_routing = __esm({
|
|
|
1637
2222
|
init_cc_agent_support();
|
|
1638
2223
|
init_mcp_prefix();
|
|
1639
2224
|
init_provider_table();
|
|
2225
|
+
init_agent_config();
|
|
2226
|
+
init_runtime_table();
|
|
1640
2227
|
init_intercom_queue();
|
|
1641
2228
|
init_plan_limits();
|
|
1642
2229
|
init_employees();
|
|
1643
|
-
SPAWN_LOCK_DIR =
|
|
1644
|
-
SESSION_CACHE =
|
|
1645
|
-
INTERCOM_LOG2 =
|
|
1646
|
-
DEBOUNCE_FILE =
|
|
2230
|
+
SPAWN_LOCK_DIR = path10.join(os5.homedir(), ".exe-os", "spawn-locks");
|
|
2231
|
+
SESSION_CACHE = path10.join(os5.homedir(), ".exe-os", "session-cache");
|
|
2232
|
+
INTERCOM_LOG2 = path10.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
2233
|
+
DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
|
|
1647
2234
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
1648
2235
|
}
|
|
1649
2236
|
});
|
|
@@ -1686,8 +2273,8 @@ __export(cto_delegation_gate_exports, {
|
|
|
1686
2273
|
scratchpadPath: () => scratchpadPath
|
|
1687
2274
|
});
|
|
1688
2275
|
import os6 from "os";
|
|
1689
|
-
import
|
|
1690
|
-
import { existsSync as
|
|
2276
|
+
import path11 from "path";
|
|
2277
|
+
import { existsSync as existsSync9, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
|
|
1691
2278
|
function resolveGatedAgent() {
|
|
1692
2279
|
try {
|
|
1693
2280
|
const employees = loadEmployeesSync();
|
|
@@ -1701,12 +2288,12 @@ function getGatedAgent() {
|
|
|
1701
2288
|
return resolveGatedAgent() || GATED_AGENT;
|
|
1702
2289
|
}
|
|
1703
2290
|
function toWorkspaceRelative(filePath, cwd = process.cwd()) {
|
|
1704
|
-
const normalized =
|
|
1705
|
-
if (normalized.startsWith(cwd +
|
|
2291
|
+
const normalized = path11.normalize(filePath);
|
|
2292
|
+
if (normalized.startsWith(cwd + path11.sep)) {
|
|
1706
2293
|
return normalized.slice(cwd.length + 1);
|
|
1707
2294
|
}
|
|
1708
|
-
if (
|
|
1709
|
-
return
|
|
2295
|
+
if (path11.isAbsolute(normalized)) {
|
|
2296
|
+
return path11.basename(normalized);
|
|
1710
2297
|
}
|
|
1711
2298
|
return normalized;
|
|
1712
2299
|
}
|
|
@@ -1715,8 +2302,8 @@ function isDockerfile(basename) {
|
|
|
1715
2302
|
}
|
|
1716
2303
|
function classifyPath(filePath, cwd) {
|
|
1717
2304
|
const rel = toWorkspaceRelative(filePath, cwd);
|
|
1718
|
-
const basename =
|
|
1719
|
-
const ext =
|
|
2305
|
+
const basename = path11.basename(rel);
|
|
2306
|
+
const ext = path11.extname(rel).toLowerCase();
|
|
1720
2307
|
if (ext === ".md") {
|
|
1721
2308
|
for (const prefix of EXEMPT_MD_DIR_PREFIXES) {
|
|
1722
2309
|
if (rel.startsWith(prefix)) return "exempt";
|
|
@@ -1759,7 +2346,7 @@ async function hasRecentEngineerDispatch(now = Date.now()) {
|
|
|
1759
2346
|
}
|
|
1760
2347
|
}
|
|
1761
2348
|
function scratchpadPath(sessionId, homeDir = os6.homedir()) {
|
|
1762
|
-
return
|
|
2349
|
+
return path11.join(
|
|
1763
2350
|
homeDir,
|
|
1764
2351
|
".exe-os",
|
|
1765
2352
|
"session-cache",
|
|
@@ -1769,11 +2356,11 @@ function scratchpadPath(sessionId, homeDir = os6.homedir()) {
|
|
|
1769
2356
|
function hasValidScratchpadEscape(sessionId, now = Date.now(), homeDir = os6.homedir()) {
|
|
1770
2357
|
const paths = [scratchpadPath(sessionId, homeDir)];
|
|
1771
2358
|
for (const filePath of paths) {
|
|
1772
|
-
if (!
|
|
2359
|
+
if (!existsSync9(filePath)) continue;
|
|
1773
2360
|
try {
|
|
1774
|
-
const stat =
|
|
2361
|
+
const stat = statSync2(filePath);
|
|
1775
2362
|
if (now - stat.mtimeMs > SCRATCHPAD_MAX_AGE_MS) continue;
|
|
1776
|
-
const body =
|
|
2363
|
+
const body = readFileSync10(filePath, "utf-8");
|
|
1777
2364
|
if (SCRATCHPAD_ESCAPE_PATTERN.test(body)) return true;
|
|
1778
2365
|
} catch {
|
|
1779
2366
|
}
|
|
@@ -1864,14 +2451,14 @@ var init_memory = __esm({
|
|
|
1864
2451
|
|
|
1865
2452
|
// src/lib/keychain.ts
|
|
1866
2453
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
1867
|
-
import { existsSync as
|
|
1868
|
-
import
|
|
2454
|
+
import { existsSync as existsSync10 } from "fs";
|
|
2455
|
+
import path12 from "path";
|
|
1869
2456
|
import os7 from "os";
|
|
1870
2457
|
function getKeyDir() {
|
|
1871
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
2458
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path12.join(os7.homedir(), ".exe-os");
|
|
1872
2459
|
}
|
|
1873
2460
|
function getKeyPath() {
|
|
1874
|
-
return
|
|
2461
|
+
return path12.join(getKeyDir(), "master.key");
|
|
1875
2462
|
}
|
|
1876
2463
|
async function tryKeytar() {
|
|
1877
2464
|
try {
|
|
@@ -1892,13 +2479,21 @@ async function getMasterKey() {
|
|
|
1892
2479
|
}
|
|
1893
2480
|
}
|
|
1894
2481
|
const keyPath = getKeyPath();
|
|
1895
|
-
if (!
|
|
2482
|
+
if (!existsSync10(keyPath)) {
|
|
2483
|
+
process.stderr.write(
|
|
2484
|
+
`[keychain] Key not found at ${keyPath} (HOME=${os7.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
2485
|
+
`
|
|
2486
|
+
);
|
|
1896
2487
|
return null;
|
|
1897
2488
|
}
|
|
1898
2489
|
try {
|
|
1899
2490
|
const content = await readFile3(keyPath, "utf-8");
|
|
1900
2491
|
return Buffer.from(content.trim(), "base64");
|
|
1901
|
-
} catch {
|
|
2492
|
+
} catch (err) {
|
|
2493
|
+
process.stderr.write(
|
|
2494
|
+
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
2495
|
+
`
|
|
2496
|
+
);
|
|
1902
2497
|
return null;
|
|
1903
2498
|
}
|
|
1904
2499
|
}
|
|
@@ -1979,13 +2574,13 @@ __export(shard_manager_exports, {
|
|
|
1979
2574
|
listShards: () => listShards,
|
|
1980
2575
|
shardExists: () => shardExists
|
|
1981
2576
|
});
|
|
1982
|
-
import
|
|
1983
|
-
import { existsSync as
|
|
2577
|
+
import path13 from "path";
|
|
2578
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync6, readdirSync as readdirSync2 } from "fs";
|
|
1984
2579
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1985
2580
|
function initShardManager(encryptionKey) {
|
|
1986
2581
|
_encryptionKey = encryptionKey;
|
|
1987
|
-
if (!
|
|
1988
|
-
|
|
2582
|
+
if (!existsSync11(SHARDS_DIR)) {
|
|
2583
|
+
mkdirSync6(SHARDS_DIR, { recursive: true });
|
|
1989
2584
|
}
|
|
1990
2585
|
_shardingEnabled = true;
|
|
1991
2586
|
}
|
|
@@ -2005,7 +2600,7 @@ function getShardClient(projectName) {
|
|
|
2005
2600
|
}
|
|
2006
2601
|
const cached = _shards.get(safeName);
|
|
2007
2602
|
if (cached) return cached;
|
|
2008
|
-
const dbPath =
|
|
2603
|
+
const dbPath = path13.join(SHARDS_DIR, `${safeName}.db`);
|
|
2009
2604
|
const client = createClient2({
|
|
2010
2605
|
url: `file:${dbPath}`,
|
|
2011
2606
|
encryptionKey: _encryptionKey
|
|
@@ -2015,10 +2610,10 @@ function getShardClient(projectName) {
|
|
|
2015
2610
|
}
|
|
2016
2611
|
function shardExists(projectName) {
|
|
2017
2612
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2018
|
-
return
|
|
2613
|
+
return existsSync11(path13.join(SHARDS_DIR, `${safeName}.db`));
|
|
2019
2614
|
}
|
|
2020
2615
|
function listShards() {
|
|
2021
|
-
if (!
|
|
2616
|
+
if (!existsSync11(SHARDS_DIR)) return [];
|
|
2022
2617
|
return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2023
2618
|
}
|
|
2024
2619
|
async function ensureShardSchema(client) {
|
|
@@ -2204,7 +2799,7 @@ var init_shard_manager = __esm({
|
|
|
2204
2799
|
"src/lib/shard-manager.ts"() {
|
|
2205
2800
|
"use strict";
|
|
2206
2801
|
init_config();
|
|
2207
|
-
SHARDS_DIR =
|
|
2802
|
+
SHARDS_DIR = path13.join(EXE_AI_DIR, "shards");
|
|
2208
2803
|
_shards = /* @__PURE__ */ new Map();
|
|
2209
2804
|
_encryptionKey = null;
|
|
2210
2805
|
_shardingEnabled = false;
|
|
@@ -2329,7 +2924,7 @@ __export(global_procedures_exports, {
|
|
|
2329
2924
|
loadGlobalProcedures: () => loadGlobalProcedures,
|
|
2330
2925
|
storeGlobalProcedure: () => storeGlobalProcedure
|
|
2331
2926
|
});
|
|
2332
|
-
import { randomUUID as
|
|
2927
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2333
2928
|
async function loadGlobalProcedures() {
|
|
2334
2929
|
const client = getClient();
|
|
2335
2930
|
const result = await client.execute({
|
|
@@ -2358,7 +2953,7 @@ ${sections.join("\n\n")}
|
|
|
2358
2953
|
`;
|
|
2359
2954
|
}
|
|
2360
2955
|
async function storeGlobalProcedure(input2) {
|
|
2361
|
-
const id =
|
|
2956
|
+
const id = randomUUID3();
|
|
2362
2957
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2363
2958
|
const client = getClient();
|
|
2364
2959
|
await client.execute({
|
|
@@ -2409,6 +3004,7 @@ __export(store_exports, {
|
|
|
2409
3004
|
vectorToBlob: () => vectorToBlob,
|
|
2410
3005
|
writeMemory: () => writeMemory
|
|
2411
3006
|
});
|
|
3007
|
+
import { createHash } from "crypto";
|
|
2412
3008
|
function isBusyError2(err) {
|
|
2413
3009
|
if (err instanceof Error) {
|
|
2414
3010
|
const msg = err.message.toLowerCase();
|
|
@@ -2482,12 +3078,52 @@ function classifyTier(record) {
|
|
|
2482
3078
|
if (["store_memory", "manual"].includes(record.tool_name ?? "") && (record.importance ?? 0) >= 5) return 2;
|
|
2483
3079
|
return 3;
|
|
2484
3080
|
}
|
|
3081
|
+
function inferFilePaths(record) {
|
|
3082
|
+
if (!["Read", "Write", "Edit"].includes(record.tool_name)) return null;
|
|
3083
|
+
const firstLine = record.raw_text.split("\n")[0] ?? "";
|
|
3084
|
+
const match = firstLine.match(/(\/[\w./-]+\.\w+)/);
|
|
3085
|
+
return match ? JSON.stringify([match[1]]) : null;
|
|
3086
|
+
}
|
|
3087
|
+
function inferCommitHash(record) {
|
|
3088
|
+
if (record.tool_name !== "Bash") return null;
|
|
3089
|
+
const match = record.raw_text.match(/\b([a-f0-9]{7,40})\b/);
|
|
3090
|
+
return match ? match[1] : null;
|
|
3091
|
+
}
|
|
3092
|
+
function inferLanguageType(record) {
|
|
3093
|
+
const text = record.raw_text;
|
|
3094
|
+
if (!text || text.length < 10) return null;
|
|
3095
|
+
const trimmed = text.trimStart();
|
|
3096
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return "json";
|
|
3097
|
+
if (/\b(SELECT|INSERT|UPDATE|DELETE|CREATE TABLE|ALTER TABLE)\b/i.test(text)) return "sql";
|
|
3098
|
+
if (/\b(function |const |import |export |class |def |async |=>)\b/.test(text)) return "code";
|
|
3099
|
+
if (trimmed.startsWith("#") || trimmed.startsWith("*")) return "prose";
|
|
3100
|
+
return "mixed";
|
|
3101
|
+
}
|
|
3102
|
+
function inferDomain(record) {
|
|
3103
|
+
const proj = (record.project_name ?? "").toLowerCase();
|
|
3104
|
+
if (proj.includes("marketing") || proj.includes("content")) return "marketing";
|
|
3105
|
+
if (proj.includes("crm") || proj.includes("customer")) return "customer";
|
|
3106
|
+
return null;
|
|
3107
|
+
}
|
|
2485
3108
|
async function writeMemory(record) {
|
|
2486
3109
|
if (record.vector !== null && record.vector.length !== EMBEDDING_DIM) {
|
|
2487
3110
|
throw new Error(
|
|
2488
3111
|
`Expected ${EMBEDDING_DIM}-dim vector, got ${record.vector.length}`
|
|
2489
3112
|
);
|
|
2490
3113
|
}
|
|
3114
|
+
const contentHash = createHash("md5").update(record.raw_text).digest("hex");
|
|
3115
|
+
if (_pendingRecords.some((r) => r.content_hash === contentHash && r.agent_id === record.agent_id)) {
|
|
3116
|
+
return;
|
|
3117
|
+
}
|
|
3118
|
+
try {
|
|
3119
|
+
const client = getClient();
|
|
3120
|
+
const existing = await client.execute({
|
|
3121
|
+
sql: "SELECT id FROM memories WHERE content_hash = ? AND agent_id = ? LIMIT 1",
|
|
3122
|
+
args: [contentHash, record.agent_id]
|
|
3123
|
+
});
|
|
3124
|
+
if (existing.rows.length > 0) return;
|
|
3125
|
+
} catch {
|
|
3126
|
+
}
|
|
2491
3127
|
const dbRow = {
|
|
2492
3128
|
id: record.id,
|
|
2493
3129
|
agent_id: record.agent_id,
|
|
@@ -2517,7 +3153,23 @@ async function writeMemory(record) {
|
|
|
2517
3153
|
supersedes_id: record.supersedes_id ?? null,
|
|
2518
3154
|
draft: record.draft ? 1 : 0,
|
|
2519
3155
|
memory_type: record.memory_type ?? "raw",
|
|
2520
|
-
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null
|
|
3156
|
+
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
3157
|
+
content_hash: contentHash,
|
|
3158
|
+
intent: record.intent ?? null,
|
|
3159
|
+
outcome: record.outcome ?? null,
|
|
3160
|
+
domain: record.domain ?? inferDomain(record),
|
|
3161
|
+
referenced_entities: record.referenced_entities ?? null,
|
|
3162
|
+
retrieval_count: record.retrieval_count ?? 0,
|
|
3163
|
+
chain_position: record.chain_position ?? null,
|
|
3164
|
+
review_status: record.review_status ?? null,
|
|
3165
|
+
context_window_pct: record.context_window_pct ?? null,
|
|
3166
|
+
file_paths: record.file_paths ?? inferFilePaths(record),
|
|
3167
|
+
commit_hash: record.commit_hash ?? inferCommitHash(record),
|
|
3168
|
+
duration_ms: record.duration_ms ?? null,
|
|
3169
|
+
token_cost: record.token_cost ?? null,
|
|
3170
|
+
audience: record.audience ?? null,
|
|
3171
|
+
language_type: record.language_type ?? inferLanguageType(record),
|
|
3172
|
+
parent_memory_id: record.parent_memory_id ?? null
|
|
2521
3173
|
};
|
|
2522
3174
|
_pendingRecords.push(dbRow);
|
|
2523
3175
|
orgBus.emit({
|
|
@@ -2575,80 +3227,85 @@ async function flushBatch() {
|
|
|
2575
3227
|
const draft = row.draft ? 1 : 0;
|
|
2576
3228
|
const memoryType = row.memory_type ?? "raw";
|
|
2577
3229
|
const trajectory = row.trajectory ?? null;
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
3230
|
+
const contentHash = row.content_hash ?? null;
|
|
3231
|
+
const intent = row.intent ?? null;
|
|
3232
|
+
const outcome = row.outcome ?? null;
|
|
3233
|
+
const domain = row.domain ?? null;
|
|
3234
|
+
const referencedEntities = row.referenced_entities ?? null;
|
|
3235
|
+
const retrievalCount = row.retrieval_count ?? 0;
|
|
3236
|
+
const chainPosition = row.chain_position ?? null;
|
|
3237
|
+
const reviewStatus = row.review_status ?? null;
|
|
3238
|
+
const contextWindowPct = row.context_window_pct ?? null;
|
|
3239
|
+
const filePaths = row.file_paths ?? null;
|
|
3240
|
+
const commitHash = row.commit_hash ?? null;
|
|
3241
|
+
const durationMs = row.duration_ms ?? null;
|
|
3242
|
+
const tokenCost = row.token_cost ?? null;
|
|
3243
|
+
const audience = row.audience ?? null;
|
|
3244
|
+
const languageType = row.language_type ?? null;
|
|
3245
|
+
const parentMemoryId = row.parent_memory_id ?? null;
|
|
3246
|
+
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
2581
3247
|
tool_name, project_name,
|
|
2582
3248
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
2583
3249
|
confidence, last_accessed,
|
|
2584
3250
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
2585
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
pageNumber,
|
|
2644
|
-
sourcePath,
|
|
2645
|
-
sourceType,
|
|
2646
|
-
tier,
|
|
2647
|
-
supersedesId,
|
|
2648
|
-
draft,
|
|
2649
|
-
memoryType,
|
|
2650
|
-
trajectory
|
|
2651
|
-
]
|
|
3251
|
+
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
3252
|
+
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
3253
|
+
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
3254
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
3255
|
+
const metaArgs = [
|
|
3256
|
+
intent,
|
|
3257
|
+
outcome,
|
|
3258
|
+
domain,
|
|
3259
|
+
referencedEntities,
|
|
3260
|
+
retrievalCount,
|
|
3261
|
+
chainPosition,
|
|
3262
|
+
reviewStatus,
|
|
3263
|
+
contextWindowPct,
|
|
3264
|
+
filePaths,
|
|
3265
|
+
commitHash,
|
|
3266
|
+
durationMs,
|
|
3267
|
+
tokenCost,
|
|
3268
|
+
audience,
|
|
3269
|
+
languageType,
|
|
3270
|
+
parentMemoryId
|
|
3271
|
+
];
|
|
3272
|
+
const baseArgs = [
|
|
3273
|
+
row.id,
|
|
3274
|
+
row.agent_id,
|
|
3275
|
+
row.agent_role,
|
|
3276
|
+
row.session_id,
|
|
3277
|
+
row.timestamp,
|
|
3278
|
+
row.tool_name,
|
|
3279
|
+
row.project_name,
|
|
3280
|
+
row.has_error,
|
|
3281
|
+
row.raw_text
|
|
3282
|
+
];
|
|
3283
|
+
const sharedArgs = [
|
|
3284
|
+
row.version,
|
|
3285
|
+
taskId,
|
|
3286
|
+
importance,
|
|
3287
|
+
status,
|
|
3288
|
+
confidence,
|
|
3289
|
+
lastAccessed,
|
|
3290
|
+
workspaceId,
|
|
3291
|
+
documentId,
|
|
3292
|
+
userId,
|
|
3293
|
+
charOffset,
|
|
3294
|
+
pageNumber,
|
|
3295
|
+
sourcePath,
|
|
3296
|
+
sourceType,
|
|
3297
|
+
tier,
|
|
3298
|
+
supersedesId,
|
|
3299
|
+
draft,
|
|
3300
|
+
memoryType,
|
|
3301
|
+
trajectory,
|
|
3302
|
+
contentHash
|
|
3303
|
+
];
|
|
3304
|
+
return {
|
|
3305
|
+
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
3306
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
3307
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3308
|
+
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
2652
3309
|
};
|
|
2653
3310
|
};
|
|
2654
3311
|
const globalClient = getClient();
|
|
@@ -2908,7 +3565,7 @@ __export(review_gate_exports, {
|
|
|
2908
3565
|
runReviewGate: () => runReviewGate
|
|
2909
3566
|
});
|
|
2910
3567
|
import { execSync as execSync5 } from "child_process";
|
|
2911
|
-
import { existsSync as
|
|
3568
|
+
import { existsSync as existsSync12 } from "fs";
|
|
2912
3569
|
function checkCommitsExist(taskCreatedAt) {
|
|
2913
3570
|
try {
|
|
2914
3571
|
const since = new Date(taskCreatedAt).toISOString();
|
|
@@ -2971,7 +3628,7 @@ function checkTestCoverage(taskCreatedAt) {
|
|
|
2971
3628
|
const testPath = file.replace(/^src\//, "tests/").replace(/\.ts$/, ".test.ts");
|
|
2972
3629
|
const baseName = file.split("/").pop()?.replace(/\.ts$/, "") ?? "";
|
|
2973
3630
|
const testDir = testPath.substring(0, testPath.lastIndexOf("/"));
|
|
2974
|
-
const hasDirectTest =
|
|
3631
|
+
const hasDirectTest = existsSync12(testPath);
|
|
2975
3632
|
let hasRelatedTest = false;
|
|
2976
3633
|
try {
|
|
2977
3634
|
const related = execSync5(
|
|
@@ -3025,9 +3682,9 @@ var init_review_gate = __esm({
|
|
|
3025
3682
|
});
|
|
3026
3683
|
|
|
3027
3684
|
// src/adapters/claude/hooks/pre-tool-use.ts
|
|
3028
|
-
import { existsSync as
|
|
3685
|
+
import { existsSync as existsSync13, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "fs";
|
|
3029
3686
|
import { execSync as execSync6 } from "child_process";
|
|
3030
|
-
import
|
|
3687
|
+
import path14 from "path";
|
|
3031
3688
|
|
|
3032
3689
|
// src/adapters/claude/active-agent.ts
|
|
3033
3690
|
init_config();
|
|
@@ -3140,25 +3797,25 @@ if (!process.env.AGENT_ID) {
|
|
|
3140
3797
|
}
|
|
3141
3798
|
var DELEGATION_TASK_THRESHOLD = 3;
|
|
3142
3799
|
var CTO_ROLES = ["CTO", "executive"];
|
|
3143
|
-
var CACHE_DIR2 =
|
|
3800
|
+
var CACHE_DIR2 = path14.join(EXE_AI_DIR, "session-cache");
|
|
3144
3801
|
var timeout = setTimeout(() => {
|
|
3145
3802
|
process.exit(0);
|
|
3146
3803
|
}, 5e3);
|
|
3147
3804
|
timeout.unref();
|
|
3148
3805
|
function getDelegationFlagPath() {
|
|
3149
|
-
return
|
|
3806
|
+
return path14.join(CACHE_DIR2, `delegation-checkpoint-${getSessionKey()}.json`);
|
|
3150
3807
|
}
|
|
3151
3808
|
function hasDelegationFired() {
|
|
3152
3809
|
try {
|
|
3153
|
-
return
|
|
3810
|
+
return existsSync13(getDelegationFlagPath());
|
|
3154
3811
|
} catch {
|
|
3155
3812
|
return false;
|
|
3156
3813
|
}
|
|
3157
3814
|
}
|
|
3158
3815
|
function markDelegationFired() {
|
|
3159
3816
|
try {
|
|
3160
|
-
|
|
3161
|
-
|
|
3817
|
+
mkdirSync7(CACHE_DIR2, { recursive: true });
|
|
3818
|
+
writeFileSync7(getDelegationFlagPath(), JSON.stringify({ fired: true }));
|
|
3162
3819
|
} catch {
|
|
3163
3820
|
}
|
|
3164
3821
|
}
|