ctxloom-pro 1.7.9 → 1.7.10

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/README.md CHANGED
@@ -69,7 +69,7 @@ The full first-run flow is **one install + one trial + one init per project.** E
69
69
  npm install -g ctxloom-pro
70
70
  ```
71
71
 
72
- > **For local trial / dev use the unpinned command above is fine.** For unattended CI usage, pin to the exact version (`ctxloom-pro@1.7.9`) so future CLI releases don't silently desync your agent-spec coverage — see the workflow example below.
72
+ > **For local trial / dev use the unpinned command above is fine.** For unattended CI usage, pin to the exact version (`ctxloom-pro@1.7.10`) so future CLI releases don't silently desync your agent-spec coverage — see the workflow example below.
73
73
 
74
74
  ### 2 — Start your free trial (once per email)
75
75
 
@@ -383,7 +383,7 @@ jobs:
383
383
  # Exact pin (not `@^1`) so future CLI releases that add/remove MCP
384
384
  # tools don't silently desync your reviewer-agent specs. Bump on
385
385
  # every release; see CHANGELOG.md for the live version table.
386
- - run: npm install -g ctxloom-pro@1.7.9
386
+ - run: npm install -g ctxloom-pro@1.7.10
387
387
  - run: ctxloom index
388
388
  - run: ctxloom rules check --json
389
389
  ```
@@ -233,12 +233,12 @@ var init_VectorStore = __esm({
233
233
  // server/index.ts
234
234
  import express from "express";
235
235
  import cors from "cors";
236
- import path47 from "path";
237
- import fs35 from "fs";
236
+ import path48 from "path";
237
+ import fs36 from "fs";
238
238
  import { fileURLToPath as fileURLToPath2 } from "url";
239
239
 
240
240
  // server/loader.ts
241
- import path41 from "path";
241
+ import path42 from "path";
242
242
 
243
243
  // ../../packages/core/src/graph/DependencyGraph.ts
244
244
  import fs7 from "fs";
@@ -2929,7 +2929,7 @@ var CallGraphIndex = class _CallGraphIndex {
2929
2929
  var TS_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".vue"]);
2930
2930
  var PY_EXTENSIONS = /* @__PURE__ */ new Set([".py", ".ipynb"]);
2931
2931
  var AST_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".py", ".go", ".rs", ".java", ".cs", ".rb", ".kt", ".kts", ".swift", ".ipynb", ".php", ".dart"]);
2932
- var CTXLOOM_VERSION = "1.7.9".length > 0 ? "1.7.9" : "dev";
2932
+ var CTXLOOM_VERSION = "1.7.10".length > 0 ? "1.7.10" : "dev";
2933
2933
  var SNAPSHOT_SCHEMA_VERSION = 2;
2934
2934
  function compareCtxloomVersions(snapshotVer, currentVer) {
2935
2935
  if (snapshotVer === currentVer) return "same";
@@ -4004,8 +4004,8 @@ var CoChangeIndex = class _CoChangeIndex {
4004
4004
  if (event.isBulk || event.isMerge) return;
4005
4005
  const paths = event.files.map((f) => f.path);
4006
4006
  if (paths.length === 0) return;
4007
- for (const path48 of paths) {
4008
- this.nodeCounts.set(path48, (this.nodeCounts.get(path48) ?? 0) + 1);
4007
+ for (const path49 of paths) {
4008
+ this.nodeCounts.set(path49, (this.nodeCounts.get(path49) ?? 0) + 1);
4009
4009
  }
4010
4010
  for (let i = 0; i < paths.length; i++) {
4011
4011
  for (let j = i + 1; j < paths.length; j++) {
@@ -4152,8 +4152,8 @@ var ChurnIndex = class _ChurnIndex {
4152
4152
  */
4153
4153
  snapshot() {
4154
4154
  const nodes = {};
4155
- for (const [path48, raw] of this.nodes) {
4156
- nodes[path48] = {
4155
+ for (const [path49, raw] of this.nodes) {
4156
+ nodes[path49] = {
4157
4157
  commits: raw.commits,
4158
4158
  churnLines: raw.churnLines,
4159
4159
  bugCommits: raw.bugCommits,
@@ -4168,8 +4168,8 @@ var ChurnIndex = class _ChurnIndex {
4168
4168
  */
4169
4169
  static load(s) {
4170
4170
  const idx = new _ChurnIndex();
4171
- for (const [path48, raw] of Object.entries(s.nodes)) {
4172
- idx.nodes.set(path48, {
4171
+ for (const [path49, raw] of Object.entries(s.nodes)) {
4172
+ idx.nodes.set(path49, {
4173
4173
  commits: raw.commits,
4174
4174
  churnLines: raw.churnLines,
4175
4175
  bugCommits: raw.bugCommits,
@@ -4182,8 +4182,8 @@ var ChurnIndex = class _ChurnIndex {
4182
4182
  // -------------------------------------------------------------------------
4183
4183
  // Private helpers
4184
4184
  // -------------------------------------------------------------------------
4185
- getOrCreate(path48) {
4186
- const existing = this.nodes.get(path48);
4185
+ getOrCreate(path49) {
4186
+ const existing = this.nodes.get(path49);
4187
4187
  if (existing !== void 0) return existing;
4188
4188
  const fresh = {
4189
4189
  commits: 0,
@@ -4192,7 +4192,7 @@ var ChurnIndex = class _ChurnIndex {
4192
4192
  authorCounts: {},
4193
4193
  lastTouch: 0
4194
4194
  };
4195
- this.nodes.set(path48, fresh);
4195
+ this.nodes.set(path49, fresh);
4196
4196
  return fresh;
4197
4197
  }
4198
4198
  };
@@ -4273,12 +4273,12 @@ var OwnershipIndex = class _OwnershipIndex {
4273
4273
  */
4274
4274
  snapshot() {
4275
4275
  const nodes = {};
4276
- for (const [path48, raw] of this.nodes) {
4276
+ for (const [path49, raw] of this.nodes) {
4277
4277
  const authorWeights = {};
4278
4278
  for (const [email, entry] of Object.entries(raw.authorWeights)) {
4279
4279
  authorWeights[email] = { ...entry };
4280
4280
  }
4281
- nodes[path48] = { authorWeights, lastTouch: raw.lastTouch };
4281
+ nodes[path49] = { authorWeights, lastTouch: raw.lastTouch };
4282
4282
  }
4283
4283
  return { version: 1, nodes };
4284
4284
  }
@@ -4287,23 +4287,23 @@ var OwnershipIndex = class _OwnershipIndex {
4287
4287
  */
4288
4288
  static load(s) {
4289
4289
  const idx = new _OwnershipIndex();
4290
- for (const [path48, raw] of Object.entries(s.nodes)) {
4290
+ for (const [path49, raw] of Object.entries(s.nodes)) {
4291
4291
  const authorWeights = {};
4292
4292
  for (const [email, entry] of Object.entries(raw.authorWeights)) {
4293
4293
  authorWeights[email] = { ...entry };
4294
4294
  }
4295
- idx.nodes.set(path48, { authorWeights, lastTouch: raw.lastTouch });
4295
+ idx.nodes.set(path49, { authorWeights, lastTouch: raw.lastTouch });
4296
4296
  }
4297
4297
  return idx;
4298
4298
  }
4299
4299
  // -------------------------------------------------------------------------
4300
4300
  // Private helpers
4301
4301
  // -------------------------------------------------------------------------
4302
- getOrCreate(path48) {
4303
- const existing = this.nodes.get(path48);
4302
+ getOrCreate(path49) {
4303
+ const existing = this.nodes.get(path49);
4304
4304
  if (existing !== void 0) return existing;
4305
4305
  const fresh = { authorWeights: {}, lastTouch: 0 };
4306
- this.nodes.set(path48, fresh);
4306
+ this.nodes.set(path49, fresh);
4307
4307
  return fresh;
4308
4308
  }
4309
4309
  };
@@ -5546,8 +5546,8 @@ function getErrorMap() {
5546
5546
 
5547
5547
  // ../../node_modules/zod/v3/helpers/parseUtil.js
5548
5548
  var makeIssue = (params) => {
5549
- const { data, path: path48, errorMaps, issueData } = params;
5550
- const fullPath = [...path48, ...issueData.path || []];
5549
+ const { data, path: path49, errorMaps, issueData } = params;
5550
+ const fullPath = [...path49, ...issueData.path || []];
5551
5551
  const fullIssue = {
5552
5552
  ...issueData,
5553
5553
  path: fullPath
@@ -5663,11 +5663,11 @@ var errorUtil;
5663
5663
 
5664
5664
  // ../../node_modules/zod/v3/types.js
5665
5665
  var ParseInputLazyPath = class {
5666
- constructor(parent, value, path48, key) {
5666
+ constructor(parent, value, path49, key) {
5667
5667
  this._cachedPath = [];
5668
5668
  this.parent = parent;
5669
5669
  this.data = value;
5670
- this._path = path48;
5670
+ this._path = path49;
5671
5671
  this._key = key;
5672
5672
  }
5673
5673
  get path() {
@@ -9569,6 +9569,10 @@ var schema3 = external_exports.object({
9569
9569
  response_format: external_exports.enum(["full", "skeleton", "auto"]).optional().describe("'full'/'auto' default; 'skeleton' produces the same output (response is already compact).")
9570
9570
  });
9571
9571
 
9572
+ // ../../packages/core/src/tools/overlayNote.ts
9573
+ import fs25 from "fs";
9574
+ import path27 from "path";
9575
+
9572
9576
  // ../../packages/core/src/tools/git-coupling.ts
9573
9577
  var Schema26 = external_exports.object({
9574
9578
  file: external_exports.string().describe("File path to look up co-changed siblings for"),
@@ -9585,8 +9589,8 @@ var Schema27 = external_exports.object({
9585
9589
  });
9586
9590
 
9587
9591
  // ../../packages/core/src/rules/loadConfig.ts
9588
- import fs25 from "fs/promises";
9589
- import path27 from "path";
9592
+ import fs26 from "fs/promises";
9593
+ import path28 from "path";
9590
9594
 
9591
9595
  // ../../node_modules/js-yaml/dist/js-yaml.mjs
9592
9596
  function isNothing(subject) {
@@ -12227,24 +12231,24 @@ var Schema30 = external_exports.object({
12227
12231
  });
12228
12232
 
12229
12233
  // ../../packages/core/src/tools/ruleManager.ts
12230
- import fs26 from "fs";
12231
- import path28 from "path";
12232
-
12233
- // ../../packages/core/src/review/AuthorResolver.ts
12234
- import fs27 from "fs/promises";
12234
+ import fs27 from "fs";
12235
12235
  import path29 from "path";
12236
12236
 
12237
- // ../../packages/core/src/review/CodeownersWriter.ts
12237
+ // ../../packages/core/src/review/AuthorResolver.ts
12238
12238
  import fs28 from "fs/promises";
12239
12239
  import path30 from "path";
12240
12240
 
12241
- // ../../packages/core/src/review/loadConfig.ts
12241
+ // ../../packages/core/src/review/CodeownersWriter.ts
12242
12242
  import fs29 from "fs/promises";
12243
12243
  import path31 from "path";
12244
12244
 
12245
- // ../../packages/core/src/security/PathValidator.ts
12245
+ // ../../packages/core/src/review/loadConfig.ts
12246
+ import fs30 from "fs/promises";
12246
12247
  import path32 from "path";
12247
- import fs30 from "fs";
12248
+
12249
+ // ../../packages/core/src/security/PathValidator.ts
12250
+ import path33 from "path";
12251
+ import fs31 from "fs";
12248
12252
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
12249
12253
 
12250
12254
  // ../../packages/core/src/index.ts
@@ -12256,7 +12260,7 @@ init_logger();
12256
12260
 
12257
12261
  // ../../packages/core/src/license/LicenseStore.ts
12258
12262
  import { readFileSync, writeFileSync, unlinkSync, mkdirSync, chmodSync, existsSync } from "fs";
12259
- import path33 from "path";
12263
+ import path34 from "path";
12260
12264
 
12261
12265
  // ../../packages/core/src/license/types.ts
12262
12266
  var FINGERPRINT_RE = /^sha256:[0-9a-f]{64}$/;
@@ -12287,11 +12291,11 @@ import os6 from "os";
12287
12291
 
12288
12292
  // ../../packages/core/src/license/DistinctIdStore.ts
12289
12293
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
12290
- import path34 from "path";
12294
+ import path35 from "path";
12291
12295
  import os4 from "os";
12292
12296
  var UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
12293
12297
  function distinctIdPath(home) {
12294
- return path34.join(home ?? os4.homedir(), ".ctxloom", "distinct_id");
12298
+ return path35.join(home ?? os4.homedir(), ".ctxloom", "distinct_id");
12295
12299
  }
12296
12300
  function isValidV4(id) {
12297
12301
  return typeof id === "string" && UUID_V4_REGEX.test(id);
@@ -12312,7 +12316,7 @@ function getOrCreateDistinctId(home) {
12312
12316
  id: crypto.randomUUID(),
12313
12317
  alias_pending: os4.hostname()
12314
12318
  };
12315
- mkdirSync2(path34.dirname(filePath), { recursive: true });
12319
+ mkdirSync2(path35.dirname(filePath), { recursive: true });
12316
12320
  writeFileSync2(filePath, JSON.stringify(record), { mode: 384 });
12317
12321
  return record;
12318
12322
  }
@@ -12338,7 +12342,7 @@ function resolveTelemetryLevel() {
12338
12342
  }
12339
12343
  var TELEMETRY_LEVEL = resolveTelemetryLevel();
12340
12344
  var TELEMETRY_DISABLED = TELEMETRY_LEVEL === "off";
12341
- var CTXLOOM_VERSION2 = "1.7.9".length > 0 ? "1.7.9" : "dev";
12345
+ var CTXLOOM_VERSION2 = "1.7.10".length > 0 ? "1.7.10" : "dev";
12342
12346
  var POSTHOG_HOST = "https://eu.i.posthog.com";
12343
12347
  var POSTHOG_KEY = process.env["POSTHOG_API_KEY"] ?? (true ? "phc_CiDkmFLcZ2K6uCpcoSUQLmFrnnUvsyXGhSxopX5TVKE6" : "");
12344
12348
  var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528" : "");
@@ -12471,32 +12475,32 @@ function parseStack(stack) {
12471
12475
 
12472
12476
  // ../../packages/core/src/license/FunnelMilestones.ts
12473
12477
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
12474
- import path35 from "path";
12478
+ import path36 from "path";
12475
12479
  import os5 from "os";
12476
12480
 
12477
12481
  // ../../packages/core/src/license/TelemetryNotice.ts
12478
12482
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
12479
- import path36 from "path";
12483
+ import path37 from "path";
12480
12484
  import os7 from "os";
12481
12485
 
12482
12486
  // ../../packages/core/src/server/ProjectState.ts
12483
- import path38 from "path";
12487
+ import path39 from "path";
12484
12488
 
12485
12489
  // ../../packages/core/src/server/projectId.ts
12486
12490
  import crypto5 from "crypto";
12487
- import path37 from "path";
12491
+ import path38 from "path";
12488
12492
 
12489
12493
  // ../../packages/core/src/server/ProjectStateManager.ts
12490
12494
  init_logger();
12491
12495
 
12492
12496
  // ../../packages/core/src/server/resolveProjectRoot.ts
12493
- import fs31 from "fs";
12494
- import path39 from "path";
12495
-
12496
- // ../../packages/core/src/install/installer.ts
12497
12497
  import fs32 from "fs";
12498
12498
  import path40 from "path";
12499
12499
 
12500
+ // ../../packages/core/src/install/installer.ts
12501
+ import fs33 from "fs";
12502
+ import path41 from "path";
12503
+
12500
12504
  // ../../packages/core/src/install/templates.ts
12501
12505
  var RULES_BLOCK_CONTENT = `## MCP Tools: ctxloom
12502
12506
 
@@ -12761,7 +12765,7 @@ function summarize(events, windowStart, windowEnd) {
12761
12765
 
12762
12766
  // server/loader.ts
12763
12767
  async function loadContext(root) {
12764
- const absRoot = path41.resolve(root);
12768
+ const absRoot = path42.resolve(root);
12765
12769
  const overlay = new GitOverlayStore(absRoot);
12766
12770
  const gitEnabled = await overlay.loadSnapshot();
12767
12771
  const graph = new DependencyGraph();
@@ -13014,21 +13018,21 @@ function buildOwnershipRouter(ctx) {
13014
13018
 
13015
13019
  // server/routes/file.ts
13016
13020
  import { Router as Router7 } from "express";
13017
- import fs33 from "fs/promises";
13018
- import path42 from "path";
13021
+ import fs34 from "fs/promises";
13022
+ import path43 from "path";
13019
13023
  function buildFileRouter(ctx) {
13020
13024
  const router = Router7();
13021
13025
  router.get("/", async (req, res) => {
13022
13026
  const rel = req.query.path;
13023
13027
  if (!rel) return res.status(400).json({ error: "missing path" });
13024
- const abs = path42.resolve(ctx.root, rel);
13025
- const rootBoundary = ctx.root.endsWith(path42.sep) ? ctx.root : ctx.root + path42.sep;
13028
+ const abs = path43.resolve(ctx.root, rel);
13029
+ const rootBoundary = ctx.root.endsWith(path43.sep) ? ctx.root : ctx.root + path43.sep;
13026
13030
  if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
13027
13031
  return res.status(403).json({ error: "forbidden" });
13028
13032
  }
13029
13033
  try {
13030
- const content = await fs33.readFile(abs, "utf-8");
13031
- const ext = path42.extname(abs).slice(1);
13034
+ const content = await fs34.readFile(abs, "utf-8");
13035
+ const ext = path43.extname(abs).slice(1);
13032
13036
  res.json({ content, lines: content.split("\n").length, ext });
13033
13037
  } catch {
13034
13038
  res.status(404).json({ error: "not found" });
@@ -13040,7 +13044,7 @@ function buildFileRouter(ctx) {
13040
13044
  // server/routes/open.ts
13041
13045
  import { Router as Router8 } from "express";
13042
13046
  import { execFile as execFile2 } from "child_process";
13043
- import path43 from "path";
13047
+ import path44 from "path";
13044
13048
  function tryOpen(bin, abs) {
13045
13049
  return new Promise((resolve) => {
13046
13050
  execFile2(bin, [abs], { timeout: 5e3 }, (err) => resolve(!err));
@@ -13051,8 +13055,8 @@ function buildOpenRouter(ctx) {
13051
13055
  router.post("/", async (req, res) => {
13052
13056
  const rel = req.body?.path;
13053
13057
  if (!rel || typeof rel !== "string") return res.status(400).json({ error: "missing path" });
13054
- const abs = path43.resolve(ctx.root, rel);
13055
- const rootBoundary = ctx.root.endsWith(path43.sep) ? ctx.root : ctx.root + path43.sep;
13058
+ const abs = path44.resolve(ctx.root, rel);
13059
+ const rootBoundary = ctx.root.endsWith(path44.sep) ? ctx.root : ctx.root + path44.sep;
13056
13060
  if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
13057
13061
  return res.status(403).json({ error: "forbidden" });
13058
13062
  }
@@ -13064,8 +13068,8 @@ function buildOpenRouter(ctx) {
13064
13068
 
13065
13069
  // server/routes/tokens.ts
13066
13070
  import { Router as Router9 } from "express";
13067
- import path44 from "path";
13068
- import fs34 from "fs";
13071
+ import path45 from "path";
13072
+ import fs35 from "fs";
13069
13073
  var CHARS_PER_TOKEN = 4;
13070
13074
  var cache = null;
13071
13075
  function buildTokensRouter(ctx) {
@@ -13080,9 +13084,9 @@ function buildTokensRouter(ctx) {
13080
13084
  let fullChars = 0;
13081
13085
  let skeletonChars = 0;
13082
13086
  for (const file of files) {
13083
- const absPath = path44.join(ctx.root, file);
13087
+ const absPath = path45.join(ctx.root, file);
13084
13088
  try {
13085
- const content = fs34.readFileSync(absPath, "utf-8");
13089
+ const content = fs35.readFileSync(absPath, "utf-8");
13086
13090
  fullChars += content.length;
13087
13091
  const skeleton = await skeletonizer.skeletonize(absPath);
13088
13092
  skeletonChars += skeleton.length;
@@ -13183,17 +13187,17 @@ function buildFileTrendsRouter(ctx) {
13183
13187
 
13184
13188
  // server/routes/projects.ts
13185
13189
  import { Router as Router12 } from "express";
13186
- import path46 from "path";
13190
+ import path47 from "path";
13187
13191
 
13188
13192
  // server/projects.ts
13189
13193
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
13190
13194
  import os8 from "os";
13191
- import path45 from "path";
13195
+ import path46 from "path";
13192
13196
  import crypto7 from "crypto";
13193
13197
  var HOME = os8.homedir();
13194
- var REGISTRY_PATH = path45.join(HOME, ".ctxloom", "repos.json");
13198
+ var REGISTRY_PATH = path46.join(HOME, ".ctxloom", "repos.json");
13195
13199
  function slugFor(root) {
13196
- const abs = path45.resolve(root);
13200
+ const abs = path46.resolve(root);
13197
13201
  return crypto7.createHash("sha1").update(abs).digest("hex").slice(0, 12);
13198
13202
  }
13199
13203
  function readRegistry() {
@@ -13208,27 +13212,27 @@ function readRegistry() {
13208
13212
  }
13209
13213
  }
13210
13214
  function listProjects(defaultRoot) {
13211
- const absDefault = path45.resolve(defaultRoot);
13215
+ const absDefault = path46.resolve(defaultRoot);
13212
13216
  const out = [
13213
13217
  {
13214
13218
  slug: slugFor(absDefault),
13215
- name: path45.basename(absDefault) || absDefault,
13219
+ name: path46.basename(absDefault) || absDefault,
13216
13220
  root: absDefault,
13217
13221
  isDefault: true,
13218
- hasSnapshot: existsSync5(path45.join(absDefault, ".ctxloom"))
13222
+ hasSnapshot: existsSync5(path46.join(absDefault, ".ctxloom"))
13219
13223
  }
13220
13224
  ];
13221
13225
  const seen = /* @__PURE__ */ new Set([absDefault]);
13222
13226
  for (const entry of readRegistry()) {
13223
- const abs = path45.resolve(entry.root);
13227
+ const abs = path46.resolve(entry.root);
13224
13228
  if (seen.has(abs)) continue;
13225
13229
  seen.add(abs);
13226
13230
  const item = {
13227
13231
  slug: slugFor(abs),
13228
- name: entry.name ?? (path45.basename(abs) || abs),
13232
+ name: entry.name ?? (path46.basename(abs) || abs),
13229
13233
  root: abs,
13230
13234
  isDefault: false,
13231
- hasSnapshot: existsSync5(path45.join(abs, ".ctxloom"))
13235
+ hasSnapshot: existsSync5(path46.join(abs, ".ctxloom"))
13232
13236
  };
13233
13237
  if (entry.alias !== void 0) item.alias = entry.alias;
13234
13238
  out.push(item);
@@ -13281,7 +13285,7 @@ function buildProjectsRouter(deps) {
13281
13285
  } catch (err) {
13282
13286
  const detail = err instanceof Error ? err.message : String(err);
13283
13287
  res.status(500).json({
13284
- error: `failed to switch to ${path46.basename(target.root)}: ${detail}`
13288
+ error: `failed to switch to ${path47.basename(target.root)}: ${detail}`
13285
13289
  });
13286
13290
  }
13287
13291
  });
@@ -13391,7 +13395,7 @@ function buildBudgetEventsRouter() {
13391
13395
  }
13392
13396
 
13393
13397
  // server/index.ts
13394
- var __dirname2 = path47.dirname(fileURLToPath2(import.meta.url));
13398
+ var __dirname2 = path48.dirname(fileURLToPath2(import.meta.url));
13395
13399
  async function startDashboard(options) {
13396
13400
  const { root, port, open } = options;
13397
13401
  console.log(`ctxloom dashboard \u2014 loading context from ${root}...`);
@@ -13451,9 +13455,9 @@ async function startDashboard(options) {
13451
13455
  }
13452
13456
  activeWatcher = null;
13453
13457
  }
13454
- const snapshotDir = path47.join(targetRoot, ".ctxloom");
13458
+ const snapshotDir = path48.join(targetRoot, ".ctxloom");
13455
13459
  try {
13456
- activeWatcher = fs35.watch(snapshotDir, (_event, filename) => {
13460
+ activeWatcher = fs36.watch(snapshotDir, (_event, filename) => {
13457
13461
  if (!filename || !filename.includes("snapshot")) return;
13458
13462
  if (debounce) clearTimeout(debounce);
13459
13463
  debounce = setTimeout(async () => {
@@ -13482,12 +13486,12 @@ async function startDashboard(options) {
13482
13486
  attachSnapshotWatcher(newRoot);
13483
13487
  }
13484
13488
  }));
13485
- const clientDist = path47.join(__dirname2, "../dashboard/client");
13486
- const clientDistExists = fs35.existsSync(path47.join(clientDist, "index.html"));
13489
+ const clientDist = path48.join(__dirname2, "../dashboard/client");
13490
+ const clientDistExists = fs36.existsSync(path48.join(clientDist, "index.html"));
13487
13491
  if (clientDistExists) {
13488
13492
  app.use(express.static(clientDist, { dotfiles: "allow" }));
13489
13493
  app.get(/.*/, (_req, res) => {
13490
- res.sendFile(path47.join(clientDist, "index.html"), { dotfiles: "allow" });
13494
+ res.sendFile(path48.join(clientDist, "index.html"), { dotfiles: "allow" });
13491
13495
  });
13492
13496
  } else {
13493
13497
  app.get(/^\/(?!api\/).*/, (_req, res) => {