@askexenow/exe-os 0.8.80 → 0.8.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/backfill-conversations.js +359 -267
- package/dist/bin/backfill-responses.js +357 -265
- package/dist/bin/backfill-vectors.js +339 -264
- package/dist/bin/cleanup-stale-review-tasks.js +315 -256
- package/dist/bin/cli.js +494 -240
- package/dist/bin/exe-agent.js +141 -46
- package/dist/bin/exe-assign.js +151 -63
- package/dist/bin/exe-boot.js +294 -115
- package/dist/bin/exe-call.js +76 -51
- package/dist/bin/exe-cloud.js +58 -45
- package/dist/bin/exe-dispatch.js +434 -277
- package/dist/bin/exe-doctor.js +317 -246
- package/dist/bin/exe-export-behaviors.js +328 -248
- package/dist/bin/exe-forget.js +314 -231
- package/dist/bin/exe-gateway.js +2676 -1402
- package/dist/bin/exe-heartbeat.js +329 -264
- package/dist/bin/exe-kill.js +324 -244
- package/dist/bin/exe-launch-agent.js +574 -463
- package/dist/bin/exe-link.js +1055 -95
- package/dist/bin/exe-new-employee.js +49 -54
- package/dist/bin/exe-pending-messages.js +310 -253
- package/dist/bin/exe-pending-notifications.js +299 -228
- package/dist/bin/exe-pending-reviews.js +314 -245
- package/dist/bin/exe-rename.js +259 -195
- package/dist/bin/exe-review.js +140 -64
- package/dist/bin/exe-search.js +543 -356
- package/dist/bin/exe-session-cleanup.js +463 -382
- package/dist/bin/exe-settings.js +129 -99
- package/dist/bin/exe-start.sh +6 -6
- package/dist/bin/exe-status.js +95 -36
- package/dist/bin/exe-team.js +116 -51
- package/dist/bin/git-sweep.js +482 -307
- package/dist/bin/graph-backfill.js +357 -245
- package/dist/bin/graph-export.js +324 -244
- package/dist/bin/install.js +33 -10
- package/dist/bin/scan-tasks.js +481 -307
- package/dist/bin/setup.js +1147 -140
- package/dist/bin/shard-migrate.js +321 -241
- package/dist/bin/update.js +1 -7
- package/dist/bin/wiki-sync.js +318 -238
- package/dist/gateway/index.js +2656 -1383
- package/dist/hooks/bug-report-worker.js +641 -472
- package/dist/hooks/commit-complete.js +482 -307
- package/dist/hooks/error-recall.js +363 -135
- package/dist/hooks/exe-heartbeat-hook.js +97 -27
- package/dist/hooks/ingest-worker.js +584 -397
- package/dist/hooks/ingest.js +123 -58
- package/dist/hooks/instructions-loaded.js +212 -82
- package/dist/hooks/notification.js +200 -70
- package/dist/hooks/post-compact.js +199 -81
- package/dist/hooks/pre-compact.js +352 -140
- package/dist/hooks/pre-tool-use.js +416 -278
- package/dist/hooks/prompt-ingest-worker.js +376 -299
- package/dist/hooks/prompt-submit.js +414 -188
- package/dist/hooks/response-ingest-worker.js +408 -338
- package/dist/hooks/session-end.js +209 -83
- package/dist/hooks/session-start.js +382 -158
- package/dist/hooks/stop.js +209 -83
- package/dist/hooks/subagent-stop.js +209 -85
- package/dist/hooks/summary-worker.js +606 -510
- package/dist/index.js +2133 -855
- package/dist/lib/cloud-sync.js +1175 -184
- package/dist/lib/config.js +1 -9
- package/dist/lib/consolidation.js +71 -34
- package/dist/lib/database.js +166 -14
- package/dist/lib/device-registry.js +189 -117
- package/dist/lib/embedder.js +6 -10
- package/dist/lib/employee-templates.js +134 -39
- package/dist/lib/employees.js +30 -7
- package/dist/lib/exe-daemon-client.js +5 -7
- package/dist/lib/exe-daemon.js +514 -152
- package/dist/lib/hybrid-search.js +543 -356
- package/dist/lib/identity-templates.js +15 -15
- package/dist/lib/identity.js +19 -15
- package/dist/lib/license.js +1 -7
- package/dist/lib/messaging.js +157 -135
- package/dist/lib/reminders.js +97 -0
- package/dist/lib/schedules.js +302 -231
- package/dist/lib/skill-learning.js +33 -27
- package/dist/lib/status-brief.js +11 -14
- package/dist/lib/store.js +326 -237
- package/dist/lib/task-router.js +105 -1
- package/dist/lib/tasks.js +233 -116
- package/dist/lib/tmux-routing.js +173 -56
- package/dist/lib/ws-client.js +13 -3
- package/dist/mcp/server.js +2009 -1015
- package/dist/mcp/tools/complete-reminder.js +97 -0
- package/dist/mcp/tools/create-reminder.js +97 -0
- package/dist/mcp/tools/create-task.js +426 -262
- package/dist/mcp/tools/deactivate-behavior.js +119 -44
- package/dist/mcp/tools/list-reminders.js +97 -0
- package/dist/mcp/tools/list-tasks.js +56 -57
- package/dist/mcp/tools/send-message.js +206 -143
- package/dist/mcp/tools/update-task.js +259 -85
- package/dist/runtime/index.js +495 -316
- package/dist/tui/App.js +1128 -919
- package/package.json +2 -10
- package/src/commands/exe/afk.md +8 -8
- package/src/commands/exe/assign.md +1 -1
- package/src/commands/exe/build-adv.md +1 -1
- package/src/commands/exe/call.md +10 -10
- package/src/commands/exe/employee-heartbeat.md +9 -6
- package/src/commands/exe/heartbeat.md +5 -5
- package/src/commands/exe/intercom.md +26 -15
- package/src/commands/exe/launch.md +2 -2
- package/src/commands/exe/new-employee.md +1 -1
- package/src/commands/exe/review.md +2 -2
- package/src/commands/exe/schedule.md +1 -1
- package/src/commands/exe/sessions.md +2 -2
- package/src/commands/exe.md +22 -20
package/dist/hooks/ingest.js
CHANGED
|
@@ -58,13 +58,7 @@ var DEFAULT_CONFIG = {
|
|
|
58
58
|
wikiUrl: "",
|
|
59
59
|
wikiApiKey: "",
|
|
60
60
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
61
|
-
wikiWorkspaceMapping: {
|
|
62
|
-
exe: "Executive",
|
|
63
|
-
yoshi: "Engineering",
|
|
64
|
-
mari: "Marketing",
|
|
65
|
-
tom: "Engineering",
|
|
66
|
-
sasha: "Production"
|
|
67
|
-
},
|
|
61
|
+
wikiWorkspaceMapping: {},
|
|
68
62
|
wikiAutoUpdate: true,
|
|
69
63
|
wikiAutoUpdateThreshold: 0.5,
|
|
70
64
|
wikiAutoUpdateCreateNew: true,
|
|
@@ -170,14 +164,14 @@ function loadConfigSync() {
|
|
|
170
164
|
|
|
171
165
|
// src/adapters/claude/hooks/ingest.ts
|
|
172
166
|
import { spawn } from "child_process";
|
|
173
|
-
import { readFileSync as
|
|
174
|
-
import
|
|
167
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, existsSync as existsSync4, openSync, closeSync } from "fs";
|
|
168
|
+
import path5 from "path";
|
|
175
169
|
import { fileURLToPath } from "url";
|
|
176
170
|
|
|
177
171
|
// src/adapters/claude/active-agent.ts
|
|
178
|
-
import { readFileSync as
|
|
179
|
-
import { execSync as
|
|
180
|
-
import
|
|
172
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, unlinkSync as unlinkSync2, readdirSync } from "fs";
|
|
173
|
+
import { execSync as execSync3 } from "child_process";
|
|
174
|
+
import path3 from "path";
|
|
181
175
|
|
|
182
176
|
// src/lib/session-key.ts
|
|
183
177
|
import { execSync } from "child_process";
|
|
@@ -208,23 +202,98 @@ function getSessionKey() {
|
|
|
208
202
|
return _cached;
|
|
209
203
|
}
|
|
210
204
|
|
|
205
|
+
// src/lib/employees.ts
|
|
206
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
207
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
208
|
+
import { execSync as execSync2 } from "child_process";
|
|
209
|
+
import path2 from "path";
|
|
210
|
+
import os2 from "os";
|
|
211
|
+
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
212
|
+
var DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
213
|
+
var COORDINATOR_ROLE = "COO";
|
|
214
|
+
function normalizeRole(role) {
|
|
215
|
+
return (role ?? "").trim().toLowerCase();
|
|
216
|
+
}
|
|
217
|
+
function isCoordinatorRole(role) {
|
|
218
|
+
return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
|
|
219
|
+
}
|
|
220
|
+
function getCoordinatorEmployee(employees) {
|
|
221
|
+
return employees.find((e) => isCoordinatorRole(e.role));
|
|
222
|
+
}
|
|
223
|
+
function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
224
|
+
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
225
|
+
}
|
|
226
|
+
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
227
|
+
if (!existsSync2(employeesPath)) return [];
|
|
228
|
+
try {
|
|
229
|
+
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
230
|
+
} catch {
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function getEmployee(employees, name) {
|
|
235
|
+
return employees.find((e) => e.name.toLowerCase() === name.toLowerCase());
|
|
236
|
+
}
|
|
237
|
+
|
|
211
238
|
// src/adapters/claude/active-agent.ts
|
|
212
|
-
var CACHE_DIR =
|
|
239
|
+
var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
|
|
213
240
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
241
|
+
function isNameWithOptionalInstance(candidate, baseName) {
|
|
242
|
+
if (candidate === baseName) return true;
|
|
243
|
+
if (!candidate.startsWith(baseName)) return false;
|
|
244
|
+
return /^\d+$/.test(candidate.slice(baseName.length));
|
|
245
|
+
}
|
|
246
|
+
function resolveEmployeeFromSessionPrefix(prefix, employees) {
|
|
247
|
+
const sorted = [...employees].sort((a, b) => b.name.length - a.name.length);
|
|
248
|
+
for (const employee of sorted) {
|
|
249
|
+
if (isNameWithOptionalInstance(prefix, employee.name)) {
|
|
250
|
+
return { agentId: employee.name, agentRole: employee.role };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
function resolveActiveAgentFromTmuxSession(sessionName) {
|
|
256
|
+
const employees = loadEmployeesSync();
|
|
257
|
+
const coordinator = getCoordinatorEmployee(employees);
|
|
258
|
+
const coordinatorName = coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
259
|
+
if (isNameWithOptionalInstance(sessionName, coordinatorName)) {
|
|
260
|
+
return {
|
|
261
|
+
agentId: coordinatorName,
|
|
262
|
+
agentRole: coordinator?.role ?? "COO"
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (isNameWithOptionalInstance(sessionName, DEFAULT_COORDINATOR_TEMPLATE_NAME)) {
|
|
266
|
+
return {
|
|
267
|
+
agentId: coordinator?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME,
|
|
268
|
+
agentRole: coordinator?.role ?? "COO"
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (sessionName.includes("-")) {
|
|
272
|
+
const prefix = sessionName.split("-")[0] ?? "";
|
|
273
|
+
const employee = resolveEmployeeFromSessionPrefix(prefix, employees);
|
|
274
|
+
if (employee) return employee;
|
|
275
|
+
const legacy = prefix.match(/^([a-zA-Z]+)\d*$/);
|
|
276
|
+
if (legacy?.[1] && legacy[1] !== DEFAULT_COORDINATOR_TEMPLATE_NAME) {
|
|
277
|
+
const emp = getEmployee(employees, legacy[1]);
|
|
278
|
+
return { agentId: emp?.name ?? legacy[1], agentRole: emp?.role ?? "employee" };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
214
283
|
function getMarkerPath() {
|
|
215
|
-
return
|
|
284
|
+
return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
|
|
216
285
|
}
|
|
217
286
|
function getActiveAgent() {
|
|
218
287
|
try {
|
|
219
288
|
const markerPath = getMarkerPath();
|
|
220
|
-
const raw =
|
|
289
|
+
const raw = readFileSync3(markerPath, "utf8");
|
|
221
290
|
const data = JSON.parse(raw);
|
|
222
291
|
if (data.agentId) {
|
|
223
292
|
if (data.startedAt) {
|
|
224
293
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
225
294
|
if (age > STALE_MS) {
|
|
226
295
|
try {
|
|
227
|
-
|
|
296
|
+
unlinkSync2(markerPath);
|
|
228
297
|
} catch {
|
|
229
298
|
}
|
|
230
299
|
} else {
|
|
@@ -243,17 +312,12 @@ function getActiveAgent() {
|
|
|
243
312
|
} catch {
|
|
244
313
|
}
|
|
245
314
|
try {
|
|
246
|
-
const sessionName =
|
|
315
|
+
const sessionName = execSync3(
|
|
247
316
|
"tmux display-message -p '#{session_name}' 2>/dev/null",
|
|
248
317
|
{ encoding: "utf8", timeout: 2e3 }
|
|
249
318
|
).trim();
|
|
250
|
-
const
|
|
251
|
-
if (
|
|
252
|
-
return { agentId: empMatch[1], agentRole: "employee" };
|
|
253
|
-
}
|
|
254
|
-
if (/^exe\d+$/.test(sessionName)) {
|
|
255
|
-
return { agentId: "exe", agentRole: "COO" };
|
|
256
|
-
}
|
|
319
|
+
const resolved = resolveActiveAgentFromTmuxSession(sessionName);
|
|
320
|
+
if (resolved) return resolved;
|
|
257
321
|
} catch {
|
|
258
322
|
}
|
|
259
323
|
return {
|
|
@@ -413,16 +477,16 @@ function errorFingerprint(toolName, errorText) {
|
|
|
413
477
|
}
|
|
414
478
|
|
|
415
479
|
// src/lib/worker-gate.ts
|
|
416
|
-
import { readdirSync as readdirSync2, writeFileSync as
|
|
417
|
-
import
|
|
418
|
-
var WORKER_PID_DIR =
|
|
480
|
+
import { readdirSync as readdirSync2, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
|
|
481
|
+
import path4 from "path";
|
|
482
|
+
var WORKER_PID_DIR = path4.join(EXE_AI_DIR, "worker-pids");
|
|
419
483
|
var MAX_CONCURRENT_WORKERS = 3;
|
|
420
484
|
function tryAcquireWorkerSlot() {
|
|
421
485
|
try {
|
|
422
486
|
mkdirSync2(WORKER_PID_DIR, { recursive: true });
|
|
423
487
|
const reservationId = `res-${process.pid}-${Date.now()}`;
|
|
424
|
-
const reservationPath =
|
|
425
|
-
|
|
488
|
+
const reservationPath = path4.join(WORKER_PID_DIR, `${reservationId}.pid`);
|
|
489
|
+
writeFileSync3(reservationPath, String(process.pid));
|
|
426
490
|
const files = readdirSync2(WORKER_PID_DIR);
|
|
427
491
|
let alive = 0;
|
|
428
492
|
for (const f of files) {
|
|
@@ -439,20 +503,20 @@ function tryAcquireWorkerSlot() {
|
|
|
439
503
|
alive++;
|
|
440
504
|
} catch {
|
|
441
505
|
try {
|
|
442
|
-
|
|
506
|
+
unlinkSync3(path4.join(WORKER_PID_DIR, f));
|
|
443
507
|
} catch {
|
|
444
508
|
}
|
|
445
509
|
}
|
|
446
510
|
}
|
|
447
511
|
if (alive > MAX_CONCURRENT_WORKERS) {
|
|
448
512
|
try {
|
|
449
|
-
|
|
513
|
+
unlinkSync3(reservationPath);
|
|
450
514
|
} catch {
|
|
451
515
|
}
|
|
452
516
|
return false;
|
|
453
517
|
}
|
|
454
518
|
try {
|
|
455
|
-
|
|
519
|
+
unlinkSync3(reservationPath);
|
|
456
520
|
} catch {
|
|
457
521
|
}
|
|
458
522
|
return true;
|
|
@@ -463,11 +527,11 @@ function tryAcquireWorkerSlot() {
|
|
|
463
527
|
function registerWorkerPid(pid) {
|
|
464
528
|
try {
|
|
465
529
|
mkdirSync2(WORKER_PID_DIR, { recursive: true });
|
|
466
|
-
|
|
530
|
+
writeFileSync3(path4.join(WORKER_PID_DIR, `worker-${pid}.pid`), String(pid));
|
|
467
531
|
} catch {
|
|
468
532
|
}
|
|
469
533
|
}
|
|
470
|
-
var BACKFILL_LOCK =
|
|
534
|
+
var BACKFILL_LOCK = path4.join(WORKER_PID_DIR, "backfill.lock");
|
|
471
535
|
|
|
472
536
|
// src/adapters/claude/hooks/ingest.ts
|
|
473
537
|
if (!process.env.AGENT_ID) {
|
|
@@ -477,7 +541,7 @@ if (!process.env.AGENT_ID) {
|
|
|
477
541
|
if (!loadConfigSync().autoIngestion) {
|
|
478
542
|
process.exit(0);
|
|
479
543
|
}
|
|
480
|
-
var WORKER_LOG_PATH =
|
|
544
|
+
var WORKER_LOG_PATH = path5.join(EXE_AI_DIR, "workers.log");
|
|
481
545
|
function openWorkerLog() {
|
|
482
546
|
try {
|
|
483
547
|
return openSync(WORKER_LOG_PATH, "a");
|
|
@@ -489,13 +553,13 @@ var ALLOWED_TOOL_RE = /^(Bash|Edit|Write|Read|Glob|Grep|Agent|mcp__.*)$/;
|
|
|
489
553
|
var WRITE_TOOL_RE = /^(Bash|Edit|Write)$/;
|
|
490
554
|
var SUMMARY_INTERVAL = 25;
|
|
491
555
|
var MIN_WRITES_FOR_SUMMARY = 3;
|
|
492
|
-
var COUNTER_DIR =
|
|
556
|
+
var COUNTER_DIR = path5.join(EXE_AI_DIR, "session-cache");
|
|
493
557
|
function getCounterPath(sessionId) {
|
|
494
|
-
return
|
|
558
|
+
return path5.join(COUNTER_DIR, `counter-${sessionId}.json`);
|
|
495
559
|
}
|
|
496
560
|
function loadCounter(sessionId) {
|
|
497
561
|
try {
|
|
498
|
-
const raw =
|
|
562
|
+
const raw = readFileSync4(getCounterPath(sessionId), "utf8");
|
|
499
563
|
return JSON.parse(raw);
|
|
500
564
|
} catch {
|
|
501
565
|
return { total: 0, writes: 0, pipelineWrites: 0, lastSummaryAt: 0, pipelineDetected: false };
|
|
@@ -504,7 +568,7 @@ function loadCounter(sessionId) {
|
|
|
504
568
|
function saveCounter(sessionId, counter) {
|
|
505
569
|
try {
|
|
506
570
|
mkdirSync3(COUNTER_DIR, { recursive: true });
|
|
507
|
-
|
|
571
|
+
writeFileSync4(getCounterPath(sessionId), JSON.stringify(counter));
|
|
508
572
|
} catch {
|
|
509
573
|
}
|
|
510
574
|
}
|
|
@@ -542,14 +606,15 @@ Do NOT read, write, or modify files in another employee's folder.`
|
|
|
542
606
|
}
|
|
543
607
|
if (/^(Read|Glob|Grep|Bash)$/.test(data.tool_name) && agent.agentRole === "COO") {
|
|
544
608
|
const target = data.tool_input?.file_path ?? data.tool_input?.path ?? data.tool_input?.pattern ?? String(data.tool_input?.command ?? "");
|
|
545
|
-
|
|
609
|
+
const coordinatorName = getCoordinatorName();
|
|
610
|
+
if (new RegExp(`exe/(${coordinatorName}|exe)/`).test(target)) {
|
|
546
611
|
const warning = JSON.stringify({
|
|
547
612
|
hookSpecificOutput: {
|
|
548
613
|
hookEventName: "PostToolUse",
|
|
549
614
|
additionalContext: `## Review Count Warning
|
|
550
|
-
WARNING:
|
|
615
|
+
WARNING: coordinator review folders may contain stale done review files. NEVER count files there to determine review counts.
|
|
551
616
|
The boot brief has the correct open review count from the DB. Use that number, not filesystem counts.
|
|
552
|
-
Open reviews are tracked in the tasks table
|
|
617
|
+
Open reviews are tracked in the tasks table by status and reviewer assignment.`
|
|
553
618
|
}
|
|
554
619
|
});
|
|
555
620
|
process.stdout.write(warning);
|
|
@@ -579,14 +644,14 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
579
644
|
const classification = classifyError(errorText);
|
|
580
645
|
if (classification === "system" && data.session_id) {
|
|
581
646
|
const fp = errorFingerprint(data.tool_name, errorText);
|
|
582
|
-
const fpFilePath =
|
|
647
|
+
const fpFilePath = path5.join(COUNTER_DIR, `bug-fingerprints-${data.session_id}.json`);
|
|
583
648
|
let fpData = {
|
|
584
649
|
seen: {},
|
|
585
650
|
taskCount: 0,
|
|
586
651
|
lastTaskAt: ""
|
|
587
652
|
};
|
|
588
653
|
try {
|
|
589
|
-
fpData = JSON.parse(
|
|
654
|
+
fpData = JSON.parse(readFileSync4(fpFilePath, "utf8"));
|
|
590
655
|
} catch {
|
|
591
656
|
}
|
|
592
657
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -604,13 +669,13 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
604
669
|
fpData.seen[fp] = { count: 1, firstAt: now, lastAt: now };
|
|
605
670
|
fpData.taskCount++;
|
|
606
671
|
fpData.lastTaskAt = now;
|
|
607
|
-
const bugWorkerPath =
|
|
608
|
-
|
|
672
|
+
const bugWorkerPath = path5.resolve(
|
|
673
|
+
path5.dirname(fileURLToPath(import.meta.url)),
|
|
609
674
|
"bug-report-worker.js"
|
|
610
675
|
);
|
|
611
|
-
if (
|
|
676
|
+
if (existsSync4(bugWorkerPath) && tryAcquireWorkerSlot()) {
|
|
612
677
|
const stderrFd2 = openWorkerLog();
|
|
613
|
-
const projectName = process.cwd().split(
|
|
678
|
+
const projectName = process.cwd().split(path5.sep).pop() ?? "unknown";
|
|
614
679
|
const bugToolInput = data.tool_input ?? {};
|
|
615
680
|
const bugWorker = spawn(process.execPath, [bugWorkerPath], {
|
|
616
681
|
detached: true,
|
|
@@ -639,7 +704,7 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
639
704
|
}
|
|
640
705
|
try {
|
|
641
706
|
mkdirSync3(COUNTER_DIR, { recursive: true });
|
|
642
|
-
|
|
707
|
+
writeFileSync4(fpFilePath, JSON.stringify(fpData));
|
|
643
708
|
} catch {
|
|
644
709
|
}
|
|
645
710
|
}
|
|
@@ -656,11 +721,11 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
656
721
|
}
|
|
657
722
|
const callsSinceLastSummary = counter.total - counter.lastSummaryAt;
|
|
658
723
|
if (callsSinceLastSummary >= SUMMARY_INTERVAL && counter.writes >= MIN_WRITES_FOR_SUMMARY) {
|
|
659
|
-
const summaryWorkerPath =
|
|
660
|
-
|
|
724
|
+
const summaryWorkerPath = path5.resolve(
|
|
725
|
+
path5.dirname(fileURLToPath(import.meta.url)),
|
|
661
726
|
"summary-worker.js"
|
|
662
727
|
);
|
|
663
|
-
if (
|
|
728
|
+
if (existsSync4(summaryWorkerPath) && tryAcquireWorkerSlot()) {
|
|
664
729
|
const stderrFd2 = openWorkerLog();
|
|
665
730
|
const summaryWorker = spawn(process.execPath, [summaryWorkerPath], {
|
|
666
731
|
detached: true,
|
|
@@ -702,13 +767,13 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
702
767
|
const bashOutput = typeof data.tool_response === "string" ? data.tool_response : JSON.stringify(data.tool_response ?? "");
|
|
703
768
|
const commitMatch = bashOutput.match(/\[(\S+)\s+([a-f0-9]{7,40})\]\s+(.+)/);
|
|
704
769
|
if (commitMatch) {
|
|
705
|
-
const commitWorkerPath =
|
|
706
|
-
|
|
770
|
+
const commitWorkerPath = path5.resolve(
|
|
771
|
+
path5.dirname(fileURLToPath(import.meta.url)),
|
|
707
772
|
"commit-complete.js"
|
|
708
773
|
);
|
|
709
|
-
if (
|
|
774
|
+
if (existsSync4(commitWorkerPath) && tryAcquireWorkerSlot()) {
|
|
710
775
|
const stderrFd2 = openWorkerLog();
|
|
711
|
-
const projectName = process.cwd().split(
|
|
776
|
+
const projectName = process.cwd().split(path5.sep).pop() ?? "unknown";
|
|
712
777
|
const commitWorker = spawn(process.execPath, [commitWorkerPath], {
|
|
713
778
|
detached: true,
|
|
714
779
|
stdio: ["ignore", "ignore", stderrFd2],
|
|
@@ -732,8 +797,8 @@ Your output files must start with: exe/output/${agent.agentId}-`
|
|
|
732
797
|
if (!ALLOWED_TOOL_RE.test(data.tool_name)) {
|
|
733
798
|
process.exit(0);
|
|
734
799
|
}
|
|
735
|
-
const workerPath =
|
|
736
|
-
|
|
800
|
+
const workerPath = path5.resolve(
|
|
801
|
+
path5.dirname(fileURLToPath(import.meta.url)),
|
|
737
802
|
"ingest-worker.js"
|
|
738
803
|
);
|
|
739
804
|
if (!tryAcquireWorkerSlot()) {
|