@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.
@@ -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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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
- now,
3881
- now
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, now, now, row.id]
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, now]
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, now]
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 now = /* @__PURE__ */ new Date();
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
- now
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
- now
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
- now,
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
- now
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
- now
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 now = Date.now();
4946
+ const now2 = Date.now();
4947
4947
  const toEvict = [];
4948
4948
  for (const [name, lastAccess] of _shardLastAccess) {
4949
- if (now - lastAccess > SHARD_IDLE_MS) {
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: readFileSync37 } = __require("fs");
5158
- return readFileSync37("/etc/machine-id", "utf-8").trim();
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, now]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, id]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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 now = Date.now();
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 = now - new Date(entry.timestamp).getTime();
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 now = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
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 ${now}. Convert relative time references (yesterday, last week) to ISO timestamps.`,
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: existsSync44 } = await import("fs");
6978
- const path57 = await import("path");
6979
- const modelPath = path57.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
6980
- if (!existsSync44(modelPath)) {
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 path57 = await import("path");
8072
- const os24 = await import("os");
8073
- const logPath = path57.join(os24.homedir(), ".exe-os", "search-quality.jsonl");
8074
- fs.mkdirSync(path57.dirname(logPath), { recursive: true });
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, ...ids]
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, path57, method = "GET", body) {
9708
- const url = `${config2.baseUrl}/api/v1${path57}`;
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} ${path57}: ${response.status} ${response.statusText}`);
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, cluster.projectName, rawText, vectorToBlob(vector)] : [consolidatedId, cluster.agentId, now, cluster.projectName, rawText];
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, now]
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 now = Date.now();
10609
- return now - lastMs >= idleMinutes * 60 * 1e3;
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: appendFileSync4 } = __require("fs");
11482
- appendFileSync4(INTERCOM_LOG, line);
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, now = Date.now()) {
11720
+ function confirmCapacityKill(agentId, now2 = Date.now()) {
11721
11721
  const pendingSince = _pendingCapacityKill.get(agentId);
11722
11722
  if (pendingSince === void 0) {
11723
- _pendingCapacityKill.set(agentId, now);
11723
+ _pendingCapacityKill.set(agentId, now2);
11724
11724
  return false;
11725
11725
  }
11726
- if (now - pendingSince > CONFIRMATION_WINDOW_MS) {
11727
- _pendingCapacityKill.set(agentId, now);
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, now = Date.now()) {
11753
+ async function isWithinRelaunchCooldown(agentId, now2 = Date.now()) {
11754
11754
  const cached = _lastRelaunch.get(agentId);
11755
- if (cached !== void 0) return now - cached < RELAUNCH_COOLDOWN_MS;
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 (now - persisted >= RELAUNCH_COOLDOWN_MS) return false;
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, taskId]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now]
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: [now]
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: [now, staleThreshold]
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, now) {
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, now, originalTaskId]
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: now
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: [now, originalTaskId]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, parentId]
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: [now, legacyTaskFile, `tasks/%/${agent}/${slug}.md`]
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, isAlive = isEmployeeAlive) {
12454
+ function findFreeInstance(employeeName, exeSession, maxInstances = 10, isAlive2 = isEmployeeAlive) {
12455
12455
  const base = employeeSessionName(employeeName, exeSession);
12456
- if (!isAlive(base) && acquireSpawnLock2(base)) return 0;
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 (!isAlive(candidate) && acquireSpawnLock2(candidate)) return i;
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: now
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), now, taskId]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now,
13491
- now
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:** ${now.split("T")[0]}${parentTaskId ? `
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: now,
13541
- updatedAt: now,
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, taskId]
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: [now, taskId]
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, now, taskId]
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, now, taskId]
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, now, taskId]
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, now, taskId]
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, now) {
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: [now, taskId]
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: [now, ...ubScope.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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, now, vector ? vector.buffer : null]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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: [now, `%left '${escaped}' as in\\_progress%`]
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 now2 = (/* @__PURE__ */ new Date()).toISOString();
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: [now2, assignedAgent]
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: [now, taskId]
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, now);
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: now
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: now,
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: existsSync44, mkdirSync: mkdirSync23, writeFileSync: writeFileSync27 } = await import("fs");
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 (!existsSync44(idPath)) {
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 (!existsSync44(dir)) mkdirSync23(dir, { recursive: true });
15332
- writeFileSync27(idPath, template.replace(/^agent_id: \w+/m, `agent_id: ${assigned_to}`), "utf-8");
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, String(row.id)]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, messageId]
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now, dueDate ?? null]
16598
+ args: [id, text3, now2, dueDate ?? null]
16599
16599
  });
16600
- return { id, text: text3, createdAt: now, dueDate: dueDate ?? null, completedAt: null };
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, id]
16632
+ args: [now2, id]
16633
16633
  });
16634
- return { id, text: String(row.text), createdAt: "", dueDate: null, completedAt: now };
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 now = (/* @__PURE__ */ new Date()).toISOString();
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, now]
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: now,
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, id] },
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 path57 = await import("path");
18817
- const os24 = await import("os");
18818
- const outDir = path57.join(os24.homedir(), ".exe-os", "exports");
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 = path57.join(outDir, `graph-${timestamp}.html`);
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 now = Date.now();
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 (now - lastMs < IDLE_NUDGE_DEDUP_MS) continue;
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, now, IDLE_NUDGE_DEDUP_MS)) {
20956
+ if (shouldNudgeEmployee(state, true, lastMs, now2, IDLE_NUDGE_DEDUP_MS)) {
20957
20957
  deps.sendIntercom(entry.windowName);
20958
- lastNudge.set(entry.windowName, now);
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 now = Date.now();
21102
+ const now2 = Date.now();
21103
21103
  for (const exeSession of sessions) {
21104
21104
  const prev = state.lastNudge.get(exeSession);
21105
- if (prev && now - prev.at < REVIEW_NUDGE_COOLDOWN_MS) continue;
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: now, count });
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 now = (/* @__PURE__ */ new Date()).toISOString();
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: [now, ...dup.delete_ids]
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 now = Date.now();
25785
- const elapsed = now - this.lastRequestTime;
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, path57, body) {
25791
+ async request(method, path58, body) {
25792
25792
  await this.rateLimit();
25793
- const url = `${this.baseUrl}${path57}`;
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, path57 = "/dns_records", query) {
25863
- const normalizedPath = path57.startsWith("/") ? path57 : `/${path57}`;
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now
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: now
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 now = deps.now ?? Date.now();
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 (now - lastNudgeTime < TASK_ENFORCEMENT_DEBOUNCE_MS) {
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 = now - new Date(newestCreatedAt).getTime();
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(now).toISOString(),
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(now).toISOString(),
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, now);
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 readFileSync34 } from "fs";
31162
- import path54 from "path";
31458
+ import { readFileSync as readFileSync35 } from "fs";
31459
+ import path55 from "path";
31163
31460
  function getLocalVersion(packageRoot) {
31164
- const pkgPath = path54.join(packageRoot, "package.json");
31165
- const pkg = JSON.parse(readFileSync34(pkgPath, "utf-8"));
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 os22 from "os";
31237
- import { readFileSync as readFileSync35, writeFileSync as writeFileSync25, mkdirSync as mkdirSync21, existsSync as existsSync42 } from "fs";
31238
- import path55 from "path";
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 (existsSync42(DEVICE_JSON_PATH)) {
31537
+ if (existsSync43(DEVICE_JSON_PATH)) {
31241
31538
  try {
31242
- const raw = readFileSync35(DEVICE_JSON_PATH, "utf8");
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 = os22.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
- mkdirSync21(path55.dirname(DEVICE_JSON_PATH), { recursive: true });
31257
- writeFileSync25(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
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
- writeFileSync25(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
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 = path55.join(EXE_AI_DIR, "device.json");
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 os23 from "os";
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 writeFileSync26, unlinkSync as unlinkSync13, mkdirSync as mkdirSync22, existsSync as existsSync43, readFileSync as readFileSync36, chmodSync as chmodSync2 } from "fs";
31514
- import path56 from "path";
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 ?? path56.join(EXE_AI_DIR, "exed.sock");
31587
- var PID_PATH3 = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path56.join(EXE_AI_DIR, "exed.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 = 15 * 60 * 1e3;
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 = path56.join(MODELS_DIR, MODEL_FILE);
31616
- if (!existsSync43(modelPath)) {
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
- unlinkSync13(SOCKET_PATH2);
32021
+ unlinkSync14(SOCKET_PATH2);
31721
32022
  } catch {
31722
32023
  }
31723
32024
  try {
31724
- unlinkSync13(PID_PATH3);
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 now = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
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: now,
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
- mkdirSync22(path56.dirname(SOCKET_PATH2), { recursive: true });
32333
+ mkdirSync23(path57.dirname(SOCKET_PATH2), { recursive: true });
32033
32334
  try {
32034
- chmodSync2(path56.dirname(SOCKET_PATH2), 448);
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 = path56.join(path56.dirname(SOCKET_PATH2), oldFile);
32340
+ const oldPath = path57.join(path57.dirname(SOCKET_PATH2), oldFile);
32040
32341
  try {
32041
32342
  if (oldFile.endsWith(".pid")) {
32042
- const pid = parseInt(readFileSync36(oldPath, "utf8").trim(), 10);
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
- unlinkSync13(oldPath);
32349
+ unlinkSync14(oldPath);
32049
32350
  } catch {
32050
32351
  }
32051
32352
  }
32052
32353
  try {
32053
- unlinkSync13(SOCKET_PATH2);
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
- const body = await new Promise((resolve) => {
32198
- let data = "";
32199
- req.on("data", (chunk) => {
32200
- data += chunk.toString();
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
- req.on("end", () => resolve(data));
32203
- });
32204
- const parsedBody = body ? JSON.parse(body) : void 0;
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) transports.delete(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
- res.writeHead(400, { "Content-Type": "text/plain" });
32225
- res.end("Bad Request: missing session");
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
- await runWithAgent2({ agentId, agentRole }, async () => {
32229
- await transport.handleRequest(req, res, parsedBody);
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 = path56.join(EXE_AI_DIR, "agent-stats.json");
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
- writeFileSync26(AGENT_STATS_PATH, JSON.stringify(stats, null, 2), "utf8");
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 path57 = __require("path");
32693
- const { existsSync: existsSync44 } = __require("fs");
32694
- const os24 = __require("os");
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 = path57.join(os24.homedir(), ".exe-os", "session-cache", `current-task-${agent}.json`);
32697
- return existsSync44(markerPath);
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 = os23.totalmem() / 1024 ** 3;
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 (!existsSync43(PID_PATH3)) return false;
32862
- const pid = parseInt(readFileSync36(PID_PATH3, "utf8").trim(), 10);
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
- unlinkSync13(PID_PATH3);
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
- unlinkSync13(PID_PATH3);
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
- writeFileSync26(PID_PATH3, String(process.pid));
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 now = (/* @__PURE__ */ new Date()).toISOString();
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
- now,
33427
+ now2,
33022
33428
  d.friendlyName,
33023
33429
  d.hostname,
33024
33430
  JSON.stringify(d.projects),
33025
33431
  JSON.stringify(d.agents),
33026
- now
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
- unlinkSync13(SOCKET_PATH2);
33468
+ unlinkSync14(SOCKET_PATH2);
33063
33469
  } catch {
33064
33470
  }
33065
33471
  try {
33066
- unlinkSync13(PID_PATH3);
33472
+ unlinkSync14(PID_PATH3);
33067
33473
  } catch {
33068
33474
  }
33069
33475
  process.exit(1);