@askexenow/exe-os 0.8.85 → 0.8.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cleanup-stale-review-tasks.js +57 -19
- package/dist/bin/cli.js +507 -337
- package/dist/bin/exe-agent-config.js +242 -0
- package/dist/bin/exe-agent.js +3 -3
- package/dist/bin/exe-boot.js +344 -346
- package/dist/bin/exe-dispatch.js +375 -250
- package/dist/bin/exe-forget.js +5 -1
- package/dist/bin/exe-gateway.js +260 -135
- package/dist/bin/exe-healthcheck.js +133 -1
- package/dist/bin/exe-heartbeat.js +72 -31
- package/dist/bin/exe-link.js +25 -2
- package/dist/bin/exe-new-employee.js +22 -0
- package/dist/bin/exe-pending-messages.js +55 -17
- package/dist/bin/exe-pending-reviews.js +57 -19
- package/dist/bin/exe-search.js +6 -2
- package/dist/bin/exe-session-cleanup.js +260 -135
- package/dist/bin/exe-start-codex.js +2598 -0
- package/dist/bin/exe-start.sh +15 -3
- package/dist/bin/exe-status.js +57 -19
- package/dist/bin/git-sweep.js +391 -266
- package/dist/bin/install.js +22 -0
- package/dist/bin/scan-tasks.js +394 -269
- package/dist/bin/setup.js +47 -2
- package/dist/gateway/index.js +257 -132
- package/dist/hooks/bug-report-worker.js +242 -117
- package/dist/hooks/commit-complete.js +389 -264
- package/dist/hooks/error-recall.js +6 -2
- package/dist/hooks/ingest-worker.js +314 -193
- package/dist/hooks/post-compact.js +84 -46
- package/dist/hooks/pre-compact.js +272 -147
- package/dist/hooks/pre-tool-use.js +104 -66
- package/dist/hooks/prompt-submit.js +126 -66
- package/dist/hooks/session-end.js +277 -152
- package/dist/hooks/session-start.js +70 -28
- package/dist/hooks/stop.js +90 -52
- package/dist/hooks/subagent-stop.js +84 -46
- package/dist/hooks/summary-worker.js +175 -114
- package/dist/index.js +296 -171
- package/dist/lib/agent-config.js +167 -0
- package/dist/lib/cloud-sync.js +25 -2
- package/dist/lib/exe-daemon.js +338 -213
- package/dist/lib/hybrid-search.js +7 -2
- package/dist/lib/messaging.js +95 -39
- package/dist/lib/runtime-table.js +16 -0
- package/dist/lib/session-wrappers.js +22 -0
- package/dist/lib/tasks.js +242 -117
- package/dist/lib/tmux-routing.js +314 -189
- package/dist/mcp/server.js +573 -274
- package/dist/mcp/tools/create-task.js +260 -135
- package/dist/mcp/tools/list-tasks.js +68 -30
- package/dist/mcp/tools/send-message.js +100 -44
- package/dist/mcp/tools/update-task.js +123 -67
- package/dist/runtime/index.js +276 -151
- package/dist/tui/App.js +479 -354
- package/package.json +1 -1
- package/src/commands/exe/agent-config.md +27 -0
- package/src/commands/exe/cc-doctor.md +10 -0
|
@@ -3064,10 +3064,10 @@ async function disposeEmbedder() {
|
|
|
3064
3064
|
async function embedDirect(text) {
|
|
3065
3065
|
const llamaCpp = await import("node-llama-cpp");
|
|
3066
3066
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3067
|
-
const { existsSync:
|
|
3068
|
-
const
|
|
3069
|
-
const modelPath =
|
|
3070
|
-
if (!
|
|
3067
|
+
const { existsSync: existsSync16 } = await import("fs");
|
|
3068
|
+
const path19 = await import("path");
|
|
3069
|
+
const modelPath = path19.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
3070
|
+
if (!existsSync16(modelPath)) {
|
|
3071
3071
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
3072
3072
|
}
|
|
3073
3073
|
const llama = await llamaCpp.getLlama();
|
|
@@ -4130,6 +4130,42 @@ var init_provider_table = __esm({
|
|
|
4130
4130
|
}
|
|
4131
4131
|
});
|
|
4132
4132
|
|
|
4133
|
+
// src/lib/runtime-table.ts
|
|
4134
|
+
var RUNTIME_TABLE;
|
|
4135
|
+
var init_runtime_table = __esm({
|
|
4136
|
+
"src/lib/runtime-table.ts"() {
|
|
4137
|
+
"use strict";
|
|
4138
|
+
RUNTIME_TABLE = {
|
|
4139
|
+
codex: {
|
|
4140
|
+
binary: "codex",
|
|
4141
|
+
launchMode: "exec",
|
|
4142
|
+
autoApproveFlag: "--full-auto",
|
|
4143
|
+
inlineFlag: "--no-alt-screen",
|
|
4144
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
4145
|
+
defaultModel: "gpt-5.4"
|
|
4146
|
+
}
|
|
4147
|
+
};
|
|
4148
|
+
}
|
|
4149
|
+
});
|
|
4150
|
+
|
|
4151
|
+
// src/lib/agent-config.ts
|
|
4152
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync8, mkdirSync as mkdirSync3 } from "fs";
|
|
4153
|
+
import path11 from "path";
|
|
4154
|
+
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
4155
|
+
var init_agent_config = __esm({
|
|
4156
|
+
"src/lib/agent-config.ts"() {
|
|
4157
|
+
"use strict";
|
|
4158
|
+
init_config();
|
|
4159
|
+
init_runtime_table();
|
|
4160
|
+
AGENT_CONFIG_PATH = path11.join(EXE_AI_DIR, "agent-config.json");
|
|
4161
|
+
DEFAULT_MODELS = {
|
|
4162
|
+
claude: "claude-opus-4",
|
|
4163
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
4164
|
+
opencode: "minimax-m2.7"
|
|
4165
|
+
};
|
|
4166
|
+
}
|
|
4167
|
+
});
|
|
4168
|
+
|
|
4133
4169
|
// src/lib/intercom-queue.ts
|
|
4134
4170
|
var intercom_queue_exports = {};
|
|
4135
4171
|
__export(intercom_queue_exports, {
|
|
@@ -4138,17 +4174,17 @@ __export(intercom_queue_exports, {
|
|
|
4138
4174
|
queueIntercom: () => queueIntercom,
|
|
4139
4175
|
readQueue: () => readQueue
|
|
4140
4176
|
});
|
|
4141
|
-
import { readFileSync as
|
|
4142
|
-
import
|
|
4177
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
|
|
4178
|
+
import path12 from "path";
|
|
4143
4179
|
import os5 from "os";
|
|
4144
4180
|
function ensureDir() {
|
|
4145
|
-
const dir =
|
|
4146
|
-
if (!
|
|
4181
|
+
const dir = path12.dirname(QUEUE_PATH);
|
|
4182
|
+
if (!existsSync9(dir)) mkdirSync4(dir, { recursive: true });
|
|
4147
4183
|
}
|
|
4148
4184
|
function readQueue() {
|
|
4149
4185
|
try {
|
|
4150
|
-
if (!
|
|
4151
|
-
return JSON.parse(
|
|
4186
|
+
if (!existsSync9(QUEUE_PATH)) return [];
|
|
4187
|
+
return JSON.parse(readFileSync7(QUEUE_PATH, "utf8"));
|
|
4152
4188
|
} catch {
|
|
4153
4189
|
return [];
|
|
4154
4190
|
}
|
|
@@ -4156,7 +4192,7 @@ function readQueue() {
|
|
|
4156
4192
|
function writeQueue(queue) {
|
|
4157
4193
|
ensureDir();
|
|
4158
4194
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
4159
|
-
|
|
4195
|
+
writeFileSync4(tmp, JSON.stringify(queue, null, 2));
|
|
4160
4196
|
renameSync3(tmp, QUEUE_PATH);
|
|
4161
4197
|
}
|
|
4162
4198
|
function queueIntercom(targetSession, reason) {
|
|
@@ -4239,32 +4275,32 @@ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
|
4239
4275
|
var init_intercom_queue = __esm({
|
|
4240
4276
|
"src/lib/intercom-queue.ts"() {
|
|
4241
4277
|
"use strict";
|
|
4242
|
-
QUEUE_PATH =
|
|
4278
|
+
QUEUE_PATH = path12.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
4243
4279
|
MAX_RETRIES2 = 5;
|
|
4244
4280
|
TTL_MS = 60 * 60 * 1e3;
|
|
4245
|
-
INTERCOM_LOG =
|
|
4281
|
+
INTERCOM_LOG = path12.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
4246
4282
|
}
|
|
4247
4283
|
});
|
|
4248
4284
|
|
|
4249
4285
|
// src/lib/license.ts
|
|
4250
|
-
import { readFileSync as
|
|
4286
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
|
|
4251
4287
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4252
|
-
import
|
|
4288
|
+
import path13 from "path";
|
|
4253
4289
|
import { jwtVerify, importSPKI } from "jose";
|
|
4254
4290
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
4255
4291
|
var init_license = __esm({
|
|
4256
4292
|
"src/lib/license.ts"() {
|
|
4257
4293
|
"use strict";
|
|
4258
4294
|
init_config();
|
|
4259
|
-
LICENSE_PATH =
|
|
4260
|
-
CACHE_PATH =
|
|
4261
|
-
DEVICE_ID_PATH =
|
|
4295
|
+
LICENSE_PATH = path13.join(EXE_AI_DIR, "license.key");
|
|
4296
|
+
CACHE_PATH = path13.join(EXE_AI_DIR, "license-cache.json");
|
|
4297
|
+
DEVICE_ID_PATH = path13.join(EXE_AI_DIR, "device-id");
|
|
4262
4298
|
}
|
|
4263
4299
|
});
|
|
4264
4300
|
|
|
4265
4301
|
// src/lib/plan-limits.ts
|
|
4266
|
-
import { readFileSync as
|
|
4267
|
-
import
|
|
4302
|
+
import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
|
|
4303
|
+
import path14 from "path";
|
|
4268
4304
|
var CACHE_PATH2;
|
|
4269
4305
|
var init_plan_limits = __esm({
|
|
4270
4306
|
"src/lib/plan-limits.ts"() {
|
|
@@ -4273,13 +4309,13 @@ var init_plan_limits = __esm({
|
|
|
4273
4309
|
init_employees();
|
|
4274
4310
|
init_license();
|
|
4275
4311
|
init_config();
|
|
4276
|
-
CACHE_PATH2 =
|
|
4312
|
+
CACHE_PATH2 = path14.join(EXE_AI_DIR, "license-cache.json");
|
|
4277
4313
|
}
|
|
4278
4314
|
});
|
|
4279
4315
|
|
|
4280
4316
|
// src/lib/tmux-routing.ts
|
|
4281
|
-
import { readFileSync as
|
|
4282
|
-
import
|
|
4317
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
|
|
4318
|
+
import path15 from "path";
|
|
4283
4319
|
import os6 from "os";
|
|
4284
4320
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4285
4321
|
function getMySession() {
|
|
@@ -4320,7 +4356,7 @@ function extractRootExe(name) {
|
|
|
4320
4356
|
}
|
|
4321
4357
|
function getParentExe(sessionKey) {
|
|
4322
4358
|
try {
|
|
4323
|
-
const data = JSON.parse(
|
|
4359
|
+
const data = JSON.parse(readFileSync10(path15.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
4324
4360
|
return data.parentExe || null;
|
|
4325
4361
|
} catch {
|
|
4326
4362
|
return null;
|
|
@@ -4344,32 +4380,50 @@ function isEmployeeAlive(sessionName) {
|
|
|
4344
4380
|
}
|
|
4345
4381
|
function readDebounceState() {
|
|
4346
4382
|
try {
|
|
4347
|
-
if (!
|
|
4348
|
-
|
|
4383
|
+
if (!existsSync12(DEBOUNCE_FILE)) return {};
|
|
4384
|
+
const raw = JSON.parse(readFileSync10(DEBOUNCE_FILE, "utf8"));
|
|
4385
|
+
const state = {};
|
|
4386
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
4387
|
+
if (typeof val === "number") {
|
|
4388
|
+
state[key] = { lastSent: val, pending: 0 };
|
|
4389
|
+
} else if (val && typeof val === "object" && "lastSent" in val) {
|
|
4390
|
+
state[key] = val;
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
return state;
|
|
4349
4394
|
} catch {
|
|
4350
4395
|
return {};
|
|
4351
4396
|
}
|
|
4352
4397
|
}
|
|
4353
4398
|
function writeDebounceState(state) {
|
|
4354
4399
|
try {
|
|
4355
|
-
if (!
|
|
4356
|
-
|
|
4400
|
+
if (!existsSync12(SESSION_CACHE)) mkdirSync6(SESSION_CACHE, { recursive: true });
|
|
4401
|
+
writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
|
|
4357
4402
|
} catch {
|
|
4358
4403
|
}
|
|
4359
4404
|
}
|
|
4360
4405
|
function isDebounced(targetSession) {
|
|
4361
4406
|
const state = readDebounceState();
|
|
4362
|
-
const
|
|
4363
|
-
|
|
4407
|
+
const entry = state[targetSession];
|
|
4408
|
+
const lastSent = entry?.lastSent ?? 0;
|
|
4409
|
+
if (Date.now() - lastSent < INTERCOM_DEBOUNCE_MS) {
|
|
4410
|
+
if (!state[targetSession]) state[targetSession] = { lastSent, pending: 0 };
|
|
4411
|
+
state[targetSession].pending++;
|
|
4412
|
+
writeDebounceState(state);
|
|
4413
|
+
return true;
|
|
4414
|
+
}
|
|
4415
|
+
return false;
|
|
4364
4416
|
}
|
|
4365
4417
|
function recordDebounce(targetSession) {
|
|
4366
4418
|
const state = readDebounceState();
|
|
4367
|
-
state[targetSession]
|
|
4419
|
+
const batched = state[targetSession]?.pending ?? 0;
|
|
4420
|
+
state[targetSession] = { lastSent: Date.now(), pending: 0 };
|
|
4368
4421
|
const cutoff = Date.now() - DEBOUNCE_CLEANUP_AGE_MS;
|
|
4369
4422
|
for (const key of Object.keys(state)) {
|
|
4370
|
-
if ((state[key] ?? 0) < cutoff) delete state[key];
|
|
4423
|
+
if ((state[key]?.lastSent ?? 0) < cutoff) delete state[key];
|
|
4371
4424
|
}
|
|
4372
4425
|
writeDebounceState(state);
|
|
4426
|
+
return batched;
|
|
4373
4427
|
}
|
|
4374
4428
|
function logIntercom(msg) {
|
|
4375
4429
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${msg}
|
|
@@ -4410,7 +4464,7 @@ function sendIntercom(targetSession) {
|
|
|
4410
4464
|
return "skipped_exe";
|
|
4411
4465
|
}
|
|
4412
4466
|
if (isDebounced(targetSession)) {
|
|
4413
|
-
logIntercom(`DEBOUNCE \u2192 ${targetSession} (
|
|
4467
|
+
logIntercom(`DEBOUNCE \u2192 ${targetSession} (nudge batched, task safe in DB)`);
|
|
4414
4468
|
return "debounced";
|
|
4415
4469
|
}
|
|
4416
4470
|
try {
|
|
@@ -4422,14 +4476,14 @@ function sendIntercom(targetSession) {
|
|
|
4422
4476
|
const sessionState = getSessionState(targetSession);
|
|
4423
4477
|
if (sessionState === "no_claude") {
|
|
4424
4478
|
queueIntercom(targetSession, "claude not running in session");
|
|
4425
|
-
recordDebounce(targetSession);
|
|
4426
|
-
logIntercom(`QUEUED \u2192 ${targetSession} (no claude process
|
|
4479
|
+
const batched2 = recordDebounce(targetSession);
|
|
4480
|
+
logIntercom(`QUEUED \u2192 ${targetSession} (no claude process)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
|
|
4427
4481
|
return "queued";
|
|
4428
4482
|
}
|
|
4429
4483
|
if (sessionState === "thinking" || sessionState === "tool") {
|
|
4430
4484
|
queueIntercom(targetSession, "session busy at send time");
|
|
4431
|
-
recordDebounce(targetSession);
|
|
4432
|
-
logIntercom(`QUEUED \u2192 ${targetSession} (session busy
|
|
4485
|
+
const batched2 = recordDebounce(targetSession);
|
|
4486
|
+
logIntercom(`QUEUED \u2192 ${targetSession} (session busy)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
|
|
4433
4487
|
return "queued";
|
|
4434
4488
|
}
|
|
4435
4489
|
if (transport.isPaneInCopyMode(targetSession)) {
|
|
@@ -4437,8 +4491,8 @@ function sendIntercom(targetSession) {
|
|
|
4437
4491
|
transport.sendKeys(targetSession, "q");
|
|
4438
4492
|
}
|
|
4439
4493
|
transport.sendKeys(targetSession, "/exe-intercom");
|
|
4440
|
-
recordDebounce(targetSession);
|
|
4441
|
-
logIntercom(`DELIVERED \u2192 ${targetSession} (fire-and-forget)`);
|
|
4494
|
+
const batched = recordDebounce(targetSession);
|
|
4495
|
+
logIntercom(`DELIVERED \u2192 ${targetSession}${batched > 0 ? ` [${batched} nudges batched during debounce]` : ""} (fire-and-forget)`);
|
|
4442
4496
|
return "delivered";
|
|
4443
4497
|
} catch {
|
|
4444
4498
|
logIntercom(`FAIL \u2192 ${targetSession}`);
|
|
@@ -4455,15 +4509,17 @@ var init_tmux_routing = __esm({
|
|
|
4455
4509
|
init_cc_agent_support();
|
|
4456
4510
|
init_mcp_prefix();
|
|
4457
4511
|
init_provider_table();
|
|
4512
|
+
init_agent_config();
|
|
4513
|
+
init_runtime_table();
|
|
4458
4514
|
init_intercom_queue();
|
|
4459
4515
|
init_plan_limits();
|
|
4460
4516
|
init_employees();
|
|
4461
|
-
SPAWN_LOCK_DIR =
|
|
4462
|
-
SESSION_CACHE =
|
|
4517
|
+
SPAWN_LOCK_DIR = path15.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
4518
|
+
SESSION_CACHE = path15.join(os6.homedir(), ".exe-os", "session-cache");
|
|
4463
4519
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
4464
4520
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
4465
|
-
INTERCOM_LOG2 =
|
|
4466
|
-
DEBOUNCE_FILE =
|
|
4521
|
+
INTERCOM_LOG2 = path15.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
4522
|
+
DEBOUNCE_FILE = path15.join(SESSION_CACHE, "intercom-debounce.json");
|
|
4467
4523
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
4468
4524
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
4469
4525
|
}
|
|
@@ -4722,13 +4778,13 @@ var init_messaging = __esm({
|
|
|
4722
4778
|
|
|
4723
4779
|
// src/lib/notifications.ts
|
|
4724
4780
|
import crypto3 from "crypto";
|
|
4725
|
-
import
|
|
4781
|
+
import path16 from "path";
|
|
4726
4782
|
import os7 from "os";
|
|
4727
4783
|
import {
|
|
4728
|
-
readFileSync as
|
|
4784
|
+
readFileSync as readFileSync11,
|
|
4729
4785
|
readdirSync as readdirSync4,
|
|
4730
4786
|
unlinkSync as unlinkSync4,
|
|
4731
|
-
existsSync as
|
|
4787
|
+
existsSync as existsSync13,
|
|
4732
4788
|
rmdirSync
|
|
4733
4789
|
} from "fs";
|
|
4734
4790
|
async function writeNotification(notification) {
|
|
@@ -4773,8 +4829,8 @@ __export(tasks_review_exports, {
|
|
|
4773
4829
|
getReviewChecklist: () => getReviewChecklist,
|
|
4774
4830
|
listPendingReviews: () => listPendingReviews
|
|
4775
4831
|
});
|
|
4776
|
-
import
|
|
4777
|
-
import { existsSync as
|
|
4832
|
+
import path17 from "path";
|
|
4833
|
+
import { existsSync as existsSync14, readdirSync as readdirSync5, unlinkSync as unlinkSync5 } from "fs";
|
|
4778
4834
|
async function countPendingReviews(sessionScope) {
|
|
4779
4835
|
const client = getClient();
|
|
4780
4836
|
if (sessionScope) {
|
|
@@ -5044,11 +5100,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
5044
5100
|
);
|
|
5045
5101
|
}
|
|
5046
5102
|
try {
|
|
5047
|
-
const cacheDir =
|
|
5048
|
-
if (
|
|
5103
|
+
const cacheDir = path17.join(EXE_AI_DIR, "session-cache");
|
|
5104
|
+
if (existsSync14(cacheDir)) {
|
|
5049
5105
|
for (const f of readdirSync5(cacheDir)) {
|
|
5050
5106
|
if (f.startsWith("review-notified-")) {
|
|
5051
|
-
unlinkSync5(
|
|
5107
|
+
unlinkSync5(path17.join(cacheDir, f));
|
|
5052
5108
|
}
|
|
5053
5109
|
}
|
|
5054
5110
|
}
|
|
@@ -5073,8 +5129,8 @@ init_config();
|
|
|
5073
5129
|
init_config();
|
|
5074
5130
|
init_store();
|
|
5075
5131
|
import { spawn as spawn2 } from "child_process";
|
|
5076
|
-
import { readFileSync as
|
|
5077
|
-
import
|
|
5132
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync15, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
5133
|
+
import path18 from "path";
|
|
5078
5134
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
5079
5135
|
|
|
5080
5136
|
// src/lib/hybrid-search.ts
|
|
@@ -5138,7 +5194,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
5138
5194
|
process.stderr.write("[hybrid-search] Embed daemon unavailable \u2014 FTS-only mode\n");
|
|
5139
5195
|
}
|
|
5140
5196
|
let grepPromise = Promise.resolve([]);
|
|
5141
|
-
if (config.fileGrepEnabled
|
|
5197
|
+
if (config.fileGrepEnabled === true) {
|
|
5142
5198
|
try {
|
|
5143
5199
|
const { getProjectName: getProjectName2 } = await Promise.resolve().then(() => (init_project_name(), project_name_exports));
|
|
5144
5200
|
const projectRoot = process.cwd();
|
|
@@ -5404,7 +5460,7 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
|
5404
5460
|
source_type: row.source_type ?? null
|
|
5405
5461
|
}));
|
|
5406
5462
|
}
|
|
5407
|
-
async function recentRecords(agentId, options, limit) {
|
|
5463
|
+
async function recentRecords(agentId, options, limit, textFilter) {
|
|
5408
5464
|
const client = getClient();
|
|
5409
5465
|
const statusFilter = options?.includeArchived ? "" : `
|
|
5410
5466
|
AND COALESCE(status, 'active') = 'active'`;
|
|
@@ -5444,6 +5500,10 @@ async function recentRecords(agentId, options, limit) {
|
|
|
5444
5500
|
sql += ` AND memory_type = ?`;
|
|
5445
5501
|
args.push(options.memoryType);
|
|
5446
5502
|
}
|
|
5503
|
+
if (textFilter) {
|
|
5504
|
+
sql += ` AND raw_text LIKE '%' || ? || '%'`;
|
|
5505
|
+
args.push(textFilter);
|
|
5506
|
+
}
|
|
5447
5507
|
sql += ` ORDER BY timestamp DESC LIMIT ?`;
|
|
5448
5508
|
args.push(limit);
|
|
5449
5509
|
const result = await client.execute({ sql, args });
|
|
@@ -5666,7 +5726,7 @@ if (!process.env.AGENT_ID) {
|
|
|
5666
5726
|
if (!loadConfigSync().autoRetrieval) {
|
|
5667
5727
|
process.exit(0);
|
|
5668
5728
|
}
|
|
5669
|
-
var WORKER_LOG_PATH =
|
|
5729
|
+
var WORKER_LOG_PATH = path18.join(EXE_AI_DIR, "workers.log");
|
|
5670
5730
|
function openWorkerLog() {
|
|
5671
5731
|
try {
|
|
5672
5732
|
return openSync2(WORKER_LOG_PATH, "a");
|
|
@@ -5674,10 +5734,10 @@ function openWorkerLog() {
|
|
|
5674
5734
|
return "ignore";
|
|
5675
5735
|
}
|
|
5676
5736
|
}
|
|
5677
|
-
var CACHE_DIR2 =
|
|
5737
|
+
var CACHE_DIR2 = path18.join(EXE_AI_DIR, "session-cache");
|
|
5678
5738
|
function loadInjectedIds(sessionId) {
|
|
5679
5739
|
try {
|
|
5680
|
-
const raw =
|
|
5740
|
+
const raw = readFileSync12(path18.join(CACHE_DIR2, `${sessionId}.json`), "utf8");
|
|
5681
5741
|
return new Set(JSON.parse(raw));
|
|
5682
5742
|
} catch {
|
|
5683
5743
|
return /* @__PURE__ */ new Set();
|
|
@@ -5685,9 +5745,9 @@ function loadInjectedIds(sessionId) {
|
|
|
5685
5745
|
}
|
|
5686
5746
|
function saveInjectedIds(sessionId, ids) {
|
|
5687
5747
|
try {
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5748
|
+
mkdirSync7(CACHE_DIR2, { recursive: true });
|
|
5749
|
+
writeFileSync7(
|
|
5750
|
+
path18.join(CACHE_DIR2, `${sessionId}.json`),
|
|
5691
5751
|
JSON.stringify([...ids])
|
|
5692
5752
|
);
|
|
5693
5753
|
} catch {
|
|
@@ -5770,7 +5830,7 @@ ${fresh.map(
|
|
|
5770
5830
|
try {
|
|
5771
5831
|
const { countPendingReviews: countPendingReviews2, countNewPendingReviewsSince: countNewPendingReviewsSince2 } = await Promise.resolve().then(() => (init_tasks_review(), tasks_review_exports));
|
|
5772
5832
|
const sessionKey = getSessionKey();
|
|
5773
|
-
const lastCheckPath =
|
|
5833
|
+
const lastCheckPath = path18.join(CACHE_DIR2, `review-lastcheck-${sessionKey}.json`);
|
|
5774
5834
|
let sessionScope;
|
|
5775
5835
|
try {
|
|
5776
5836
|
const { execSync: execSync7 } = await import("child_process");
|
|
@@ -5780,7 +5840,7 @@ ${fresh.map(
|
|
|
5780
5840
|
}
|
|
5781
5841
|
let lastCheckedAt = "";
|
|
5782
5842
|
try {
|
|
5783
|
-
lastCheckedAt =
|
|
5843
|
+
lastCheckedAt = readFileSync12(lastCheckPath, "utf8").trim();
|
|
5784
5844
|
} catch {
|
|
5785
5845
|
}
|
|
5786
5846
|
const totalCount = await countPendingReviews2(sessionScope);
|
|
@@ -5838,11 +5898,11 @@ IMPORTANT: After completing your current task, you MUST address the pending revi
|
|
|
5838
5898
|
function spawnPromptWorker(prompt, sessionId, agent) {
|
|
5839
5899
|
if (!loadConfigSync().autoIngestion) return;
|
|
5840
5900
|
try {
|
|
5841
|
-
const workerPath =
|
|
5842
|
-
|
|
5901
|
+
const workerPath = path18.resolve(
|
|
5902
|
+
path18.dirname(fileURLToPath3(import.meta.url)),
|
|
5843
5903
|
"prompt-ingest-worker.js"
|
|
5844
5904
|
);
|
|
5845
|
-
if (!
|
|
5905
|
+
if (!existsSync15(workerPath)) {
|
|
5846
5906
|
process.stderr.write(`[prompt-submit] WARN: prompt-ingest-worker not found at ${workerPath}
|
|
5847
5907
|
`);
|
|
5848
5908
|
return;
|