@askexenow/exe-os 0.9.12 → 0.9.14

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.
Files changed (70) hide show
  1. package/dist/bin/backfill-conversations.js +53 -5
  2. package/dist/bin/backfill-responses.js +53 -5
  3. package/dist/bin/backfill-vectors.js +47 -5
  4. package/dist/bin/cleanup-stale-review-tasks.js +23 -2
  5. package/dist/bin/cli.js +77 -9
  6. package/dist/bin/exe-assign.js +53 -5
  7. package/dist/bin/exe-boot.js +47 -5
  8. package/dist/bin/exe-dispatch.js +23 -2
  9. package/dist/bin/exe-doctor.js +23 -2
  10. package/dist/bin/exe-export-behaviors.js +23 -2
  11. package/dist/bin/exe-forget.js +23 -2
  12. package/dist/bin/exe-gateway.js +469 -22
  13. package/dist/bin/exe-heartbeat.js +23 -2
  14. package/dist/bin/exe-kill.js +23 -2
  15. package/dist/bin/exe-launch-agent.js +23 -2
  16. package/dist/bin/exe-link.js +53 -5
  17. package/dist/bin/exe-pending-messages.js +23 -2
  18. package/dist/bin/exe-pending-notifications.js +23 -2
  19. package/dist/bin/exe-pending-reviews.js +23 -2
  20. package/dist/bin/exe-rename.js +53 -5
  21. package/dist/bin/exe-review.js +23 -2
  22. package/dist/bin/exe-search.js +53 -5
  23. package/dist/bin/exe-session-cleanup.js +47 -5
  24. package/dist/bin/exe-start-codex.js +23 -2
  25. package/dist/bin/exe-start-opencode.js +23 -2
  26. package/dist/bin/exe-status.js +23 -2
  27. package/dist/bin/exe-team.js +23 -2
  28. package/dist/bin/git-sweep.js +47 -5
  29. package/dist/bin/graph-backfill.js +23 -2
  30. package/dist/bin/graph-export.js +23 -2
  31. package/dist/bin/scan-tasks.js +47 -5
  32. package/dist/bin/setup.js +68 -9
  33. package/dist/bin/shard-migrate.js +23 -2
  34. package/dist/bin/wiki-sync.js +23 -2
  35. package/dist/gateway/index.js +150 -126
  36. package/dist/hooks/bug-report-worker.js +23 -2
  37. package/dist/hooks/codex-stop-task-finalizer.js +23 -2
  38. package/dist/hooks/commit-complete.js +47 -5
  39. package/dist/hooks/error-recall.js +53 -5
  40. package/dist/hooks/ingest-worker.js +47 -5
  41. package/dist/hooks/ingest.js +3345 -232
  42. package/dist/hooks/instructions-loaded.js +53 -5
  43. package/dist/hooks/notification.js +53 -5
  44. package/dist/hooks/post-compact.js +53 -5
  45. package/dist/hooks/pre-compact.js +47 -5
  46. package/dist/hooks/pre-tool-use.js +53 -5
  47. package/dist/hooks/prompt-ingest-worker.js +47 -5
  48. package/dist/hooks/prompt-submit.js +1726 -1401
  49. package/dist/hooks/response-ingest-worker.js +47 -5
  50. package/dist/hooks/session-end.js +369 -190
  51. package/dist/hooks/session-start.js +335 -19
  52. package/dist/hooks/stop.js +47 -5
  53. package/dist/hooks/subagent-stop.js +53 -5
  54. package/dist/hooks/summary-worker.js +47 -5
  55. package/dist/index.js +150 -126
  56. package/dist/lib/cloud-sync.js +53 -5
  57. package/dist/lib/database.js +53 -5
  58. package/dist/lib/db-daemon-client.js +31 -3
  59. package/dist/lib/db.js +53 -5
  60. package/dist/lib/device-registry.js +53 -5
  61. package/dist/lib/embedder.js +30 -3
  62. package/dist/lib/exe-daemon-client.js +31 -3
  63. package/dist/lib/exe-daemon.js +1973 -147
  64. package/dist/lib/hybrid-search.js +53 -5
  65. package/dist/lib/schedules.js +23 -2
  66. package/dist/lib/store.js +23 -2
  67. package/dist/mcp/server.js +151 -5
  68. package/dist/runtime/index.js +47 -5
  69. package/dist/tui/App.js +56 -5
  70. package/package.json +1 -1
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
4
10
  var __esm = (fn, res) => function __init() {
5
11
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
12
  };
@@ -661,7 +667,7 @@ async function ensureCompatibilityViews(prisma) {
661
667
  for (const mapping of VIEW_MAPPINGS) {
662
668
  const relation = mapping.source.replace(/"/g, "");
663
669
  const rows = await prisma.$queryRawUnsafe(
664
- "SELECT to_regclass($1) AS regclass",
670
+ "SELECT to_regclass($1)::text AS regclass",
665
671
  relation
666
672
  );
667
673
  if (!rows[0]?.regclass) {
@@ -1749,12 +1755,26 @@ async function ensureSchema() {
1749
1755
  session_name TEXT,
1750
1756
  task_id TEXT,
1751
1757
  project_name TEXT,
1752
- started_at TEXT NOT NULL
1758
+ started_at TEXT NOT NULL,
1759
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
1753
1760
  );
1754
1761
 
1755
1762
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1756
1763
  ON session_agent_map(agent_id);
1757
1764
  `);
1765
+ await client.executeMultiple(`
1766
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
1767
+ session_uuid TEXT NOT NULL,
1768
+ agent_id TEXT NOT NULL,
1769
+ file_path TEXT NOT NULL,
1770
+ read_at TEXT NOT NULL,
1771
+ commit_hash TEXT,
1772
+ PRIMARY KEY (session_uuid, file_path)
1773
+ );
1774
+
1775
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
1776
+ ON agent_file_reads(agent_id, read_at);
1777
+ `);
1758
1778
  try {
1759
1779
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1760
1780
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -1769,6 +1789,13 @@ async function ensureSchema() {
1769
1789
  }
1770
1790
  } catch {
1771
1791
  }
1792
+ try {
1793
+ await client.execute({
1794
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
1795
+ args: []
1796
+ });
1797
+ } catch {
1798
+ }
1772
1799
  try {
1773
1800
  await client.execute({
1774
1801
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -2559,8 +2586,29 @@ function findPackageRoot() {
2559
2586
  }
2560
2587
  return null;
2561
2588
  }
2589
+ function getAvailableMemoryGB() {
2590
+ if (process.platform === "darwin") {
2591
+ try {
2592
+ const { execSync: execSync2 } = __require("child_process");
2593
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
2594
+ const pageSize = 16384;
2595
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2596
+ const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
2597
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
2598
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
2599
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
2600
+ const freePages = free ? parseInt(free[1], 10) : 0;
2601
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
2602
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
2603
+ return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
2604
+ } catch {
2605
+ return os5.freemem() / (1024 * 1024 * 1024);
2606
+ }
2607
+ }
2608
+ return os5.freemem() / (1024 * 1024 * 1024);
2609
+ }
2562
2610
  function spawnDaemon() {
2563
- const freeGB = os5.freemem() / (1024 * 1024 * 1024);
2611
+ const freeGB = getAvailableMemoryGB();
2564
2612
  const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
2565
2613
  if (totalGB <= 8) {
2566
2614
  process.stderr.write(
@@ -2569,9 +2617,9 @@ function spawnDaemon() {
2569
2617
  );
2570
2618
  return;
2571
2619
  }
2572
- if (totalGB <= 16 && freeGB < 4) {
2620
+ if (totalGB <= 16 && freeGB < 2) {
2573
2621
  process.stderr.write(
2574
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2622
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2575
2623
  `
2576
2624
  );
2577
2625
  return;
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
4
10
  var __esm = (fn, res) => function __init() {
5
11
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
12
  };
@@ -661,7 +667,7 @@ async function ensureCompatibilityViews(prisma) {
661
667
  for (const mapping of VIEW_MAPPINGS) {
662
668
  const relation = mapping.source.replace(/"/g, "");
663
669
  const rows = await prisma.$queryRawUnsafe(
664
- "SELECT to_regclass($1) AS regclass",
670
+ "SELECT to_regclass($1)::text AS regclass",
665
671
  relation
666
672
  );
667
673
  if (!rows[0]?.regclass) {
@@ -1749,12 +1755,26 @@ async function ensureSchema() {
1749
1755
  session_name TEXT,
1750
1756
  task_id TEXT,
1751
1757
  project_name TEXT,
1752
- started_at TEXT NOT NULL
1758
+ started_at TEXT NOT NULL,
1759
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
1753
1760
  );
1754
1761
 
1755
1762
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1756
1763
  ON session_agent_map(agent_id);
1757
1764
  `);
1765
+ await client.executeMultiple(`
1766
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
1767
+ session_uuid TEXT NOT NULL,
1768
+ agent_id TEXT NOT NULL,
1769
+ file_path TEXT NOT NULL,
1770
+ read_at TEXT NOT NULL,
1771
+ commit_hash TEXT,
1772
+ PRIMARY KEY (session_uuid, file_path)
1773
+ );
1774
+
1775
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
1776
+ ON agent_file_reads(agent_id, read_at);
1777
+ `);
1758
1778
  try {
1759
1779
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1760
1780
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -1769,6 +1789,13 @@ async function ensureSchema() {
1769
1789
  }
1770
1790
  } catch {
1771
1791
  }
1792
+ try {
1793
+ await client.execute({
1794
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
1795
+ args: []
1796
+ });
1797
+ } catch {
1798
+ }
1772
1799
  try {
1773
1800
  await client.execute({
1774
1801
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -2559,8 +2586,29 @@ function findPackageRoot() {
2559
2586
  }
2560
2587
  return null;
2561
2588
  }
2589
+ function getAvailableMemoryGB() {
2590
+ if (process.platform === "darwin") {
2591
+ try {
2592
+ const { execSync: execSync2 } = __require("child_process");
2593
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
2594
+ const pageSize = 16384;
2595
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2596
+ const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
2597
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
2598
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
2599
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
2600
+ const freePages = free ? parseInt(free[1], 10) : 0;
2601
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
2602
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
2603
+ return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
2604
+ } catch {
2605
+ return os5.freemem() / (1024 * 1024 * 1024);
2606
+ }
2607
+ }
2608
+ return os5.freemem() / (1024 * 1024 * 1024);
2609
+ }
2562
2610
  function spawnDaemon() {
2563
- const freeGB = os5.freemem() / (1024 * 1024 * 1024);
2611
+ const freeGB = getAvailableMemoryGB();
2564
2612
  const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
2565
2613
  if (totalGB <= 8) {
2566
2614
  process.stderr.write(
@@ -2569,9 +2617,9 @@ function spawnDaemon() {
2569
2617
  );
2570
2618
  return;
2571
2619
  }
2572
- if (totalGB <= 16 && freeGB < 4) {
2620
+ if (totalGB <= 16 && freeGB < 2) {
2573
2621
  process.stderr.write(
2574
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2622
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2575
2623
  `
2576
2624
  );
2577
2625
  return;
@@ -663,7 +663,7 @@ async function ensureCompatibilityViews(prisma) {
663
663
  for (const mapping of VIEW_MAPPINGS) {
664
664
  const relation = mapping.source.replace(/"/g, "");
665
665
  const rows = await prisma.$queryRawUnsafe(
666
- "SELECT to_regclass($1) AS regclass",
666
+ "SELECT to_regclass($1)::text AS regclass",
667
667
  relation
668
668
  );
669
669
  if (!rows[0]?.regclass) {
@@ -1751,12 +1751,26 @@ async function ensureSchema() {
1751
1751
  session_name TEXT,
1752
1752
  task_id TEXT,
1753
1753
  project_name TEXT,
1754
- started_at TEXT NOT NULL
1754
+ started_at TEXT NOT NULL,
1755
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
1755
1756
  );
1756
1757
 
1757
1758
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1758
1759
  ON session_agent_map(agent_id);
1759
1760
  `);
1761
+ await client.executeMultiple(`
1762
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
1763
+ session_uuid TEXT NOT NULL,
1764
+ agent_id TEXT NOT NULL,
1765
+ file_path TEXT NOT NULL,
1766
+ read_at TEXT NOT NULL,
1767
+ commit_hash TEXT,
1768
+ PRIMARY KEY (session_uuid, file_path)
1769
+ );
1770
+
1771
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
1772
+ ON agent_file_reads(agent_id, read_at);
1773
+ `);
1760
1774
  try {
1761
1775
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1762
1776
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -1771,6 +1785,13 @@ async function ensureSchema() {
1771
1785
  }
1772
1786
  } catch {
1773
1787
  }
1788
+ try {
1789
+ await client.execute({
1790
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
1791
+ args: []
1792
+ });
1793
+ } catch {
1794
+ }
1774
1795
  try {
1775
1796
  await client.execute({
1776
1797
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -2561,8 +2582,29 @@ function findPackageRoot() {
2561
2582
  }
2562
2583
  return null;
2563
2584
  }
2585
+ function getAvailableMemoryGB() {
2586
+ if (process.platform === "darwin") {
2587
+ try {
2588
+ const { execSync: execSync2 } = __require("child_process");
2589
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
2590
+ const pageSize = 16384;
2591
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2592
+ const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
2593
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
2594
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
2595
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
2596
+ const freePages = free ? parseInt(free[1], 10) : 0;
2597
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
2598
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
2599
+ return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
2600
+ } catch {
2601
+ return os5.freemem() / (1024 * 1024 * 1024);
2602
+ }
2603
+ }
2604
+ return os5.freemem() / (1024 * 1024 * 1024);
2605
+ }
2564
2606
  function spawnDaemon() {
2565
- const freeGB = os5.freemem() / (1024 * 1024 * 1024);
2607
+ const freeGB = getAvailableMemoryGB();
2566
2608
  const totalGB = os5.totalmem() / (1024 * 1024 * 1024);
2567
2609
  if (totalGB <= 8) {
2568
2610
  process.stderr.write(
@@ -2571,9 +2613,9 @@ function spawnDaemon() {
2571
2613
  );
2572
2614
  return;
2573
2615
  }
2574
- if (totalGB <= 16 && freeGB < 4) {
2616
+ if (totalGB <= 16 && freeGB < 2) {
2575
2617
  process.stderr.write(
2576
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2618
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2577
2619
  `
2578
2620
  );
2579
2621
  return;
@@ -655,7 +655,7 @@ async function ensureCompatibilityViews(prisma) {
655
655
  for (const mapping of VIEW_MAPPINGS) {
656
656
  const relation = mapping.source.replace(/"/g, "");
657
657
  const rows = await prisma.$queryRawUnsafe(
658
- "SELECT to_regclass($1) AS regclass",
658
+ "SELECT to_regclass($1)::text AS regclass",
659
659
  relation
660
660
  );
661
661
  if (!rows[0]?.regclass) {
@@ -1743,12 +1743,26 @@ async function ensureSchema() {
1743
1743
  session_name TEXT,
1744
1744
  task_id TEXT,
1745
1745
  project_name TEXT,
1746
- started_at TEXT NOT NULL
1746
+ started_at TEXT NOT NULL,
1747
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
1747
1748
  );
1748
1749
 
1749
1750
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
1750
1751
  ON session_agent_map(agent_id);
1751
1752
  `);
1753
+ await client.executeMultiple(`
1754
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
1755
+ session_uuid TEXT NOT NULL,
1756
+ agent_id TEXT NOT NULL,
1757
+ file_path TEXT NOT NULL,
1758
+ read_at TEXT NOT NULL,
1759
+ commit_hash TEXT,
1760
+ PRIMARY KEY (session_uuid, file_path)
1761
+ );
1762
+
1763
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
1764
+ ON agent_file_reads(agent_id, read_at);
1765
+ `);
1752
1766
  try {
1753
1767
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
1754
1768
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -1763,6 +1777,13 @@ async function ensureSchema() {
1763
1777
  }
1764
1778
  } catch {
1765
1779
  }
1780
+ try {
1781
+ await client.execute({
1782
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
1783
+ args: []
1784
+ });
1785
+ } catch {
1786
+ }
1766
1787
  try {
1767
1788
  await client.execute({
1768
1789
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
package/dist/bin/cli.js CHANGED
@@ -2153,7 +2153,7 @@ async function ensureCompatibilityViews(prisma) {
2153
2153
  for (const mapping of VIEW_MAPPINGS) {
2154
2154
  const relation = mapping.source.replace(/"/g, "");
2155
2155
  const rows = await prisma.$queryRawUnsafe(
2156
- "SELECT to_regclass($1) AS regclass",
2156
+ "SELECT to_regclass($1)::text AS regclass",
2157
2157
  relation
2158
2158
  );
2159
2159
  if (!rows[0]?.regclass) {
@@ -2507,8 +2507,29 @@ function findPackageRoot() {
2507
2507
  }
2508
2508
  return null;
2509
2509
  }
2510
+ function getAvailableMemoryGB() {
2511
+ if (process.platform === "darwin") {
2512
+ try {
2513
+ const { execSync: execSync15 } = __require("child_process");
2514
+ const vmstat = execSync15("vm_stat", { encoding: "utf8" });
2515
+ const pageSize = 16384;
2516
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2517
+ const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
2518
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
2519
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
2520
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
2521
+ const freePages = free ? parseInt(free[1], 10) : 0;
2522
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
2523
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
2524
+ return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
2525
+ } catch {
2526
+ return os8.freemem() / (1024 * 1024 * 1024);
2527
+ }
2528
+ }
2529
+ return os8.freemem() / (1024 * 1024 * 1024);
2530
+ }
2510
2531
  function spawnDaemon() {
2511
- const freeGB = os8.freemem() / (1024 * 1024 * 1024);
2532
+ const freeGB = getAvailableMemoryGB();
2512
2533
  const totalGB = os8.totalmem() / (1024 * 1024 * 1024);
2513
2534
  if (totalGB <= 8) {
2514
2535
  process.stderr.write(
@@ -2517,9 +2538,9 @@ function spawnDaemon() {
2517
2538
  );
2518
2539
  return;
2519
2540
  }
2520
- if (totalGB <= 16 && freeGB < 4) {
2541
+ if (totalGB <= 16 && freeGB < 2) {
2521
2542
  process.stderr.write(
2522
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2543
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
2523
2544
  `
2524
2545
  );
2525
2546
  return;
@@ -3917,12 +3938,26 @@ async function ensureSchema() {
3917
3938
  session_name TEXT,
3918
3939
  task_id TEXT,
3919
3940
  project_name TEXT,
3920
- started_at TEXT NOT NULL
3941
+ started_at TEXT NOT NULL,
3942
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
3921
3943
  );
3922
3944
 
3923
3945
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
3924
3946
  ON session_agent_map(agent_id);
3925
3947
  `);
3948
+ await client.executeMultiple(`
3949
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
3950
+ session_uuid TEXT NOT NULL,
3951
+ agent_id TEXT NOT NULL,
3952
+ file_path TEXT NOT NULL,
3953
+ read_at TEXT NOT NULL,
3954
+ commit_hash TEXT,
3955
+ PRIMARY KEY (session_uuid, file_path)
3956
+ );
3957
+
3958
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
3959
+ ON agent_file_reads(agent_id, read_at);
3960
+ `);
3926
3961
  try {
3927
3962
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
3928
3963
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -3937,6 +3972,13 @@ async function ensureSchema() {
3937
3972
  }
3938
3973
  } catch {
3939
3974
  }
3975
+ try {
3976
+ await client.execute({
3977
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
3978
+ args: []
3979
+ });
3980
+ } catch {
3981
+ }
3940
3982
  try {
3941
3983
  await client.execute({
3942
3984
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
@@ -14627,18 +14669,35 @@ function ask2(rl, prompt) {
14627
14669
  doAsk();
14628
14670
  });
14629
14671
  }
14630
- function getAvailableMemoryGB() {
14672
+ function getAvailableMemoryGB2() {
14673
+ if (process.platform === "darwin") {
14674
+ try {
14675
+ const { execSync: execSync15 } = __require("child_process");
14676
+ const vmstat = execSync15("vm_stat", { encoding: "utf8" });
14677
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
14678
+ const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
14679
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
14680
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
14681
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
14682
+ const freePages = free ? parseInt(free[1], 10) : 0;
14683
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
14684
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
14685
+ return (freePages + inactivePages + speculativePages) * pageSize / (1024 * 1024 * 1024);
14686
+ } catch {
14687
+ return os16.freemem() / (1024 * 1024 * 1024);
14688
+ }
14689
+ }
14631
14690
  return os16.freemem() / (1024 * 1024 * 1024);
14632
14691
  }
14633
14692
  function getTotalMemoryGB() {
14634
14693
  return os16.totalmem() / (1024 * 1024 * 1024);
14635
14694
  }
14636
14695
  function isLowMemory() {
14637
- return getAvailableMemoryGB() < 2;
14696
+ return getAvailableMemoryGB2() < 2;
14638
14697
  }
14639
14698
  async function validateModel(log) {
14640
14699
  const totalGB = getTotalMemoryGB();
14641
- const freeGB = getAvailableMemoryGB();
14700
+ const freeGB = getAvailableMemoryGB2();
14642
14701
  if (totalGB <= 8 || isLowMemory()) {
14643
14702
  log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
14644
14703
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
@@ -14854,7 +14913,7 @@ async function runSetupWizard(opts = {}) {
14854
14913
  skipModel = true;
14855
14914
  }
14856
14915
  if (!skipModel) {
14857
- const freeGB = getAvailableMemoryGB();
14916
+ const freeGB = getAvailableMemoryGB2();
14858
14917
  if (freeGB < 2) {
14859
14918
  log(`\u26A0 Low memory detected: ${freeGB.toFixed(1)}GB free of ${totalGB.toFixed(0)}GB total`);
14860
14919
  log(" Close other applications (browser, Slack, etc.) before continuing.");
@@ -24119,6 +24178,15 @@ __export(factory_exports, {
24119
24178
  function createProvider(opts) {
24120
24179
  const { providerId, model, apiKey } = opts;
24121
24180
  if (providerId === "anthropic") {
24181
+ const routerUrl = process.env.API_ROUTER_URL;
24182
+ const routerKey = process.env.API_ROUTER_KEY;
24183
+ const byok = process.env.BYOK_ENABLED === "true";
24184
+ if (routerUrl && routerKey && !byok) {
24185
+ return new AnthropicProvider("anthropic", {
24186
+ apiKey: routerKey,
24187
+ baseUrl: routerUrl
24188
+ });
24189
+ }
24122
24190
  return new AnthropicProvider("anthropic", { apiKey });
24123
24191
  }
24124
24192
  if (providerId === "openai") {
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
4
10
  var __esm = (fn, res) => function __init() {
5
11
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
12
  };
@@ -386,8 +392,29 @@ function findPackageRoot() {
386
392
  }
387
393
  return null;
388
394
  }
395
+ function getAvailableMemoryGB() {
396
+ if (process.platform === "darwin") {
397
+ try {
398
+ const { execSync: execSync2 } = __require("child_process");
399
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
400
+ const pageSize = 16384;
401
+ const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
402
+ const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
403
+ const free = vmstat.match(/Pages free:\s+(\d+)/);
404
+ const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
405
+ const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
406
+ const freePages = free ? parseInt(free[1], 10) : 0;
407
+ const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
408
+ const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
409
+ return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
410
+ } catch {
411
+ return os3.freemem() / (1024 * 1024 * 1024);
412
+ }
413
+ }
414
+ return os3.freemem() / (1024 * 1024 * 1024);
415
+ }
389
416
  function spawnDaemon() {
390
- const freeGB = os3.freemem() / (1024 * 1024 * 1024);
417
+ const freeGB = getAvailableMemoryGB();
391
418
  const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
392
419
  if (totalGB <= 8) {
393
420
  process.stderr.write(
@@ -396,9 +423,9 @@ function spawnDaemon() {
396
423
  );
397
424
  return;
398
425
  }
399
- if (totalGB <= 16 && freeGB < 4) {
426
+ if (totalGB <= 16 && freeGB < 2) {
400
427
  process.stderr.write(
401
- `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB free / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
428
+ `[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
402
429
  `
403
430
  );
404
431
  return;
@@ -1103,7 +1130,7 @@ async function ensureCompatibilityViews(prisma) {
1103
1130
  for (const mapping of VIEW_MAPPINGS) {
1104
1131
  const relation = mapping.source.replace(/"/g, "");
1105
1132
  const rows = await prisma.$queryRawUnsafe(
1106
- "SELECT to_regclass($1) AS regclass",
1133
+ "SELECT to_regclass($1)::text AS regclass",
1107
1134
  relation
1108
1135
  );
1109
1136
  if (!rows[0]?.regclass) {
@@ -2191,12 +2218,26 @@ async function ensureSchema() {
2191
2218
  session_name TEXT,
2192
2219
  task_id TEXT,
2193
2220
  project_name TEXT,
2194
- started_at TEXT NOT NULL
2221
+ started_at TEXT NOT NULL,
2222
+ cache_cold_count INTEGER NOT NULL DEFAULT 0
2195
2223
  );
2196
2224
 
2197
2225
  CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
2198
2226
  ON session_agent_map(agent_id);
2199
2227
  `);
2228
+ await client.executeMultiple(`
2229
+ CREATE TABLE IF NOT EXISTS agent_file_reads (
2230
+ session_uuid TEXT NOT NULL,
2231
+ agent_id TEXT NOT NULL,
2232
+ file_path TEXT NOT NULL,
2233
+ read_at TEXT NOT NULL,
2234
+ commit_hash TEXT,
2235
+ PRIMARY KEY (session_uuid, file_path)
2236
+ );
2237
+
2238
+ CREATE INDEX IF NOT EXISTS idx_agent_file_reads_agent_read_at
2239
+ ON agent_file_reads(agent_id, read_at);
2240
+ `);
2200
2241
  try {
2201
2242
  const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
2202
2243
  if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
@@ -2211,6 +2252,13 @@ async function ensureSchema() {
2211
2252
  }
2212
2253
  } catch {
2213
2254
  }
2255
+ try {
2256
+ await client.execute({
2257
+ sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
2258
+ args: []
2259
+ });
2260
+ } catch {
2261
+ }
2214
2262
  try {
2215
2263
  await client.execute({
2216
2264
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,