@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.
- package/dist/hooks/post-tool-combined.js +770 -767
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/stop.js +15 -15
- package/dist/lib/exe-daemon.js +2 -0
- package/dist/mcp/server.js +2 -0
- package/package.json +1 -1
|
@@ -7413,590 +7413,282 @@ var init_hybrid_search = __esm({
|
|
|
7413
7413
|
}
|
|
7414
7414
|
});
|
|
7415
7415
|
|
|
7416
|
-
// src/lib/
|
|
7417
|
-
import {
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
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
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
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
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
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
|
-
|
|
7462
|
-
if (
|
|
7463
|
-
if (process.env.
|
|
7464
|
-
|
|
7465
|
-
return
|
|
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
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
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
|
|
7481
|
-
|
|
7470
|
+
var _cached2, _cachedRuntime, RUNTIME_COMMANDS;
|
|
7471
|
+
var init_session_key = __esm({
|
|
7472
|
+
"src/lib/session-key.ts"() {
|
|
7482
7473
|
"use strict";
|
|
7483
|
-
|
|
7484
|
-
|
|
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/
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
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
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
if (
|
|
7517
|
-
|
|
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
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
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
|
|
7543
|
-
|
|
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
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
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
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
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
|
|
7573
|
-
const
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
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
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
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
|
-
|
|
7658
|
-
|
|
7636
|
+
}
|
|
7637
|
+
return sessions;
|
|
7638
|
+
} catch {
|
|
7639
|
+
return [];
|
|
7659
7640
|
}
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
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
|
|
7671
|
-
var
|
|
7672
|
-
"src/lib/
|
|
7653
|
+
var CACHE_DIR, STALE_MS;
|
|
7654
|
+
var init_active_agent = __esm({
|
|
7655
|
+
"src/lib/active-agent.ts"() {
|
|
7673
7656
|
"use strict";
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
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/
|
|
7681
|
-
var
|
|
7682
|
-
__export(
|
|
7683
|
-
|
|
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
|
-
|
|
7686
|
-
|
|
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
|
-
|
|
7719
|
-
init_error_detector();
|
|
7720
|
-
init_project_name();
|
|
7679
|
+
init_active_agent();
|
|
7721
7680
|
}
|
|
7722
7681
|
});
|
|
7723
7682
|
|
|
7724
|
-
// src/
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
}
|
|
7731
|
-
|
|
7732
|
-
|
|
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
|
|
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 =
|
|
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
|
|
8234
|
-
import
|
|
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 =
|
|
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
|
|
8253
|
-
import
|
|
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
|
|
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
|
-
|
|
8260
|
-
|
|
8261
|
-
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
|
|
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
|
|
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 =
|
|
8279
|
-
CACHE_PATH =
|
|
8280
|
-
DEVICE_ID_PATH =
|
|
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
|
|
8286
|
-
import
|
|
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 =
|
|
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
|
|
7993
|
+
import path17 from "path";
|
|
8302
7994
|
import {
|
|
8303
|
-
existsSync as
|
|
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
|
|
8318
|
-
import
|
|
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
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
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
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
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
|
|
8355
|
-
}
|
|
8356
|
-
} catch {
|
|
8477
|
+
return "";
|
|
8478
|
+
}).filter(Boolean).join("\n");
|
|
8357
8479
|
}
|
|
8358
|
-
return
|
|
8480
|
+
return JSON.stringify(response).slice(0, MAX_OUTPUT);
|
|
8359
8481
|
}
|
|
8360
|
-
var
|
|
8361
|
-
var
|
|
8362
|
-
"src/lib/
|
|
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
|
-
|
|
8370
|
-
|
|
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/
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
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
|
-
|
|
8393
|
-
const
|
|
8394
|
-
|
|
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
|
-
|
|
8398
|
-
|
|
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
|
|
8402
|
-
"src/lib/
|
|
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
|
-
|
|
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
|
|
8612
|
-
if (
|
|
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);
|