@askexenow/exe-os 0.9.67 → 0.9.68
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/age-ontology-load.js +263 -0
- package/dist/bin/agentic-ontology-backfill.js +178 -17
- package/dist/bin/agentic-reflection-backfill.js +165 -10
- package/dist/bin/agentic-semantic-label.js +173 -12
- package/dist/bin/backfill-vectors.js +176 -13
- package/dist/bin/cli.js +1175 -855
- package/dist/bin/graph-backfill.js +176 -17
- package/dist/bin/postgres-agentic-reflection-backfill.js +270 -0
- package/dist/bin/postgres-agentic-semantic-backfill.js +271 -1
- package/dist/lib/exe-daemon.js +626 -220
- package/package.json +1 -1
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -3830,7 +3830,7 @@ async function insertOntologyForMemory(row, client) {
|
|
|
3830
3830
|
const intention = inferIntention(row);
|
|
3831
3831
|
const outcome = inferOutcome(row);
|
|
3832
3832
|
const eventId = stableId("event", row.id);
|
|
3833
|
-
const
|
|
3833
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
3834
3834
|
await db.execute({
|
|
3835
3835
|
sql: `INSERT INTO agent_sessions (id, agent_id, project_name, started_at, last_event_at, event_count, properties)
|
|
3836
3836
|
VALUES (?, ?, ?, ?, ?, 1, ?)
|
|
@@ -3859,7 +3859,7 @@ async function insertOntologyForMemory(row, client) {
|
|
|
3859
3859
|
row.id,
|
|
3860
3860
|
row.has_error ? "negative" : outcome === "success_signal" ? "positive" : "neutral",
|
|
3861
3861
|
JSON.stringify(ontologyPayload(row)),
|
|
3862
|
-
|
|
3862
|
+
now2
|
|
3863
3863
|
]
|
|
3864
3864
|
});
|
|
3865
3865
|
const semantic = inferSemanticLabel(row);
|
|
@@ -3877,8 +3877,8 @@ async function insertOntologyForMemory(row, client) {
|
|
|
3877
3877
|
semantic.schemaVersion,
|
|
3878
3878
|
semantic.confidence,
|
|
3879
3879
|
JSON.stringify(semantic),
|
|
3880
|
-
|
|
3881
|
-
|
|
3880
|
+
now2,
|
|
3881
|
+
now2
|
|
3882
3882
|
]
|
|
3883
3883
|
});
|
|
3884
3884
|
for (const statement of extractGoalCandidates(row)) {
|
|
@@ -3889,19 +3889,19 @@ async function insertOntologyForMemory(row, client) {
|
|
|
3889
3889
|
parent_goal_id, due_at, achieved_at, supersedes_id, created_at, updated_at, source_memory_id)
|
|
3890
3890
|
VALUES (?, ?, ?, ?, 'open', 5, NULL, NULL, NULL, NULL, NULL, ?, ?, ?)
|
|
3891
3891
|
ON CONFLICT(id) DO UPDATE SET updated_at = excluded.updated_at`,
|
|
3892
|
-
args: [goalId, statement, row.agent_id, row.project_name,
|
|
3892
|
+
args: [goalId, statement, row.agent_id, row.project_name, now2, now2, row.id]
|
|
3893
3893
|
});
|
|
3894
3894
|
await db.execute({
|
|
3895
3895
|
sql: `INSERT OR IGNORE INTO agent_goal_links
|
|
3896
3896
|
(id, goal_id, link_type, target_id, target_type, created_at)
|
|
3897
3897
|
VALUES (?, ?, 'evidence', ?, 'memory', ?)`,
|
|
3898
|
-
args: [stableId("goal_link", goalId, row.id, "memory"), goalId, row.id,
|
|
3898
|
+
args: [stableId("goal_link", goalId, row.id, "memory"), goalId, row.id, now2]
|
|
3899
3899
|
});
|
|
3900
3900
|
await db.execute({
|
|
3901
3901
|
sql: `INSERT OR IGNORE INTO agent_goal_links
|
|
3902
3902
|
(id, goal_id, link_type, target_id, target_type, created_at)
|
|
3903
3903
|
VALUES (?, ?, 'event', ?, 'event', ?)`,
|
|
3904
|
-
args: [stableId("goal_link", goalId, eventId, "event"), goalId, eventId,
|
|
3904
|
+
args: [stableId("goal_link", goalId, eventId, "event"), goalId, eventId, now2]
|
|
3905
3905
|
});
|
|
3906
3906
|
}
|
|
3907
3907
|
}
|
|
@@ -4241,7 +4241,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4241
4241
|
const sequence = Number(row.version ?? 0) || Math.floor(timestamp.getTime() / 1e3);
|
|
4242
4242
|
const intention = inferIntention(row);
|
|
4243
4243
|
const outcome = inferOutcome(row);
|
|
4244
|
-
const
|
|
4244
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
4245
4245
|
await prisma.$executeRawUnsafe(
|
|
4246
4246
|
`INSERT INTO "memory"."agent_sessions" ("id", "agent_id", "project_name", "started_at", "last_event_at", "event_count", "properties")
|
|
4247
4247
|
VALUES ($1, $2, $3, $4, $4, 1, $5::jsonb)
|
|
@@ -4274,7 +4274,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4274
4274
|
row.id,
|
|
4275
4275
|
row.has_error ? "negative" : outcome === "success_signal" ? "positive" : "neutral",
|
|
4276
4276
|
JSON.stringify(ontologyPayload(row)),
|
|
4277
|
-
|
|
4277
|
+
now2
|
|
4278
4278
|
);
|
|
4279
4279
|
const semantic = inferSemanticLabel(row);
|
|
4280
4280
|
await prisma.$executeRawUnsafe(
|
|
@@ -4290,7 +4290,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4290
4290
|
semantic.schemaVersion,
|
|
4291
4291
|
semantic.confidence,
|
|
4292
4292
|
JSON.stringify(semantic),
|
|
4293
|
-
|
|
4293
|
+
now2
|
|
4294
4294
|
);
|
|
4295
4295
|
let goals = 0;
|
|
4296
4296
|
for (const statement of extractGoalCandidates(row)) {
|
|
@@ -4304,7 +4304,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4304
4304
|
statement,
|
|
4305
4305
|
row.agent_id,
|
|
4306
4306
|
row.project_name,
|
|
4307
|
-
|
|
4307
|
+
now2,
|
|
4308
4308
|
row.id
|
|
4309
4309
|
);
|
|
4310
4310
|
await prisma.$executeRawUnsafe(
|
|
@@ -4314,7 +4314,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4314
4314
|
stableId2(`goal_link:${goalId}:${row.id}:memory`),
|
|
4315
4315
|
goalId,
|
|
4316
4316
|
row.id,
|
|
4317
|
-
|
|
4317
|
+
now2
|
|
4318
4318
|
);
|
|
4319
4319
|
await prisma.$executeRawUnsafe(
|
|
4320
4320
|
`INSERT INTO "memory"."agent_goal_links" ("id", "goal_id", "link_type", "target_id", "target_type", "created_at")
|
|
@@ -4323,7 +4323,7 @@ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
|
|
|
4323
4323
|
stableId2(`goal_link:${goalId}:${eventId}:event`),
|
|
4324
4324
|
goalId,
|
|
4325
4325
|
eventId,
|
|
4326
|
-
|
|
4326
|
+
now2
|
|
4327
4327
|
);
|
|
4328
4328
|
goals++;
|
|
4329
4329
|
}
|
|
@@ -4943,10 +4943,10 @@ function evictLRU() {
|
|
|
4943
4943
|
}
|
|
4944
4944
|
}
|
|
4945
4945
|
function evictIdleShards() {
|
|
4946
|
-
const
|
|
4946
|
+
const now2 = Date.now();
|
|
4947
4947
|
const toEvict = [];
|
|
4948
4948
|
for (const [name, lastAccess] of _shardLastAccess) {
|
|
4949
|
-
if (
|
|
4949
|
+
if (now2 - lastAccess > SHARD_IDLE_MS) {
|
|
4950
4950
|
toEvict.push(name);
|
|
4951
4951
|
}
|
|
4952
4952
|
}
|
|
@@ -5154,8 +5154,8 @@ function deriveMachineKey() {
|
|
|
5154
5154
|
}
|
|
5155
5155
|
function readMachineId() {
|
|
5156
5156
|
try {
|
|
5157
|
-
const { readFileSync:
|
|
5158
|
-
return
|
|
5157
|
+
const { readFileSync: readFileSync38 } = __require("fs");
|
|
5158
|
+
return readFileSync38("/etc/machine-id", "utf-8").trim();
|
|
5159
5159
|
} catch {
|
|
5160
5160
|
return "";
|
|
5161
5161
|
}
|
|
@@ -5758,22 +5758,22 @@ ${sections.join("\n\n")}
|
|
|
5758
5758
|
}
|
|
5759
5759
|
async function storeGlobalProcedure(input) {
|
|
5760
5760
|
const id = randomUUID2();
|
|
5761
|
-
const
|
|
5761
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
5762
5762
|
const client = getClient();
|
|
5763
5763
|
await client.execute({
|
|
5764
5764
|
sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
|
|
5765
5765
|
VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
|
|
5766
|
-
args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null,
|
|
5766
|
+
args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now2, now2]
|
|
5767
5767
|
});
|
|
5768
5768
|
await loadGlobalProcedures();
|
|
5769
5769
|
return id;
|
|
5770
5770
|
}
|
|
5771
5771
|
async function deactivateGlobalProcedure(id) {
|
|
5772
|
-
const
|
|
5772
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
5773
5773
|
const client = getClient();
|
|
5774
5774
|
const result2 = await client.execute({
|
|
5775
5775
|
sql: "UPDATE company_procedures SET active = 0, updated_at = ? WHERE id = ?",
|
|
5776
|
-
args: [
|
|
5776
|
+
args: [now2, id]
|
|
5777
5777
|
});
|
|
5778
5778
|
await loadGlobalProcedures();
|
|
5779
5779
|
return result2.rowsAffected > 0;
|
|
@@ -5866,7 +5866,7 @@ function extractMemoryCards(row) {
|
|
|
5866
5866
|
async function insertMemoryCardsForBatch(rows) {
|
|
5867
5867
|
const cards = rows.flatMap(extractMemoryCards);
|
|
5868
5868
|
if (cards.length === 0) return 0;
|
|
5869
|
-
const
|
|
5869
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
5870
5870
|
const client = getClient();
|
|
5871
5871
|
const stmts = cards.map((card) => ({
|
|
5872
5872
|
sql: `INSERT OR IGNORE INTO memory_cards
|
|
@@ -5887,7 +5887,7 @@ async function insertMemoryCardsForBatch(rows) {
|
|
|
5887
5887
|
card.content,
|
|
5888
5888
|
card.source_ref,
|
|
5889
5889
|
card.confidence,
|
|
5890
|
-
|
|
5890
|
+
now2
|
|
5891
5891
|
]
|
|
5892
5892
|
}));
|
|
5893
5893
|
await client.batch(stmts, "write");
|
|
@@ -6622,7 +6622,7 @@ function queueDepth() {
|
|
|
6622
6622
|
}
|
|
6623
6623
|
}
|
|
6624
6624
|
function parseQueueFile(filePath) {
|
|
6625
|
-
const
|
|
6625
|
+
const now2 = Date.now();
|
|
6626
6626
|
const entries = [];
|
|
6627
6627
|
let content;
|
|
6628
6628
|
try {
|
|
@@ -6636,7 +6636,7 @@ function parseQueueFile(filePath) {
|
|
|
6636
6636
|
try {
|
|
6637
6637
|
const entry = JSON.parse(trimmed);
|
|
6638
6638
|
if (entry.timestamp) {
|
|
6639
|
-
const age =
|
|
6639
|
+
const age = now2 - new Date(entry.timestamp).getTime();
|
|
6640
6640
|
if (age > TTL_MS) continue;
|
|
6641
6641
|
}
|
|
6642
6642
|
entries.push(entry);
|
|
@@ -6737,11 +6737,11 @@ async function routeQuery(query, model = "claude-haiku-4-5-20251001") {
|
|
|
6737
6737
|
try {
|
|
6738
6738
|
const Anthropic = (await import("@anthropic-ai/sdk")).default;
|
|
6739
6739
|
const client = new Anthropic();
|
|
6740
|
-
const
|
|
6740
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
6741
6741
|
const response = await client.messages.create({
|
|
6742
6742
|
model,
|
|
6743
6743
|
max_tokens: 256,
|
|
6744
|
-
system: `You are a search query router. Extract metadata filters from the user's memory search query. Today is ${
|
|
6744
|
+
system: `You are a search query router. Extract metadata filters from the user's memory search query. Today is ${now2}. Convert relative time references (yesterday, last week) to ISO timestamps.`,
|
|
6745
6745
|
messages: [{ role: "user", content: query }],
|
|
6746
6746
|
tools: [EXTRACT_TOOL],
|
|
6747
6747
|
tool_choice: { type: "tool", name: "extract_search_filters" }
|
|
@@ -6974,10 +6974,10 @@ async function disposeEmbedder() {
|
|
|
6974
6974
|
async function embedDirect(text3) {
|
|
6975
6975
|
const llamaCpp = await import("node-llama-cpp");
|
|
6976
6976
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6977
|
-
const { existsSync:
|
|
6978
|
-
const
|
|
6979
|
-
const modelPath =
|
|
6980
|
-
if (!
|
|
6977
|
+
const { existsSync: existsSync45 } = await import("fs");
|
|
6978
|
+
const path58 = await import("path");
|
|
6979
|
+
const modelPath = path58.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
6980
|
+
if (!existsSync45(modelPath)) {
|
|
6981
6981
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
6982
6982
|
}
|
|
6983
6983
|
const llama = await llamaCpp.getLlama();
|
|
@@ -8068,23 +8068,23 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
8068
8068
|
};
|
|
8069
8069
|
try {
|
|
8070
8070
|
const fs = await import("fs");
|
|
8071
|
-
const
|
|
8072
|
-
const
|
|
8073
|
-
const logPath =
|
|
8074
|
-
fs.mkdirSync(
|
|
8071
|
+
const path58 = await import("path");
|
|
8072
|
+
const os25 = await import("os");
|
|
8073
|
+
const logPath = path58.join(os25.homedir(), ".exe-os", "search-quality.jsonl");
|
|
8074
|
+
fs.mkdirSync(path58.dirname(logPath), { recursive: true });
|
|
8075
8075
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
8076
8076
|
} catch {
|
|
8077
8077
|
}
|
|
8078
8078
|
}
|
|
8079
8079
|
if (finalResults.length > 0) {
|
|
8080
|
-
const
|
|
8080
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
8081
8081
|
const ids = finalResults.map((r) => r.id);
|
|
8082
8082
|
const placeholders = ids.map(() => "?").join(",");
|
|
8083
8083
|
try {
|
|
8084
8084
|
const client = getClient();
|
|
8085
8085
|
void client.execute({
|
|
8086
8086
|
sql: `UPDATE memories SET last_accessed = ?, retrieval_count = COALESCE(retrieval_count, 0) + 1 WHERE id IN (${placeholders})`,
|
|
8087
|
-
args: [
|
|
8087
|
+
args: [now2, ...ids]
|
|
8088
8088
|
}).catch(() => {
|
|
8089
8089
|
});
|
|
8090
8090
|
} catch {
|
|
@@ -9704,8 +9704,8 @@ __export(wiki_client_exports, {
|
|
|
9704
9704
|
listDocuments: () => listDocuments,
|
|
9705
9705
|
listWorkspaces: () => listWorkspaces
|
|
9706
9706
|
});
|
|
9707
|
-
async function wikiFetch(config2,
|
|
9708
|
-
const url = `${config2.baseUrl}/api/v1${
|
|
9707
|
+
async function wikiFetch(config2, path58, method = "GET", body) {
|
|
9708
|
+
const url = `${config2.baseUrl}/api/v1${path58}`;
|
|
9709
9709
|
const headers = {
|
|
9710
9710
|
Authorization: `Bearer ${config2.apiKey}`,
|
|
9711
9711
|
"Content-Type": "application/json"
|
|
@@ -9738,7 +9738,7 @@ async function wikiFetch(config2, path57, method = "GET", body) {
|
|
|
9738
9738
|
}
|
|
9739
9739
|
}
|
|
9740
9740
|
if (!response.ok) {
|
|
9741
|
-
throw new Error(`Wiki API ${method} ${
|
|
9741
|
+
throw new Error(`Wiki API ${method} ${path58}: ${response.status} ${response.statusText}`);
|
|
9742
9742
|
}
|
|
9743
9743
|
return response.json();
|
|
9744
9744
|
} finally {
|
|
@@ -10355,7 +10355,7 @@ async function consolidateCluster(cluster, model, agentRole) {
|
|
|
10355
10355
|
}
|
|
10356
10356
|
async function storeConsolidation(client, cluster, synthesisText, embedFn) {
|
|
10357
10357
|
const consolidatedId = randomUUID4();
|
|
10358
|
-
const
|
|
10358
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
10359
10359
|
const rawText = `CONSOLIDATION [${cluster.dateRange}, ${cluster.projectName}]:
|
|
10360
10360
|
|
|
10361
10361
|
${synthesisText}`;
|
|
@@ -10373,13 +10373,13 @@ ${synthesisText}`;
|
|
|
10373
10373
|
(id, agent_id, agent_role, session_id, timestamp,
|
|
10374
10374
|
tool_name, project_name, has_error, raw_text, vector, version, consolidated, importance)
|
|
10375
10375
|
VALUES (?, ?, 'consolidation', 'daemon-consolidation', ?, 'consolidation', ?, 0, ?, NULL, 0, 1, 9)`;
|
|
10376
|
-
const insertArgs = vector ? [consolidatedId, cluster.agentId,
|
|
10376
|
+
const insertArgs = vector ? [consolidatedId, cluster.agentId, now2, cluster.projectName, rawText, vectorToBlob(vector)] : [consolidatedId, cluster.agentId, now2, cluster.projectName, rawText];
|
|
10377
10377
|
await client.execute({ sql: insertSql, args: insertArgs });
|
|
10378
10378
|
const sourceIds = cluster.memories.map((m) => m.id);
|
|
10379
10379
|
const linkStmts = sourceIds.map((sourceId) => ({
|
|
10380
10380
|
sql: `INSERT INTO consolidations (id, consolidated_memory_id, source_memory_id, created_at)
|
|
10381
10381
|
VALUES (?, ?, ?, ?)`,
|
|
10382
|
-
args: [randomUUID4(), consolidatedId, sourceId,
|
|
10382
|
+
args: [randomUUID4(), consolidatedId, sourceId, now2]
|
|
10383
10383
|
}));
|
|
10384
10384
|
const placeholders = sourceIds.map(() => "?").join(",");
|
|
10385
10385
|
const markStmt = {
|
|
@@ -10605,8 +10605,8 @@ async function isUserIdle(client, idleMinutes = 30) {
|
|
|
10605
10605
|
const lastActivity = result2.rows[0]?.last_activity;
|
|
10606
10606
|
if (!lastActivity) return true;
|
|
10607
10607
|
const lastMs = new Date(lastActivity).getTime();
|
|
10608
|
-
const
|
|
10609
|
-
return
|
|
10608
|
+
const now2 = Date.now();
|
|
10609
|
+
return now2 - lastMs >= idleMinutes * 60 * 1e3;
|
|
10610
10610
|
}
|
|
10611
10611
|
async function countUnconsolidated(client) {
|
|
10612
10612
|
const result2 = await client.execute({
|
|
@@ -11478,8 +11478,8 @@ function logQueue(msg) {
|
|
|
11478
11478
|
process.stderr.write(`[intercom-queue] ${msg}
|
|
11479
11479
|
`);
|
|
11480
11480
|
try {
|
|
11481
|
-
const { appendFileSync:
|
|
11482
|
-
|
|
11481
|
+
const { appendFileSync: appendFileSync5 } = __require("fs");
|
|
11482
|
+
appendFileSync5(INTERCOM_LOG, line);
|
|
11483
11483
|
} catch {
|
|
11484
11484
|
}
|
|
11485
11485
|
}
|
|
@@ -11717,14 +11717,14 @@ function isAtCapacity(paneOutput) {
|
|
|
11717
11717
|
const filtered = filterPaneContent(paneOutput);
|
|
11718
11718
|
return CAPACITY_PATTERNS.some((p) => p.test(filtered));
|
|
11719
11719
|
}
|
|
11720
|
-
function confirmCapacityKill(agentId,
|
|
11720
|
+
function confirmCapacityKill(agentId, now2 = Date.now()) {
|
|
11721
11721
|
const pendingSince = _pendingCapacityKill.get(agentId);
|
|
11722
11722
|
if (pendingSince === void 0) {
|
|
11723
|
-
_pendingCapacityKill.set(agentId,
|
|
11723
|
+
_pendingCapacityKill.set(agentId, now2);
|
|
11724
11724
|
return false;
|
|
11725
11725
|
}
|
|
11726
|
-
if (
|
|
11727
|
-
_pendingCapacityKill.set(agentId,
|
|
11726
|
+
if (now2 - pendingSince > CONFIRMATION_WINDOW_MS) {
|
|
11727
|
+
_pendingCapacityKill.set(agentId, now2);
|
|
11728
11728
|
return false;
|
|
11729
11729
|
}
|
|
11730
11730
|
_pendingCapacityKill.delete(agentId);
|
|
@@ -11750,18 +11750,18 @@ async function lastResumeCreatedAtMs(agentId) {
|
|
|
11750
11750
|
const parsed = Date.parse(String(raw));
|
|
11751
11751
|
return Number.isNaN(parsed) ? null : parsed;
|
|
11752
11752
|
}
|
|
11753
|
-
async function isWithinRelaunchCooldown(agentId,
|
|
11753
|
+
async function isWithinRelaunchCooldown(agentId, now2 = Date.now()) {
|
|
11754
11754
|
const cached = _lastRelaunch.get(agentId);
|
|
11755
|
-
if (cached !== void 0) return
|
|
11755
|
+
if (cached !== void 0) return now2 - cached < RELAUNCH_COOLDOWN_MS;
|
|
11756
11756
|
const persisted = await lastResumeCreatedAtMs(agentId);
|
|
11757
11757
|
if (persisted === null) return false;
|
|
11758
|
-
if (
|
|
11758
|
+
if (now2 - persisted >= RELAUNCH_COOLDOWN_MS) return false;
|
|
11759
11759
|
_lastRelaunch.set(agentId, persisted);
|
|
11760
11760
|
return true;
|
|
11761
11761
|
}
|
|
11762
11762
|
async function createOrRefreshResumeTask(agentId, projectDir, openTasks) {
|
|
11763
11763
|
const client = getClient();
|
|
11764
|
-
const
|
|
11764
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
11765
11765
|
const context = buildResumeContext(agentId, openTasks);
|
|
11766
11766
|
const rdScope = sessionScopeFilter(null);
|
|
11767
11767
|
const existing = await client.execute({
|
|
@@ -11777,7 +11777,7 @@ async function createOrRefreshResumeTask(agentId, projectDir, openTasks) {
|
|
|
11777
11777
|
const taskId = String(existing.rows[0].id);
|
|
11778
11778
|
await client.execute({
|
|
11779
11779
|
sql: `UPDATE tasks SET context = ?, updated_at = ? WHERE id = ?`,
|
|
11780
|
-
args: [context,
|
|
11780
|
+
args: [context, now2, taskId]
|
|
11781
11781
|
});
|
|
11782
11782
|
return { created: false, taskId };
|
|
11783
11783
|
}
|
|
@@ -12016,21 +12016,21 @@ async function listPendingReviews(limit, sessionScope) {
|
|
|
12016
12016
|
}
|
|
12017
12017
|
async function cleanupOrphanedReviews() {
|
|
12018
12018
|
const client = getClient();
|
|
12019
|
-
const
|
|
12019
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
12020
12020
|
const r1 = await client.execute({
|
|
12021
12021
|
sql: `UPDATE tasks SET status = 'cancelled', updated_at = ?
|
|
12022
12022
|
WHERE status IN ('open', 'needs_review', 'in_progress')
|
|
12023
12023
|
AND assigned_by = 'system'
|
|
12024
12024
|
AND title LIKE 'Review:%'
|
|
12025
12025
|
AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled', 'closed'))`,
|
|
12026
|
-
args: [
|
|
12026
|
+
args: [now2]
|
|
12027
12027
|
});
|
|
12028
12028
|
const r1b = await client.execute({
|
|
12029
12029
|
sql: `UPDATE tasks SET status = 'cancelled', updated_at = ?
|
|
12030
12030
|
WHERE status IN ('open', 'needs_review')
|
|
12031
12031
|
AND title LIKE 'Review:%completed%'
|
|
12032
12032
|
AND (parent_task_id IS NULL OR parent_task_id NOT IN (SELECT id FROM tasks WHERE status IN ('open', 'in_progress', 'needs_review', 'blocked')))`,
|
|
12033
|
-
args: [
|
|
12033
|
+
args: [now2]
|
|
12034
12034
|
});
|
|
12035
12035
|
const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
|
|
12036
12036
|
const r2 = await client.execute({
|
|
@@ -12038,7 +12038,7 @@ async function cleanupOrphanedReviews() {
|
|
|
12038
12038
|
WHERE status = 'needs_review'
|
|
12039
12039
|
AND result IS NOT NULL
|
|
12040
12040
|
AND updated_at < ?`,
|
|
12041
|
-
args: [
|
|
12041
|
+
args: [now2, staleThreshold]
|
|
12042
12042
|
});
|
|
12043
12043
|
const total = r1.rowsAffected + (r1b?.rowsAffected ?? 0) + r2.rowsAffected;
|
|
12044
12044
|
if (total > 0) {
|
|
@@ -12097,7 +12097,7 @@ function getReviewChecklist(role, agent, taskSlug) {
|
|
|
12097
12097
|
]
|
|
12098
12098
|
};
|
|
12099
12099
|
}
|
|
12100
|
-
async function createReviewForCompletedTask(row, result2, _baseDir,
|
|
12100
|
+
async function createReviewForCompletedTask(row, result2, _baseDir, now2) {
|
|
12101
12101
|
const taskFile = String(row.task_file);
|
|
12102
12102
|
const employees = await loadEmployees();
|
|
12103
12103
|
const coordinatorName = getCoordinatorName(employees);
|
|
@@ -12146,14 +12146,14 @@ async function createReviewForCompletedTask(row, result2, _baseDir, now) {
|
|
|
12146
12146
|
await client.execute({
|
|
12147
12147
|
sql: `UPDATE tasks SET result = ?, status = 'needs_review', updated_at = ?
|
|
12148
12148
|
WHERE id = ?`,
|
|
12149
|
-
args: [updatedResult,
|
|
12149
|
+
args: [updatedResult, now2, originalTaskId]
|
|
12150
12150
|
});
|
|
12151
12151
|
orgBus.emit({
|
|
12152
12152
|
type: "review_created",
|
|
12153
12153
|
reviewId: originalTaskId,
|
|
12154
12154
|
employee: agent,
|
|
12155
12155
|
reviewer,
|
|
12156
|
-
timestamp:
|
|
12156
|
+
timestamp: now2
|
|
12157
12157
|
});
|
|
12158
12158
|
await writeNotification({
|
|
12159
12159
|
agentId: agent,
|
|
@@ -12182,7 +12182,7 @@ async function createReviewForCompletedTask(row, result2, _baseDir, now) {
|
|
|
12182
12182
|
);
|
|
12183
12183
|
await client.execute({
|
|
12184
12184
|
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE id = ?",
|
|
12185
|
-
args: [
|
|
12185
|
+
args: [now2, originalTaskId]
|
|
12186
12186
|
});
|
|
12187
12187
|
}
|
|
12188
12188
|
}
|
|
@@ -12190,12 +12190,12 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
12190
12190
|
if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
|
|
12191
12191
|
try {
|
|
12192
12192
|
const client = getClient();
|
|
12193
|
-
const
|
|
12193
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
12194
12194
|
const parentId = row.parent_task_id ? String(row.parent_task_id) : null;
|
|
12195
12195
|
if (parentId) {
|
|
12196
12196
|
const result2 = await client.execute({
|
|
12197
12197
|
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE id = ? AND status = 'needs_review'",
|
|
12198
|
-
args: [
|
|
12198
|
+
args: [now2, parentId]
|
|
12199
12199
|
});
|
|
12200
12200
|
if (result2.rowsAffected > 0) {
|
|
12201
12201
|
process.stderr.write(
|
|
@@ -12213,7 +12213,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
12213
12213
|
const legacyTaskFile = `exe/${agent}/${slug}.md`;
|
|
12214
12214
|
const result2 = await client.execute({
|
|
12215
12215
|
sql: "UPDATE tasks SET status = 'done', updated_at = ? WHERE (task_file = ? OR task_file LIKE ?) AND status = 'needs_review'",
|
|
12216
|
-
args: [
|
|
12216
|
+
args: [now2, legacyTaskFile, `tasks/%/${agent}/${slug}.md`]
|
|
12217
12217
|
});
|
|
12218
12218
|
if (result2.rowsAffected > 0) {
|
|
12219
12219
|
process.stderr.write(
|
|
@@ -12451,12 +12451,12 @@ function resolveExeSession() {
|
|
|
12451
12451
|
function isEmployeeAlive(sessionName) {
|
|
12452
12452
|
return getTransport().isAlive(sessionName);
|
|
12453
12453
|
}
|
|
12454
|
-
function findFreeInstance(employeeName, exeSession, maxInstances = 10,
|
|
12454
|
+
function findFreeInstance(employeeName, exeSession, maxInstances = 10, isAlive2 = isEmployeeAlive) {
|
|
12455
12455
|
const base = employeeSessionName(employeeName, exeSession);
|
|
12456
|
-
if (!
|
|
12456
|
+
if (!isAlive2(base) && acquireSpawnLock2(base)) return 0;
|
|
12457
12457
|
for (let i = 2; i <= maxInstances; i++) {
|
|
12458
12458
|
const candidate = employeeSessionName(employeeName, exeSession, i);
|
|
12459
|
-
if (!
|
|
12459
|
+
if (!isAlive2(candidate) && acquireSpawnLock2(candidate)) return i;
|
|
12460
12460
|
}
|
|
12461
12461
|
return null;
|
|
12462
12462
|
}
|
|
@@ -13131,7 +13131,7 @@ async function writeNotification(notification) {
|
|
|
13131
13131
|
try {
|
|
13132
13132
|
const client = getClient();
|
|
13133
13133
|
const id = crypto7.randomUUID();
|
|
13134
|
-
const
|
|
13134
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
13135
13135
|
const sessionScope = notification.sessionScope === void 0 ? getCurrentSessionScope() : notification.sessionScope;
|
|
13136
13136
|
await client.execute({
|
|
13137
13137
|
sql: `INSERT INTO notifications (id, agent_id, agent_role, event, project, summary, task_file, session_scope, read, created_at)
|
|
@@ -13145,7 +13145,7 @@ async function writeNotification(notification) {
|
|
|
13145
13145
|
notification.summary,
|
|
13146
13146
|
notification.taskFile ?? null,
|
|
13147
13147
|
sessionScope,
|
|
13148
|
-
|
|
13148
|
+
now2
|
|
13149
13149
|
]
|
|
13150
13150
|
});
|
|
13151
13151
|
} catch (err) {
|
|
@@ -13262,7 +13262,7 @@ async function writeCheckpoint(input) {
|
|
|
13262
13262
|
const client = getClient();
|
|
13263
13263
|
const row = await resolveTask(client, input.taskId);
|
|
13264
13264
|
const taskId = String(row.id);
|
|
13265
|
-
const
|
|
13265
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
13266
13266
|
const blockedByIds = [];
|
|
13267
13267
|
if (row.blocked_by) {
|
|
13268
13268
|
blockedByIds.push(String(row.blocked_by));
|
|
@@ -13272,11 +13272,11 @@ async function writeCheckpoint(input) {
|
|
|
13272
13272
|
context_summary: input.contextSummary,
|
|
13273
13273
|
files_touched: input.filesTouched ?? [],
|
|
13274
13274
|
blocked_by_ids: blockedByIds,
|
|
13275
|
-
last_checkpoint_at:
|
|
13275
|
+
last_checkpoint_at: now2
|
|
13276
13276
|
};
|
|
13277
13277
|
const result2 = await client.execute({
|
|
13278
13278
|
sql: `UPDATE tasks SET checkpoint = ?, checkpoint_count = checkpoint_count + 1, updated_at = ? WHERE id = ?`,
|
|
13279
|
-
args: [JSON.stringify(checkpoint),
|
|
13279
|
+
args: [JSON.stringify(checkpoint), now2, taskId]
|
|
13280
13280
|
});
|
|
13281
13281
|
if (result2.rowsAffected === 0) {
|
|
13282
13282
|
throw new Error(`Checkpoint write failed: task ${taskId} not found`);
|
|
@@ -13374,7 +13374,7 @@ async function resolveTask(client, identifier, scopeSession) {
|
|
|
13374
13374
|
async function createTaskCore(input) {
|
|
13375
13375
|
const client = getClient();
|
|
13376
13376
|
const id = crypto8.randomUUID();
|
|
13377
|
-
const
|
|
13377
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
13378
13378
|
const slug = slugify(input.title);
|
|
13379
13379
|
let earlySessionScope = null;
|
|
13380
13380
|
let scopeMismatchWarning;
|
|
@@ -13487,8 +13487,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
13487
13487
|
0,
|
|
13488
13488
|
null,
|
|
13489
13489
|
sessionScope,
|
|
13490
|
-
|
|
13491
|
-
|
|
13490
|
+
now2,
|
|
13491
|
+
now2
|
|
13492
13492
|
]
|
|
13493
13493
|
});
|
|
13494
13494
|
if (input.baseDir) {
|
|
@@ -13512,7 +13512,7 @@ Do NOT let a failed commit or any error prevent you from calling update_task(don
|
|
|
13512
13512
|
**Assigned by:** ${input.assignedBy}
|
|
13513
13513
|
**Assigned to:** ${input.assignedTo}
|
|
13514
13514
|
**Project:** ${input.projectName}
|
|
13515
|
-
**Created:** ${
|
|
13515
|
+
**Created:** ${now2.split("T")[0]}${parentTaskId ? `
|
|
13516
13516
|
**Parent task:** ${parentTaskId}` : ""}
|
|
13517
13517
|
**Reviewer:** ${reviewer}
|
|
13518
13518
|
|
|
@@ -13537,8 +13537,8 @@ ${input.context}
|
|
|
13537
13537
|
priority: input.priority,
|
|
13538
13538
|
status: initialStatus,
|
|
13539
13539
|
taskFile,
|
|
13540
|
-
createdAt:
|
|
13541
|
-
updatedAt:
|
|
13540
|
+
createdAt: now2,
|
|
13541
|
+
updatedAt: now2,
|
|
13542
13542
|
warning,
|
|
13543
13543
|
budgetTokens: input.budgetTokens ?? null,
|
|
13544
13544
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
@@ -13651,7 +13651,7 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
|
|
|
13651
13651
|
}
|
|
13652
13652
|
async function updateTaskStatus(input) {
|
|
13653
13653
|
const client = getClient();
|
|
13654
|
-
const
|
|
13654
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
13655
13655
|
const row = await resolveTask(client, input.taskId);
|
|
13656
13656
|
const taskId = String(row.id);
|
|
13657
13657
|
const taskFile = String(row.task_file);
|
|
@@ -13684,7 +13684,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13684
13684
|
sql: `UPDATE tasks
|
|
13685
13685
|
SET status = 'in_progress', assigned_tmux = ?, updated_at = ?
|
|
13686
13686
|
WHERE id = ? AND status = 'open'`,
|
|
13687
|
-
args: [tmuxSession,
|
|
13687
|
+
args: [tmuxSession, now2, taskId]
|
|
13688
13688
|
});
|
|
13689
13689
|
if (claim.rowsAffected === 0) {
|
|
13690
13690
|
const current = await client.execute({
|
|
@@ -13702,11 +13702,11 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13702
13702
|
);
|
|
13703
13703
|
await client.execute({
|
|
13704
13704
|
sql: "UPDATE tasks SET status = 'open', assigned_tmux = NULL, updated_at = ? WHERE id = ?",
|
|
13705
|
-
args: [
|
|
13705
|
+
args: [now2, taskId]
|
|
13706
13706
|
});
|
|
13707
13707
|
const retried = await client.execute({
|
|
13708
13708
|
sql: `UPDATE tasks SET status = 'in_progress', assigned_tmux = ?, updated_at = ? WHERE id = ? AND status = 'open'`,
|
|
13709
|
-
args: [tmuxSession,
|
|
13709
|
+
args: [tmuxSession, now2, taskId]
|
|
13710
13710
|
});
|
|
13711
13711
|
if (retried.rowsAffected > 0) {
|
|
13712
13712
|
try {
|
|
@@ -13717,7 +13717,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13717
13717
|
});
|
|
13718
13718
|
} catch {
|
|
13719
13719
|
}
|
|
13720
|
-
return { row, taskFile, now, taskId };
|
|
13720
|
+
return { row, taskFile, now: now2, taskId };
|
|
13721
13721
|
}
|
|
13722
13722
|
}
|
|
13723
13723
|
if (curStatus === "in_progress" && input.callerAgentId && (input.callerAgentId === assignedBy || isCoordinatorName(input.callerAgentId))) {
|
|
@@ -13727,7 +13727,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13727
13727
|
);
|
|
13728
13728
|
await client.execute({
|
|
13729
13729
|
sql: `UPDATE tasks SET status = 'in_progress', assigned_tmux = ?, updated_at = ? WHERE id = ?`,
|
|
13730
|
-
args: [tmuxSession,
|
|
13730
|
+
args: [tmuxSession, now2, taskId]
|
|
13731
13731
|
});
|
|
13732
13732
|
try {
|
|
13733
13733
|
await writeCheckpoint({
|
|
@@ -13737,7 +13737,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13737
13737
|
});
|
|
13738
13738
|
} catch {
|
|
13739
13739
|
}
|
|
13740
|
-
return { row, taskFile, now, taskId };
|
|
13740
|
+
return { row, taskFile, now: now2, taskId };
|
|
13741
13741
|
}
|
|
13742
13742
|
const claimedBy = claimedBySession ? ` (claimed by ${claimedBySession})` : "";
|
|
13743
13743
|
throw new Error(`${TASK_ALREADY_CLAIMED_PREFIX}: task ${taskId} is ${curStatus}${claimedBy}`);
|
|
@@ -13750,17 +13750,17 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13750
13750
|
});
|
|
13751
13751
|
} catch {
|
|
13752
13752
|
}
|
|
13753
|
-
return { row, taskFile, now, taskId };
|
|
13753
|
+
return { row, taskFile, now: now2, taskId };
|
|
13754
13754
|
}
|
|
13755
13755
|
if (input.result) {
|
|
13756
13756
|
await client.execute({
|
|
13757
13757
|
sql: "UPDATE tasks SET status = ?, result = ?, updated_at = ? WHERE id = ?",
|
|
13758
|
-
args: [input.status, input.result,
|
|
13758
|
+
args: [input.status, input.result, now2, taskId]
|
|
13759
13759
|
});
|
|
13760
13760
|
} else {
|
|
13761
13761
|
await client.execute({
|
|
13762
13762
|
sql: "UPDATE tasks SET status = ?, updated_at = ? WHERE id = ?",
|
|
13763
|
-
args: [input.status,
|
|
13763
|
+
args: [input.status, now2, taskId]
|
|
13764
13764
|
});
|
|
13765
13765
|
}
|
|
13766
13766
|
try {
|
|
@@ -13782,7 +13782,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
13782
13782
|
});
|
|
13783
13783
|
} catch {
|
|
13784
13784
|
}
|
|
13785
|
-
return { row, taskFile, now, taskId };
|
|
13785
|
+
return { row, taskFile, now: now2, taskId };
|
|
13786
13786
|
}
|
|
13787
13787
|
async function deleteTaskCore(taskId, _baseDir) {
|
|
13788
13788
|
const client = getClient();
|
|
@@ -13867,18 +13867,18 @@ var init_tasks_crud = __esm({
|
|
|
13867
13867
|
// src/lib/tasks-chain.ts
|
|
13868
13868
|
import path27 from "path";
|
|
13869
13869
|
import { readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
13870
|
-
async function cascadeUnblock(taskId, baseDir,
|
|
13870
|
+
async function cascadeUnblock(taskId, baseDir, now2) {
|
|
13871
13871
|
const client = getClient();
|
|
13872
13872
|
const unblocked = await client.execute({
|
|
13873
13873
|
sql: `UPDATE tasks SET status = 'open', blocked_by = NULL, updated_at = ?
|
|
13874
13874
|
WHERE blocked_by = ? AND status = 'blocked'`,
|
|
13875
|
-
args: [
|
|
13875
|
+
args: [now2, taskId]
|
|
13876
13876
|
});
|
|
13877
13877
|
if (baseDir && unblocked.rowsAffected > 0) {
|
|
13878
13878
|
const ubScope = sessionScopeFilter();
|
|
13879
13879
|
const unblockedRows = await client.execute({
|
|
13880
13880
|
sql: `SELECT task_file FROM tasks WHERE blocked_by IS NULL AND updated_at = ?${ubScope.sql}`,
|
|
13881
|
-
args: [
|
|
13881
|
+
args: [now2, ...ubScope.args]
|
|
13882
13882
|
});
|
|
13883
13883
|
for (const ur of unblockedRows.rows) {
|
|
13884
13884
|
try {
|
|
@@ -14034,7 +14034,7 @@ import crypto9 from "crypto";
|
|
|
14034
14034
|
async function storeBehavior(opts) {
|
|
14035
14035
|
const client = getClient();
|
|
14036
14036
|
const id = crypto9.randomUUID();
|
|
14037
|
-
const
|
|
14037
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
14038
14038
|
let vector = null;
|
|
14039
14039
|
try {
|
|
14040
14040
|
const { embed: embed2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
|
|
@@ -14045,7 +14045,7 @@ async function storeBehavior(opts) {
|
|
|
14045
14045
|
await client.execute({
|
|
14046
14046
|
sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector)
|
|
14047
14047
|
VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?)`,
|
|
14048
|
-
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content,
|
|
14048
|
+
args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now2, now2, vector ? vector.buffer : null]
|
|
14049
14049
|
});
|
|
14050
14050
|
return id;
|
|
14051
14051
|
}
|
|
@@ -14132,7 +14132,7 @@ function hashSignature(signature) {
|
|
|
14132
14132
|
async function storeTrajectory(opts) {
|
|
14133
14133
|
const client = getClient();
|
|
14134
14134
|
const id = crypto10.randomUUID();
|
|
14135
|
-
const
|
|
14135
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
14136
14136
|
const signatureHash = hashSignature(opts.signature);
|
|
14137
14137
|
await client.execute({
|
|
14138
14138
|
sql: `INSERT INTO trajectories (id, task_id, agent_id, project_name, task_title, signature, signature_hash, tool_count, created_at)
|
|
@@ -14146,7 +14146,7 @@ async function storeTrajectory(opts) {
|
|
|
14146
14146
|
JSON.stringify(opts.signature),
|
|
14147
14147
|
signatureHash,
|
|
14148
14148
|
opts.signature.length,
|
|
14149
|
-
|
|
14149
|
+
now2
|
|
14150
14150
|
]
|
|
14151
14151
|
});
|
|
14152
14152
|
return id;
|
|
@@ -14413,7 +14413,7 @@ async function createTask(input) {
|
|
|
14413
14413
|
return result2;
|
|
14414
14414
|
}
|
|
14415
14415
|
async function updateTask(input) {
|
|
14416
|
-
const { row, taskFile, now, taskId } = await updateTaskStatus(input);
|
|
14416
|
+
const { row, taskFile, now: now2, taskId } = await updateTaskStatus(input);
|
|
14417
14417
|
try {
|
|
14418
14418
|
const agent = String(row.assigned_to);
|
|
14419
14419
|
const cacheDir = path28.join(EXE_AI_DIR, "session-cache");
|
|
@@ -14440,7 +14440,7 @@ async function updateTask(input) {
|
|
|
14440
14440
|
await client.execute({
|
|
14441
14441
|
sql: `UPDATE tasks SET status = 'cancelled', updated_at = ?
|
|
14442
14442
|
WHERE title LIKE ? ESCAPE '\\' AND status IN ('open', 'in_progress')`,
|
|
14443
|
-
args: [
|
|
14443
|
+
args: [now2, `%left '${escaped}' as in\\_progress%`]
|
|
14444
14444
|
});
|
|
14445
14445
|
} catch {
|
|
14446
14446
|
}
|
|
@@ -14454,10 +14454,10 @@ async function updateTask(input) {
|
|
|
14454
14454
|
args: [assignedAgent]
|
|
14455
14455
|
});
|
|
14456
14456
|
} else if (input.status === "cancelled") {
|
|
14457
|
-
const
|
|
14457
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
14458
14458
|
await draftClient.execute({
|
|
14459
14459
|
sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
|
|
14460
|
-
args: [
|
|
14460
|
+
args: [now3, assignedAgent]
|
|
14461
14461
|
});
|
|
14462
14462
|
}
|
|
14463
14463
|
} catch {
|
|
@@ -14468,7 +14468,7 @@ async function updateTask(input) {
|
|
|
14468
14468
|
const cascaded = await client.execute({
|
|
14469
14469
|
sql: `UPDATE tasks SET status = 'closed', updated_at = ?
|
|
14470
14470
|
WHERE parent_task_id = ? AND status = 'needs_review'`,
|
|
14471
|
-
args: [
|
|
14471
|
+
args: [now2, taskId]
|
|
14472
14472
|
});
|
|
14473
14473
|
if (cascaded.rowsAffected > 0) {
|
|
14474
14474
|
process.stderr.write(
|
|
@@ -14488,7 +14488,7 @@ async function updateTask(input) {
|
|
|
14488
14488
|
await markTaskNotificationsRead(taskFile);
|
|
14489
14489
|
if (input.status === "done" || input.status === "closed") {
|
|
14490
14490
|
try {
|
|
14491
|
-
await cascadeUnblock(taskId, input.baseDir,
|
|
14491
|
+
await cascadeUnblock(taskId, input.baseDir, now2);
|
|
14492
14492
|
} catch {
|
|
14493
14493
|
}
|
|
14494
14494
|
orgBus.emit({
|
|
@@ -14496,7 +14496,7 @@ async function updateTask(input) {
|
|
|
14496
14496
|
taskId,
|
|
14497
14497
|
employee: String(row.assigned_to),
|
|
14498
14498
|
result: input.result ?? "",
|
|
14499
|
-
timestamp:
|
|
14499
|
+
timestamp: now2
|
|
14500
14500
|
});
|
|
14501
14501
|
if (row.parent_task_id) {
|
|
14502
14502
|
try {
|
|
@@ -14538,7 +14538,7 @@ async function updateTask(input) {
|
|
|
14538
14538
|
status: input.status,
|
|
14539
14539
|
taskFile,
|
|
14540
14540
|
createdAt: String(row.created_at),
|
|
14541
|
-
updatedAt:
|
|
14541
|
+
updatedAt: now2,
|
|
14542
14542
|
budgetTokens: row.budget_tokens !== void 0 && row.budget_tokens !== null ? Number(row.budget_tokens) : null,
|
|
14543
14543
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
14544
14544
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
@@ -15316,10 +15316,10 @@ function registerCreateTask(server) {
|
|
|
15316
15316
|
skipDispatch: true
|
|
15317
15317
|
});
|
|
15318
15318
|
try {
|
|
15319
|
-
const { existsSync:
|
|
15319
|
+
const { existsSync: existsSync45, mkdirSync: mkdirSync24, writeFileSync: writeFileSync28 } = await import("fs");
|
|
15320
15320
|
const { identityPath: identityPath2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
15321
15321
|
const idPath = identityPath2(assigned_to);
|
|
15322
|
-
if (!
|
|
15322
|
+
if (!existsSync45(idPath)) {
|
|
15323
15323
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
15324
15324
|
const employees = await loadEmployees2();
|
|
15325
15325
|
const emp = employees.find((e) => e.name === assigned_to);
|
|
@@ -15328,8 +15328,8 @@ function registerCreateTask(server) {
|
|
|
15328
15328
|
const template = getTemplateForTitle2(emp.role);
|
|
15329
15329
|
if (template) {
|
|
15330
15330
|
const dir = (await import("path")).dirname(idPath);
|
|
15331
|
-
if (!
|
|
15332
|
-
|
|
15331
|
+
if (!existsSync45(dir)) mkdirSync24(dir, { recursive: true });
|
|
15332
|
+
writeFileSync28(idPath, template.replace(/^agent_id: \w+/m, `agent_id: ${assigned_to}`), "utf-8");
|
|
15333
15333
|
}
|
|
15334
15334
|
}
|
|
15335
15335
|
}
|
|
@@ -15953,14 +15953,14 @@ function registerResumeEmployee(server) {
|
|
|
15953
15953
|
}
|
|
15954
15954
|
try {
|
|
15955
15955
|
const { isTmuxSessionAlive: isTmuxSessionAlive2 } = await Promise.resolve().then(() => (init_tasks_crud(), tasks_crud_exports));
|
|
15956
|
-
const
|
|
15956
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
15957
15957
|
for (const row of openTasks.rows) {
|
|
15958
15958
|
const status = String(row.status);
|
|
15959
15959
|
const assignedTmux = row.assigned_tmux != null ? String(row.assigned_tmux) : null;
|
|
15960
15960
|
if (status === "in_progress" && assignedTmux && !isTmuxSessionAlive2(assignedTmux)) {
|
|
15961
15961
|
await client.execute({
|
|
15962
15962
|
sql: "UPDATE tasks SET status = 'open', assigned_tmux = NULL, updated_at = ? WHERE id = ?",
|
|
15963
|
-
args: [
|
|
15963
|
+
args: [now2, String(row.id)]
|
|
15964
15964
|
});
|
|
15965
15965
|
process.stderr.write(
|
|
15966
15966
|
`[resume_employee] Released dead claim on "${String(row.title)}" (was ${assignedTmux})
|
|
@@ -16227,7 +16227,7 @@ function rowToMessage(row) {
|
|
|
16227
16227
|
async function sendMessage(input) {
|
|
16228
16228
|
const client = getClient();
|
|
16229
16229
|
const id = generateUlid();
|
|
16230
|
-
const
|
|
16230
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16231
16231
|
const targetDevice = input.targetDevice ?? "local";
|
|
16232
16232
|
const sessionScope = input.sessionScope === void 0 ? resolveExeSession() : input.sessionScope;
|
|
16233
16233
|
await client.execute({
|
|
@@ -16242,7 +16242,7 @@ async function sendMessage(input) {
|
|
|
16242
16242
|
sessionScope,
|
|
16243
16243
|
input.content,
|
|
16244
16244
|
input.priority ?? "normal",
|
|
16245
|
-
|
|
16245
|
+
now2
|
|
16246
16246
|
]
|
|
16247
16247
|
});
|
|
16248
16248
|
try {
|
|
@@ -16305,7 +16305,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
16305
16305
|
const msg = rowToMessage(result2.rows[0]);
|
|
16306
16306
|
if (msg.status !== "pending") return false;
|
|
16307
16307
|
const targetAgent = msg.targetAgent;
|
|
16308
|
-
const
|
|
16308
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16309
16309
|
try {
|
|
16310
16310
|
const exeSession = resolveExeSession();
|
|
16311
16311
|
if (!exeSession) {
|
|
@@ -16318,7 +16318,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
16318
16318
|
sendIntercom(sessionName);
|
|
16319
16319
|
await client.execute({
|
|
16320
16320
|
sql: "UPDATE messages SET status = 'delivered', delivered_at = ? WHERE id = ?",
|
|
16321
|
-
args: [
|
|
16321
|
+
args: [now2, messageId]
|
|
16322
16322
|
});
|
|
16323
16323
|
return true;
|
|
16324
16324
|
} catch {
|
|
@@ -16592,12 +16592,12 @@ import crypto12 from "crypto";
|
|
|
16592
16592
|
async function createReminder(text3, dueDate) {
|
|
16593
16593
|
const client = getClient();
|
|
16594
16594
|
const id = crypto12.randomUUID();
|
|
16595
|
-
const
|
|
16595
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16596
16596
|
await client.execute({
|
|
16597
16597
|
sql: `INSERT INTO reminders (id, text, created_at, due_date) VALUES (?, ?, ?, ?)`,
|
|
16598
|
-
args: [id, text3,
|
|
16598
|
+
args: [id, text3, now2, dueDate ?? null]
|
|
16599
16599
|
});
|
|
16600
|
-
return { id, text: text3, createdAt:
|
|
16600
|
+
return { id, text: text3, createdAt: now2, dueDate: dueDate ?? null, completedAt: null };
|
|
16601
16601
|
}
|
|
16602
16602
|
async function listReminders(includeCompleted = false) {
|
|
16603
16603
|
const client = getClient();
|
|
@@ -16613,7 +16613,7 @@ async function listReminders(includeCompleted = false) {
|
|
|
16613
16613
|
}
|
|
16614
16614
|
async function completeReminder(idOrText) {
|
|
16615
16615
|
const client = getClient();
|
|
16616
|
-
const
|
|
16616
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
16617
16617
|
let result2 = await client.execute({
|
|
16618
16618
|
sql: `SELECT id, text FROM reminders WHERE id = ? AND completed_at IS NULL`,
|
|
16619
16619
|
args: [idOrText]
|
|
@@ -16629,9 +16629,9 @@ async function completeReminder(idOrText) {
|
|
|
16629
16629
|
const id = String(row.id);
|
|
16630
16630
|
await client.execute({
|
|
16631
16631
|
sql: `UPDATE reminders SET completed_at = ? WHERE id = ?`,
|
|
16632
|
-
args: [
|
|
16632
|
+
args: [now2, id]
|
|
16633
16633
|
});
|
|
16634
|
-
return { id, text: String(row.text), createdAt: "", dueDate: null, completedAt:
|
|
16634
|
+
return { id, text: String(row.text), createdAt: "", dueDate: null, completedAt: now2 };
|
|
16635
16635
|
}
|
|
16636
16636
|
var init_reminders = __esm({
|
|
16637
16637
|
"src/lib/reminders.ts"() {
|
|
@@ -17108,18 +17108,18 @@ async function resolveWorkspace(slug_or_id, name) {
|
|
|
17108
17108
|
return rowToWorkspace(existing.rows[0]);
|
|
17109
17109
|
}
|
|
17110
17110
|
const id = crypto13.randomUUID();
|
|
17111
|
-
const
|
|
17111
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
17112
17112
|
const resolvedName = name ?? slug_or_id;
|
|
17113
17113
|
await client.execute({
|
|
17114
17114
|
sql: `INSERT INTO workspaces (id, slug, name, created_at) VALUES (?, ?, ?, ?)`,
|
|
17115
|
-
args: [id, slug_or_id, resolvedName,
|
|
17115
|
+
args: [id, slug_or_id, resolvedName, now2]
|
|
17116
17116
|
});
|
|
17117
17117
|
return {
|
|
17118
17118
|
id,
|
|
17119
17119
|
slug: slug_or_id,
|
|
17120
17120
|
name: resolvedName,
|
|
17121
17121
|
owner_agent_id: null,
|
|
17122
|
-
created_at:
|
|
17122
|
+
created_at: now2,
|
|
17123
17123
|
metadata: null
|
|
17124
17124
|
};
|
|
17125
17125
|
}
|
|
@@ -17273,10 +17273,10 @@ async function deleteDocumentAndChunks(id) {
|
|
|
17273
17273
|
args: [id]
|
|
17274
17274
|
});
|
|
17275
17275
|
const deletedChunks = Number(countResult.rows[0]?.cnt) || 0;
|
|
17276
|
-
const
|
|
17276
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
17277
17277
|
await client.batch(
|
|
17278
17278
|
[
|
|
17279
|
-
{ sql: "UPDATE memories SET status = 'deleted', deleted_at = ? WHERE document_id = ? AND COALESCE(status, 'active') = 'active'", args: [
|
|
17279
|
+
{ sql: "UPDATE memories SET status = 'deleted', deleted_at = ? WHERE document_id = ? AND COALESCE(status, 'active') = 'active'", args: [now2, id] },
|
|
17280
17280
|
{ sql: "DELETE FROM documents WHERE id = ?", args: [id] }
|
|
17281
17281
|
],
|
|
17282
17282
|
"write"
|
|
@@ -18813,12 +18813,12 @@ function registerExportGraph(server) {
|
|
|
18813
18813
|
}
|
|
18814
18814
|
const html = await exportGraphHTML(client);
|
|
18815
18815
|
const fs = await import("fs");
|
|
18816
|
-
const
|
|
18817
|
-
const
|
|
18818
|
-
const outDir =
|
|
18816
|
+
const path58 = await import("path");
|
|
18817
|
+
const os25 = await import("os");
|
|
18818
|
+
const outDir = path58.join(os25.homedir(), ".exe-os", "exports");
|
|
18819
18819
|
fs.mkdirSync(outDir, { recursive: true });
|
|
18820
18820
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18821
|
-
const filePath =
|
|
18821
|
+
const filePath = path58.join(outDir, `graph-${timestamp}.html`);
|
|
18822
18822
|
fs.writeFileSync(filePath, html, "utf-8");
|
|
18823
18823
|
return {
|
|
18824
18824
|
content: [
|
|
@@ -20944,18 +20944,18 @@ async function pollIdleEmployees(deps, lastNudge) {
|
|
|
20944
20944
|
return [];
|
|
20945
20945
|
}
|
|
20946
20946
|
const nudged = [];
|
|
20947
|
-
const
|
|
20947
|
+
const now2 = Date.now();
|
|
20948
20948
|
for (const entry of registered) {
|
|
20949
20949
|
if (!liveSessions.has(entry.windowName)) continue;
|
|
20950
20950
|
const state = deps.getSessionState(entry.windowName);
|
|
20951
20951
|
const lastMs = lastNudge.get(entry.windowName) ?? 0;
|
|
20952
20952
|
if (state !== "idle") continue;
|
|
20953
|
-
if (
|
|
20953
|
+
if (now2 - lastMs < IDLE_NUDGE_DEDUP_MS) continue;
|
|
20954
20954
|
const task = await deps.queryOpenTask(entry.agentId);
|
|
20955
20955
|
if (!task) continue;
|
|
20956
|
-
if (shouldNudgeEmployee(state, true, lastMs,
|
|
20956
|
+
if (shouldNudgeEmployee(state, true, lastMs, now2, IDLE_NUDGE_DEDUP_MS)) {
|
|
20957
20957
|
deps.sendIntercom(entry.windowName);
|
|
20958
|
-
lastNudge.set(entry.windowName,
|
|
20958
|
+
lastNudge.set(entry.windowName, now2);
|
|
20959
20959
|
nudged.push(entry.windowName);
|
|
20960
20960
|
}
|
|
20961
20961
|
}
|
|
@@ -21099,10 +21099,10 @@ async function pollReviewNudge(deps, state) {
|
|
|
21099
21099
|
}
|
|
21100
21100
|
if (sessions.length === 0) return [];
|
|
21101
21101
|
const nudged = [];
|
|
21102
|
-
const
|
|
21102
|
+
const now2 = Date.now();
|
|
21103
21103
|
for (const exeSession of sessions) {
|
|
21104
21104
|
const prev = state.lastNudge.get(exeSession);
|
|
21105
|
-
if (prev &&
|
|
21105
|
+
if (prev && now2 - prev.at < REVIEW_NUDGE_COOLDOWN_MS) continue;
|
|
21106
21106
|
const sessionState = deps.getSessionState(exeSession);
|
|
21107
21107
|
if (sessionState !== "idle") continue;
|
|
21108
21108
|
let count;
|
|
@@ -21115,7 +21115,7 @@ async function pollReviewNudge(deps, state) {
|
|
|
21115
21115
|
if (prev && prev.count === count) continue;
|
|
21116
21116
|
try {
|
|
21117
21117
|
deps.sendNudge(exeSession);
|
|
21118
|
-
state.lastNudge.set(exeSession, { at:
|
|
21118
|
+
state.lastNudge.set(exeSession, { at: now2, count });
|
|
21119
21119
|
nudged.push(exeSession);
|
|
21120
21120
|
} catch {
|
|
21121
21121
|
}
|
|
@@ -23016,10 +23016,10 @@ async function fixDuplicates(client, duplicates, dryRun) {
|
|
|
23016
23016
|
continue;
|
|
23017
23017
|
}
|
|
23018
23018
|
const placeholders = dup.delete_ids.map(() => "?").join(",");
|
|
23019
|
-
const
|
|
23019
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
23020
23020
|
await client.execute({
|
|
23021
23021
|
sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE id IN (${placeholders})`,
|
|
23022
|
-
args: [
|
|
23022
|
+
args: [now2, ...dup.delete_ids]
|
|
23023
23023
|
});
|
|
23024
23024
|
deleted += dup.delete_ids.length;
|
|
23025
23025
|
}
|
|
@@ -25781,16 +25781,16 @@ var init_hostinger_api = __esm({
|
|
|
25781
25781
|
// Internal
|
|
25782
25782
|
// -----------------------------------------------------------------------
|
|
25783
25783
|
async rateLimit() {
|
|
25784
|
-
const
|
|
25785
|
-
const elapsed =
|
|
25784
|
+
const now2 = Date.now();
|
|
25785
|
+
const elapsed = now2 - this.lastRequestTime;
|
|
25786
25786
|
if (elapsed < RATE_LIMIT_DELAY_MS) {
|
|
25787
25787
|
await new Promise((resolve) => setTimeout(resolve, RATE_LIMIT_DELAY_MS - elapsed));
|
|
25788
25788
|
}
|
|
25789
25789
|
this.lastRequestTime = Date.now();
|
|
25790
25790
|
}
|
|
25791
|
-
async request(method,
|
|
25791
|
+
async request(method, path58, body) {
|
|
25792
25792
|
await this.rateLimit();
|
|
25793
|
-
const url = `${this.baseUrl}${
|
|
25793
|
+
const url = `${this.baseUrl}${path58}`;
|
|
25794
25794
|
const headers = {
|
|
25795
25795
|
Authorization: `Bearer ${this.apiKey}`,
|
|
25796
25796
|
"Content-Type": "application/json",
|
|
@@ -25859,8 +25859,8 @@ async function requestCloudflare(cfApiToken, zoneId, options) {
|
|
|
25859
25859
|
}
|
|
25860
25860
|
return envelope.result;
|
|
25861
25861
|
}
|
|
25862
|
-
function buildUrl(zoneId,
|
|
25863
|
-
const normalizedPath =
|
|
25862
|
+
function buildUrl(zoneId, path58 = "/dns_records", query) {
|
|
25863
|
+
const normalizedPath = path58.startsWith("/") ? path58 : `/${path58}`;
|
|
25864
25864
|
const url = new URL(
|
|
25865
25865
|
`${CLOUDFLARE_API_BASE_URL}/zones/${zoneId}${normalizedPath}`
|
|
25866
25866
|
);
|
|
@@ -26639,7 +26639,7 @@ async function createSchedule(input) {
|
|
|
26639
26639
|
await ensureDb();
|
|
26640
26640
|
const client = getClient();
|
|
26641
26641
|
const id = crypto17.randomUUID().slice(0, 8);
|
|
26642
|
-
const
|
|
26642
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26643
26643
|
const prompt = input.prompt ?? input.description;
|
|
26644
26644
|
await client.execute({
|
|
26645
26645
|
sql: `INSERT INTO schedules (id, cron, description, job_type, prompt, assigned_to, project_name, active, use_crontab, created_at)
|
|
@@ -26653,7 +26653,7 @@ async function createSchedule(input) {
|
|
|
26653
26653
|
input.assignedTo ?? null,
|
|
26654
26654
|
input.projectName ?? null,
|
|
26655
26655
|
input.useCrontab ? 1 : 0,
|
|
26656
|
-
|
|
26656
|
+
now2
|
|
26657
26657
|
]
|
|
26658
26658
|
});
|
|
26659
26659
|
if (input.useCrontab) {
|
|
@@ -26669,7 +26669,7 @@ async function createSchedule(input) {
|
|
|
26669
26669
|
projectName: input.projectName,
|
|
26670
26670
|
active: true,
|
|
26671
26671
|
useCrontab: input.useCrontab ?? false,
|
|
26672
|
-
createdAt:
|
|
26672
|
+
createdAt: now2
|
|
26673
26673
|
};
|
|
26674
26674
|
}
|
|
26675
26675
|
function addToCrontab(id, cron, prompt, projectDir) {
|
|
@@ -31005,14 +31005,14 @@ function _resetNudgeState() {
|
|
|
31005
31005
|
}
|
|
31006
31006
|
async function runTaskEnforcementTick(deps) {
|
|
31007
31007
|
const { transport, employees, client, scopeFilter } = deps;
|
|
31008
|
-
const
|
|
31008
|
+
const now2 = deps.now ?? Date.now();
|
|
31009
31009
|
const sessions = transport.listSessions();
|
|
31010
31010
|
for (const session of sessions) {
|
|
31011
31011
|
if (!session.includes("-")) continue;
|
|
31012
31012
|
const agentName = session.split("-")[0]?.replace(/\d+$/, "");
|
|
31013
31013
|
if (!agentName) continue;
|
|
31014
31014
|
const lastNudgeTime = _lastNudge.get(session) ?? 0;
|
|
31015
|
-
if (
|
|
31015
|
+
if (now2 - lastNudgeTime < TASK_ENFORCEMENT_DEBOUNCE_MS) {
|
|
31016
31016
|
continue;
|
|
31017
31017
|
}
|
|
31018
31018
|
const employee = employees.find((e) => e.name === agentName);
|
|
@@ -31057,7 +31057,7 @@ async function runTaskEnforcementTick(deps) {
|
|
|
31057
31057
|
});
|
|
31058
31058
|
const newestCreatedAt = newestResult.rows[0]?.created_at;
|
|
31059
31059
|
if (newestCreatedAt) {
|
|
31060
|
-
const taskAge =
|
|
31060
|
+
const taskAge = now2 - new Date(newestCreatedAt).getTime();
|
|
31061
31061
|
if (taskAge < MANAGER_GRACE_PERIOD_MS) {
|
|
31062
31062
|
withinGracePeriod = true;
|
|
31063
31063
|
graceRemaining = Math.round((MANAGER_GRACE_PERIOD_MS - taskAge) / 1e3);
|
|
@@ -31073,7 +31073,7 @@ async function runTaskEnforcementTick(deps) {
|
|
|
31073
31073
|
else if (action === "nudge") reason = `${openTasks} open tasks, 0 delegated, pane idle`;
|
|
31074
31074
|
else if (action === "soft_nudge") reason = `${openTasks} open tasks, ${activeSubtasks} delegated, pane idle`;
|
|
31075
31075
|
writeAuditEntry({
|
|
31076
|
-
timestamp: new Date(
|
|
31076
|
+
timestamp: new Date(now2).toISOString(),
|
|
31077
31077
|
session,
|
|
31078
31078
|
agent: agentName,
|
|
31079
31079
|
role: "manager",
|
|
@@ -31104,7 +31104,7 @@ async function runTaskEnforcementTick(deps) {
|
|
|
31104
31104
|
else if (action === "idle") reason = `${taskCount} tasks but pane active`;
|
|
31105
31105
|
else if (action === "nudge") reason = `${taskCount} tasks, pane idle`;
|
|
31106
31106
|
writeAuditEntry({
|
|
31107
|
-
timestamp: new Date(
|
|
31107
|
+
timestamp: new Date(now2).toISOString(),
|
|
31108
31108
|
session,
|
|
31109
31109
|
agent: agentName,
|
|
31110
31110
|
role: "worker",
|
|
@@ -31120,7 +31120,7 @@ async function runTaskEnforcementTick(deps) {
|
|
|
31120
31120
|
}
|
|
31121
31121
|
if (action === "skip" || action === "idle" || action === "grace_period" || action === "active") continue;
|
|
31122
31122
|
queueIntercom(session, `enforcement: ${reason}`);
|
|
31123
|
-
_lastNudge.set(session,
|
|
31123
|
+
_lastNudge.set(session, now2);
|
|
31124
31124
|
} catch {
|
|
31125
31125
|
}
|
|
31126
31126
|
}
|
|
@@ -31150,6 +31150,303 @@ var init_task_enforcement = __esm({
|
|
|
31150
31150
|
}
|
|
31151
31151
|
});
|
|
31152
31152
|
|
|
31153
|
+
// src/lib/background-jobs.ts
|
|
31154
|
+
var background_jobs_exports = {};
|
|
31155
|
+
__export(background_jobs_exports, {
|
|
31156
|
+
acquireJobLock: () => acquireJobLock,
|
|
31157
|
+
cancelBackgroundJob: () => cancelBackgroundJob,
|
|
31158
|
+
enforceBackgroundJobGuardrails: () => enforceBackgroundJobGuardrails,
|
|
31159
|
+
formatJobs: () => formatJobs,
|
|
31160
|
+
listBackgroundJobs: () => listBackgroundJobs,
|
|
31161
|
+
politeBatchPause: () => politeBatchPause,
|
|
31162
|
+
releaseJobLock: () => releaseJobLock,
|
|
31163
|
+
reniceCurrentProcess: () => reniceCurrentProcess,
|
|
31164
|
+
startManagedJob: () => startManagedJob
|
|
31165
|
+
});
|
|
31166
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync21, readFileSync as readFileSync34, writeFileSync as writeFileSync25, unlinkSync as unlinkSync13 } from "fs";
|
|
31167
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
31168
|
+
import os22 from "os";
|
|
31169
|
+
import path54 from "path";
|
|
31170
|
+
function ensureDirs() {
|
|
31171
|
+
mkdirSync21(LOCK_DIR, { recursive: true });
|
|
31172
|
+
}
|
|
31173
|
+
function now() {
|
|
31174
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
31175
|
+
}
|
|
31176
|
+
function isAlive(pid) {
|
|
31177
|
+
if (!pid || pid <= 0) return false;
|
|
31178
|
+
try {
|
|
31179
|
+
process.kill(pid, 0);
|
|
31180
|
+
return true;
|
|
31181
|
+
} catch {
|
|
31182
|
+
return false;
|
|
31183
|
+
}
|
|
31184
|
+
}
|
|
31185
|
+
function readJobsRaw() {
|
|
31186
|
+
ensureDirs();
|
|
31187
|
+
if (!existsSync42(JOBS_FILE)) return [];
|
|
31188
|
+
try {
|
|
31189
|
+
const parsed = JSON.parse(readFileSync34(JOBS_FILE, "utf8"));
|
|
31190
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
31191
|
+
} catch {
|
|
31192
|
+
return [];
|
|
31193
|
+
}
|
|
31194
|
+
}
|
|
31195
|
+
function writeJobsRaw(jobs) {
|
|
31196
|
+
ensureDirs();
|
|
31197
|
+
const running2 = jobs.filter((j) => j.status === "running");
|
|
31198
|
+
const rest = jobs.filter((j) => j.status !== "running").slice(-MAX_HISTORY);
|
|
31199
|
+
writeFileSync25(JOBS_FILE, JSON.stringify([...rest, ...running2], null, 2) + "\n");
|
|
31200
|
+
}
|
|
31201
|
+
function listBackgroundJobs() {
|
|
31202
|
+
const jobs = readJobsRaw();
|
|
31203
|
+
let changed = false;
|
|
31204
|
+
for (const job of jobs) {
|
|
31205
|
+
if (job.status === "running" && !isAlive(job.pid)) {
|
|
31206
|
+
job.status = "stale";
|
|
31207
|
+
job.updatedAt = now();
|
|
31208
|
+
changed = true;
|
|
31209
|
+
}
|
|
31210
|
+
}
|
|
31211
|
+
if (changed) writeJobsRaw(jobs);
|
|
31212
|
+
return jobs;
|
|
31213
|
+
}
|
|
31214
|
+
function lockPath(type) {
|
|
31215
|
+
return path54.join(LOCK_DIR, `${type.replace(/[^a-zA-Z0-9_.-]/g, "_")}.lock`);
|
|
31216
|
+
}
|
|
31217
|
+
function acquireJobLock(type, ttlMs = DEFAULT_LOCK_TTL_MS) {
|
|
31218
|
+
ensureDirs();
|
|
31219
|
+
const file = lockPath(type);
|
|
31220
|
+
if (existsSync42(file)) {
|
|
31221
|
+
try {
|
|
31222
|
+
const lock = JSON.parse(readFileSync34(file, "utf8"));
|
|
31223
|
+
const age = Date.now() - Date.parse(lock.updatedAt ?? "");
|
|
31224
|
+
if (lock.pid && isAlive(lock.pid) && Number.isFinite(age) && age < ttlMs) return false;
|
|
31225
|
+
} catch {
|
|
31226
|
+
}
|
|
31227
|
+
try {
|
|
31228
|
+
unlinkSync13(file);
|
|
31229
|
+
} catch {
|
|
31230
|
+
}
|
|
31231
|
+
}
|
|
31232
|
+
try {
|
|
31233
|
+
writeFileSync25(file, JSON.stringify({ pid: process.pid, updatedAt: now() }, null, 2) + "\n", { flag: "wx" });
|
|
31234
|
+
return true;
|
|
31235
|
+
} catch {
|
|
31236
|
+
return false;
|
|
31237
|
+
}
|
|
31238
|
+
}
|
|
31239
|
+
function releaseJobLock(type) {
|
|
31240
|
+
const file = lockPath(type);
|
|
31241
|
+
try {
|
|
31242
|
+
if (!existsSync42(file)) return;
|
|
31243
|
+
const lock = JSON.parse(readFileSync34(file, "utf8"));
|
|
31244
|
+
if (lock.pid === process.pid || !lock.pid || !isAlive(lock.pid)) unlinkSync13(file);
|
|
31245
|
+
} catch {
|
|
31246
|
+
try {
|
|
31247
|
+
unlinkSync13(file);
|
|
31248
|
+
} catch {
|
|
31249
|
+
}
|
|
31250
|
+
}
|
|
31251
|
+
}
|
|
31252
|
+
function startManagedJob(options) {
|
|
31253
|
+
const lowPriority = options.lowPriority ?? true;
|
|
31254
|
+
if (!acquireJobLock(options.type, options.lockTtlMs)) return null;
|
|
31255
|
+
if (lowPriority) {
|
|
31256
|
+
try {
|
|
31257
|
+
os22.setPriority(process.pid, 10);
|
|
31258
|
+
} catch {
|
|
31259
|
+
}
|
|
31260
|
+
}
|
|
31261
|
+
const id = `${options.type}-${Date.now()}-${process.pid}`.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
31262
|
+
const record = {
|
|
31263
|
+
id,
|
|
31264
|
+
type: options.type,
|
|
31265
|
+
name: options.name,
|
|
31266
|
+
pid: process.pid,
|
|
31267
|
+
command: options.command ?? process.argv.join(" "),
|
|
31268
|
+
cwd: process.cwd(),
|
|
31269
|
+
status: "running",
|
|
31270
|
+
startedAt: now(),
|
|
31271
|
+
updatedAt: now(),
|
|
31272
|
+
lastHeartbeatAt: now(),
|
|
31273
|
+
cancelCommand: `exe-os jobs cancel ${id}`,
|
|
31274
|
+
lowPriority
|
|
31275
|
+
};
|
|
31276
|
+
const upsert = (patch) => {
|
|
31277
|
+
const jobs = readJobsRaw().filter((j) => j.id !== id);
|
|
31278
|
+
Object.assign(record, patch, { updatedAt: now() });
|
|
31279
|
+
writeJobsRaw([...jobs, record]);
|
|
31280
|
+
const file = lockPath(options.type);
|
|
31281
|
+
try {
|
|
31282
|
+
writeFileSync25(file, JSON.stringify({ pid: process.pid, jobId: id, updatedAt: record.updatedAt }, null, 2) + "\n");
|
|
31283
|
+
} catch {
|
|
31284
|
+
}
|
|
31285
|
+
};
|
|
31286
|
+
upsert({});
|
|
31287
|
+
const timer = setInterval(() => upsert({ lastHeartbeatAt: now() }), 3e4);
|
|
31288
|
+
timer.unref?.();
|
|
31289
|
+
const cleanup = (status, error) => {
|
|
31290
|
+
clearInterval(timer);
|
|
31291
|
+
upsert({ status, error, lastHeartbeatAt: now() });
|
|
31292
|
+
releaseJobLock(options.type);
|
|
31293
|
+
};
|
|
31294
|
+
process.once("SIGTERM", () => {
|
|
31295
|
+
cleanup("cancelled");
|
|
31296
|
+
process.exit(0);
|
|
31297
|
+
});
|
|
31298
|
+
process.once("SIGINT", () => {
|
|
31299
|
+
cleanup("cancelled");
|
|
31300
|
+
process.exit(130);
|
|
31301
|
+
});
|
|
31302
|
+
process.once("exit", () => releaseJobLock(options.type));
|
|
31303
|
+
return {
|
|
31304
|
+
id,
|
|
31305
|
+
update(progress) {
|
|
31306
|
+
upsert({ progressCurrent: progress.current, progressTotal: progress.total, progressLabel: progress.label, lastHeartbeatAt: now() });
|
|
31307
|
+
},
|
|
31308
|
+
complete() {
|
|
31309
|
+
cleanup("completed");
|
|
31310
|
+
},
|
|
31311
|
+
fail(err) {
|
|
31312
|
+
cleanup("failed", err instanceof Error ? err.message : String(err));
|
|
31313
|
+
},
|
|
31314
|
+
cancel() {
|
|
31315
|
+
cleanup("cancelled");
|
|
31316
|
+
}
|
|
31317
|
+
};
|
|
31318
|
+
}
|
|
31319
|
+
async function politeBatchPause(ms = 250) {
|
|
31320
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
31321
|
+
}
|
|
31322
|
+
function cancelBackgroundJob(id) {
|
|
31323
|
+
const jobs = listBackgroundJobs();
|
|
31324
|
+
const job = jobs.find((j) => j.id === id || String(j.pid) === id);
|
|
31325
|
+
if (!job) return null;
|
|
31326
|
+
if (job.status === "running" && isAlive(job.pid)) {
|
|
31327
|
+
try {
|
|
31328
|
+
process.kill(job.pid, "SIGTERM");
|
|
31329
|
+
} catch {
|
|
31330
|
+
}
|
|
31331
|
+
}
|
|
31332
|
+
job.status = "cancelled";
|
|
31333
|
+
job.updatedAt = now();
|
|
31334
|
+
writeJobsRaw(jobs.map((j) => j.id === job.id ? job : j));
|
|
31335
|
+
releaseJobLock(job.type);
|
|
31336
|
+
return job;
|
|
31337
|
+
}
|
|
31338
|
+
function formatJobs(jobs = listBackgroundJobs()) {
|
|
31339
|
+
if (jobs.length === 0) return "No exe-os background jobs found.";
|
|
31340
|
+
const recent = [...jobs].sort((a, b) => b.startedAt.localeCompare(a.startedAt)).slice(0, 30);
|
|
31341
|
+
const lines = ["EXE OS BACKGROUND JOBS", ""];
|
|
31342
|
+
for (const job of recent) {
|
|
31343
|
+
const progress = job.progressTotal ? ` ${job.progressCurrent ?? 0}/${job.progressTotal}` : job.progressCurrent != null ? ` ${job.progressCurrent}` : "";
|
|
31344
|
+
lines.push(`${job.status === "running" ? "\u25CF" : "\u25CB"} ${job.name} [${job.status}]${progress}`);
|
|
31345
|
+
lines.push(` id: ${job.id}`);
|
|
31346
|
+
lines.push(` pid: ${job.pid} started: ${job.startedAt}`);
|
|
31347
|
+
if (job.progressLabel) lines.push(` ${job.progressLabel}`);
|
|
31348
|
+
if (job.status === "running") lines.push(` cancel: exe-os jobs cancel ${job.id}`);
|
|
31349
|
+
if (job.error) lines.push(` error: ${job.error}`);
|
|
31350
|
+
}
|
|
31351
|
+
return lines.join("\n");
|
|
31352
|
+
}
|
|
31353
|
+
function reniceCurrentProcess(priority = 10) {
|
|
31354
|
+
try {
|
|
31355
|
+
os22.setPriority(process.pid, priority);
|
|
31356
|
+
return;
|
|
31357
|
+
} catch {
|
|
31358
|
+
}
|
|
31359
|
+
try {
|
|
31360
|
+
execFileSync3("renice", [String(priority), "-p", String(process.pid)], { stdio: "ignore" });
|
|
31361
|
+
} catch {
|
|
31362
|
+
}
|
|
31363
|
+
}
|
|
31364
|
+
function readCpuPercent(pid) {
|
|
31365
|
+
try {
|
|
31366
|
+
const out = execFileSync3("ps", ["-p", String(pid), "-o", "%cpu="], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
31367
|
+
const cpu = Number.parseFloat(out);
|
|
31368
|
+
return Number.isFinite(cpu) ? cpu : null;
|
|
31369
|
+
} catch {
|
|
31370
|
+
return null;
|
|
31371
|
+
}
|
|
31372
|
+
}
|
|
31373
|
+
function renicePid(pid, priority = 15) {
|
|
31374
|
+
try {
|
|
31375
|
+
execFileSync3("renice", [String(priority), "-p", String(pid)], { stdio: "ignore" });
|
|
31376
|
+
} catch {
|
|
31377
|
+
}
|
|
31378
|
+
}
|
|
31379
|
+
function enforceBackgroundJobGuardrails(options = {}) {
|
|
31380
|
+
const reniceAt = options.reniceCpuPercent ?? 80;
|
|
31381
|
+
const cancelAt = options.cancelCpuPercent ?? 180;
|
|
31382
|
+
const cancelAfter = options.cancelAfterStrikes ?? 2;
|
|
31383
|
+
const staleAfter = options.heartbeatStaleMs ?? 5 * 6e4;
|
|
31384
|
+
const jobs = readJobsRaw();
|
|
31385
|
+
const actions = [];
|
|
31386
|
+
let changed = false;
|
|
31387
|
+
const ts2 = now();
|
|
31388
|
+
for (const job of jobs) {
|
|
31389
|
+
if (job.status !== "running") continue;
|
|
31390
|
+
if (!isAlive(job.pid)) {
|
|
31391
|
+
job.status = "stale";
|
|
31392
|
+
job.updatedAt = ts2;
|
|
31393
|
+
actions.push({ jobId: job.id, name: job.name, pid: job.pid, action: "marked-stale" });
|
|
31394
|
+
changed = true;
|
|
31395
|
+
continue;
|
|
31396
|
+
}
|
|
31397
|
+
const heartbeatAge = Date.now() - Date.parse(job.lastHeartbeatAt || job.updatedAt || job.startedAt);
|
|
31398
|
+
if (Number.isFinite(heartbeatAge) && heartbeatAge > staleAfter) {
|
|
31399
|
+
job.status = "stale";
|
|
31400
|
+
job.updatedAt = ts2;
|
|
31401
|
+
actions.push({ jobId: job.id, name: job.name, pid: job.pid, action: "marked-stale" });
|
|
31402
|
+
changed = true;
|
|
31403
|
+
continue;
|
|
31404
|
+
}
|
|
31405
|
+
const cpu = readCpuPercent(job.pid);
|
|
31406
|
+
if (cpu == null) continue;
|
|
31407
|
+
job.lastCpuPercent = cpu;
|
|
31408
|
+
if (cpu >= cancelAt) {
|
|
31409
|
+
job.heatStrikes = (job.heatStrikes ?? 0) + 1;
|
|
31410
|
+
if (job.heatStrikes >= cancelAfter) {
|
|
31411
|
+
try {
|
|
31412
|
+
process.kill(job.pid, "SIGTERM");
|
|
31413
|
+
} catch {
|
|
31414
|
+
}
|
|
31415
|
+
job.status = "cancelled";
|
|
31416
|
+
job.updatedAt = ts2;
|
|
31417
|
+
job.progressLabel = `Cancelled by heat guardrail after sustained high CPU (${cpu.toFixed(1)}%).`;
|
|
31418
|
+
releaseJobLock(job.type);
|
|
31419
|
+
actions.push({ jobId: job.id, name: job.name, pid: job.pid, action: "cancelled-hot", cpuPercent: cpu, heatStrikes: job.heatStrikes });
|
|
31420
|
+
changed = true;
|
|
31421
|
+
continue;
|
|
31422
|
+
}
|
|
31423
|
+
} else if (cpu < reniceAt / 2) {
|
|
31424
|
+
job.heatStrikes = 0;
|
|
31425
|
+
}
|
|
31426
|
+
if (cpu >= reniceAt) {
|
|
31427
|
+
renicePid(job.pid, 15);
|
|
31428
|
+
job.updatedAt = ts2;
|
|
31429
|
+
job.progressLabel = `Throttled by heat guardrail (${cpu.toFixed(1)}% CPU).`;
|
|
31430
|
+
actions.push({ jobId: job.id, name: job.name, pid: job.pid, action: "reniced", cpuPercent: cpu, heatStrikes: job.heatStrikes });
|
|
31431
|
+
changed = true;
|
|
31432
|
+
}
|
|
31433
|
+
}
|
|
31434
|
+
if (changed) writeJobsRaw(jobs);
|
|
31435
|
+
return actions;
|
|
31436
|
+
}
|
|
31437
|
+
var JOB_DIR, JOBS_FILE, LOCK_DIR, DEFAULT_LOCK_TTL_MS, MAX_HISTORY;
|
|
31438
|
+
var init_background_jobs = __esm({
|
|
31439
|
+
"src/lib/background-jobs.ts"() {
|
|
31440
|
+
"use strict";
|
|
31441
|
+
init_config();
|
|
31442
|
+
JOB_DIR = path54.join(EXE_AI_DIR, "jobs");
|
|
31443
|
+
JOBS_FILE = path54.join(JOB_DIR, "jobs.json");
|
|
31444
|
+
LOCK_DIR = path54.join(JOB_DIR, "locks");
|
|
31445
|
+
DEFAULT_LOCK_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
31446
|
+
MAX_HISTORY = 200;
|
|
31447
|
+
}
|
|
31448
|
+
});
|
|
31449
|
+
|
|
31153
31450
|
// src/lib/update-check.ts
|
|
31154
31451
|
var update_check_exports = {};
|
|
31155
31452
|
__export(update_check_exports, {
|
|
@@ -31158,11 +31455,11 @@ __export(update_check_exports, {
|
|
|
31158
31455
|
getRemoteVersion: () => getRemoteVersion
|
|
31159
31456
|
});
|
|
31160
31457
|
import { execSync as execSync15 } from "child_process";
|
|
31161
|
-
import { readFileSync as
|
|
31162
|
-
import
|
|
31458
|
+
import { readFileSync as readFileSync35 } from "fs";
|
|
31459
|
+
import path55 from "path";
|
|
31163
31460
|
function getLocalVersion(packageRoot) {
|
|
31164
|
-
const pkgPath =
|
|
31165
|
-
const pkg = JSON.parse(
|
|
31461
|
+
const pkgPath = path55.join(packageRoot, "package.json");
|
|
31462
|
+
const pkg = JSON.parse(readFileSync35(pkgPath, "utf-8"));
|
|
31166
31463
|
return pkg.version;
|
|
31167
31464
|
}
|
|
31168
31465
|
function getRemoteVersion() {
|
|
@@ -31233,13 +31530,13 @@ __export(device_registry_exports, {
|
|
|
31233
31530
|
setFriendlyName: () => setFriendlyName
|
|
31234
31531
|
});
|
|
31235
31532
|
import crypto22 from "crypto";
|
|
31236
|
-
import
|
|
31237
|
-
import { readFileSync as
|
|
31238
|
-
import
|
|
31533
|
+
import os23 from "os";
|
|
31534
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync26, mkdirSync as mkdirSync22, existsSync as existsSync43 } from "fs";
|
|
31535
|
+
import path56 from "path";
|
|
31239
31536
|
function getDeviceInfo() {
|
|
31240
|
-
if (
|
|
31537
|
+
if (existsSync43(DEVICE_JSON_PATH)) {
|
|
31241
31538
|
try {
|
|
31242
|
-
const raw =
|
|
31539
|
+
const raw = readFileSync36(DEVICE_JSON_PATH, "utf8");
|
|
31243
31540
|
const data = JSON.parse(raw);
|
|
31244
31541
|
if (data.deviceId && data.friendlyName && data.hostname) {
|
|
31245
31542
|
return data;
|
|
@@ -31247,20 +31544,20 @@ function getDeviceInfo() {
|
|
|
31247
31544
|
} catch {
|
|
31248
31545
|
}
|
|
31249
31546
|
}
|
|
31250
|
-
const hostname =
|
|
31547
|
+
const hostname = os23.hostname();
|
|
31251
31548
|
const info = {
|
|
31252
31549
|
deviceId: crypto22.randomUUID(),
|
|
31253
31550
|
friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
|
|
31254
31551
|
hostname
|
|
31255
31552
|
};
|
|
31256
|
-
|
|
31257
|
-
|
|
31553
|
+
mkdirSync22(path56.dirname(DEVICE_JSON_PATH), { recursive: true });
|
|
31554
|
+
writeFileSync26(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
|
|
31258
31555
|
return info;
|
|
31259
31556
|
}
|
|
31260
31557
|
function setFriendlyName(name) {
|
|
31261
31558
|
const info = getDeviceInfo();
|
|
31262
31559
|
info.friendlyName = name;
|
|
31263
|
-
|
|
31560
|
+
writeFileSync26(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
|
|
31264
31561
|
}
|
|
31265
31562
|
async function resolveTargetDevice(targetAgent, targetProject) {
|
|
31266
31563
|
const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
@@ -31294,7 +31591,7 @@ var init_device_registry = __esm({
|
|
|
31294
31591
|
"src/lib/device-registry.ts"() {
|
|
31295
31592
|
"use strict";
|
|
31296
31593
|
init_config();
|
|
31297
|
-
DEVICE_JSON_PATH =
|
|
31594
|
+
DEVICE_JSON_PATH = path56.join(EXE_AI_DIR, "device.json");
|
|
31298
31595
|
}
|
|
31299
31596
|
});
|
|
31300
31597
|
|
|
@@ -31506,12 +31803,12 @@ init_config();
|
|
|
31506
31803
|
init_memory();
|
|
31507
31804
|
init_daemon_protocol();
|
|
31508
31805
|
init_daemon_auth();
|
|
31509
|
-
import
|
|
31806
|
+
import os24 from "os";
|
|
31510
31807
|
import net2 from "net";
|
|
31511
31808
|
import { createServer as createHttpServer } from "http";
|
|
31512
31809
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
31513
|
-
import { writeFileSync as
|
|
31514
|
-
import
|
|
31810
|
+
import { appendFileSync as appendFileSync4, writeFileSync as writeFileSync27, unlinkSync as unlinkSync14, mkdirSync as mkdirSync23, existsSync as existsSync44, readFileSync as readFileSync37, chmodSync as chmodSync2 } from "fs";
|
|
31811
|
+
import path57 from "path";
|
|
31515
31812
|
|
|
31516
31813
|
// src/lib/orchestration-metrics.ts
|
|
31517
31814
|
init_config();
|
|
@@ -31583,10 +31880,10 @@ function initMetrics() {
|
|
|
31583
31880
|
|
|
31584
31881
|
// src/lib/exe-daemon.ts
|
|
31585
31882
|
init_memory_write_governor();
|
|
31586
|
-
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ??
|
|
31587
|
-
var PID_PATH3 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ??
|
|
31883
|
+
var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path57.join(EXE_AI_DIR, "exed.sock");
|
|
31884
|
+
var PID_PATH3 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path57.join(EXE_AI_DIR, "exed.pid");
|
|
31588
31885
|
var MODEL_FILE = "jina-embeddings-v5-small-q4_k_m.gguf";
|
|
31589
|
-
var IDLE_TIMEOUT_MS2 =
|
|
31886
|
+
var IDLE_TIMEOUT_MS2 = parseInt(process.env.EXE_DAEMON_IDLE_TIMEOUT_MS || "0", 10);
|
|
31590
31887
|
var REVIEW_POLL_INTERVAL_MS = 60 * 1e3;
|
|
31591
31888
|
var DAEMON_TOKEN_ENV2 = "EXE_DAEMON_TOKEN";
|
|
31592
31889
|
var _context = null;
|
|
@@ -31612,8 +31909,8 @@ function enqueue(queue, entry) {
|
|
|
31612
31909
|
queue.push(entry);
|
|
31613
31910
|
}
|
|
31614
31911
|
async function loadModel() {
|
|
31615
|
-
const modelPath =
|
|
31616
|
-
if (!
|
|
31912
|
+
const modelPath = path57.join(MODELS_DIR, MODEL_FILE);
|
|
31913
|
+
if (!existsSync44(modelPath)) {
|
|
31617
31914
|
process.stderr.write(`[exed] No model at ${modelPath} \u2014 running without embeddings (VPS mode).
|
|
31618
31915
|
`);
|
|
31619
31916
|
return;
|
|
@@ -31679,6 +31976,10 @@ function resetIdleTimer2() {
|
|
|
31679
31976
|
}
|
|
31680
31977
|
}
|
|
31681
31978
|
function checkIdle() {
|
|
31979
|
+
if (IDLE_TIMEOUT_MS2 <= 0) {
|
|
31980
|
+
resetIdleTimer2();
|
|
31981
|
+
return;
|
|
31982
|
+
}
|
|
31682
31983
|
if (_activeConnections === 0 && highQueue.length === 0 && lowQueue.length === 0) {
|
|
31683
31984
|
resetIdleTimer2();
|
|
31684
31985
|
_idleTimer2 = setTimeout(() => {
|
|
@@ -31717,11 +32018,11 @@ async function shutdown() {
|
|
|
31717
32018
|
}
|
|
31718
32019
|
_llama = null;
|
|
31719
32020
|
try {
|
|
31720
|
-
|
|
32021
|
+
unlinkSync14(SOCKET_PATH2);
|
|
31721
32022
|
} catch {
|
|
31722
32023
|
}
|
|
31723
32024
|
try {
|
|
31724
|
-
|
|
32025
|
+
unlinkSync14(PID_PATH3);
|
|
31725
32026
|
} catch {
|
|
31726
32027
|
}
|
|
31727
32028
|
process.stderr.write("[exed] Shutdown complete.\n");
|
|
@@ -31873,13 +32174,13 @@ async function handleBatchWriteMemory(socket, requestId, entries) {
|
|
|
31873
32174
|
}
|
|
31874
32175
|
async function writeMemoryRecord(entry) {
|
|
31875
32176
|
const id = randomUUID9();
|
|
31876
|
-
const
|
|
32177
|
+
const now2 = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
31877
32178
|
const governed = governMemoryRecord({
|
|
31878
32179
|
id,
|
|
31879
32180
|
agent_id: entry.agent_id,
|
|
31880
32181
|
agent_role: entry.agent_role ?? "",
|
|
31881
32182
|
session_id: entry.session_id,
|
|
31882
|
-
timestamp:
|
|
32183
|
+
timestamp: now2,
|
|
31883
32184
|
tool_name: entry.tool_name,
|
|
31884
32185
|
project_name: entry.project_name,
|
|
31885
32186
|
has_error: !!entry.has_error,
|
|
@@ -32029,28 +32330,28 @@ function startMemoryQueueDrain() {
|
|
|
32029
32330
|
`);
|
|
32030
32331
|
}
|
|
32031
32332
|
function startServer() {
|
|
32032
|
-
|
|
32333
|
+
mkdirSync23(path57.dirname(SOCKET_PATH2), { recursive: true });
|
|
32033
32334
|
try {
|
|
32034
|
-
chmodSync2(
|
|
32335
|
+
chmodSync2(path57.dirname(SOCKET_PATH2), 448);
|
|
32035
32336
|
} catch {
|
|
32036
32337
|
}
|
|
32037
32338
|
_daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV2] ?? null);
|
|
32038
32339
|
for (const oldFile of ["embed.sock", "embed.pid"]) {
|
|
32039
|
-
const oldPath =
|
|
32340
|
+
const oldPath = path57.join(path57.dirname(SOCKET_PATH2), oldFile);
|
|
32040
32341
|
try {
|
|
32041
32342
|
if (oldFile.endsWith(".pid")) {
|
|
32042
|
-
const pid = parseInt(
|
|
32343
|
+
const pid = parseInt(readFileSync37(oldPath, "utf8").trim(), 10);
|
|
32043
32344
|
if (pid > 0) try {
|
|
32044
32345
|
process.kill(pid, "SIGKILL");
|
|
32045
32346
|
} catch {
|
|
32046
32347
|
}
|
|
32047
32348
|
}
|
|
32048
|
-
|
|
32349
|
+
unlinkSync14(oldPath);
|
|
32049
32350
|
} catch {
|
|
32050
32351
|
}
|
|
32051
32352
|
}
|
|
32052
32353
|
try {
|
|
32053
|
-
|
|
32354
|
+
unlinkSync14(SOCKET_PATH2);
|
|
32054
32355
|
} catch {
|
|
32055
32356
|
}
|
|
32056
32357
|
const server = net2.createServer((socket) => {
|
|
@@ -32162,14 +32463,31 @@ function startServer() {
|
|
|
32162
32463
|
}
|
|
32163
32464
|
async function startMcpHttpServer() {
|
|
32164
32465
|
try {
|
|
32466
|
+
let recordMcpHttpEvent2 = function(event) {
|
|
32467
|
+
try {
|
|
32468
|
+
appendFileSync4(MCP_HTTP_EVENTS_PATH, JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...event }) + "\n");
|
|
32469
|
+
} catch {
|
|
32470
|
+
}
|
|
32471
|
+
}, sendJsonRpcError2 = function(res, status, message, extra) {
|
|
32472
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
32473
|
+
res.end(JSON.stringify({
|
|
32474
|
+
jsonrpc: "2.0",
|
|
32475
|
+
error: { code: -32e3, message },
|
|
32476
|
+
id: null
|
|
32477
|
+
}));
|
|
32478
|
+
recordMcpHttpEvent2({ level: "warn", message, status, ...extra });
|
|
32479
|
+
};
|
|
32480
|
+
var recordMcpHttpEvent = recordMcpHttpEvent2, sendJsonRpcError = sendJsonRpcError2;
|
|
32165
32481
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
32166
32482
|
const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
32483
|
+
const { isInitializeRequest } = await import("@modelcontextprotocol/sdk/types.js");
|
|
32167
32484
|
const { registerAllTools: registerAllTools2 } = await Promise.resolve().then(() => (init_register_tools(), register_tools_exports));
|
|
32168
32485
|
const { runWithAgent: runWithAgent2 } = await Promise.resolve().then(() => (init_agent_context(), agent_context_exports));
|
|
32169
32486
|
const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
32170
32487
|
await initStore2();
|
|
32171
32488
|
const transports = /* @__PURE__ */ new Map();
|
|
32172
32489
|
const MCP_HTTP_PORT = parseInt(process.env.EXE_MCP_PORT || "48739", 10);
|
|
32490
|
+
const MCP_HTTP_EVENTS_PATH = path57.join(EXE_AI_DIR, "mcp-http-events.jsonl");
|
|
32173
32491
|
const httpServer = createHttpServer(async (req, res) => {
|
|
32174
32492
|
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1");
|
|
32175
32493
|
res.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
|
|
@@ -32194,40 +32512,102 @@ async function startMcpHttpServer() {
|
|
|
32194
32512
|
}
|
|
32195
32513
|
const agentId = req.headers["x-agent-id"] || "default";
|
|
32196
32514
|
const agentRole = req.headers["x-agent-role"] || "employee";
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32200
|
-
data
|
|
32515
|
+
let parsedBody;
|
|
32516
|
+
try {
|
|
32517
|
+
const body = await new Promise((resolve) => {
|
|
32518
|
+
let data = "";
|
|
32519
|
+
req.on("data", (chunk) => {
|
|
32520
|
+
data += chunk.toString();
|
|
32521
|
+
});
|
|
32522
|
+
req.on("end", () => resolve(data));
|
|
32201
32523
|
});
|
|
32202
|
-
|
|
32203
|
-
})
|
|
32204
|
-
|
|
32524
|
+
parsedBody = body ? JSON.parse(body) : void 0;
|
|
32525
|
+
} catch (err) {
|
|
32526
|
+
sendJsonRpcError2(res, 400, "Bad Request: invalid JSON body", {
|
|
32527
|
+
method: req.method,
|
|
32528
|
+
error: err instanceof Error ? err.message : String(err)
|
|
32529
|
+
});
|
|
32530
|
+
return;
|
|
32531
|
+
}
|
|
32205
32532
|
const sessionId = req.headers["mcp-session-id"];
|
|
32206
32533
|
let transport;
|
|
32207
32534
|
if (sessionId && transports.has(sessionId)) {
|
|
32208
32535
|
transport = transports.get(sessionId);
|
|
32209
|
-
} else if (!sessionId && req.method === "POST") {
|
|
32536
|
+
} else if (!sessionId && req.method === "POST" && isInitializeRequest(parsedBody)) {
|
|
32210
32537
|
transport = new StreamableHTTPServerTransport({
|
|
32211
32538
|
sessionIdGenerator: () => randomUUID9(),
|
|
32212
32539
|
onsessioninitialized: (sid) => {
|
|
32213
32540
|
transports.set(sid, transport);
|
|
32541
|
+
recordMcpHttpEvent2({
|
|
32542
|
+
level: "info",
|
|
32543
|
+
message: "session_initialized",
|
|
32544
|
+
sessionId: sid,
|
|
32545
|
+
agentId,
|
|
32546
|
+
agentRole,
|
|
32547
|
+
activeSessions: transports.size
|
|
32548
|
+
});
|
|
32214
32549
|
}
|
|
32215
32550
|
});
|
|
32216
32551
|
transport.onclose = () => {
|
|
32217
32552
|
const sid = Array.from(transports.entries()).find(([, t]) => t === transport)?.[0];
|
|
32218
|
-
if (sid)
|
|
32553
|
+
if (sid) {
|
|
32554
|
+
transports.delete(sid);
|
|
32555
|
+
recordMcpHttpEvent2({
|
|
32556
|
+
level: "info",
|
|
32557
|
+
message: "session_closed",
|
|
32558
|
+
sessionId: sid,
|
|
32559
|
+
agentId,
|
|
32560
|
+
agentRole,
|
|
32561
|
+
activeSessions: transports.size
|
|
32562
|
+
});
|
|
32563
|
+
}
|
|
32219
32564
|
};
|
|
32220
32565
|
const sessionMcp = new McpServer({ name: "exe-os", version: "1.3.0" });
|
|
32221
32566
|
registerAllTools2(sessionMcp);
|
|
32222
32567
|
await sessionMcp.connect(transport);
|
|
32223
32568
|
} else {
|
|
32224
|
-
|
|
32225
|
-
res
|
|
32569
|
+
const message = sessionId ? "Bad Request: MCP session is stale or unknown; reconnect MCP client" : "Bad Request: missing MCP session; initialize before tool calls";
|
|
32570
|
+
sendJsonRpcError2(res, 400, message, {
|
|
32571
|
+
method: req.method,
|
|
32572
|
+
hasSessionId: Boolean(sessionId),
|
|
32573
|
+
sessionId,
|
|
32574
|
+
agentId,
|
|
32575
|
+
agentRole,
|
|
32576
|
+
activeSessions: transports.size
|
|
32577
|
+
});
|
|
32226
32578
|
return;
|
|
32227
32579
|
}
|
|
32228
|
-
|
|
32229
|
-
await
|
|
32230
|
-
|
|
32580
|
+
try {
|
|
32581
|
+
await runWithAgent2({ agentId, agentRole }, async () => {
|
|
32582
|
+
await transport.handleRequest(req, res, parsedBody);
|
|
32583
|
+
});
|
|
32584
|
+
recordMcpHttpEvent2({
|
|
32585
|
+
level: "info",
|
|
32586
|
+
message: "request_ok",
|
|
32587
|
+
method: req.method,
|
|
32588
|
+
sessionId: sessionId ?? "new",
|
|
32589
|
+
agentId,
|
|
32590
|
+
agentRole
|
|
32591
|
+
});
|
|
32592
|
+
} catch (err) {
|
|
32593
|
+
recordMcpHttpEvent2({
|
|
32594
|
+
level: "error",
|
|
32595
|
+
message: "request_failed",
|
|
32596
|
+
method: req.method,
|
|
32597
|
+
sessionId,
|
|
32598
|
+
agentId,
|
|
32599
|
+
agentRole,
|
|
32600
|
+
error: err instanceof Error ? err.message : String(err)
|
|
32601
|
+
});
|
|
32602
|
+
if (!res.headersSent) {
|
|
32603
|
+
sendJsonRpcError2(res, 500, "Internal Server Error: MCP request failed", {
|
|
32604
|
+
method: req.method,
|
|
32605
|
+
sessionId,
|
|
32606
|
+
agentId,
|
|
32607
|
+
agentRole
|
|
32608
|
+
});
|
|
32609
|
+
}
|
|
32610
|
+
}
|
|
32231
32611
|
});
|
|
32232
32612
|
httpServer.listen(MCP_HTTP_PORT, "127.0.0.1", () => {
|
|
32233
32613
|
process.stderr.write(`[exed] MCP HTTP listening on 127.0.0.1:${MCP_HTTP_PORT}
|
|
@@ -32512,7 +32892,7 @@ function startGraphExtraction() {
|
|
|
32512
32892
|
`);
|
|
32513
32893
|
}
|
|
32514
32894
|
var AGENT_STATS_INTERVAL_MS = 60 * 1e3;
|
|
32515
|
-
var AGENT_STATS_PATH =
|
|
32895
|
+
var AGENT_STATS_PATH = path57.join(EXE_AI_DIR, "agent-stats.json");
|
|
32516
32896
|
async function writeAgentStats() {
|
|
32517
32897
|
fired("agent_stats");
|
|
32518
32898
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -32572,7 +32952,7 @@ async function writeAgentStats() {
|
|
|
32572
32952
|
pid: process.pid
|
|
32573
32953
|
}
|
|
32574
32954
|
};
|
|
32575
|
-
|
|
32955
|
+
writeFileSync27(AGENT_STATS_PATH, JSON.stringify(stats, null, 2), "utf8");
|
|
32576
32956
|
} catch (err) {
|
|
32577
32957
|
process.stderr.write(`[exed] Agent stats error: ${err instanceof Error ? err.message : String(err)}
|
|
32578
32958
|
`);
|
|
@@ -32689,12 +33069,12 @@ function startIntercomQueueDrain() {
|
|
|
32689
33069
|
const hasInProgressTask = (session) => {
|
|
32690
33070
|
try {
|
|
32691
33071
|
const { baseAgentName: ban } = (init_employees(), __toCommonJS(employees_exports));
|
|
32692
|
-
const
|
|
32693
|
-
const { existsSync:
|
|
32694
|
-
const
|
|
33072
|
+
const path58 = __require("path");
|
|
33073
|
+
const { existsSync: existsSync45 } = __require("fs");
|
|
33074
|
+
const os25 = __require("os");
|
|
32695
33075
|
const agent = ban(session.split("-")[0] ?? session);
|
|
32696
|
-
const markerPath =
|
|
32697
|
-
return
|
|
33076
|
+
const markerPath = path58.join(os25.homedir(), ".exe-os", "session-cache", `current-task-${agent}.json`);
|
|
33077
|
+
return existsSync45(markerPath);
|
|
32698
33078
|
} catch {
|
|
32699
33079
|
return false;
|
|
32700
33080
|
}
|
|
@@ -32789,7 +33169,7 @@ function startAutoWake() {
|
|
|
32789
33169
|
process.stderr.write(`[exed] Auto-wake started (every ${AUTO_WAKE_INTERVAL_MS / 1e3}s)
|
|
32790
33170
|
`);
|
|
32791
33171
|
}
|
|
32792
|
-
var TOTAL_MEM_GB =
|
|
33172
|
+
var TOTAL_MEM_GB = os24.totalmem() / 1024 ** 3;
|
|
32793
33173
|
var RSS_WARN_BYTES = Number(process.env.EXE_RSS_WARN_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 6 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 4 * 1024 ** 3 : 1024 ** 3);
|
|
32794
33174
|
var RSS_RESTART_BYTES = Number(process.env.EXE_RSS_RESTART_MB) * 1024 * 1024 || (TOTAL_MEM_GB >= 64 ? 8 * 1024 ** 3 : TOTAL_MEM_GB >= 32 ? 6 * 1024 ** 3 : 2 * 1024 ** 3);
|
|
32795
33175
|
var RSS_CHECK_INTERVAL_MS = 30 * 1e3;
|
|
@@ -32854,16 +33234,41 @@ function startRssWatchdog() {
|
|
|
32854
33234
|
process.stderr.write(`[exed] RSS watchdog started (warn: ${(RSS_WARN_BYTES / 1024 ** 3).toFixed(1)} GB, restart: ${(RSS_RESTART_BYTES / 1024 ** 3).toFixed(1)} GB)
|
|
32855
33235
|
`);
|
|
32856
33236
|
}
|
|
33237
|
+
function startBackgroundJobGuardrails() {
|
|
33238
|
+
const tick = async () => {
|
|
33239
|
+
fired("background_job_guardrails");
|
|
33240
|
+
try {
|
|
33241
|
+
const { enforceBackgroundJobGuardrails: enforceBackgroundJobGuardrails2 } = await Promise.resolve().then(() => (init_background_jobs(), background_jobs_exports));
|
|
33242
|
+
const actions = enforceBackgroundJobGuardrails2();
|
|
33243
|
+
if (actions.length > 0) {
|
|
33244
|
+
acted("background_job_guardrails");
|
|
33245
|
+
for (const action of actions) {
|
|
33246
|
+
const cpu = action.cpuPercent == null ? "" : ` cpu=${action.cpuPercent.toFixed(1)}%`;
|
|
33247
|
+
process.stderr.write(
|
|
33248
|
+
`[exed] Background job guardrail: ${action.action} ${action.name} pid=${action.pid}${cpu}
|
|
33249
|
+
`
|
|
33250
|
+
);
|
|
33251
|
+
}
|
|
33252
|
+
}
|
|
33253
|
+
} catch (err) {
|
|
33254
|
+
process.stderr.write(`[exed] Background job guardrail error: ${err instanceof Error ? err.message : String(err)}
|
|
33255
|
+
`);
|
|
33256
|
+
}
|
|
33257
|
+
};
|
|
33258
|
+
const timer = setInterval(() => void tick(), 6e4);
|
|
33259
|
+
timer.unref();
|
|
33260
|
+
process.stderr.write("[exed] Background job guardrails started (every 60s)\n");
|
|
33261
|
+
}
|
|
32857
33262
|
process.on("SIGINT", () => void shutdown());
|
|
32858
33263
|
process.on("SIGTERM", () => void shutdown());
|
|
32859
33264
|
function checkExistingDaemon() {
|
|
32860
33265
|
try {
|
|
32861
|
-
if (!
|
|
32862
|
-
const pid = parseInt(
|
|
33266
|
+
if (!existsSync44(PID_PATH3)) return false;
|
|
33267
|
+
const pid = parseInt(readFileSync37(PID_PATH3, "utf8").trim(), 10);
|
|
32863
33268
|
if (!pid || isNaN(pid)) return false;
|
|
32864
33269
|
if (pid === process.pid) {
|
|
32865
33270
|
try {
|
|
32866
|
-
|
|
33271
|
+
unlinkSync14(PID_PATH3);
|
|
32867
33272
|
} catch {
|
|
32868
33273
|
}
|
|
32869
33274
|
return false;
|
|
@@ -32879,7 +33284,7 @@ function checkExistingDaemon() {
|
|
|
32879
33284
|
return true;
|
|
32880
33285
|
}
|
|
32881
33286
|
try {
|
|
32882
|
-
|
|
33287
|
+
unlinkSync14(PID_PATH3);
|
|
32883
33288
|
} catch {
|
|
32884
33289
|
}
|
|
32885
33290
|
return false;
|
|
@@ -32936,7 +33341,7 @@ function startAutoUpdateCheck() {
|
|
|
32936
33341
|
if (checkExistingDaemon()) {
|
|
32937
33342
|
process.exit(0);
|
|
32938
33343
|
}
|
|
32939
|
-
|
|
33344
|
+
writeFileSync27(PID_PATH3, String(process.pid));
|
|
32940
33345
|
try {
|
|
32941
33346
|
chmodSync2(PID_PATH3, 384);
|
|
32942
33347
|
} catch {
|
|
@@ -32963,6 +33368,7 @@ try {
|
|
|
32963
33368
|
startSoftDeletePurge();
|
|
32964
33369
|
startAutoUpdateCheck();
|
|
32965
33370
|
startRssWatchdog();
|
|
33371
|
+
startBackgroundJobGuardrails();
|
|
32966
33372
|
startTaskEnforcementScanner();
|
|
32967
33373
|
const { startProjectionWorker: startProjectionWorker2 } = await Promise.resolve().then(() => (init_projection_worker(), projection_worker_exports));
|
|
32968
33374
|
startProjectionWorker2();
|
|
@@ -33005,7 +33411,7 @@ try {
|
|
|
33005
33411
|
onRegistry: async (devices) => {
|
|
33006
33412
|
try {
|
|
33007
33413
|
const client = getClient2();
|
|
33008
|
-
const
|
|
33414
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
33009
33415
|
for (const d of devices) {
|
|
33010
33416
|
await client.execute({
|
|
33011
33417
|
sql: `INSERT INTO device_registry (device_id, friendly_name, hostname, projects, agents, connected, last_seen)
|
|
@@ -33018,12 +33424,12 @@ try {
|
|
|
33018
33424
|
d.hostname,
|
|
33019
33425
|
JSON.stringify(d.projects),
|
|
33020
33426
|
JSON.stringify(d.agents),
|
|
33021
|
-
|
|
33427
|
+
now2,
|
|
33022
33428
|
d.friendlyName,
|
|
33023
33429
|
d.hostname,
|
|
33024
33430
|
JSON.stringify(d.projects),
|
|
33025
33431
|
JSON.stringify(d.agents),
|
|
33026
|
-
|
|
33432
|
+
now2
|
|
33027
33433
|
]
|
|
33028
33434
|
});
|
|
33029
33435
|
}
|
|
@@ -33059,11 +33465,11 @@ try {
|
|
|
33059
33465
|
process.stderr.write(`[exed] FATAL: ${err instanceof Error ? err.message : String(err)}
|
|
33060
33466
|
`);
|
|
33061
33467
|
try {
|
|
33062
|
-
|
|
33468
|
+
unlinkSync14(SOCKET_PATH2);
|
|
33063
33469
|
} catch {
|
|
33064
33470
|
}
|
|
33065
33471
|
try {
|
|
33066
|
-
|
|
33472
|
+
unlinkSync14(PID_PATH3);
|
|
33067
33473
|
} catch {
|
|
33068
33474
|
}
|
|
33069
33475
|
process.exit(1);
|