@askexenow/exe-os 0.8.39 → 0.8.41
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/cli.js +58 -10
- package/dist/bin/exe-boot.js +75 -16
- package/dist/bin/exe-cloud.js +12 -2
- package/dist/bin/exe-doctor.js +1 -1
- package/dist/bin/exe-gateway.js +48 -2
- package/dist/bin/exe-link.js +35 -11
- package/dist/bin/exe-pending-reviews.js +29 -0
- package/dist/bin/exe-search.js +3 -1
- package/dist/bin/exe-session-cleanup.js +32 -1
- package/dist/bin/exe-settings.js +2 -1
- package/dist/bin/git-sweep.js +1 -1
- package/dist/bin/setup.js +3 -1
- package/dist/gateway/index.js +48 -2
- package/dist/hooks/commit-complete.js +1 -1
- package/dist/hooks/error-recall.js +3 -1
- package/dist/hooks/ingest-worker.js +48 -2
- package/dist/hooks/prompt-ingest-worker.js +3 -1
- package/dist/hooks/prompt-submit.js +33 -2
- package/dist/hooks/response-ingest-worker.js +3 -1
- package/dist/hooks/session-start.js +3 -1
- package/dist/hooks/subagent-stop.js +4 -2
- package/dist/hooks/summary-worker.js +30 -15
- package/dist/index.js +48 -2
- package/dist/lib/cloud-sync.js +22 -9
- package/dist/lib/config.js +2 -0
- package/dist/lib/embedder.js +3 -1
- package/dist/lib/exe-daemon.js +49 -2
- package/dist/lib/hybrid-search.js +3 -1
- package/dist/lib/tasks.js +45 -1
- package/dist/lib/tmux-routing.js +45 -1
- package/dist/mcp/server.js +48 -2
- package/dist/mcp/tools/create-task.js +3 -1
- package/dist/mcp/tools/list-tasks.js +1 -1
- package/dist/mcp/tools/update-task.js +15 -0
- package/dist/runtime/index.js +45 -1
- package/dist/tui/App.js +58 -10
- package/package.json +1 -1
|
@@ -922,6 +922,7 @@ var config_exports = {};
|
|
|
922
922
|
__export(config_exports, {
|
|
923
923
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
924
924
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
925
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
925
926
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
926
927
|
DB_PATH: () => DB_PATH,
|
|
927
928
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -1077,7 +1078,7 @@ async function loadConfigFrom(configPath) {
|
|
|
1077
1078
|
return { ...DEFAULT_CONFIG };
|
|
1078
1079
|
}
|
|
1079
1080
|
}
|
|
1080
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1081
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1081
1082
|
var init_config = __esm({
|
|
1082
1083
|
"src/lib/config.ts"() {
|
|
1083
1084
|
"use strict";
|
|
@@ -1085,6 +1086,7 @@ var init_config = __esm({
|
|
|
1085
1086
|
DB_PATH = path2.join(EXE_AI_DIR, "memories.db");
|
|
1086
1087
|
MODELS_DIR = path2.join(EXE_AI_DIR, "models");
|
|
1087
1088
|
CONFIG_PATH = path2.join(EXE_AI_DIR, "config.json");
|
|
1089
|
+
COO_AGENT_NAME = "exe";
|
|
1088
1090
|
LEGACY_LANCE_PATH = path2.join(EXE_AI_DIR, "local.lance");
|
|
1089
1091
|
CURRENT_CONFIG_VERSION = 1;
|
|
1090
1092
|
DEFAULT_CONFIG = {
|
|
@@ -2537,6 +2539,7 @@ var init_tmux_routing = __esm({
|
|
|
2537
2539
|
// src/lib/tasks-review.ts
|
|
2538
2540
|
var tasks_review_exports = {};
|
|
2539
2541
|
__export(tasks_review_exports, {
|
|
2542
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
2540
2543
|
cleanupReviewFile: () => cleanupReviewFile,
|
|
2541
2544
|
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
2542
2545
|
countPendingReviews: () => countPendingReviews,
|
|
@@ -2573,6 +2576,34 @@ async function listPendingReviews(limit) {
|
|
|
2573
2576
|
});
|
|
2574
2577
|
return result.rows;
|
|
2575
2578
|
}
|
|
2579
|
+
async function cleanupOrphanedReviews() {
|
|
2580
|
+
const client = getClient();
|
|
2581
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2582
|
+
const r1 = await client.execute({
|
|
2583
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
2584
|
+
WHERE status = 'needs_review'
|
|
2585
|
+
AND assigned_by = 'system'
|
|
2586
|
+
AND title LIKE 'Review:%'
|
|
2587
|
+
AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
|
|
2588
|
+
args: [now]
|
|
2589
|
+
});
|
|
2590
|
+
const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
|
|
2591
|
+
const r2 = await client.execute({
|
|
2592
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
2593
|
+
WHERE status = 'needs_review'
|
|
2594
|
+
AND result IS NOT NULL
|
|
2595
|
+
AND updated_at < ?`,
|
|
2596
|
+
args: [now, staleThreshold]
|
|
2597
|
+
});
|
|
2598
|
+
const total = r1.rowsAffected + r2.rowsAffected;
|
|
2599
|
+
if (total > 0) {
|
|
2600
|
+
process.stderr.write(
|
|
2601
|
+
`[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
|
|
2602
|
+
`
|
|
2603
|
+
);
|
|
2604
|
+
}
|
|
2605
|
+
return total;
|
|
2606
|
+
}
|
|
2576
2607
|
function getReviewChecklist(role, agent, taskSlug) {
|
|
2577
2608
|
const roleLower = role.toLowerCase();
|
|
2578
2609
|
if (roleLower.includes("engineer") || roleLower === "principal engineer") {
|
package/dist/bin/exe-settings.js
CHANGED
|
@@ -208,7 +208,8 @@ function isMainModule(importMetaUrl) {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// src/lib/cloud-sync.ts
|
|
211
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync5, readdirSync, mkdirSync as mkdirSync2, appendFileSync, unlinkSync } from "fs";
|
|
211
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync5, readdirSync, mkdirSync as mkdirSync2, appendFileSync, unlinkSync, openSync, closeSync } from "fs";
|
|
212
|
+
import crypto2 from "crypto";
|
|
212
213
|
import path5 from "path";
|
|
213
214
|
import { homedir } from "os";
|
|
214
215
|
|
package/dist/bin/git-sweep.js
CHANGED
|
@@ -2109,7 +2109,7 @@ async function listTasks(input) {
|
|
|
2109
2109
|
}
|
|
2110
2110
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2111
2111
|
const result = await client.execute({
|
|
2112
|
-
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
|
|
2112
|
+
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
|
|
2113
2113
|
args: args2
|
|
2114
2114
|
});
|
|
2115
2115
|
return result.rows.map((r) => ({
|
package/dist/bin/setup.js
CHANGED
|
@@ -20,6 +20,7 @@ var config_exports = {};
|
|
|
20
20
|
__export(config_exports, {
|
|
21
21
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
22
22
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
23
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
23
24
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
24
25
|
DB_PATH: () => DB_PATH,
|
|
25
26
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -175,7 +176,7 @@ async function loadConfigFrom(configPath) {
|
|
|
175
176
|
return { ...DEFAULT_CONFIG };
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
179
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
179
180
|
var init_config = __esm({
|
|
180
181
|
"src/lib/config.ts"() {
|
|
181
182
|
"use strict";
|
|
@@ -183,6 +184,7 @@ var init_config = __esm({
|
|
|
183
184
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
184
185
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
185
186
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
187
|
+
COO_AGENT_NAME = "exe";
|
|
186
188
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
187
189
|
CURRENT_CONFIG_VERSION = 1;
|
|
188
190
|
DEFAULT_CONFIG = {
|
package/dist/gateway/index.js
CHANGED
|
@@ -1185,6 +1185,7 @@ var config_exports = {};
|
|
|
1185
1185
|
__export(config_exports, {
|
|
1186
1186
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
1187
1187
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
1188
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
1188
1189
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
1189
1190
|
DB_PATH: () => DB_PATH,
|
|
1190
1191
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -1340,7 +1341,7 @@ async function loadConfigFrom(configPath) {
|
|
|
1340
1341
|
return { ...DEFAULT_CONFIG };
|
|
1341
1342
|
}
|
|
1342
1343
|
}
|
|
1343
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1344
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1344
1345
|
var init_config = __esm({
|
|
1345
1346
|
"src/lib/config.ts"() {
|
|
1346
1347
|
"use strict";
|
|
@@ -1348,6 +1349,7 @@ var init_config = __esm({
|
|
|
1348
1349
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
1349
1350
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
1350
1351
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
1352
|
+
COO_AGENT_NAME = "exe";
|
|
1351
1353
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
1352
1354
|
CURRENT_CONFIG_VERSION = 1;
|
|
1353
1355
|
DEFAULT_CONFIG = {
|
|
@@ -4281,7 +4283,7 @@ async function listTasks(input) {
|
|
|
4281
4283
|
}
|
|
4282
4284
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
4283
4285
|
const result = await client.execute({
|
|
4284
|
-
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
|
|
4286
|
+
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
|
|
4285
4287
|
args
|
|
4286
4288
|
});
|
|
4287
4289
|
return result.rows.map((r) => ({
|
|
@@ -4502,6 +4504,34 @@ async function listPendingReviews(limit) {
|
|
|
4502
4504
|
});
|
|
4503
4505
|
return result.rows;
|
|
4504
4506
|
}
|
|
4507
|
+
async function cleanupOrphanedReviews() {
|
|
4508
|
+
const client = getClient();
|
|
4509
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4510
|
+
const r1 = await client.execute({
|
|
4511
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
4512
|
+
WHERE status = 'needs_review'
|
|
4513
|
+
AND assigned_by = 'system'
|
|
4514
|
+
AND title LIKE 'Review:%'
|
|
4515
|
+
AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
|
|
4516
|
+
args: [now]
|
|
4517
|
+
});
|
|
4518
|
+
const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
|
|
4519
|
+
const r2 = await client.execute({
|
|
4520
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
4521
|
+
WHERE status = 'needs_review'
|
|
4522
|
+
AND result IS NOT NULL
|
|
4523
|
+
AND updated_at < ?`,
|
|
4524
|
+
args: [now, staleThreshold]
|
|
4525
|
+
});
|
|
4526
|
+
const total = r1.rowsAffected + r2.rowsAffected;
|
|
4527
|
+
if (total > 0) {
|
|
4528
|
+
process.stderr.write(
|
|
4529
|
+
`[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
|
|
4530
|
+
`
|
|
4531
|
+
);
|
|
4532
|
+
}
|
|
4533
|
+
return total;
|
|
4534
|
+
}
|
|
4505
4535
|
function getReviewChecklist(role, agent, taskSlug) {
|
|
4506
4536
|
const roleLower = role.toLowerCase();
|
|
4507
4537
|
if (roleLower.includes("engineer") || roleLower === "principal engineer") {
|
|
@@ -5181,6 +5211,7 @@ var init_skill_learning = __esm({
|
|
|
5181
5211
|
// src/lib/tasks.ts
|
|
5182
5212
|
var tasks_exports = {};
|
|
5183
5213
|
__export(tasks_exports, {
|
|
5214
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
5184
5215
|
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
5185
5216
|
countPendingReviews: () => countPendingReviews,
|
|
5186
5217
|
createTask: () => createTask,
|
|
@@ -5246,6 +5277,21 @@ async function updateTask(input) {
|
|
|
5246
5277
|
});
|
|
5247
5278
|
} catch {
|
|
5248
5279
|
}
|
|
5280
|
+
try {
|
|
5281
|
+
const client = getClient();
|
|
5282
|
+
const cascaded = await client.execute({
|
|
5283
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
5284
|
+
WHERE parent_task_id = ? AND status = 'needs_review'`,
|
|
5285
|
+
args: [now, taskId]
|
|
5286
|
+
});
|
|
5287
|
+
if (cascaded.rowsAffected > 0) {
|
|
5288
|
+
process.stderr.write(
|
|
5289
|
+
`[cascade] Closed ${cascaded.rowsAffected} orphaned review task(s) for parent ${taskId}
|
|
5290
|
+
`
|
|
5291
|
+
);
|
|
5292
|
+
}
|
|
5293
|
+
} catch {
|
|
5294
|
+
}
|
|
5249
5295
|
}
|
|
5250
5296
|
const isTerminal = input.status === "done" || input.status === "needs_review";
|
|
5251
5297
|
if (isTerminal) {
|
|
@@ -2108,7 +2108,7 @@ async function listTasks(input) {
|
|
|
2108
2108
|
}
|
|
2109
2109
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2110
2110
|
const result = await client.execute({
|
|
2111
|
-
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
|
|
2111
|
+
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
|
|
2112
2112
|
args
|
|
2113
2113
|
});
|
|
2114
2114
|
return result.rows.map((r) => ({
|
|
@@ -13,6 +13,7 @@ var config_exports = {};
|
|
|
13
13
|
__export(config_exports, {
|
|
14
14
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
15
15
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
16
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
16
17
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
17
18
|
DB_PATH: () => DB_PATH,
|
|
18
19
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -168,7 +169,7 @@ async function loadConfigFrom(configPath) {
|
|
|
168
169
|
return { ...DEFAULT_CONFIG };
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
173
|
var init_config = __esm({
|
|
173
174
|
"src/lib/config.ts"() {
|
|
174
175
|
"use strict";
|
|
@@ -176,6 +177,7 @@ var init_config = __esm({
|
|
|
176
177
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
177
178
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
178
179
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
180
|
+
COO_AGENT_NAME = "exe";
|
|
179
181
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
180
182
|
CURRENT_CONFIG_VERSION = 1;
|
|
181
183
|
DEFAULT_CONFIG = {
|
|
@@ -1024,6 +1024,7 @@ var config_exports = {};
|
|
|
1024
1024
|
__export(config_exports, {
|
|
1025
1025
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
1026
1026
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
1027
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
1027
1028
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
1028
1029
|
DB_PATH: () => DB_PATH,
|
|
1029
1030
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -1179,7 +1180,7 @@ async function loadConfigFrom(configPath) {
|
|
|
1179
1180
|
return { ...DEFAULT_CONFIG };
|
|
1180
1181
|
}
|
|
1181
1182
|
}
|
|
1182
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1183
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1183
1184
|
var init_config = __esm({
|
|
1184
1185
|
"src/lib/config.ts"() {
|
|
1185
1186
|
"use strict";
|
|
@@ -1187,6 +1188,7 @@ var init_config = __esm({
|
|
|
1187
1188
|
DB_PATH = path4.join(EXE_AI_DIR, "memories.db");
|
|
1188
1189
|
MODELS_DIR = path4.join(EXE_AI_DIR, "models");
|
|
1189
1190
|
CONFIG_PATH = path4.join(EXE_AI_DIR, "config.json");
|
|
1191
|
+
COO_AGENT_NAME = "exe";
|
|
1190
1192
|
LEGACY_LANCE_PATH = path4.join(EXE_AI_DIR, "local.lance");
|
|
1191
1193
|
CURRENT_CONFIG_VERSION = 1;
|
|
1192
1194
|
DEFAULT_CONFIG = {
|
|
@@ -2479,7 +2481,7 @@ async function listTasks(input2) {
|
|
|
2479
2481
|
}
|
|
2480
2482
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2481
2483
|
const result = await client.execute({
|
|
2482
|
-
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
|
|
2484
|
+
sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
|
|
2483
2485
|
args
|
|
2484
2486
|
});
|
|
2485
2487
|
return result.rows.map((r) => ({
|
|
@@ -3515,6 +3517,34 @@ async function listPendingReviews(limit) {
|
|
|
3515
3517
|
});
|
|
3516
3518
|
return result.rows;
|
|
3517
3519
|
}
|
|
3520
|
+
async function cleanupOrphanedReviews() {
|
|
3521
|
+
const client = getClient();
|
|
3522
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3523
|
+
const r1 = await client.execute({
|
|
3524
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
3525
|
+
WHERE status = 'needs_review'
|
|
3526
|
+
AND assigned_by = 'system'
|
|
3527
|
+
AND title LIKE 'Review:%'
|
|
3528
|
+
AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
|
|
3529
|
+
args: [now]
|
|
3530
|
+
});
|
|
3531
|
+
const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
|
|
3532
|
+
const r2 = await client.execute({
|
|
3533
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
3534
|
+
WHERE status = 'needs_review'
|
|
3535
|
+
AND result IS NOT NULL
|
|
3536
|
+
AND updated_at < ?`,
|
|
3537
|
+
args: [now, staleThreshold]
|
|
3538
|
+
});
|
|
3539
|
+
const total = r1.rowsAffected + r2.rowsAffected;
|
|
3540
|
+
if (total > 0) {
|
|
3541
|
+
process.stderr.write(
|
|
3542
|
+
`[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
|
|
3543
|
+
`
|
|
3544
|
+
);
|
|
3545
|
+
}
|
|
3546
|
+
return total;
|
|
3547
|
+
}
|
|
3518
3548
|
function getReviewChecklist(role, agent, taskSlug) {
|
|
3519
3549
|
const roleLower = role.toLowerCase();
|
|
3520
3550
|
if (roleLower.includes("engineer") || roleLower === "principal engineer") {
|
|
@@ -4152,6 +4182,7 @@ var init_skill_learning = __esm({
|
|
|
4152
4182
|
// src/lib/tasks.ts
|
|
4153
4183
|
var tasks_exports = {};
|
|
4154
4184
|
__export(tasks_exports, {
|
|
4185
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
4155
4186
|
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
4156
4187
|
countPendingReviews: () => countPendingReviews,
|
|
4157
4188
|
createTask: () => createTask,
|
|
@@ -4217,6 +4248,21 @@ async function updateTask(input2) {
|
|
|
4217
4248
|
});
|
|
4218
4249
|
} catch {
|
|
4219
4250
|
}
|
|
4251
|
+
try {
|
|
4252
|
+
const client = getClient();
|
|
4253
|
+
const cascaded = await client.execute({
|
|
4254
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
4255
|
+
WHERE parent_task_id = ? AND status = 'needs_review'`,
|
|
4256
|
+
args: [now, taskId]
|
|
4257
|
+
});
|
|
4258
|
+
if (cascaded.rowsAffected > 0) {
|
|
4259
|
+
process.stderr.write(
|
|
4260
|
+
`[cascade] Closed ${cascaded.rowsAffected} orphaned review task(s) for parent ${taskId}
|
|
4261
|
+
`
|
|
4262
|
+
);
|
|
4263
|
+
}
|
|
4264
|
+
} catch {
|
|
4265
|
+
}
|
|
4220
4266
|
}
|
|
4221
4267
|
const isTerminal = input2.status === "done" || input2.status === "needs_review";
|
|
4222
4268
|
if (isTerminal) {
|
|
@@ -28,6 +28,7 @@ var config_exports = {};
|
|
|
28
28
|
__export(config_exports, {
|
|
29
29
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
30
30
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
31
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
31
32
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
32
33
|
DB_PATH: () => DB_PATH,
|
|
33
34
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -183,7 +184,7 @@ async function loadConfigFrom(configPath) {
|
|
|
183
184
|
return { ...DEFAULT_CONFIG };
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
187
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
187
188
|
var init_config = __esm({
|
|
188
189
|
"src/lib/config.ts"() {
|
|
189
190
|
"use strict";
|
|
@@ -191,6 +192,7 @@ var init_config = __esm({
|
|
|
191
192
|
DB_PATH = path3.join(EXE_AI_DIR, "memories.db");
|
|
192
193
|
MODELS_DIR = path3.join(EXE_AI_DIR, "models");
|
|
193
194
|
CONFIG_PATH = path3.join(EXE_AI_DIR, "config.json");
|
|
195
|
+
COO_AGENT_NAME = "exe";
|
|
194
196
|
LEGACY_LANCE_PATH = path3.join(EXE_AI_DIR, "local.lance");
|
|
195
197
|
CURRENT_CONFIG_VERSION = 1;
|
|
196
198
|
DEFAULT_CONFIG = {
|
|
@@ -30,6 +30,7 @@ var config_exports = {};
|
|
|
30
30
|
__export(config_exports, {
|
|
31
31
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
32
32
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
33
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
33
34
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
34
35
|
DB_PATH: () => DB_PATH,
|
|
35
36
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -185,7 +186,7 @@ async function loadConfigFrom(configPath) {
|
|
|
185
186
|
return { ...DEFAULT_CONFIG };
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
189
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
189
190
|
var init_config = __esm({
|
|
190
191
|
"src/lib/config.ts"() {
|
|
191
192
|
"use strict";
|
|
@@ -193,6 +194,7 @@ var init_config = __esm({
|
|
|
193
194
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
194
195
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
195
196
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
197
|
+
COO_AGENT_NAME = "exe";
|
|
196
198
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
197
199
|
CURRENT_CONFIG_VERSION = 1;
|
|
198
200
|
DEFAULT_CONFIG = {
|
|
@@ -4338,6 +4340,7 @@ var init_tasks_crud = __esm({
|
|
|
4338
4340
|
// src/lib/tasks-review.ts
|
|
4339
4341
|
var tasks_review_exports = {};
|
|
4340
4342
|
__export(tasks_review_exports, {
|
|
4343
|
+
cleanupOrphanedReviews: () => cleanupOrphanedReviews,
|
|
4341
4344
|
cleanupReviewFile: () => cleanupReviewFile,
|
|
4342
4345
|
countNewPendingReviewsSince: () => countNewPendingReviewsSince,
|
|
4343
4346
|
countPendingReviews: () => countPendingReviews,
|
|
@@ -4374,6 +4377,34 @@ async function listPendingReviews(limit) {
|
|
|
4374
4377
|
});
|
|
4375
4378
|
return result.rows;
|
|
4376
4379
|
}
|
|
4380
|
+
async function cleanupOrphanedReviews() {
|
|
4381
|
+
const client = getClient();
|
|
4382
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4383
|
+
const r1 = await client.execute({
|
|
4384
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
4385
|
+
WHERE status = 'needs_review'
|
|
4386
|
+
AND assigned_by = 'system'
|
|
4387
|
+
AND title LIKE 'Review:%'
|
|
4388
|
+
AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
|
|
4389
|
+
args: [now]
|
|
4390
|
+
});
|
|
4391
|
+
const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
|
|
4392
|
+
const r2 = await client.execute({
|
|
4393
|
+
sql: `UPDATE tasks SET status = 'done', updated_at = ?
|
|
4394
|
+
WHERE status = 'needs_review'
|
|
4395
|
+
AND result IS NOT NULL
|
|
4396
|
+
AND updated_at < ?`,
|
|
4397
|
+
args: [now, staleThreshold]
|
|
4398
|
+
});
|
|
4399
|
+
const total = r1.rowsAffected + r2.rowsAffected;
|
|
4400
|
+
if (total > 0) {
|
|
4401
|
+
process.stderr.write(
|
|
4402
|
+
`[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
|
|
4403
|
+
`
|
|
4404
|
+
);
|
|
4405
|
+
}
|
|
4406
|
+
return total;
|
|
4407
|
+
}
|
|
4377
4408
|
function getReviewChecklist(role, agent, taskSlug) {
|
|
4378
4409
|
const roleLower = role.toLowerCase();
|
|
4379
4410
|
if (roleLower.includes("engineer") || roleLower === "principal engineer") {
|
|
@@ -5117,7 +5148,7 @@ ${fresh.map(
|
|
|
5117
5148
|
}
|
|
5118
5149
|
}
|
|
5119
5150
|
let reviewContext = "";
|
|
5120
|
-
if (agent.agentId ===
|
|
5151
|
+
if (agent.agentId === COO_AGENT_NAME || agent.agentId === "default") {
|
|
5121
5152
|
try {
|
|
5122
5153
|
const { countPendingReviews: countPendingReviews2, countNewPendingReviewsSince: countNewPendingReviewsSince2 } = await Promise.resolve().then(() => (init_tasks_review(), tasks_review_exports));
|
|
5123
5154
|
const sessionKey = getSessionKey();
|
|
@@ -919,6 +919,7 @@ var config_exports = {};
|
|
|
919
919
|
__export(config_exports, {
|
|
920
920
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
921
921
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
922
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
922
923
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
923
924
|
DB_PATH: () => DB_PATH,
|
|
924
925
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -1074,7 +1075,7 @@ async function loadConfigFrom(configPath) {
|
|
|
1074
1075
|
return { ...DEFAULT_CONFIG };
|
|
1075
1076
|
}
|
|
1076
1077
|
}
|
|
1077
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1078
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1078
1079
|
var init_config = __esm({
|
|
1079
1080
|
"src/lib/config.ts"() {
|
|
1080
1081
|
"use strict";
|
|
@@ -1082,6 +1083,7 @@ var init_config = __esm({
|
|
|
1082
1083
|
DB_PATH = path3.join(EXE_AI_DIR, "memories.db");
|
|
1083
1084
|
MODELS_DIR = path3.join(EXE_AI_DIR, "models");
|
|
1084
1085
|
CONFIG_PATH = path3.join(EXE_AI_DIR, "config.json");
|
|
1086
|
+
COO_AGENT_NAME = "exe";
|
|
1085
1087
|
LEGACY_LANCE_PATH = path3.join(EXE_AI_DIR, "local.lance");
|
|
1086
1088
|
CURRENT_CONFIG_VERSION = 1;
|
|
1087
1089
|
DEFAULT_CONFIG = {
|
|
@@ -13,6 +13,7 @@ var config_exports = {};
|
|
|
13
13
|
__export(config_exports, {
|
|
14
14
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
15
15
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
16
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
16
17
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
17
18
|
DB_PATH: () => DB_PATH,
|
|
18
19
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -168,7 +169,7 @@ async function loadConfigFrom(configPath) {
|
|
|
168
169
|
return { ...DEFAULT_CONFIG };
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
173
|
var init_config = __esm({
|
|
173
174
|
"src/lib/config.ts"() {
|
|
174
175
|
"use strict";
|
|
@@ -176,6 +177,7 @@ var init_config = __esm({
|
|
|
176
177
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
177
178
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
178
179
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
180
|
+
COO_AGENT_NAME = "exe";
|
|
179
181
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
180
182
|
CURRENT_CONFIG_VERSION = 1;
|
|
181
183
|
DEFAULT_CONFIG = {
|
|
@@ -111,7 +111,7 @@ async function loadConfig() {
|
|
|
111
111
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
114
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
115
115
|
var init_config = __esm({
|
|
116
116
|
"src/lib/config.ts"() {
|
|
117
117
|
"use strict";
|
|
@@ -119,6 +119,7 @@ var init_config = __esm({
|
|
|
119
119
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
120
120
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
121
121
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
122
|
+
COO_AGENT_NAME = "exe";
|
|
122
123
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
123
124
|
CURRENT_CONFIG_VERSION = 1;
|
|
124
125
|
DEFAULT_CONFIG = {
|
|
@@ -1973,6 +1974,7 @@ function getActiveAgent() {
|
|
|
1973
1974
|
}
|
|
1974
1975
|
|
|
1975
1976
|
// src/adapters/claude/hooks/subagent-stop.ts
|
|
1977
|
+
init_config();
|
|
1976
1978
|
if (!process.env.AGENT_ID) {
|
|
1977
1979
|
process.env.AGENT_ID = "default";
|
|
1978
1980
|
process.env.AGENT_ROLE = "employee";
|
|
@@ -1991,7 +1993,7 @@ process.stdin.on("end", async () => {
|
|
|
1991
1993
|
try {
|
|
1992
1994
|
JSON.parse(input);
|
|
1993
1995
|
const agent = getActiveAgent();
|
|
1994
|
-
if (agent.agentId ===
|
|
1996
|
+
if (agent.agentId === COO_AGENT_NAME || agent.agentId === "default") {
|
|
1995
1997
|
process.exit(0);
|
|
1996
1998
|
}
|
|
1997
1999
|
const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
@@ -1085,6 +1085,7 @@ var config_exports = {};
|
|
|
1085
1085
|
__export(config_exports, {
|
|
1086
1086
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
1087
1087
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
1088
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
1088
1089
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
1089
1090
|
DB_PATH: () => DB_PATH,
|
|
1090
1091
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -1240,7 +1241,7 @@ async function loadConfigFrom(configPath) {
|
|
|
1240
1241
|
return { ...DEFAULT_CONFIG };
|
|
1241
1242
|
}
|
|
1242
1243
|
}
|
|
1243
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1244
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
1244
1245
|
var init_config = __esm({
|
|
1245
1246
|
"src/lib/config.ts"() {
|
|
1246
1247
|
"use strict";
|
|
@@ -1248,6 +1249,7 @@ var init_config = __esm({
|
|
|
1248
1249
|
DB_PATH = path2.join(EXE_AI_DIR, "memories.db");
|
|
1249
1250
|
MODELS_DIR = path2.join(EXE_AI_DIR, "models");
|
|
1250
1251
|
CONFIG_PATH = path2.join(EXE_AI_DIR, "config.json");
|
|
1252
|
+
COO_AGENT_NAME = "exe";
|
|
1251
1253
|
LEGACY_LANCE_PATH = path2.join(EXE_AI_DIR, "local.lance");
|
|
1252
1254
|
CURRENT_CONFIG_VERSION = 1;
|
|
1253
1255
|
DEFAULT_CONFIG = {
|
|
@@ -2458,7 +2460,8 @@ __export(cloud_sync_exports, {
|
|
|
2458
2460
|
mergeRosterFromRemote: () => mergeRosterFromRemote,
|
|
2459
2461
|
recordRosterDeletion: () => recordRosterDeletion
|
|
2460
2462
|
});
|
|
2461
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync2, existsSync as existsSync9, readdirSync as readdirSync3, mkdirSync as mkdirSync3, appendFileSync, unlinkSync as unlinkSync3 } from "fs";
|
|
2463
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync2, existsSync as existsSync9, readdirSync as readdirSync3, mkdirSync as mkdirSync3, appendFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
2464
|
+
import crypto4 from "crypto";
|
|
2462
2465
|
import path9 from "path";
|
|
2463
2466
|
import { homedir } from "os";
|
|
2464
2467
|
function logError(msg) {
|
|
@@ -2470,17 +2473,29 @@ function logError(msg) {
|
|
|
2470
2473
|
}
|
|
2471
2474
|
}
|
|
2472
2475
|
async function withRosterLock(fn) {
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2476
|
+
try {
|
|
2477
|
+
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
2478
|
+
closeSync2(fd);
|
|
2479
|
+
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
2480
|
+
} catch (err) {
|
|
2481
|
+
if (err.code === "EEXIST") {
|
|
2482
|
+
try {
|
|
2483
|
+
const ts = parseInt(readFileSync7(ROSTER_LOCK_PATH, "utf-8"), 10);
|
|
2484
|
+
if (Date.now() - ts < LOCK_STALE_MS) {
|
|
2485
|
+
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
2486
|
+
}
|
|
2487
|
+
unlinkSync3(ROSTER_LOCK_PATH);
|
|
2488
|
+
const fd = openSync2(ROSTER_LOCK_PATH, "wx");
|
|
2489
|
+
closeSync2(fd);
|
|
2490
|
+
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
2491
|
+
} catch (retryErr) {
|
|
2492
|
+
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
2477
2493
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
2478
2494
|
}
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2495
|
+
} else {
|
|
2496
|
+
throw err;
|
|
2481
2497
|
}
|
|
2482
2498
|
}
|
|
2483
|
-
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
2484
2499
|
try {
|
|
2485
2500
|
return await fn();
|
|
2486
2501
|
} finally {
|
|
@@ -2802,7 +2817,7 @@ function buildRosterBlob(paths) {
|
|
|
2802
2817
|
}
|
|
2803
2818
|
const deletedNames = consumeRosterDeletions();
|
|
2804
2819
|
const content = JSON.stringify({ roster, identities, config, deletedNames });
|
|
2805
|
-
const hash =
|
|
2820
|
+
const hash = crypto4.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
2806
2821
|
return { roster, identities, config, deletedNames, version: hash };
|
|
2807
2822
|
}
|
|
2808
2823
|
async function cloudPushRoster(config) {
|
|
@@ -3653,7 +3668,7 @@ function vectorToBlob(vector) {
|
|
|
3653
3668
|
|
|
3654
3669
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
3655
3670
|
init_database();
|
|
3656
|
-
import
|
|
3671
|
+
import crypto5 from "crypto";
|
|
3657
3672
|
|
|
3658
3673
|
// src/lib/notifications.ts
|
|
3659
3674
|
init_database();
|
|
@@ -3694,7 +3709,7 @@ async function writeNotification(notification) {
|
|
|
3694
3709
|
|
|
3695
3710
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
3696
3711
|
import { execSync as execSync2 } from "child_process";
|
|
3697
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync5, openSync as
|
|
3712
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, openSync as openSync3, closeSync as closeSync3 } from "fs";
|
|
3698
3713
|
import path11 from "path";
|
|
3699
3714
|
async function main() {
|
|
3700
3715
|
const agentId = process.env.AGENT_ID ?? "default";
|
|
@@ -3764,7 +3779,7 @@ async function main() {
|
|
|
3764
3779
|
process.exit(0);
|
|
3765
3780
|
}
|
|
3766
3781
|
await writeMemory({
|
|
3767
|
-
id:
|
|
3782
|
+
id: crypto5.randomUUID(),
|
|
3768
3783
|
agent_id: agentId,
|
|
3769
3784
|
agent_role: agentRole,
|
|
3770
3785
|
session_id: `auto-summary-${Date.now()}`,
|
|
@@ -3829,14 +3844,14 @@ async function main() {
|
|
|
3829
3844
|
const { EXE_AI_DIR: exeDir2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3830
3845
|
const bLogPath = path11.join(exeDir2, "workers.log");
|
|
3831
3846
|
mkdirSync5(path11.dirname(bLogPath), { recursive: true });
|
|
3832
|
-
const bLogFd =
|
|
3847
|
+
const bLogFd = openSync3(bLogPath, "a");
|
|
3833
3848
|
const child = spawn2(process.execPath, [backfillPath], {
|
|
3834
3849
|
detached: true,
|
|
3835
3850
|
stdio: ["ignore", "ignore", bLogFd]
|
|
3836
3851
|
});
|
|
3837
3852
|
child.unref();
|
|
3838
3853
|
try {
|
|
3839
|
-
|
|
3854
|
+
closeSync3(bLogFd);
|
|
3840
3855
|
} catch {
|
|
3841
3856
|
}
|
|
3842
3857
|
process.stderr.write("[summary-worker] Spawned backfill job\n");
|