@askexenow/exe-os 0.8.40 → 0.8.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tui/App.js CHANGED
@@ -954,6 +954,7 @@ var config_exports = {};
954
954
  __export(config_exports, {
955
955
  CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
956
956
  CONFIG_PATH: () => CONFIG_PATH,
957
+ COO_AGENT_NAME: () => COO_AGENT_NAME,
957
958
  CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
958
959
  DB_PATH: () => DB_PATH,
959
960
  EXE_AI_DIR: () => EXE_AI_DIR,
@@ -1109,7 +1110,7 @@ async function loadConfigFrom(configPath) {
1109
1110
  return { ...DEFAULT_CONFIG };
1110
1111
  }
1111
1112
  }
1112
- var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
1113
+ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
1113
1114
  var init_config = __esm({
1114
1115
  "src/lib/config.ts"() {
1115
1116
  "use strict";
@@ -1117,6 +1118,7 @@ var init_config = __esm({
1117
1118
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
1118
1119
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
1119
1120
  CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
1121
+ COO_AGENT_NAME = "exe";
1120
1122
  LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
1121
1123
  CURRENT_CONFIG_VERSION = 1;
1122
1124
  DEFAULT_CONFIG = {
@@ -4757,7 +4759,7 @@ async function listTasks(input) {
4757
4759
  }
4758
4760
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
4759
4761
  const result = await client.execute({
4760
- sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
4762
+ sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
4761
4763
  args
4762
4764
  });
4763
4765
  return result.rows.map((r) => ({
@@ -4978,6 +4980,34 @@ async function listPendingReviews(limit) {
4978
4980
  });
4979
4981
  return result.rows;
4980
4982
  }
4983
+ async function cleanupOrphanedReviews() {
4984
+ const client = getClient();
4985
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4986
+ const r1 = await client.execute({
4987
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
4988
+ WHERE status = 'needs_review'
4989
+ AND assigned_by = 'system'
4990
+ AND title LIKE 'Review:%'
4991
+ AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
4992
+ args: [now]
4993
+ });
4994
+ const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
4995
+ const r2 = await client.execute({
4996
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
4997
+ WHERE status = 'needs_review'
4998
+ AND result IS NOT NULL
4999
+ AND updated_at < ?`,
5000
+ args: [now, staleThreshold]
5001
+ });
5002
+ const total = r1.rowsAffected + r2.rowsAffected;
5003
+ if (total > 0) {
5004
+ process.stderr.write(
5005
+ `[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
5006
+ `
5007
+ );
5008
+ }
5009
+ return total;
5010
+ }
4981
5011
  function getReviewChecklist(role, agent, taskSlug) {
4982
5012
  const roleLower = role.toLowerCase();
4983
5013
  if (roleLower.includes("engineer") || roleLower === "principal engineer") {
@@ -5657,6 +5687,7 @@ var init_skill_learning = __esm({
5657
5687
  // src/lib/tasks.ts
5658
5688
  var tasks_exports = {};
5659
5689
  __export(tasks_exports, {
5690
+ cleanupOrphanedReviews: () => cleanupOrphanedReviews,
5660
5691
  countNewPendingReviewsSince: () => countNewPendingReviewsSince,
5661
5692
  countPendingReviews: () => countPendingReviews,
5662
5693
  createTask: () => createTask,
@@ -5722,6 +5753,21 @@ async function updateTask(input) {
5722
5753
  });
5723
5754
  } catch {
5724
5755
  }
5756
+ try {
5757
+ const client = getClient();
5758
+ const cascaded = await client.execute({
5759
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
5760
+ WHERE parent_task_id = ? AND status = 'needs_review'`,
5761
+ args: [now, taskId]
5762
+ });
5763
+ if (cascaded.rowsAffected > 0) {
5764
+ process.stderr.write(
5765
+ `[cascade] Closed ${cascaded.rowsAffected} orphaned review task(s) for parent ${taskId}
5766
+ `
5767
+ );
5768
+ }
5769
+ } catch {
5770
+ }
5725
5771
  }
5726
5772
  const isTerminal = input.status === "done" || input.status === "needs_review";
5727
5773
  if (isTerminal) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.8.40",
3
+ "version": "0.8.41",
4
4
  "description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
5
5
  "license": "CC-BY-NC-4.0",
6
6
  "type": "module",