@askexenow/exe-os 0.8.32 → 0.8.36
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 +332 -348
- package/dist/bin/backfill-responses.js +72 -12
- package/dist/bin/backfill-vectors.js +72 -12
- package/dist/bin/cleanup-stale-review-tasks.js +63 -3
- package/dist/bin/cli.js +1518 -1122
- package/dist/bin/exe-agent.js +4 -4
- package/dist/bin/exe-assign.js +80 -18
- package/dist/bin/exe-boot.js +408 -89
- package/dist/bin/exe-call.js +83 -24
- package/dist/bin/exe-dispatch.js +18 -10
- package/dist/bin/exe-doctor.js +63 -3
- package/dist/bin/exe-export-behaviors.js +64 -3
- package/dist/bin/exe-forget.js +69 -4
- package/dist/bin/exe-gateway.js +121 -36
- package/dist/bin/exe-heartbeat.js +77 -13
- package/dist/bin/exe-kill.js +64 -3
- package/dist/bin/exe-launch-agent.js +162 -35
- package/dist/bin/exe-link.js +946 -0
- package/dist/bin/exe-new-employee.js +121 -36
- package/dist/bin/exe-pending-messages.js +72 -7
- package/dist/bin/exe-pending-notifications.js +63 -3
- package/dist/bin/exe-pending-reviews.js +75 -10
- package/dist/bin/exe-rename.js +1287 -0
- package/dist/bin/exe-review.js +64 -4
- package/dist/bin/exe-search.js +79 -13
- package/dist/bin/exe-session-cleanup.js +91 -26
- package/dist/bin/exe-status.js +64 -4
- package/dist/bin/exe-team.js +64 -4
- package/dist/bin/git-sweep.js +71 -4
- package/dist/bin/graph-backfill.js +64 -3
- package/dist/bin/graph-export.js +64 -3
- package/dist/bin/install.js +3 -3
- package/dist/bin/scan-tasks.js +71 -4
- package/dist/bin/setup.js +156 -38
- package/dist/bin/shard-migrate.js +64 -3
- package/dist/bin/wiki-sync.js +64 -3
- package/dist/gateway/index.js +122 -37
- package/dist/hooks/bug-report-worker.js +209 -23
- package/dist/hooks/commit-complete.js +71 -4
- package/dist/hooks/error-recall.js +79 -13
- package/dist/hooks/ingest-worker.js +129 -43
- package/dist/hooks/instructions-loaded.js +71 -4
- package/dist/hooks/notification.js +71 -4
- package/dist/hooks/post-compact.js +71 -4
- package/dist/hooks/pre-compact.js +71 -4
- package/dist/hooks/pre-tool-use.js +413 -194
- package/dist/hooks/prompt-ingest-worker.js +82 -22
- package/dist/hooks/prompt-submit.js +103 -37
- package/dist/hooks/response-ingest-worker.js +87 -22
- package/dist/hooks/session-end.js +71 -4
- package/dist/hooks/session-start.js +79 -13
- package/dist/hooks/stop.js +71 -4
- package/dist/hooks/subagent-stop.js +71 -4
- package/dist/hooks/summary-worker.js +303 -50
- package/dist/index.js +134 -46
- package/dist/lib/cloud-sync.js +209 -15
- package/dist/lib/consolidation.js +4 -4
- package/dist/lib/database.js +64 -2
- package/dist/lib/device-registry.js +70 -3
- package/dist/lib/employee-templates.js +48 -22
- package/dist/lib/employees.js +34 -1
- package/dist/lib/exe-daemon.js +136 -53
- package/dist/lib/hybrid-search.js +79 -13
- package/dist/lib/identity-templates.js +57 -6
- package/dist/lib/identity.js +3 -3
- package/dist/lib/messaging.js +22 -14
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +63 -3
- package/dist/lib/skill-learning.js +3 -3
- package/dist/lib/status-brief.js +63 -5
- package/dist/lib/store.js +64 -3
- package/dist/lib/task-router.js +4 -2
- package/dist/lib/tasks.js +48 -21
- package/dist/lib/tmux-routing.js +47 -20
- package/dist/mcp/server.js +727 -58
- package/dist/mcp/tools/complete-reminder.js +3 -3
- package/dist/mcp/tools/create-reminder.js +3 -3
- package/dist/mcp/tools/create-task.js +151 -24
- package/dist/mcp/tools/deactivate-behavior.js +3 -3
- package/dist/mcp/tools/list-reminders.js +3 -3
- package/dist/mcp/tools/list-tasks.js +17 -8
- package/dist/mcp/tools/send-message.js +24 -16
- package/dist/mcp/tools/update-task.js +25 -16
- package/dist/runtime/index.js +112 -24
- package/dist/tui/App.js +139 -36
- package/package.json +6 -2
- package/src/commands/exe/rename.md +12 -0
package/dist/gateway/index.js
CHANGED
|
@@ -280,12 +280,68 @@ var init_crm_bridge = __esm({
|
|
|
280
280
|
}
|
|
281
281
|
});
|
|
282
282
|
|
|
283
|
+
// src/lib/db-retry.ts
|
|
284
|
+
function isBusyError(err) {
|
|
285
|
+
if (err instanceof Error) {
|
|
286
|
+
const msg = err.message.toLowerCase();
|
|
287
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
function delay(ms) {
|
|
292
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
293
|
+
}
|
|
294
|
+
async function retryOnBusy(fn, label) {
|
|
295
|
+
let lastError;
|
|
296
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
297
|
+
try {
|
|
298
|
+
return await fn();
|
|
299
|
+
} catch (err) {
|
|
300
|
+
lastError = err;
|
|
301
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES) {
|
|
302
|
+
throw err;
|
|
303
|
+
}
|
|
304
|
+
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
305
|
+
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
306
|
+
process.stderr.write(
|
|
307
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES} \u2014 waiting ${backoff + jitter}ms
|
|
308
|
+
`
|
|
309
|
+
);
|
|
310
|
+
await delay(backoff + jitter);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
throw lastError;
|
|
314
|
+
}
|
|
315
|
+
function wrapWithRetry(client) {
|
|
316
|
+
return new Proxy(client, {
|
|
317
|
+
get(target, prop, receiver) {
|
|
318
|
+
if (prop === "execute") {
|
|
319
|
+
return (sql) => retryOnBusy(() => target.execute(sql), "execute");
|
|
320
|
+
}
|
|
321
|
+
if (prop === "batch") {
|
|
322
|
+
return (stmts) => retryOnBusy(() => target.batch(stmts), "batch");
|
|
323
|
+
}
|
|
324
|
+
return Reflect.get(target, prop, receiver);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
var MAX_RETRIES, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
329
|
+
var init_db_retry = __esm({
|
|
330
|
+
"src/lib/db-retry.ts"() {
|
|
331
|
+
"use strict";
|
|
332
|
+
MAX_RETRIES = 3;
|
|
333
|
+
BASE_DELAY_MS = 200;
|
|
334
|
+
MAX_JITTER_MS = 300;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
283
338
|
// src/lib/database.ts
|
|
284
339
|
import { createClient } from "@libsql/client";
|
|
285
340
|
async function initDatabase(config2) {
|
|
286
341
|
if (_client) {
|
|
287
342
|
_client.close();
|
|
288
343
|
_client = null;
|
|
344
|
+
_resilientClient = null;
|
|
289
345
|
}
|
|
290
346
|
const opts = {
|
|
291
347
|
url: `file:${config2.dbPath}`
|
|
@@ -294,17 +350,24 @@ async function initDatabase(config2) {
|
|
|
294
350
|
opts.encryptionKey = config2.encryptionKey;
|
|
295
351
|
}
|
|
296
352
|
_client = createClient(opts);
|
|
353
|
+
_resilientClient = wrapWithRetry(_client);
|
|
297
354
|
}
|
|
298
355
|
function getClient() {
|
|
356
|
+
if (!_resilientClient) {
|
|
357
|
+
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
358
|
+
}
|
|
359
|
+
return _resilientClient;
|
|
360
|
+
}
|
|
361
|
+
function getRawClient() {
|
|
299
362
|
if (!_client) {
|
|
300
363
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
301
364
|
}
|
|
302
365
|
return _client;
|
|
303
366
|
}
|
|
304
367
|
async function ensureSchema() {
|
|
305
|
-
const client =
|
|
368
|
+
const client = getRawClient();
|
|
306
369
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
307
|
-
await client.execute("PRAGMA busy_timeout =
|
|
370
|
+
await client.execute("PRAGMA busy_timeout = 30000");
|
|
308
371
|
try {
|
|
309
372
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
310
373
|
} catch {
|
|
@@ -1097,13 +1160,16 @@ async function disposeDatabase() {
|
|
|
1097
1160
|
if (_client) {
|
|
1098
1161
|
_client.close();
|
|
1099
1162
|
_client = null;
|
|
1163
|
+
_resilientClient = null;
|
|
1100
1164
|
}
|
|
1101
1165
|
}
|
|
1102
|
-
var _client, initTurso, disposeTurso;
|
|
1166
|
+
var _client, _resilientClient, initTurso, disposeTurso;
|
|
1103
1167
|
var init_database = __esm({
|
|
1104
1168
|
"src/lib/database.ts"() {
|
|
1105
1169
|
"use strict";
|
|
1170
|
+
init_db_retry();
|
|
1106
1171
|
_client = null;
|
|
1172
|
+
_resilientClient = null;
|
|
1107
1173
|
initTurso = initDatabase;
|
|
1108
1174
|
disposeTurso = disposeDatabase;
|
|
1109
1175
|
}
|
|
@@ -1538,11 +1604,11 @@ async function connectEmbedDaemon() {
|
|
|
1538
1604
|
}
|
|
1539
1605
|
}
|
|
1540
1606
|
const start = Date.now();
|
|
1541
|
-
let
|
|
1607
|
+
let delay2 = 100;
|
|
1542
1608
|
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1543
|
-
await new Promise((r) => setTimeout(r,
|
|
1609
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
1544
1610
|
if (await connectToSocket()) return true;
|
|
1545
|
-
|
|
1611
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
1546
1612
|
}
|
|
1547
1613
|
return false;
|
|
1548
1614
|
}
|
|
@@ -1634,11 +1700,11 @@ async function embedViaClient(text, priority = "high") {
|
|
|
1634
1700
|
`);
|
|
1635
1701
|
killAndRespawnDaemon();
|
|
1636
1702
|
const start = Date.now();
|
|
1637
|
-
let
|
|
1703
|
+
let delay2 = 200;
|
|
1638
1704
|
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1639
|
-
await new Promise((r) => setTimeout(r,
|
|
1705
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
1640
1706
|
if (await connectToSocket()) break;
|
|
1641
|
-
|
|
1707
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
1642
1708
|
}
|
|
1643
1709
|
if (!_connected) return null;
|
|
1644
1710
|
}
|
|
@@ -1650,11 +1716,11 @@ async function embedViaClient(text, priority = "high") {
|
|
|
1650
1716
|
`);
|
|
1651
1717
|
killAndRespawnDaemon();
|
|
1652
1718
|
const start = Date.now();
|
|
1653
|
-
let
|
|
1719
|
+
let delay2 = 200;
|
|
1654
1720
|
while (Date.now() - start < CONNECT_TIMEOUT_MS) {
|
|
1655
|
-
await new Promise((r) => setTimeout(r,
|
|
1721
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
1656
1722
|
if (await connectToSocket()) break;
|
|
1657
|
-
|
|
1723
|
+
delay2 = Math.min(delay2 * 2, 3e3);
|
|
1658
1724
|
}
|
|
1659
1725
|
if (!_connected) return null;
|
|
1660
1726
|
const retry = await sendRequest([text], priority);
|
|
@@ -1872,7 +1938,7 @@ function listShards() {
|
|
|
1872
1938
|
}
|
|
1873
1939
|
async function ensureShardSchema(client) {
|
|
1874
1940
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
1875
|
-
await client.execute("PRAGMA busy_timeout =
|
|
1941
|
+
await client.execute("PRAGMA busy_timeout = 30000");
|
|
1876
1942
|
try {
|
|
1877
1943
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
1878
1944
|
} catch {
|
|
@@ -2969,20 +3035,38 @@ var init_intercom_queue = __esm({
|
|
|
2969
3035
|
|
|
2970
3036
|
// src/lib/employees.ts
|
|
2971
3037
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
2972
|
-
import { existsSync as existsSync7, symlinkSync, readlinkSync } from "fs";
|
|
3038
|
+
import { existsSync as existsSync7, symlinkSync, readlinkSync, readFileSync as readFileSync6 } from "fs";
|
|
2973
3039
|
import { execSync as execSync3 } from "child_process";
|
|
2974
3040
|
import path8 from "path";
|
|
2975
|
-
|
|
3041
|
+
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
3042
|
+
if (!existsSync7(employeesPath)) return [];
|
|
3043
|
+
try {
|
|
3044
|
+
return JSON.parse(readFileSync6(employeesPath, "utf-8"));
|
|
3045
|
+
} catch {
|
|
3046
|
+
return [];
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
function getEmployee(employees, name) {
|
|
3050
|
+
return employees.find((e) => e.name.toLowerCase() === name.toLowerCase());
|
|
3051
|
+
}
|
|
3052
|
+
function isMultiInstance(agentName, employees) {
|
|
3053
|
+
const roster = employees ?? loadEmployeesSync();
|
|
3054
|
+
const emp = getEmployee(roster, agentName);
|
|
3055
|
+
if (!emp) return false;
|
|
3056
|
+
return MULTI_INSTANCE_ROLES.has(emp.role.toLowerCase());
|
|
3057
|
+
}
|
|
3058
|
+
var EMPLOYEES_PATH, MULTI_INSTANCE_ROLES;
|
|
2976
3059
|
var init_employees = __esm({
|
|
2977
3060
|
"src/lib/employees.ts"() {
|
|
2978
3061
|
"use strict";
|
|
2979
3062
|
init_config();
|
|
2980
3063
|
EMPLOYEES_PATH = path8.join(EXE_AI_DIR, "exe-employees.json");
|
|
3064
|
+
MULTI_INSTANCE_ROLES = /* @__PURE__ */ new Set(["principal engineer", "content production specialist", "staff code reviewer"]);
|
|
2981
3065
|
}
|
|
2982
3066
|
});
|
|
2983
3067
|
|
|
2984
3068
|
// src/lib/license.ts
|
|
2985
|
-
import { readFileSync as
|
|
3069
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
|
|
2986
3070
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
2987
3071
|
import path9 from "path";
|
|
2988
3072
|
import { jwtVerify, importSPKI } from "jose";
|
|
@@ -3005,12 +3089,12 @@ var init_license = __esm({
|
|
|
3005
3089
|
});
|
|
3006
3090
|
|
|
3007
3091
|
// src/lib/plan-limits.ts
|
|
3008
|
-
import { readFileSync as
|
|
3092
|
+
import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
|
|
3009
3093
|
import path10 from "path";
|
|
3010
3094
|
function getLicenseSync() {
|
|
3011
3095
|
try {
|
|
3012
3096
|
if (!existsSync9(CACHE_PATH2)) return freeLicense();
|
|
3013
|
-
const raw = JSON.parse(
|
|
3097
|
+
const raw = JSON.parse(readFileSync8(CACHE_PATH2, "utf8"));
|
|
3014
3098
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
3015
3099
|
const parts = raw.token.split(".");
|
|
3016
3100
|
if (parts.length !== 3) return freeLicense();
|
|
@@ -3049,7 +3133,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
3049
3133
|
let count = 0;
|
|
3050
3134
|
try {
|
|
3051
3135
|
if (existsSync9(filePath)) {
|
|
3052
|
-
const raw =
|
|
3136
|
+
const raw = readFileSync8(filePath, "utf8");
|
|
3053
3137
|
const employees = JSON.parse(raw);
|
|
3054
3138
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
3055
3139
|
}
|
|
@@ -3084,7 +3168,7 @@ var init_plan_limits = __esm({
|
|
|
3084
3168
|
|
|
3085
3169
|
// src/lib/tmux-routing.ts
|
|
3086
3170
|
import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
|
|
3087
|
-
import { readFileSync as
|
|
3171
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, mkdirSync as mkdirSync6, existsSync as existsSync10, appendFileSync } from "fs";
|
|
3088
3172
|
import path11 from "path";
|
|
3089
3173
|
import os4 from "os";
|
|
3090
3174
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -3133,7 +3217,7 @@ function extractRootExe(name) {
|
|
|
3133
3217
|
}
|
|
3134
3218
|
function getParentExe(sessionKey) {
|
|
3135
3219
|
try {
|
|
3136
|
-
const data = JSON.parse(
|
|
3220
|
+
const data = JSON.parse(readFileSync9(path11.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
3137
3221
|
return data.parentExe || null;
|
|
3138
3222
|
} catch {
|
|
3139
3223
|
return null;
|
|
@@ -3141,7 +3225,7 @@ function getParentExe(sessionKey) {
|
|
|
3141
3225
|
}
|
|
3142
3226
|
function getDispatchedBy(sessionKey) {
|
|
3143
3227
|
try {
|
|
3144
|
-
const data = JSON.parse(
|
|
3228
|
+
const data = JSON.parse(readFileSync9(
|
|
3145
3229
|
path11.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
|
|
3146
3230
|
"utf8"
|
|
3147
3231
|
));
|
|
@@ -3178,7 +3262,7 @@ function findFreeInstance(employeeName, exeSession, maxInstances = 10, isAlive =
|
|
|
3178
3262
|
function readDebounceState() {
|
|
3179
3263
|
try {
|
|
3180
3264
|
if (!existsSync10(DEBOUNCE_FILE)) return {};
|
|
3181
|
-
return JSON.parse(
|
|
3265
|
+
return JSON.parse(readFileSync9(DEBOUNCE_FILE, "utf8"));
|
|
3182
3266
|
} catch {
|
|
3183
3267
|
return {};
|
|
3184
3268
|
}
|
|
@@ -3374,7 +3458,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3374
3458
|
const claudeJsonPath = path11.join(os4.homedir(), ".claude.json");
|
|
3375
3459
|
let claudeJson = {};
|
|
3376
3460
|
try {
|
|
3377
|
-
claudeJson = JSON.parse(
|
|
3461
|
+
claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
|
|
3378
3462
|
} catch {
|
|
3379
3463
|
}
|
|
3380
3464
|
if (!claudeJson.projects) claudeJson.projects = {};
|
|
@@ -3392,7 +3476,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3392
3476
|
const settingsPath = path11.join(projSettingsDir, "settings.json");
|
|
3393
3477
|
let settings = {};
|
|
3394
3478
|
try {
|
|
3395
|
-
settings = JSON.parse(
|
|
3479
|
+
settings = JSON.parse(readFileSync9(settingsPath, "utf8"));
|
|
3396
3480
|
} catch {
|
|
3397
3481
|
}
|
|
3398
3482
|
const perms = settings.permissions ?? {};
|
|
@@ -3719,7 +3803,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
3719
3803
|
return true;
|
|
3720
3804
|
} catch {
|
|
3721
3805
|
const newRetryCount = msg.retryCount + 1;
|
|
3722
|
-
if (newRetryCount >=
|
|
3806
|
+
if (newRetryCount >= MAX_RETRIES2) {
|
|
3723
3807
|
await markFailed(messageId, "session unavailable after 10 retries");
|
|
3724
3808
|
} else {
|
|
3725
3809
|
await client.execute({
|
|
@@ -3808,7 +3892,7 @@ async function retryPendingMessages() {
|
|
|
3808
3892
|
sql: `SELECT * FROM messages
|
|
3809
3893
|
WHERE status = 'pending' AND retry_count < ?
|
|
3810
3894
|
ORDER BY id`,
|
|
3811
|
-
args: [
|
|
3895
|
+
args: [MAX_RETRIES2]
|
|
3812
3896
|
});
|
|
3813
3897
|
let delivered = 0;
|
|
3814
3898
|
for (const row of result.rows) {
|
|
@@ -3821,13 +3905,13 @@ async function retryPendingMessages() {
|
|
|
3821
3905
|
}
|
|
3822
3906
|
return delivered;
|
|
3823
3907
|
}
|
|
3824
|
-
var
|
|
3908
|
+
var MAX_RETRIES2, _wsClientSend;
|
|
3825
3909
|
var init_messaging = __esm({
|
|
3826
3910
|
"src/lib/messaging.ts"() {
|
|
3827
3911
|
"use strict";
|
|
3828
3912
|
init_database();
|
|
3829
3913
|
init_tmux_routing();
|
|
3830
|
-
|
|
3914
|
+
MAX_RETRIES2 = 10;
|
|
3831
3915
|
_wsClientSend = null;
|
|
3832
3916
|
}
|
|
3833
3917
|
});
|
|
@@ -3837,7 +3921,7 @@ import crypto4 from "crypto";
|
|
|
3837
3921
|
import path12 from "path";
|
|
3838
3922
|
import os5 from "os";
|
|
3839
3923
|
import {
|
|
3840
|
-
readFileSync as
|
|
3924
|
+
readFileSync as readFileSync10,
|
|
3841
3925
|
readdirSync,
|
|
3842
3926
|
unlinkSync as unlinkSync2,
|
|
3843
3927
|
existsSync as existsSync11,
|
|
@@ -3889,7 +3973,7 @@ import crypto5 from "crypto";
|
|
|
3889
3973
|
import path13 from "path";
|
|
3890
3974
|
import { execSync as execSync5 } from "child_process";
|
|
3891
3975
|
import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
|
|
3892
|
-
import { existsSync as existsSync12, readFileSync as
|
|
3976
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "fs";
|
|
3893
3977
|
async function writeCheckpoint(input) {
|
|
3894
3978
|
const client = getClient();
|
|
3895
3979
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -4266,7 +4350,7 @@ async function ensureGitignoreExe(baseDir) {
|
|
|
4266
4350
|
const gitignorePath = path13.join(baseDir, ".gitignore");
|
|
4267
4351
|
try {
|
|
4268
4352
|
if (existsSync12(gitignorePath)) {
|
|
4269
|
-
const content =
|
|
4353
|
+
const content = readFileSync11(gitignorePath, "utf-8");
|
|
4270
4354
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
4271
4355
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
4272
4356
|
} else {
|
|
@@ -4642,7 +4726,7 @@ async function dispatchTaskToEmployee(input) {
|
|
|
4642
4726
|
} else {
|
|
4643
4727
|
const projectDir = input.projectDir ?? process.cwd();
|
|
4644
4728
|
const result = ensureEmployee(input.assignedTo, exeSession, projectDir, {
|
|
4645
|
-
autoInstance: input.assignedTo
|
|
4729
|
+
autoInstance: isMultiInstance(input.assignedTo)
|
|
4646
4730
|
});
|
|
4647
4731
|
if (result.status === "failed") {
|
|
4648
4732
|
process.stderr.write(
|
|
@@ -4677,6 +4761,7 @@ var init_tasks_notify = __esm({
|
|
|
4677
4761
|
init_session_key();
|
|
4678
4762
|
init_notifications();
|
|
4679
4763
|
init_transport();
|
|
4764
|
+
init_employees();
|
|
4680
4765
|
}
|
|
4681
4766
|
});
|
|
4682
4767
|
|
|
@@ -5232,8 +5317,8 @@ async function retryWithBackoff(fn, config2 = {}) {
|
|
|
5232
5317
|
} catch (err) {
|
|
5233
5318
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
5234
5319
|
if (attempt < maxRetries) {
|
|
5235
|
-
const
|
|
5236
|
-
await new Promise((r) => setTimeout(r,
|
|
5320
|
+
const delay2 = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);
|
|
5321
|
+
await new Promise((r) => setTimeout(r, delay2));
|
|
5237
5322
|
}
|
|
5238
5323
|
}
|
|
5239
5324
|
}
|
|
@@ -8730,7 +8815,7 @@ async function ensureCRMContact(info) {
|
|
|
8730
8815
|
}
|
|
8731
8816
|
|
|
8732
8817
|
// src/automation/trigger-engine.ts
|
|
8733
|
-
import { readFileSync as
|
|
8818
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, existsSync as existsSync14, mkdirSync as mkdirSync8 } from "fs";
|
|
8734
8819
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
8735
8820
|
import path18 from "path";
|
|
8736
8821
|
import os6 from "os";
|
|
@@ -8789,7 +8874,7 @@ function evaluateConditions(conditions, record) {
|
|
|
8789
8874
|
function loadTriggers(project) {
|
|
8790
8875
|
if (!existsSync14(TRIGGERS_PATH)) return [];
|
|
8791
8876
|
try {
|
|
8792
|
-
const raw =
|
|
8877
|
+
const raw = readFileSync12(TRIGGERS_PATH, "utf-8");
|
|
8793
8878
|
const all = JSON.parse(raw);
|
|
8794
8879
|
if (!Array.isArray(all)) return [];
|
|
8795
8880
|
if (project) {
|