@askexenow/exe-os 0.9.75 → 0.9.77

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.
@@ -7413,590 +7413,282 @@ var init_hybrid_search = __esm({
7413
7413
  }
7414
7414
  });
7415
7415
 
7416
- // src/lib/memory-queue.ts
7417
- import { appendFileSync, readFileSync as readFileSync6, renameSync as renameSync4, unlinkSync as unlinkSync3, existsSync as existsSync10, statSync as statSync5 } from "fs";
7418
- import path11 from "path";
7419
- function enqueueMemory(entry) {
7420
- appendFileSync(QUEUE_PATH, JSON.stringify(entry) + "\n");
7416
+ // src/lib/session-key.ts
7417
+ import { execSync as execSync5 } from "child_process";
7418
+ function normalizeCommand(command) {
7419
+ const trimmed = command.trim().toLowerCase();
7420
+ const parts = trimmed.split(/[\\/]/);
7421
+ return parts[parts.length - 1] ?? trimmed;
7421
7422
  }
7422
- var QUEUE_PATH, PROCESSING_PATH, TTL_MS;
7423
- var init_memory_queue = __esm({
7424
- "src/lib/memory-queue.ts"() {
7425
- "use strict";
7426
- init_config();
7427
- QUEUE_PATH = path11.join(EXE_AI_DIR, "memory-queue.jsonl");
7428
- PROCESSING_PATH = QUEUE_PATH + ".processing";
7429
- TTL_MS = 24 * 60 * 60 * 1e3;
7430
- }
7431
- });
7432
-
7433
- // src/lib/memory-queue-client.ts
7434
- var memory_queue_client_exports = {};
7435
- __export(memory_queue_client_exports, {
7436
- batchWriteMemoryViaDaemon: () => batchWriteMemoryViaDaemon,
7437
- writeMemoryViaDaemon: () => writeMemoryViaDaemon
7438
- });
7439
- async function writeMemoryViaDaemon(entry) {
7440
- if (process.env.EXE_IS_DAEMON === "1") {
7441
- enqueueMemory(entry);
7442
- return false;
7443
- }
7444
- if (!isClientConnected()) {
7445
- enqueueMemory(entry);
7446
- return false;
7423
+ function detectRuntimeFromCommand(command) {
7424
+ const normalized = normalizeCommand(command);
7425
+ for (const [runtime, commands] of Object.entries(RUNTIME_COMMANDS)) {
7426
+ if (commands.includes(normalized)) {
7427
+ return runtime;
7428
+ }
7447
7429
  }
7448
- try {
7449
- const response = await sendDaemonRequest({
7450
- type: "write-memory",
7451
- entry
7452
- });
7453
- if (response.ok) return true;
7454
- enqueueMemory(entry);
7455
- return false;
7456
- } catch {
7457
- enqueueMemory(entry);
7458
- return false;
7430
+ return null;
7431
+ }
7432
+ function resolveRuntimeProcess() {
7433
+ let pid = process.ppid;
7434
+ for (let i = 0; i < 10; i++) {
7435
+ try {
7436
+ const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
7437
+ encoding: "utf8",
7438
+ timeout: 2e3
7439
+ }).trim();
7440
+ const match = info.match(/^\s*(\d+)\s+(.+)$/);
7441
+ if (!match) break;
7442
+ const [, ppid, cmd] = match;
7443
+ const runtime = detectRuntimeFromCommand(cmd ?? "");
7444
+ if (runtime) {
7445
+ return { pid: String(pid), runtime };
7446
+ }
7447
+ pid = parseInt(ppid, 10);
7448
+ if (pid <= 1) break;
7449
+ } catch {
7450
+ break;
7451
+ }
7459
7452
  }
7453
+ return null;
7460
7454
  }
7461
- async function batchWriteMemoryViaDaemon(entries) {
7462
- if (entries.length === 0) return 0;
7463
- if (process.env.EXE_IS_DAEMON === "1" || !isClientConnected()) {
7464
- for (const entry of entries) enqueueMemory(entry);
7465
- return 0;
7455
+ function getSessionKey() {
7456
+ if (_cached2) return _cached2;
7457
+ if (process.env.EXE_SESSION_KEY) {
7458
+ _cached2 = process.env.EXE_SESSION_KEY;
7459
+ return _cached2;
7466
7460
  }
7467
- try {
7468
- const response = await sendDaemonRequest({
7469
- type: "batch-write-memory",
7470
- entries
7471
- });
7472
- if (response.ok) return response.count ?? entries.length;
7473
- for (const entry of entries) enqueueMemory(entry);
7474
- return 0;
7475
- } catch {
7476
- for (const entry of entries) enqueueMemory(entry);
7477
- return 0;
7461
+ const resolved = resolveRuntimeProcess();
7462
+ if (resolved) {
7463
+ _cachedRuntime = resolved.runtime;
7464
+ _cached2 = resolved.pid;
7465
+ return _cached2;
7478
7466
  }
7467
+ _cached2 = process.env.CLAUDE_CODE_SSE_PORT ?? String(process.ppid);
7468
+ return _cached2;
7479
7469
  }
7480
- var init_memory_queue_client = __esm({
7481
- "src/lib/memory-queue-client.ts"() {
7470
+ var _cached2, _cachedRuntime, RUNTIME_COMMANDS;
7471
+ var init_session_key = __esm({
7472
+ "src/lib/session-key.ts"() {
7482
7473
  "use strict";
7483
- init_exe_daemon_client();
7484
- init_memory_queue();
7474
+ _cached2 = null;
7475
+ _cachedRuntime = null;
7476
+ RUNTIME_COMMANDS = {
7477
+ claude: ["claude", "claude.exe", "claude-native"],
7478
+ codex: ["codex"],
7479
+ opencode: ["opencode"]
7480
+ };
7485
7481
  }
7486
7482
  });
7487
7483
 
7488
- // src/lib/content-extractor.ts
7489
- function extractSemanticText(toolName, toolInput, toolResponse) {
7490
- switch (toolName) {
7491
- case "Write":
7492
- return extractWrite(toolInput);
7493
- case "Edit":
7494
- return extractEdit(toolInput);
7495
- case "Read":
7496
- return extractRead(toolInput, toolResponse);
7497
- case "Bash":
7498
- return extractBash(toolInput, toolResponse);
7499
- case "Grep":
7500
- return extractGrep(toolInput, toolResponse);
7501
- case "Glob":
7502
- return extractGlob(toolInput, toolResponse);
7503
- default:
7504
- if (isExeMcpTool(toolName)) {
7505
- return extractExeMemMcp(toolName, toolInput, toolResponse);
7506
- }
7507
- if (toolName.startsWith("mcp__")) {
7508
- return extractGenericMcp(toolName, toolInput, toolResponse);
7509
- }
7510
- return extractDefault(toolName, toolInput, toolResponse);
7484
+ // src/mcp/agent-context.ts
7485
+ import { AsyncLocalStorage } from "async_hooks";
7486
+ function getAgentContext() {
7487
+ return agentStore.getStore();
7488
+ }
7489
+ var agentStore;
7490
+ var init_agent_context = __esm({
7491
+ "src/mcp/agent-context.ts"() {
7492
+ "use strict";
7493
+ agentStore = new AsyncLocalStorage();
7511
7494
  }
7495
+ });
7496
+
7497
+ // src/lib/active-agent.ts
7498
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, readdirSync as readdirSync3 } from "fs";
7499
+ import { execSync as execSync6 } from "child_process";
7500
+ import path11 from "path";
7501
+ function isNameWithOptionalInstance(candidate, baseName) {
7502
+ if (candidate === baseName) return true;
7503
+ if (!candidate.startsWith(baseName)) return false;
7504
+ return /^\d+$/.test(candidate.slice(baseName.length));
7512
7505
  }
7513
- function findContainingChunk(filePath, snippet) {
7514
- try {
7515
- const ext = filePath.split(".").pop()?.toLowerCase();
7516
- if (ext !== "ts" && ext !== "tsx" && ext !== "js" && ext !== "jsx") return "";
7517
- const { readFileSync: readFileSync13 } = __require("fs");
7518
- const source = readFileSync13(filePath, "utf8");
7519
- const lines = source.split("\n");
7520
- const lowerSnippet = snippet.toLowerCase().slice(0, 80);
7521
- let matchLine = -1;
7522
- for (let i = 0; i < lines.length; i++) {
7523
- if (lines[i].toLowerCase().includes(lowerSnippet)) {
7524
- matchLine = i;
7525
- break;
7526
- }
7506
+ function resolveEmployeeFromSessionPrefix(prefix, employees) {
7507
+ const sorted = [...employees].sort((a, b) => b.name.length - a.name.length);
7508
+ for (const employee of sorted) {
7509
+ if (isNameWithOptionalInstance(prefix, employee.name)) {
7510
+ return { agentId: employee.name, agentRole: employee.role };
7527
7511
  }
7528
- if (matchLine === -1) return "";
7529
- for (let i = matchLine; i >= 0; i--) {
7530
- const line = lines[i];
7531
- const fnMatch = line.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)/);
7532
- if (fnMatch) return `Function ${fnMatch[1]} in ${filePath}:${i + 1}`;
7533
- const classMatch = line.match(/(?:export\s+)?class\s+(\w+)/);
7534
- if (classMatch) return `Class ${classMatch[1]} in ${filePath}:${i + 1}`;
7535
- const arrowMatch = line.match(/(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s+)?\(/);
7536
- if (arrowMatch) return `Function ${arrowMatch[1]} in ${filePath}:${i + 1}`;
7512
+ }
7513
+ return null;
7514
+ }
7515
+ function resolveActiveAgentFromTmuxSession(sessionName) {
7516
+ const employees = loadEmployeesSync();
7517
+ const coordinator = getCoordinatorEmployee(employees);
7518
+ const coordinatorName = coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
7519
+ if (isNameWithOptionalInstance(sessionName, coordinatorName)) {
7520
+ return {
7521
+ agentId: coordinatorName,
7522
+ agentRole: coordinator?.role ?? "COO"
7523
+ };
7524
+ }
7525
+ if (isNameWithOptionalInstance(sessionName, DEFAULT_COORDINATOR_TEMPLATE_NAME)) {
7526
+ return {
7527
+ agentId: coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME,
7528
+ agentRole: coordinator?.role ?? "COO"
7529
+ };
7530
+ }
7531
+ if (sessionName.includes("-")) {
7532
+ const prefix = sessionName.split("-")[0] ?? "";
7533
+ const employee = resolveEmployeeFromSessionPrefix(prefix, employees);
7534
+ if (employee) return employee;
7535
+ const legacy = prefix.match(/^([a-zA-Z]+)\d*$/);
7536
+ if (legacy?.[1] && legacy[1] !== DEFAULT_COORDINATOR_TEMPLATE_NAME) {
7537
+ const emp = getEmployee(employees, legacy[1]);
7538
+ return { agentId: emp?.name ?? legacy[1], agentRole: emp?.role ?? "employee" };
7537
7539
  }
7538
- } catch {
7539
7540
  }
7540
- return "";
7541
+ return null;
7541
7542
  }
7542
- function extractWrite(input2) {
7543
- const filePath = String(input2.file_path ?? "");
7544
- const content = String(input2.content ?? "");
7545
- const chunkContext = findContainingChunk(filePath, content.slice(0, 200));
7546
- const prefix = chunkContext ? `Wrote ${filePath} (${chunkContext})` : `Wrote ${filePath}`;
7547
- return `${prefix}
7548
- ${content.slice(0, MAX_CONTENT)}`;
7543
+ function getMarkerPath() {
7544
+ return path11.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
7549
7545
  }
7550
- function extractEdit(input2) {
7551
- const filePath = String(input2.file_path ?? "");
7552
- const oldStr = String(input2.old_string ?? "");
7553
- const newStr = String(input2.new_string ?? "");
7554
- const chunkContext = findContainingChunk(filePath, oldStr.slice(0, 200));
7555
- const prefix = chunkContext ? `Edited ${filePath} (${chunkContext})` : `Edited ${filePath}`;
7556
- return `${prefix}
7557
- Removed: ${oldStr.slice(0, MAX_CONTENT / 2)}
7558
- Added: ${newStr.slice(0, MAX_CONTENT / 2)}`;
7546
+ function writeActiveAgent(agentId, agentRole) {
7547
+ try {
7548
+ mkdirSync3(CACHE_DIR, { recursive: true });
7549
+ writeFileSync3(
7550
+ getMarkerPath(),
7551
+ JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
7552
+ );
7553
+ } catch {
7554
+ }
7559
7555
  }
7560
- function extractRead(input2, response) {
7561
- const filePath = String(input2.file_path ?? "");
7562
- const file = response.file;
7563
- const content = file ? String(file.content ?? "") : "";
7564
- if (!content) {
7565
- const text = String(response.text ?? response.content ?? "");
7566
- return `Read ${filePath}
7567
- ${text.slice(0, MAX_CONTENT)}`;
7556
+ function clearActiveAgent() {
7557
+ try {
7558
+ unlinkSync3(getMarkerPath());
7559
+ } catch {
7568
7560
  }
7569
- return `Read ${filePath}
7570
- ${content.slice(0, MAX_CONTENT)}`;
7571
7561
  }
7572
- function extractBash(input2, response) {
7573
- const command = String(input2.command ?? "");
7574
- const description = input2.description ? String(input2.description) : "";
7575
- const stdout = String(response.stdout ?? response.text ?? "");
7576
- const stderr = String(response.stderr ?? "");
7577
- const parts = [description ? `${description}: ${command}` : `Ran: ${command}`];
7578
- if (stdout) parts.push(`Output: ${stdout.slice(0, MAX_OUTPUT)}`);
7579
- if (stderr && !stdout) parts.push(`Error: ${stderr.slice(0, MAX_OUTPUT)}`);
7580
- return parts.join("\n");
7581
- }
7582
- function extractGrep(input2, response) {
7583
- const pattern = String(input2.pattern ?? "");
7584
- const path20 = input2.path ? String(input2.path) : "";
7585
- const output = String(response.text ?? response.content ?? JSON.stringify(response).slice(0, MAX_OUTPUT));
7586
- return `Searched for "${pattern}"${path20 ? ` in ${path20}` : ""}
7587
- ${output.slice(0, MAX_OUTPUT)}`;
7588
- }
7589
- function extractGlob(input2, response) {
7590
- const pattern = String(input2.pattern ?? "");
7591
- const output = String(response.text ?? response.content ?? JSON.stringify(response).slice(0, MAX_OUTPUT));
7592
- return `Found files matching "${pattern}"
7593
- ${output.slice(0, MAX_OUTPUT)}`;
7594
- }
7595
- function extractExeMemMcp(toolName, input2, response) {
7596
- const shortName = stripExeMcpPrefix(toolName);
7597
- switch (shortName) {
7598
- case "store_memory": {
7599
- const text = String(input2.text ?? input2.query ?? "");
7600
- return `Stored memory: ${text.slice(0, MAX_CONTENT)}`;
7601
- }
7602
- case "recall_my_memory":
7603
- case "ask_team_memory": {
7604
- const query = String(input2.query ?? "");
7605
- const member = input2.team_member ? ` (from ${input2.team_member})` : "";
7606
- const resultText = extractResponseText(response);
7607
- return `Memory search${member}: "${query}"
7608
- ${resultText.slice(0, MAX_OUTPUT)}`;
7609
- }
7610
- case "create_task": {
7611
- const title = String(input2.title ?? "");
7612
- const assignedTo = String(input2.assigned_to ?? "");
7613
- const priority = String(input2.priority ?? "p1");
7614
- const context = String(input2.context ?? "");
7615
- return `Task created: "${title}" assigned to ${assignedTo} [${priority}]
7616
- ${context.slice(0, MAX_CONTENT)}`;
7617
- }
7618
- case "update_task": {
7619
- const taskId = String(input2.task_id ?? "");
7620
- const status = String(input2.status ?? "");
7621
- const result = input2.result ? String(input2.result) : "";
7622
- return `Task updated: ${taskId} \u2192 ${status}${result ? `
7623
- Result: ${result.slice(0, MAX_CONTENT)}` : ""}`;
7624
- }
7625
- case "list_tasks": {
7626
- const resultText = extractResponseText(response);
7627
- return `Listed tasks
7628
- ${resultText.slice(0, MAX_OUTPUT)}`;
7629
- }
7630
- default: {
7631
- return extractGenericMcp(toolName, input2, response);
7562
+ function getActiveAgent() {
7563
+ const httpCtx = getAgentContext();
7564
+ if (httpCtx) return httpCtx;
7565
+ try {
7566
+ const markerPath = getMarkerPath();
7567
+ const raw = readFileSync6(markerPath, "utf8");
7568
+ const data = JSON.parse(raw);
7569
+ if (data.agentId) {
7570
+ if (data.startedAt) {
7571
+ const age = Date.now() - new Date(data.startedAt).getTime();
7572
+ if (age > STALE_MS) {
7573
+ try {
7574
+ unlinkSync3(markerPath);
7575
+ } catch {
7576
+ }
7577
+ } else {
7578
+ return {
7579
+ agentId: data.agentId,
7580
+ agentRole: data.agentRole || "employee"
7581
+ };
7582
+ }
7583
+ } else {
7584
+ return {
7585
+ agentId: data.agentId,
7586
+ agentRole: data.agentRole || "employee"
7587
+ };
7588
+ }
7632
7589
  }
7590
+ } catch {
7633
7591
  }
7592
+ try {
7593
+ const sessionName = execSync6(
7594
+ "tmux display-message -p '#{session_name}' 2>/dev/null",
7595
+ { encoding: "utf8", timeout: 2e3 }
7596
+ ).trim();
7597
+ const resolved = resolveActiveAgentFromTmuxSession(sessionName);
7598
+ if (resolved) return resolved;
7599
+ } catch {
7600
+ }
7601
+ return {
7602
+ agentId: process.env.AGENT_ID || "default",
7603
+ agentRole: process.env.AGENT_ROLE || "employee"
7604
+ };
7634
7605
  }
7635
- function extractGenericMcp(toolName, input2, response) {
7636
- const shortName = toolName.replace(/^mcp__[^_]+__/, "");
7637
- const inputParts = Object.entries(input2).filter(([, v]) => v != null && String(v).length > 0).map(([k, v]) => `${k}: ${String(v).slice(0, 200)}`).join(", ");
7638
- const resultText = extractResponseText(response);
7639
- return `${shortName}(${inputParts})
7640
- ${resultText.slice(0, MAX_OUTPUT)}`;
7641
- }
7642
- function extractDefault(toolName, input2, response) {
7643
- const inputStr = JSON.stringify(input2);
7644
- const resultText = extractResponseText(response);
7645
- return `Tool: ${toolName}
7646
- ${inputStr.slice(0, MAX_CONTENT / 2)}
7647
- ${resultText.slice(0, MAX_OUTPUT)}`;
7648
- }
7649
- function extractResponseText(response) {
7650
- if (typeof response.text === "string") return response.text;
7651
- if (typeof response.content === "string") return response.content;
7652
- if (Array.isArray(response.content)) {
7653
- return response.content.map((block) => {
7654
- if (typeof block === "object" && block !== null && "text" in block) {
7655
- return String(block.text);
7606
+ function getAllActiveAgents() {
7607
+ try {
7608
+ const files = readdirSync3(CACHE_DIR);
7609
+ const sessions = [];
7610
+ for (const file of files) {
7611
+ if (!file.startsWith("active-agent-") || !file.endsWith(".json")) continue;
7612
+ const key = file.slice("active-agent-".length, -".json".length);
7613
+ if (key === "undefined") continue;
7614
+ try {
7615
+ const raw = readFileSync6(path11.join(CACHE_DIR, file), "utf8");
7616
+ const data = JSON.parse(raw);
7617
+ if (!data.agentId) continue;
7618
+ if (data.startedAt) {
7619
+ const age = Date.now() - new Date(data.startedAt).getTime();
7620
+ if (age > STALE_MS) {
7621
+ try {
7622
+ unlinkSync3(path11.join(CACHE_DIR, file));
7623
+ } catch {
7624
+ }
7625
+ continue;
7626
+ }
7627
+ }
7628
+ sessions.push({
7629
+ agentId: data.agentId,
7630
+ agentRole: data.agentRole || "employee",
7631
+ startedAt: data.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
7632
+ sessionKey: key
7633
+ });
7634
+ } catch {
7656
7635
  }
7657
- return "";
7658
- }).filter(Boolean).join("\n");
7636
+ }
7637
+ return sessions;
7638
+ } catch {
7639
+ return [];
7659
7640
  }
7660
- if (Array.isArray(response)) {
7661
- return response.map((item) => {
7662
- if (typeof item === "object" && item !== null && "text" in item) {
7663
- return String(item.text);
7664
- }
7665
- return "";
7666
- }).filter(Boolean).join("\n");
7641
+ }
7642
+ function cleanupSessionMarkers() {
7643
+ const key = getSessionKey();
7644
+ try {
7645
+ unlinkSync3(path11.join(CACHE_DIR, `active-agent-${key}.json`));
7646
+ } catch {
7647
+ }
7648
+ try {
7649
+ unlinkSync3(path11.join(CACHE_DIR, "active-agent-undefined.json"));
7650
+ } catch {
7667
7651
  }
7668
- return JSON.stringify(response).slice(0, MAX_OUTPUT);
7669
7652
  }
7670
- var MAX_CONTENT, MAX_OUTPUT;
7671
- var init_content_extractor = __esm({
7672
- "src/lib/content-extractor.ts"() {
7653
+ var CACHE_DIR, STALE_MS;
7654
+ var init_active_agent = __esm({
7655
+ "src/lib/active-agent.ts"() {
7673
7656
  "use strict";
7674
- init_mcp_prefix();
7675
- MAX_CONTENT = 2e3;
7676
- MAX_OUTPUT = 1e3;
7657
+ init_config();
7658
+ init_session_key();
7659
+ init_agent_context();
7660
+ init_employees();
7661
+ CACHE_DIR = path11.join(EXE_AI_DIR, "session-cache");
7662
+ STALE_MS = 24 * 60 * 60 * 1e3;
7677
7663
  }
7678
7664
  });
7679
7665
 
7680
- // src/lib/post-tool-memory.ts
7681
- var post_tool_memory_exports = {};
7682
- __export(post_tool_memory_exports, {
7683
- buildPostToolMemoryEntry: () => buildPostToolMemoryEntry
7666
+ // src/adapters/claude/active-agent.ts
7667
+ var active_agent_exports = {};
7668
+ __export(active_agent_exports, {
7669
+ cleanupSessionMarkers: () => cleanupSessionMarkers,
7670
+ clearActiveAgent: () => clearActiveAgent,
7671
+ getActiveAgent: () => getActiveAgent,
7672
+ getAllActiveAgents: () => getAllActiveAgents,
7673
+ resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
7674
+ writeActiveAgent: () => writeActiveAgent
7684
7675
  });
7685
- function buildPostToolMemoryEntry(data, agent) {
7686
- let rawText = extractSemanticText(data.tool_name, data.tool_input, data.tool_response);
7687
- if (rawText.trim().length < 10) {
7688
- const inputPreview = JSON.stringify(data.tool_input ?? "").slice(0, 500);
7689
- const outputPreview = JSON.stringify(data.tool_response ?? "").slice(0, 500);
7690
- rawText = `Tool call: ${data.tool_name}
7691
- Input: ${inputPreview}
7692
- Output: ${outputPreview}`;
7693
- }
7694
- if (rawText.trim().length < 10) return null;
7695
- const hasError = detectError(data);
7696
- const toolInputStr = JSON.stringify(data.tool_input ?? "").slice(0, 200);
7697
- const toolOutputStr = JSON.stringify(data.tool_response ?? "").slice(0, 200);
7698
- return {
7699
- raw_text: rawText,
7700
- agent_id: agent.agentId,
7701
- agent_role: agent.agentRole,
7702
- tool_name: data.tool_name,
7703
- project_name: getProjectName(data.cwd ?? process.cwd()),
7704
- session_id: data.session_id,
7705
- has_error: hasError,
7706
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
7707
- trajectory: JSON.stringify({
7708
- input: toolInputStr,
7709
- tool: data.tool_name,
7710
- output: toolOutputStr,
7711
- result_type: hasError ? "error" : "success"
7712
- })
7713
- };
7714
- }
7715
- var init_post_tool_memory = __esm({
7716
- "src/lib/post-tool-memory.ts"() {
7676
+ var init_active_agent2 = __esm({
7677
+ "src/adapters/claude/active-agent.ts"() {
7717
7678
  "use strict";
7718
- init_content_extractor();
7719
- init_error_detector();
7720
- init_project_name();
7679
+ init_active_agent();
7721
7680
  }
7722
7681
  });
7723
7682
 
7724
- // src/lib/session-key.ts
7725
- import { execSync as execSync5 } from "child_process";
7726
- function normalizeCommand(command) {
7727
- const trimmed = command.trim().toLowerCase();
7728
- const parts = trimmed.split(/[\\/]/);
7729
- return parts[parts.length - 1] ?? trimmed;
7730
- }
7731
- function detectRuntimeFromCommand(command) {
7732
- const normalized = normalizeCommand(command);
7733
- for (const [runtime, commands] of Object.entries(RUNTIME_COMMANDS)) {
7734
- if (commands.includes(normalized)) {
7735
- return runtime;
7736
- }
7737
- }
7738
- return null;
7739
- }
7740
- function resolveRuntimeProcess() {
7741
- let pid = process.ppid;
7742
- for (let i = 0; i < 10; i++) {
7743
- try {
7744
- const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
7745
- encoding: "utf8",
7746
- timeout: 2e3
7747
- }).trim();
7748
- const match = info.match(/^\s*(\d+)\s+(.+)$/);
7749
- if (!match) break;
7750
- const [, ppid, cmd] = match;
7751
- const runtime = detectRuntimeFromCommand(cmd ?? "");
7752
- if (runtime) {
7753
- return { pid: String(pid), runtime };
7754
- }
7755
- pid = parseInt(ppid, 10);
7756
- if (pid <= 1) break;
7757
- } catch {
7758
- break;
7759
- }
7760
- }
7761
- return null;
7762
- }
7763
- function getSessionKey() {
7764
- if (_cached2) return _cached2;
7765
- if (process.env.EXE_SESSION_KEY) {
7766
- _cached2 = process.env.EXE_SESSION_KEY;
7767
- return _cached2;
7768
- }
7769
- const resolved = resolveRuntimeProcess();
7770
- if (resolved) {
7771
- _cachedRuntime = resolved.runtime;
7772
- _cached2 = resolved.pid;
7773
- return _cached2;
7774
- }
7775
- _cached2 = process.env.CLAUDE_CODE_SSE_PORT ?? String(process.ppid);
7776
- return _cached2;
7777
- }
7778
- var _cached2, _cachedRuntime, RUNTIME_COMMANDS;
7779
- var init_session_key = __esm({
7780
- "src/lib/session-key.ts"() {
7781
- "use strict";
7782
- _cached2 = null;
7783
- _cachedRuntime = null;
7784
- RUNTIME_COMMANDS = {
7785
- claude: ["claude", "claude.exe", "claude-native"],
7786
- codex: ["codex"],
7787
- opencode: ["opencode"]
7788
- };
7789
- }
7790
- });
7791
-
7792
- // src/mcp/agent-context.ts
7793
- import { AsyncLocalStorage } from "async_hooks";
7794
- function getAgentContext() {
7795
- return agentStore.getStore();
7796
- }
7797
- var agentStore;
7798
- var init_agent_context = __esm({
7799
- "src/mcp/agent-context.ts"() {
7800
- "use strict";
7801
- agentStore = new AsyncLocalStorage();
7802
- }
7803
- });
7804
-
7805
- // src/lib/active-agent.ts
7806
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, unlinkSync as unlinkSync4, readdirSync as readdirSync3 } from "fs";
7807
- import { execSync as execSync6 } from "child_process";
7808
- import path12 from "path";
7809
- function isNameWithOptionalInstance(candidate, baseName) {
7810
- if (candidate === baseName) return true;
7811
- if (!candidate.startsWith(baseName)) return false;
7812
- return /^\d+$/.test(candidate.slice(baseName.length));
7813
- }
7814
- function resolveEmployeeFromSessionPrefix(prefix, employees) {
7815
- const sorted = [...employees].sort((a, b) => b.name.length - a.name.length);
7816
- for (const employee of sorted) {
7817
- if (isNameWithOptionalInstance(prefix, employee.name)) {
7818
- return { agentId: employee.name, agentRole: employee.role };
7819
- }
7820
- }
7821
- return null;
7822
- }
7823
- function resolveActiveAgentFromTmuxSession(sessionName) {
7824
- const employees = loadEmployeesSync();
7825
- const coordinator = getCoordinatorEmployee(employees);
7826
- const coordinatorName = coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
7827
- if (isNameWithOptionalInstance(sessionName, coordinatorName)) {
7828
- return {
7829
- agentId: coordinatorName,
7830
- agentRole: coordinator?.role ?? "COO"
7831
- };
7832
- }
7833
- if (isNameWithOptionalInstance(sessionName, DEFAULT_COORDINATOR_TEMPLATE_NAME)) {
7834
- return {
7835
- agentId: coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME,
7836
- agentRole: coordinator?.role ?? "COO"
7837
- };
7838
- }
7839
- if (sessionName.includes("-")) {
7840
- const prefix = sessionName.split("-")[0] ?? "";
7841
- const employee = resolveEmployeeFromSessionPrefix(prefix, employees);
7842
- if (employee) return employee;
7843
- const legacy = prefix.match(/^([a-zA-Z]+)\d*$/);
7844
- if (legacy?.[1] && legacy[1] !== DEFAULT_COORDINATOR_TEMPLATE_NAME) {
7845
- const emp = getEmployee(employees, legacy[1]);
7846
- return { agentId: emp?.name ?? legacy[1], agentRole: emp?.role ?? "employee" };
7847
- }
7848
- }
7849
- return null;
7850
- }
7851
- function getMarkerPath() {
7852
- return path12.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
7853
- }
7854
- function writeActiveAgent(agentId, agentRole) {
7855
- try {
7856
- mkdirSync3(CACHE_DIR, { recursive: true });
7857
- writeFileSync3(
7858
- getMarkerPath(),
7859
- JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
7860
- );
7861
- } catch {
7862
- }
7863
- }
7864
- function clearActiveAgent() {
7865
- try {
7866
- unlinkSync4(getMarkerPath());
7867
- } catch {
7868
- }
7869
- }
7870
- function getActiveAgent() {
7871
- const httpCtx = getAgentContext();
7872
- if (httpCtx) return httpCtx;
7873
- try {
7874
- const markerPath = getMarkerPath();
7875
- const raw = readFileSync7(markerPath, "utf8");
7876
- const data = JSON.parse(raw);
7877
- if (data.agentId) {
7878
- if (data.startedAt) {
7879
- const age = Date.now() - new Date(data.startedAt).getTime();
7880
- if (age > STALE_MS) {
7881
- try {
7882
- unlinkSync4(markerPath);
7883
- } catch {
7884
- }
7885
- } else {
7886
- return {
7887
- agentId: data.agentId,
7888
- agentRole: data.agentRole || "employee"
7889
- };
7890
- }
7891
- } else {
7892
- return {
7893
- agentId: data.agentId,
7894
- agentRole: data.agentRole || "employee"
7895
- };
7896
- }
7897
- }
7898
- } catch {
7899
- }
7900
- try {
7901
- const sessionName = execSync6(
7902
- "tmux display-message -p '#{session_name}' 2>/dev/null",
7903
- { encoding: "utf8", timeout: 2e3 }
7904
- ).trim();
7905
- const resolved = resolveActiveAgentFromTmuxSession(sessionName);
7906
- if (resolved) return resolved;
7907
- } catch {
7908
- }
7909
- return {
7910
- agentId: process.env.AGENT_ID || "default",
7911
- agentRole: process.env.AGENT_ROLE || "employee"
7912
- };
7913
- }
7914
- function getAllActiveAgents() {
7915
- try {
7916
- const files = readdirSync3(CACHE_DIR);
7917
- const sessions = [];
7918
- for (const file of files) {
7919
- if (!file.startsWith("active-agent-") || !file.endsWith(".json")) continue;
7920
- const key = file.slice("active-agent-".length, -".json".length);
7921
- if (key === "undefined") continue;
7922
- try {
7923
- const raw = readFileSync7(path12.join(CACHE_DIR, file), "utf8");
7924
- const data = JSON.parse(raw);
7925
- if (!data.agentId) continue;
7926
- if (data.startedAt) {
7927
- const age = Date.now() - new Date(data.startedAt).getTime();
7928
- if (age > STALE_MS) {
7929
- try {
7930
- unlinkSync4(path12.join(CACHE_DIR, file));
7931
- } catch {
7932
- }
7933
- continue;
7934
- }
7935
- }
7936
- sessions.push({
7937
- agentId: data.agentId,
7938
- agentRole: data.agentRole || "employee",
7939
- startedAt: data.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
7940
- sessionKey: key
7941
- });
7942
- } catch {
7943
- }
7944
- }
7945
- return sessions;
7946
- } catch {
7947
- return [];
7948
- }
7949
- }
7950
- function cleanupSessionMarkers() {
7951
- const key = getSessionKey();
7952
- try {
7953
- unlinkSync4(path12.join(CACHE_DIR, `active-agent-${key}.json`));
7954
- } catch {
7955
- }
7956
- try {
7957
- unlinkSync4(path12.join(CACHE_DIR, "active-agent-undefined.json"));
7958
- } catch {
7959
- }
7960
- }
7961
- var CACHE_DIR, STALE_MS;
7962
- var init_active_agent = __esm({
7963
- "src/lib/active-agent.ts"() {
7964
- "use strict";
7965
- init_config();
7966
- init_session_key();
7967
- init_agent_context();
7968
- init_employees();
7969
- CACHE_DIR = path12.join(EXE_AI_DIR, "session-cache");
7970
- STALE_MS = 24 * 60 * 60 * 1e3;
7971
- }
7972
- });
7973
-
7974
- // src/adapters/claude/active-agent.ts
7975
- var active_agent_exports = {};
7976
- __export(active_agent_exports, {
7977
- cleanupSessionMarkers: () => cleanupSessionMarkers,
7978
- clearActiveAgent: () => clearActiveAgent,
7979
- getActiveAgent: () => getActiveAgent,
7980
- getAllActiveAgents: () => getAllActiveAgents,
7981
- resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
7982
- writeActiveAgent: () => writeActiveAgent
7983
- });
7984
- var init_active_agent2 = __esm({
7985
- "src/adapters/claude/active-agent.ts"() {
7986
- "use strict";
7987
- init_active_agent();
7988
- }
7989
- });
7990
-
7991
- // src/bin/fast-db-init.ts
7992
- var fast_db_init_exports = {};
7993
- __export(fast_db_init_exports, {
7994
- fastDbInit: () => fastDbInit
7995
- });
7996
- async function fastDbInit() {
7997
- const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
7998
- if (isInitialized2()) {
7999
- return getClient2();
7683
+ // src/bin/fast-db-init.ts
7684
+ var fast_db_init_exports = {};
7685
+ __export(fast_db_init_exports, {
7686
+ fastDbInit: () => fastDbInit
7687
+ });
7688
+ async function fastDbInit() {
7689
+ const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
7690
+ if (isInitialized2()) {
7691
+ return getClient2();
8000
7692
  }
8001
7693
  try {
8002
7694
  const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
@@ -8061,13 +7753,13 @@ var init_fast_db_init = __esm({
8061
7753
  });
8062
7754
 
8063
7755
  // src/lib/session-registry.ts
8064
- import path13 from "path";
7756
+ import path12 from "path";
8065
7757
  import os6 from "os";
8066
7758
  var REGISTRY_PATH;
8067
7759
  var init_session_registry = __esm({
8068
7760
  "src/lib/session-registry.ts"() {
8069
7761
  "use strict";
8070
- REGISTRY_PATH = path13.join(os6.homedir(), ".exe-os", "session-registry.json");
7762
+ REGISTRY_PATH = path12.join(os6.homedir(), ".exe-os", "session-registry.json");
8071
7763
  }
8072
7764
  });
8073
7765
 
@@ -8230,8 +7922,8 @@ var init_runtime_table = __esm({
8230
7922
  });
8231
7923
 
8232
7924
  // src/lib/agent-config.ts
8233
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync11 } from "fs";
8234
- import path14 from "path";
7925
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync10 } from "fs";
7926
+ import path13 from "path";
8235
7927
  var AGENT_CONFIG_PATH, DEFAULT_MODELS;
8236
7928
  var init_agent_config = __esm({
8237
7929
  "src/lib/agent-config.ts"() {
@@ -8239,7 +7931,7 @@ var init_agent_config = __esm({
8239
7931
  init_config();
8240
7932
  init_runtime_table();
8241
7933
  init_secure_files();
8242
- AGENT_CONFIG_PATH = path14.join(EXE_AI_DIR, "agent-config.json");
7934
+ AGENT_CONFIG_PATH = path13.join(EXE_AI_DIR, "agent-config.json");
8243
7935
  DEFAULT_MODELS = {
8244
7936
  claude: "claude-opus-4.6",
8245
7937
  codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
@@ -8249,41 +7941,41 @@ var init_agent_config = __esm({
8249
7941
  });
8250
7942
 
8251
7943
  // src/lib/intercom-queue.ts
8252
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, renameSync as renameSync5, existsSync as existsSync12, mkdirSync as mkdirSync4 } from "fs";
8253
- import path15 from "path";
7944
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync as renameSync4, existsSync as existsSync11, mkdirSync as mkdirSync4 } from "fs";
7945
+ import path14 from "path";
8254
7946
  import os7 from "os";
8255
- var QUEUE_PATH2, TTL_MS2, INTERCOM_LOG;
7947
+ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
8256
7948
  var init_intercom_queue = __esm({
8257
7949
  "src/lib/intercom-queue.ts"() {
8258
7950
  "use strict";
8259
- QUEUE_PATH2 = path15.join(os7.homedir(), ".exe-os", "intercom-queue.json");
8260
- TTL_MS2 = 60 * 60 * 1e3;
8261
- INTERCOM_LOG = path15.join(os7.homedir(), ".exe-os", "intercom.log");
7951
+ QUEUE_PATH = path14.join(os7.homedir(), ".exe-os", "intercom-queue.json");
7952
+ TTL_MS = 60 * 60 * 1e3;
7953
+ INTERCOM_LOG = path14.join(os7.homedir(), ".exe-os", "intercom.log");
8262
7954
  }
8263
7955
  });
8264
7956
 
8265
7957
  // src/lib/license.ts
8266
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync13, mkdirSync as mkdirSync5 } from "fs";
7958
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync12, mkdirSync as mkdirSync5 } from "fs";
8267
7959
  import { randomUUID as randomUUID3 } from "crypto";
8268
7960
  import { createRequire as createRequire2 } from "module";
8269
7961
  import { pathToFileURL as pathToFileURL2 } from "url";
8270
7962
  import os8 from "os";
8271
- import path16 from "path";
7963
+ import path15 from "path";
8272
7964
  import { jwtVerify, importSPKI } from "jose";
8273
7965
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
8274
7966
  var init_license = __esm({
8275
7967
  "src/lib/license.ts"() {
8276
7968
  "use strict";
8277
7969
  init_config();
8278
- LICENSE_PATH = path16.join(EXE_AI_DIR, "license.key");
8279
- CACHE_PATH = path16.join(EXE_AI_DIR, "license-cache.json");
8280
- DEVICE_ID_PATH = path16.join(EXE_AI_DIR, "device-id");
7970
+ LICENSE_PATH = path15.join(EXE_AI_DIR, "license.key");
7971
+ CACHE_PATH = path15.join(EXE_AI_DIR, "license-cache.json");
7972
+ DEVICE_ID_PATH = path15.join(EXE_AI_DIR, "device-id");
8281
7973
  }
8282
7974
  });
8283
7975
 
8284
7976
  // src/lib/plan-limits.ts
8285
- import { readFileSync as readFileSync11, existsSync as existsSync14 } from "fs";
8286
- import path17 from "path";
7977
+ import { readFileSync as readFileSync10, existsSync as existsSync13 } from "fs";
7978
+ import path16 from "path";
8287
7979
  var CACHE_PATH2;
8288
7980
  var init_plan_limits = __esm({
8289
7981
  "src/lib/plan-limits.ts"() {
@@ -8292,15 +7984,15 @@ var init_plan_limits = __esm({
8292
7984
  init_employees();
8293
7985
  init_license();
8294
7986
  init_config();
8295
- CACHE_PATH2 = path17.join(EXE_AI_DIR, "license-cache.json");
7987
+ CACHE_PATH2 = path16.join(EXE_AI_DIR, "license-cache.json");
8296
7988
  }
8297
7989
  });
8298
7990
 
8299
7991
  // src/lib/agent-symlinks.ts
8300
7992
  import os9 from "os";
8301
- import path18 from "path";
7993
+ import path17 from "path";
8302
7994
  import {
8303
- existsSync as existsSync15,
7995
+ existsSync as existsSync14,
8304
7996
  lstatSync,
8305
7997
  mkdirSync as mkdirSync6,
8306
7998
  readlinkSync as readlinkSync2,
@@ -8314,221 +8006,529 @@ var init_agent_symlinks = __esm({
8314
8006
  });
8315
8007
 
8316
8008
  // src/lib/tmux-routing.ts
8317
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync16, appendFileSync as appendFileSync2, readdirSync as readdirSync4 } from "fs";
8318
- import path19 from "path";
8009
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync15, appendFileSync, readdirSync as readdirSync4 } from "fs";
8010
+ import path18 from "path";
8319
8011
  import os10 from "os";
8320
8012
  import { fileURLToPath as fileURLToPath2 } from "url";
8321
8013
  function getMySession() {
8322
8014
  return getTransport().getMySession();
8323
8015
  }
8324
- function extractRootExe(name) {
8325
- if (!name) return null;
8326
- if (!name.includes("-")) return name;
8327
- const parts = name.split("-").filter(Boolean);
8328
- return parts.length > 0 ? parts[parts.length - 1] : null;
8016
+ function extractRootExe(name) {
8017
+ if (!name) return null;
8018
+ if (!name.includes("-")) return name;
8019
+ const parts = name.split("-").filter(Boolean);
8020
+ return parts.length > 0 ? parts[parts.length - 1] : null;
8021
+ }
8022
+ function getParentExe(sessionKey) {
8023
+ try {
8024
+ const data = JSON.parse(readFileSync11(path18.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
8025
+ return data.parentExe || null;
8026
+ } catch {
8027
+ return null;
8028
+ }
8029
+ }
8030
+ function resolveExeSession() {
8031
+ const mySession = getMySession();
8032
+ if (!mySession) return null;
8033
+ const fromSessionName = extractRootExe(mySession);
8034
+ try {
8035
+ const key = getSessionKey();
8036
+ const parentExe = getParentExe(key);
8037
+ if (parentExe) {
8038
+ const fromCache = extractRootExe(parentExe) ?? parentExe;
8039
+ if (fromSessionName && fromCache !== fromSessionName) {
8040
+ process.stderr.write(
8041
+ `[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
8042
+ `
8043
+ );
8044
+ return fromSessionName;
8045
+ }
8046
+ return fromCache;
8047
+ }
8048
+ } catch {
8049
+ }
8050
+ return fromSessionName ?? mySession;
8051
+ }
8052
+ var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
8053
+ var init_tmux_routing = __esm({
8054
+ "src/lib/tmux-routing.ts"() {
8055
+ "use strict";
8056
+ init_session_registry();
8057
+ init_session_key();
8058
+ init_transport();
8059
+ init_cc_agent_support();
8060
+ init_mcp_prefix();
8061
+ init_provider_table();
8062
+ init_agent_config();
8063
+ init_runtime_table();
8064
+ init_intercom_queue();
8065
+ init_plan_limits();
8066
+ init_employees();
8067
+ init_agent_symlinks();
8068
+ SPAWN_LOCK_DIR = path18.join(os10.homedir(), ".exe-os", "spawn-locks");
8069
+ SESSION_CACHE = path18.join(os10.homedir(), ".exe-os", "session-cache");
8070
+ INTERCOM_LOG2 = path18.join(os10.homedir(), ".exe-os", "intercom.log");
8071
+ DEBOUNCE_FILE = path18.join(SESSION_CACHE, "intercom-debounce.json");
8072
+ DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
8073
+ }
8074
+ });
8075
+
8076
+ // src/lib/task-scope.ts
8077
+ function getCurrentSessionScope() {
8078
+ try {
8079
+ return resolveExeSession();
8080
+ } catch {
8081
+ return null;
8082
+ }
8083
+ }
8084
+ function strictSessionScopeFilter(sessionScope, tableAlias) {
8085
+ const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
8086
+ if (!scope) return { sql: "", args: [] };
8087
+ const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
8088
+ return {
8089
+ sql: ` AND ${col} = ?`,
8090
+ args: [scope]
8091
+ };
8092
+ }
8093
+ var init_task_scope = __esm({
8094
+ "src/lib/task-scope.ts"() {
8095
+ "use strict";
8096
+ init_tmux_routing();
8097
+ }
8098
+ });
8099
+
8100
+ // src/lib/session-events.ts
8101
+ var session_events_exports = {};
8102
+ __export(session_events_exports, {
8103
+ ensureSessionEventsTable: () => ensureSessionEventsTable,
8104
+ listRecentSessionEvents: () => listRecentSessionEvents,
8105
+ recordSessionEvent: () => recordSessionEvent
8106
+ });
8107
+ import { randomUUID as randomUUID4 } from "crypto";
8108
+ async function ensureSessionEventsTable(client) {
8109
+ await client.execute(`
8110
+ CREATE TABLE IF NOT EXISTS session_events (
8111
+ id TEXT PRIMARY KEY,
8112
+ agent_id TEXT NOT NULL,
8113
+ agent_role TEXT NOT NULL,
8114
+ session_id TEXT NOT NULL,
8115
+ session_scope TEXT,
8116
+ project_name TEXT NOT NULL,
8117
+ event_index INTEGER NOT NULL,
8118
+ event_type TEXT NOT NULL,
8119
+ tool_name TEXT,
8120
+ tool_use_id TEXT,
8121
+ content TEXT NOT NULL,
8122
+ payload_json TEXT,
8123
+ has_error INTEGER NOT NULL DEFAULT 0,
8124
+ created_at TEXT NOT NULL
8125
+ )
8126
+ `);
8127
+ await client.execute(`
8128
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
8129
+ ON session_events(agent_id, created_at DESC)
8130
+ `);
8131
+ await client.execute(`
8132
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
8133
+ ON session_events(session_id, event_index)
8134
+ `);
8135
+ await client.execute(`
8136
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
8137
+ ON session_events(session_scope, agent_id, created_at DESC)
8138
+ `);
8139
+ }
8140
+ async function recordSessionEvent(client, input2) {
8141
+ if (!input2.content || input2.content.trim().length === 0) return;
8142
+ await ensureSessionEventsTable(client);
8143
+ const maxResult = await client.execute({
8144
+ sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
8145
+ args: [input2.sessionId]
8146
+ });
8147
+ const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
8148
+ const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
8149
+ await client.execute({
8150
+ sql: `INSERT INTO session_events (
8151
+ id, agent_id, agent_role, session_id, session_scope, project_name,
8152
+ event_index, event_type, tool_name, tool_use_id, content,
8153
+ payload_json, has_error, created_at
8154
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8155
+ args: [
8156
+ randomUUID4(),
8157
+ input2.agentId,
8158
+ input2.agentRole,
8159
+ input2.sessionId,
8160
+ input2.sessionScope ?? getCurrentSessionScope(),
8161
+ input2.projectName ?? getProjectName(input2.cwd),
8162
+ eventIndex,
8163
+ input2.eventType,
8164
+ input2.toolName ?? null,
8165
+ input2.toolUseId ?? null,
8166
+ input2.content,
8167
+ input2.payloadJson ?? null,
8168
+ input2.hasError ? 1 : 0,
8169
+ input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
8170
+ ]
8171
+ });
8172
+ }
8173
+ async function listRecentSessionEvents(client, options) {
8174
+ await ensureSessionEventsTable(client);
8175
+ const conditions = ["agent_id = ?"];
8176
+ const args = [options.agentId];
8177
+ if (options.sessionId) {
8178
+ conditions.push("session_id = ?");
8179
+ args.push(options.sessionId);
8180
+ }
8181
+ if (options.eventType) {
8182
+ conditions.push("event_type = ?");
8183
+ args.push(options.eventType);
8184
+ }
8185
+ if (options.projectName && options.projectName !== "all") {
8186
+ conditions.push("project_name = ?");
8187
+ args.push(options.projectName);
8188
+ }
8189
+ const scope = strictSessionScopeFilter(options.sessionScope);
8190
+ const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
8191
+ args.push(...scope.args);
8192
+ args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
8193
+ const result = await client.execute({
8194
+ sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
8195
+ project_name, event_index, event_type, tool_name, tool_use_id,
8196
+ content, payload_json, has_error, created_at
8197
+ FROM session_events
8198
+ ${where}
8199
+ ORDER BY created_at DESC, event_index DESC
8200
+ LIMIT ?`,
8201
+ args
8202
+ });
8203
+ return result.rows.map((row) => ({
8204
+ id: String(row.id),
8205
+ agentId: String(row.agent_id),
8206
+ agentRole: String(row.agent_role),
8207
+ sessionId: String(row.session_id),
8208
+ sessionScope: row.session_scope == null ? null : String(row.session_scope),
8209
+ projectName: String(row.project_name),
8210
+ eventIndex: Number(row.event_index),
8211
+ eventType: String(row.event_type),
8212
+ toolName: row.tool_name == null ? null : String(row.tool_name),
8213
+ toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
8214
+ content: String(row.content),
8215
+ payloadJson: row.payload_json == null ? null : String(row.payload_json),
8216
+ hasError: Number(row.has_error) === 1,
8217
+ createdAt: String(row.created_at)
8218
+ }));
8219
+ }
8220
+ var init_session_events = __esm({
8221
+ "src/lib/session-events.ts"() {
8222
+ "use strict";
8223
+ init_task_scope();
8224
+ init_project_name();
8225
+ }
8226
+ });
8227
+
8228
+ // src/lib/memory-queue.ts
8229
+ import { appendFileSync as appendFileSync2, readFileSync as readFileSync12, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync16, statSync as statSync5 } from "fs";
8230
+ import path19 from "path";
8231
+ function enqueueMemory(entry) {
8232
+ appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
8233
+ }
8234
+ var QUEUE_PATH2, PROCESSING_PATH, TTL_MS2;
8235
+ var init_memory_queue = __esm({
8236
+ "src/lib/memory-queue.ts"() {
8237
+ "use strict";
8238
+ init_config();
8239
+ QUEUE_PATH2 = path19.join(EXE_AI_DIR, "memory-queue.jsonl");
8240
+ PROCESSING_PATH = QUEUE_PATH2 + ".processing";
8241
+ TTL_MS2 = 24 * 60 * 60 * 1e3;
8242
+ }
8243
+ });
8244
+
8245
+ // src/lib/memory-queue-client.ts
8246
+ var memory_queue_client_exports = {};
8247
+ __export(memory_queue_client_exports, {
8248
+ batchWriteMemoryViaDaemon: () => batchWriteMemoryViaDaemon,
8249
+ writeMemoryViaDaemon: () => writeMemoryViaDaemon
8250
+ });
8251
+ async function writeMemoryViaDaemon(entry) {
8252
+ if (process.env.EXE_IS_DAEMON === "1") {
8253
+ enqueueMemory(entry);
8254
+ return false;
8255
+ }
8256
+ if (!isClientConnected()) {
8257
+ enqueueMemory(entry);
8258
+ return false;
8259
+ }
8260
+ try {
8261
+ const response = await sendDaemonRequest({
8262
+ type: "write-memory",
8263
+ entry
8264
+ });
8265
+ if (response.ok) return true;
8266
+ enqueueMemory(entry);
8267
+ return false;
8268
+ } catch {
8269
+ enqueueMemory(entry);
8270
+ return false;
8271
+ }
8272
+ }
8273
+ async function batchWriteMemoryViaDaemon(entries) {
8274
+ if (entries.length === 0) return 0;
8275
+ if (process.env.EXE_IS_DAEMON === "1" || !isClientConnected()) {
8276
+ for (const entry of entries) enqueueMemory(entry);
8277
+ return 0;
8278
+ }
8279
+ try {
8280
+ const response = await sendDaemonRequest({
8281
+ type: "batch-write-memory",
8282
+ entries
8283
+ });
8284
+ if (response.ok) return response.count ?? entries.length;
8285
+ for (const entry of entries) enqueueMemory(entry);
8286
+ return 0;
8287
+ } catch {
8288
+ for (const entry of entries) enqueueMemory(entry);
8289
+ return 0;
8290
+ }
8291
+ }
8292
+ var init_memory_queue_client = __esm({
8293
+ "src/lib/memory-queue-client.ts"() {
8294
+ "use strict";
8295
+ init_exe_daemon_client();
8296
+ init_memory_queue();
8297
+ }
8298
+ });
8299
+
8300
+ // src/lib/content-extractor.ts
8301
+ function extractSemanticText(toolName, toolInput, toolResponse) {
8302
+ switch (toolName) {
8303
+ case "Write":
8304
+ return extractWrite(toolInput);
8305
+ case "Edit":
8306
+ return extractEdit(toolInput);
8307
+ case "Read":
8308
+ return extractRead(toolInput, toolResponse);
8309
+ case "Bash":
8310
+ return extractBash(toolInput, toolResponse);
8311
+ case "Grep":
8312
+ return extractGrep(toolInput, toolResponse);
8313
+ case "Glob":
8314
+ return extractGlob(toolInput, toolResponse);
8315
+ default:
8316
+ if (isExeMcpTool(toolName)) {
8317
+ return extractExeMemMcp(toolName, toolInput, toolResponse);
8318
+ }
8319
+ if (toolName.startsWith("mcp__")) {
8320
+ return extractGenericMcp(toolName, toolInput, toolResponse);
8321
+ }
8322
+ return extractDefault(toolName, toolInput, toolResponse);
8323
+ }
8324
+ }
8325
+ function findContainingChunk(filePath, snippet) {
8326
+ try {
8327
+ const ext = filePath.split(".").pop()?.toLowerCase();
8328
+ if (ext !== "ts" && ext !== "tsx" && ext !== "js" && ext !== "jsx") return "";
8329
+ const { readFileSync: readFileSync13 } = __require("fs");
8330
+ const source = readFileSync13(filePath, "utf8");
8331
+ const lines = source.split("\n");
8332
+ const lowerSnippet = snippet.toLowerCase().slice(0, 80);
8333
+ let matchLine = -1;
8334
+ for (let i = 0; i < lines.length; i++) {
8335
+ if (lines[i].toLowerCase().includes(lowerSnippet)) {
8336
+ matchLine = i;
8337
+ break;
8338
+ }
8339
+ }
8340
+ if (matchLine === -1) return "";
8341
+ for (let i = matchLine; i >= 0; i--) {
8342
+ const line = lines[i];
8343
+ const fnMatch = line.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)/);
8344
+ if (fnMatch) return `Function ${fnMatch[1]} in ${filePath}:${i + 1}`;
8345
+ const classMatch = line.match(/(?:export\s+)?class\s+(\w+)/);
8346
+ if (classMatch) return `Class ${classMatch[1]} in ${filePath}:${i + 1}`;
8347
+ const arrowMatch = line.match(/(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s+)?\(/);
8348
+ if (arrowMatch) return `Function ${arrowMatch[1]} in ${filePath}:${i + 1}`;
8349
+ }
8350
+ } catch {
8351
+ }
8352
+ return "";
8353
+ }
8354
+ function extractWrite(input2) {
8355
+ const filePath = String(input2.file_path ?? "");
8356
+ const content = String(input2.content ?? "");
8357
+ const chunkContext = findContainingChunk(filePath, content.slice(0, 200));
8358
+ const prefix = chunkContext ? `Wrote ${filePath} (${chunkContext})` : `Wrote ${filePath}`;
8359
+ return `${prefix}
8360
+ ${content.slice(0, MAX_CONTENT)}`;
8361
+ }
8362
+ function extractEdit(input2) {
8363
+ const filePath = String(input2.file_path ?? "");
8364
+ const oldStr = String(input2.old_string ?? "");
8365
+ const newStr = String(input2.new_string ?? "");
8366
+ const chunkContext = findContainingChunk(filePath, oldStr.slice(0, 200));
8367
+ const prefix = chunkContext ? `Edited ${filePath} (${chunkContext})` : `Edited ${filePath}`;
8368
+ return `${prefix}
8369
+ Removed: ${oldStr.slice(0, MAX_CONTENT / 2)}
8370
+ Added: ${newStr.slice(0, MAX_CONTENT / 2)}`;
8371
+ }
8372
+ function extractRead(input2, response) {
8373
+ const filePath = String(input2.file_path ?? "");
8374
+ const file = response.file;
8375
+ const content = file ? String(file.content ?? "") : "";
8376
+ if (!content) {
8377
+ const text = String(response.text ?? response.content ?? "");
8378
+ return `Read ${filePath}
8379
+ ${text.slice(0, MAX_CONTENT)}`;
8380
+ }
8381
+ return `Read ${filePath}
8382
+ ${content.slice(0, MAX_CONTENT)}`;
8383
+ }
8384
+ function extractBash(input2, response) {
8385
+ const command = String(input2.command ?? "");
8386
+ const description = input2.description ? String(input2.description) : "";
8387
+ const stdout = String(response.stdout ?? response.text ?? "");
8388
+ const stderr = String(response.stderr ?? "");
8389
+ const parts = [description ? `${description}: ${command}` : `Ran: ${command}`];
8390
+ if (stdout) parts.push(`Output: ${stdout.slice(0, MAX_OUTPUT)}`);
8391
+ if (stderr && !stdout) parts.push(`Error: ${stderr.slice(0, MAX_OUTPUT)}`);
8392
+ return parts.join("\n");
8393
+ }
8394
+ function extractGrep(input2, response) {
8395
+ const pattern = String(input2.pattern ?? "");
8396
+ const path20 = input2.path ? String(input2.path) : "";
8397
+ const output = String(response.text ?? response.content ?? JSON.stringify(response).slice(0, MAX_OUTPUT));
8398
+ return `Searched for "${pattern}"${path20 ? ` in ${path20}` : ""}
8399
+ ${output.slice(0, MAX_OUTPUT)}`;
8400
+ }
8401
+ function extractGlob(input2, response) {
8402
+ const pattern = String(input2.pattern ?? "");
8403
+ const output = String(response.text ?? response.content ?? JSON.stringify(response).slice(0, MAX_OUTPUT));
8404
+ return `Found files matching "${pattern}"
8405
+ ${output.slice(0, MAX_OUTPUT)}`;
8406
+ }
8407
+ function extractExeMemMcp(toolName, input2, response) {
8408
+ const shortName = stripExeMcpPrefix(toolName);
8409
+ switch (shortName) {
8410
+ case "store_memory": {
8411
+ const text = String(input2.text ?? input2.query ?? "");
8412
+ return `Stored memory: ${text.slice(0, MAX_CONTENT)}`;
8413
+ }
8414
+ case "recall_my_memory":
8415
+ case "ask_team_memory": {
8416
+ const query = String(input2.query ?? "");
8417
+ const member = input2.team_member ? ` (from ${input2.team_member})` : "";
8418
+ const resultText = extractResponseText(response);
8419
+ return `Memory search${member}: "${query}"
8420
+ ${resultText.slice(0, MAX_OUTPUT)}`;
8421
+ }
8422
+ case "create_task": {
8423
+ const title = String(input2.title ?? "");
8424
+ const assignedTo = String(input2.assigned_to ?? "");
8425
+ const priority = String(input2.priority ?? "p1");
8426
+ const context = String(input2.context ?? "");
8427
+ return `Task created: "${title}" assigned to ${assignedTo} [${priority}]
8428
+ ${context.slice(0, MAX_CONTENT)}`;
8429
+ }
8430
+ case "update_task": {
8431
+ const taskId = String(input2.task_id ?? "");
8432
+ const status = String(input2.status ?? "");
8433
+ const result = input2.result ? String(input2.result) : "";
8434
+ return `Task updated: ${taskId} \u2192 ${status}${result ? `
8435
+ Result: ${result.slice(0, MAX_CONTENT)}` : ""}`;
8436
+ }
8437
+ case "list_tasks": {
8438
+ const resultText = extractResponseText(response);
8439
+ return `Listed tasks
8440
+ ${resultText.slice(0, MAX_OUTPUT)}`;
8441
+ }
8442
+ default: {
8443
+ return extractGenericMcp(toolName, input2, response);
8444
+ }
8445
+ }
8446
+ }
8447
+ function extractGenericMcp(toolName, input2, response) {
8448
+ const shortName = toolName.replace(/^mcp__[^_]+__/, "");
8449
+ const inputParts = Object.entries(input2).filter(([, v]) => v != null && String(v).length > 0).map(([k, v]) => `${k}: ${String(v).slice(0, 200)}`).join(", ");
8450
+ const resultText = extractResponseText(response);
8451
+ return `${shortName}(${inputParts})
8452
+ ${resultText.slice(0, MAX_OUTPUT)}`;
8453
+ }
8454
+ function extractDefault(toolName, input2, response) {
8455
+ const inputStr = JSON.stringify(input2);
8456
+ const resultText = extractResponseText(response);
8457
+ return `Tool: ${toolName}
8458
+ ${inputStr.slice(0, MAX_CONTENT / 2)}
8459
+ ${resultText.slice(0, MAX_OUTPUT)}`;
8329
8460
  }
8330
- function getParentExe(sessionKey) {
8331
- try {
8332
- const data = JSON.parse(readFileSync12(path19.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
8333
- return data.parentExe || null;
8334
- } catch {
8335
- return null;
8461
+ function extractResponseText(response) {
8462
+ if (typeof response.text === "string") return response.text;
8463
+ if (typeof response.content === "string") return response.content;
8464
+ if (Array.isArray(response.content)) {
8465
+ return response.content.map((block) => {
8466
+ if (typeof block === "object" && block !== null && "text" in block) {
8467
+ return String(block.text);
8468
+ }
8469
+ return "";
8470
+ }).filter(Boolean).join("\n");
8336
8471
  }
8337
- }
8338
- function resolveExeSession() {
8339
- const mySession = getMySession();
8340
- if (!mySession) return null;
8341
- const fromSessionName = extractRootExe(mySession);
8342
- try {
8343
- const key = getSessionKey();
8344
- const parentExe = getParentExe(key);
8345
- if (parentExe) {
8346
- const fromCache = extractRootExe(parentExe) ?? parentExe;
8347
- if (fromSessionName && fromCache !== fromSessionName) {
8348
- process.stderr.write(
8349
- `[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
8350
- `
8351
- );
8352
- return fromSessionName;
8472
+ if (Array.isArray(response)) {
8473
+ return response.map((item) => {
8474
+ if (typeof item === "object" && item !== null && "text" in item) {
8475
+ return String(item.text);
8353
8476
  }
8354
- return fromCache;
8355
- }
8356
- } catch {
8477
+ return "";
8478
+ }).filter(Boolean).join("\n");
8357
8479
  }
8358
- return fromSessionName ?? mySession;
8480
+ return JSON.stringify(response).slice(0, MAX_OUTPUT);
8359
8481
  }
8360
- var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
8361
- var init_tmux_routing = __esm({
8362
- "src/lib/tmux-routing.ts"() {
8482
+ var MAX_CONTENT, MAX_OUTPUT;
8483
+ var init_content_extractor = __esm({
8484
+ "src/lib/content-extractor.ts"() {
8363
8485
  "use strict";
8364
- init_session_registry();
8365
- init_session_key();
8366
- init_transport();
8367
- init_cc_agent_support();
8368
8486
  init_mcp_prefix();
8369
- init_provider_table();
8370
- init_agent_config();
8371
- init_runtime_table();
8372
- init_intercom_queue();
8373
- init_plan_limits();
8374
- init_employees();
8375
- init_agent_symlinks();
8376
- SPAWN_LOCK_DIR = path19.join(os10.homedir(), ".exe-os", "spawn-locks");
8377
- SESSION_CACHE = path19.join(os10.homedir(), ".exe-os", "session-cache");
8378
- INTERCOM_LOG2 = path19.join(os10.homedir(), ".exe-os", "intercom.log");
8379
- DEBOUNCE_FILE = path19.join(SESSION_CACHE, "intercom-debounce.json");
8380
- DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
8487
+ MAX_CONTENT = 2e3;
8488
+ MAX_OUTPUT = 1e3;
8381
8489
  }
8382
8490
  });
8383
8491
 
8384
- // src/lib/task-scope.ts
8385
- function getCurrentSessionScope() {
8386
- try {
8387
- return resolveExeSession();
8388
- } catch {
8389
- return null;
8492
+ // src/lib/post-tool-memory.ts
8493
+ var post_tool_memory_exports = {};
8494
+ __export(post_tool_memory_exports, {
8495
+ buildPostToolMemoryEntry: () => buildPostToolMemoryEntry
8496
+ });
8497
+ function buildPostToolMemoryEntry(data, agent) {
8498
+ let rawText = extractSemanticText(data.tool_name, data.tool_input, data.tool_response);
8499
+ if (rawText.trim().length < 10) {
8500
+ const inputPreview = JSON.stringify(data.tool_input ?? "").slice(0, 500);
8501
+ const outputPreview = JSON.stringify(data.tool_response ?? "").slice(0, 500);
8502
+ rawText = `Tool call: ${data.tool_name}
8503
+ Input: ${inputPreview}
8504
+ Output: ${outputPreview}`;
8390
8505
  }
8391
- }
8392
- function strictSessionScopeFilter(sessionScope, tableAlias) {
8393
- const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
8394
- if (!scope) return { sql: "", args: [] };
8395
- const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
8506
+ if (rawText.trim().length < 10) return null;
8507
+ const hasError = detectError(data);
8508
+ const toolInputStr = JSON.stringify(data.tool_input ?? "").slice(0, 200);
8509
+ const toolOutputStr = JSON.stringify(data.tool_response ?? "").slice(0, 200);
8396
8510
  return {
8397
- sql: ` AND ${col} = ?`,
8398
- args: [scope]
8511
+ raw_text: rawText,
8512
+ agent_id: agent.agentId,
8513
+ agent_role: agent.agentRole,
8514
+ tool_name: data.tool_name,
8515
+ project_name: getProjectName(data.cwd ?? process.cwd()),
8516
+ session_id: data.session_id,
8517
+ has_error: hasError,
8518
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8519
+ trajectory: JSON.stringify({
8520
+ input: toolInputStr,
8521
+ tool: data.tool_name,
8522
+ output: toolOutputStr,
8523
+ result_type: hasError ? "error" : "success"
8524
+ })
8399
8525
  };
8400
8526
  }
8401
- var init_task_scope = __esm({
8402
- "src/lib/task-scope.ts"() {
8403
- "use strict";
8404
- init_tmux_routing();
8405
- }
8406
- });
8407
-
8408
- // src/lib/session-events.ts
8409
- var session_events_exports = {};
8410
- __export(session_events_exports, {
8411
- ensureSessionEventsTable: () => ensureSessionEventsTable,
8412
- listRecentSessionEvents: () => listRecentSessionEvents,
8413
- recordSessionEvent: () => recordSessionEvent
8414
- });
8415
- import { randomUUID as randomUUID4 } from "crypto";
8416
- async function ensureSessionEventsTable(client) {
8417
- await client.execute(`
8418
- CREATE TABLE IF NOT EXISTS session_events (
8419
- id TEXT PRIMARY KEY,
8420
- agent_id TEXT NOT NULL,
8421
- agent_role TEXT NOT NULL,
8422
- session_id TEXT NOT NULL,
8423
- session_scope TEXT,
8424
- project_name TEXT NOT NULL,
8425
- event_index INTEGER NOT NULL,
8426
- event_type TEXT NOT NULL,
8427
- tool_name TEXT,
8428
- tool_use_id TEXT,
8429
- content TEXT NOT NULL,
8430
- payload_json TEXT,
8431
- has_error INTEGER NOT NULL DEFAULT 0,
8432
- created_at TEXT NOT NULL
8433
- )
8434
- `);
8435
- await client.execute(`
8436
- CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
8437
- ON session_events(agent_id, created_at DESC)
8438
- `);
8439
- await client.execute(`
8440
- CREATE INDEX IF NOT EXISTS idx_session_events_session_index
8441
- ON session_events(session_id, event_index)
8442
- `);
8443
- await client.execute(`
8444
- CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
8445
- ON session_events(session_scope, agent_id, created_at DESC)
8446
- `);
8447
- }
8448
- async function recordSessionEvent(client, input2) {
8449
- if (!input2.content || input2.content.trim().length === 0) return;
8450
- await ensureSessionEventsTable(client);
8451
- const maxResult = await client.execute({
8452
- sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
8453
- args: [input2.sessionId]
8454
- });
8455
- const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
8456
- const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
8457
- await client.execute({
8458
- sql: `INSERT INTO session_events (
8459
- id, agent_id, agent_role, session_id, session_scope, project_name,
8460
- event_index, event_type, tool_name, tool_use_id, content,
8461
- payload_json, has_error, created_at
8462
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8463
- args: [
8464
- randomUUID4(),
8465
- input2.agentId,
8466
- input2.agentRole,
8467
- input2.sessionId,
8468
- input2.sessionScope ?? getCurrentSessionScope(),
8469
- input2.projectName ?? getProjectName(input2.cwd),
8470
- eventIndex,
8471
- input2.eventType,
8472
- input2.toolName ?? null,
8473
- input2.toolUseId ?? null,
8474
- input2.content,
8475
- input2.payloadJson ?? null,
8476
- input2.hasError ? 1 : 0,
8477
- input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
8478
- ]
8479
- });
8480
- }
8481
- async function listRecentSessionEvents(client, options) {
8482
- await ensureSessionEventsTable(client);
8483
- const conditions = ["agent_id = ?"];
8484
- const args = [options.agentId];
8485
- if (options.sessionId) {
8486
- conditions.push("session_id = ?");
8487
- args.push(options.sessionId);
8488
- }
8489
- if (options.eventType) {
8490
- conditions.push("event_type = ?");
8491
- args.push(options.eventType);
8492
- }
8493
- if (options.projectName && options.projectName !== "all") {
8494
- conditions.push("project_name = ?");
8495
- args.push(options.projectName);
8496
- }
8497
- const scope = strictSessionScopeFilter(options.sessionScope);
8498
- const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
8499
- args.push(...scope.args);
8500
- args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
8501
- const result = await client.execute({
8502
- sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
8503
- project_name, event_index, event_type, tool_name, tool_use_id,
8504
- content, payload_json, has_error, created_at
8505
- FROM session_events
8506
- ${where}
8507
- ORDER BY created_at DESC, event_index DESC
8508
- LIMIT ?`,
8509
- args
8510
- });
8511
- return result.rows.map((row) => ({
8512
- id: String(row.id),
8513
- agentId: String(row.agent_id),
8514
- agentRole: String(row.agent_role),
8515
- sessionId: String(row.session_id),
8516
- sessionScope: row.session_scope == null ? null : String(row.session_scope),
8517
- projectName: String(row.project_name),
8518
- eventIndex: Number(row.event_index),
8519
- eventType: String(row.event_type),
8520
- toolName: row.tool_name == null ? null : String(row.tool_name),
8521
- toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
8522
- content: String(row.content),
8523
- payloadJson: row.payload_json == null ? null : String(row.payload_json),
8524
- hasError: Number(row.has_error) === 1,
8525
- createdAt: String(row.created_at)
8526
- }));
8527
- }
8528
- var init_session_events = __esm({
8529
- "src/lib/session-events.ts"() {
8527
+ var init_post_tool_memory = __esm({
8528
+ "src/lib/post-tool-memory.ts"() {
8530
8529
  "use strict";
8531
- init_task_scope();
8530
+ init_content_extractor();
8531
+ init_error_detector();
8532
8532
  init_project_name();
8533
8533
  }
8534
8534
  });
@@ -8579,8 +8579,6 @@ ${context}`
8579
8579
  }
8580
8580
  try {
8581
8581
  const data = JSON.parse(input);
8582
- const { writeMemoryViaDaemon: writeMemoryViaDaemon2 } = await Promise.resolve().then(() => (init_memory_queue_client(), memory_queue_client_exports));
8583
- const { buildPostToolMemoryEntry: buildPostToolMemoryEntry2 } = await Promise.resolve().then(() => (init_post_tool_memory(), post_tool_memory_exports));
8584
8582
  const { getActiveAgent: getActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent2(), active_agent_exports));
8585
8583
  const { detectError: detectError2 } = await Promise.resolve().then(() => (init_error_detector(), error_detector_exports));
8586
8584
  const agent = getActiveAgent2();
@@ -8608,8 +8606,13 @@ result: ${toolResponse.slice(0, 8e3)}`,
8608
8606
  });
8609
8607
  } catch {
8610
8608
  }
8611
- const entry = buildPostToolMemoryEntry2(data, agent);
8612
- if (entry) await writeMemoryViaDaemon2(entry);
8609
+ const { loadConfigSync: loadConfigSync2 } = await Promise.resolve().then(() => (init_config(), config_exports));
8610
+ if (loadConfigSync2().autoIngestion) {
8611
+ const { writeMemoryViaDaemon: writeMemoryViaDaemon2 } = await Promise.resolve().then(() => (init_memory_queue_client(), memory_queue_client_exports));
8612
+ const { buildPostToolMemoryEntry: buildPostToolMemoryEntry2 } = await Promise.resolve().then(() => (init_post_tool_memory(), post_tool_memory_exports));
8613
+ const entry = buildPostToolMemoryEntry2(data, agent);
8614
+ if (entry) await writeMemoryViaDaemon2(entry);
8615
+ }
8613
8616
  } catch {
8614
8617
  }
8615
8618
  clearTimeout(timeout);