ctxloom-pro 1.5.4 → 1.5.6

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
@@ -47,7 +47,7 @@ The full first-run flow is **one install + one trial + one init per project.** E
47
47
  npm install -g ctxloom-pro
48
48
  ```
49
49
 
50
- > **For local trial / dev use the unpinned command above is fine.** For unattended CI usage, pin to the exact version (`ctxloom-pro@1.5.3`) so future CLI releases don't silently desync your agent-spec coverage — see the workflow example below.
50
+ > **For local trial / dev use the unpinned command above is fine.** For unattended CI usage, pin to the exact version (`ctxloom-pro@1.5.6`) so future CLI releases don't silently desync your agent-spec coverage — see the workflow example below.
51
51
 
52
52
  ### 2 — Start your free trial (once per email)
53
53
 
@@ -361,7 +361,7 @@ jobs:
361
361
  # Exact pin (not `@^1`) so future CLI releases that add/remove MCP
362
362
  # tools don't silently desync your reviewer-agent specs. Bump on
363
363
  # every release; see CHANGELOG.md for the live version table.
364
- - run: npm install -g ctxloom-pro@1.5.3
364
+ - run: npm install -g ctxloom-pro@1.5.6
365
365
  - run: ctxloom index
366
366
  - run: ctxloom rules check --json
367
367
  ```
@@ -166,12 +166,12 @@ var init_VectorStore = __esm({
166
166
  // server/index.ts
167
167
  import express from "express";
168
168
  import cors from "cors";
169
- import path46 from "path";
170
- import fs34 from "fs";
169
+ import path47 from "path";
170
+ import fs35 from "fs";
171
171
  import { fileURLToPath as fileURLToPath2 } from "url";
172
172
 
173
173
  // server/loader.ts
174
- import path40 from "path";
174
+ import path41 from "path";
175
175
 
176
176
  // ../../packages/core/src/graph/DependencyGraph.ts
177
177
  import fs7 from "fs";
@@ -2915,12 +2915,12 @@ var DependencyGraph = class {
2915
2915
  symbolIndex: Object.fromEntries(this.symbolIndex.entries())
2916
2916
  };
2917
2917
  const snapshotPath = this.getSnapshotPath();
2918
- const tmpPath = snapshotPath + ".tmp";
2918
+ const tmpPath = `${snapshotPath}.${process.pid}.tmp`;
2919
2919
  fs7.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
2920
2920
  fs7.renameSync(tmpPath, snapshotPath);
2921
2921
  const callData = this.callGraphIndex.toJSON();
2922
2922
  const callPath = path7.join(this.snapshotDir, "call-graph-snapshot.json");
2923
- const callTmp = callPath + ".tmp";
2923
+ const callTmp = `${callPath}.${process.pid}.tmp`;
2924
2924
  fs7.writeFileSync(callTmp, JSON.stringify(callData));
2925
2925
  fs7.renameSync(callTmp, callPath);
2926
2926
  }
@@ -3267,8 +3267,8 @@ var CoChangeIndex = class _CoChangeIndex {
3267
3267
  if (event.isBulk || event.isMerge) return;
3268
3268
  const paths = event.files.map((f) => f.path);
3269
3269
  if (paths.length === 0) return;
3270
- for (const path47 of paths) {
3271
- this.nodeCounts.set(path47, (this.nodeCounts.get(path47) ?? 0) + 1);
3270
+ for (const path48 of paths) {
3271
+ this.nodeCounts.set(path48, (this.nodeCounts.get(path48) ?? 0) + 1);
3272
3272
  }
3273
3273
  for (let i = 0; i < paths.length; i++) {
3274
3274
  for (let j = i + 1; j < paths.length; j++) {
@@ -3415,8 +3415,8 @@ var ChurnIndex = class _ChurnIndex {
3415
3415
  */
3416
3416
  snapshot() {
3417
3417
  const nodes = {};
3418
- for (const [path47, raw] of this.nodes) {
3419
- nodes[path47] = {
3418
+ for (const [path48, raw] of this.nodes) {
3419
+ nodes[path48] = {
3420
3420
  commits: raw.commits,
3421
3421
  churnLines: raw.churnLines,
3422
3422
  bugCommits: raw.bugCommits,
@@ -3431,8 +3431,8 @@ var ChurnIndex = class _ChurnIndex {
3431
3431
  */
3432
3432
  static load(s) {
3433
3433
  const idx = new _ChurnIndex();
3434
- for (const [path47, raw] of Object.entries(s.nodes)) {
3435
- idx.nodes.set(path47, {
3434
+ for (const [path48, raw] of Object.entries(s.nodes)) {
3435
+ idx.nodes.set(path48, {
3436
3436
  commits: raw.commits,
3437
3437
  churnLines: raw.churnLines,
3438
3438
  bugCommits: raw.bugCommits,
@@ -3445,8 +3445,8 @@ var ChurnIndex = class _ChurnIndex {
3445
3445
  // -------------------------------------------------------------------------
3446
3446
  // Private helpers
3447
3447
  // -------------------------------------------------------------------------
3448
- getOrCreate(path47) {
3449
- const existing = this.nodes.get(path47);
3448
+ getOrCreate(path48) {
3449
+ const existing = this.nodes.get(path48);
3450
3450
  if (existing !== void 0) return existing;
3451
3451
  const fresh = {
3452
3452
  commits: 0,
@@ -3455,7 +3455,7 @@ var ChurnIndex = class _ChurnIndex {
3455
3455
  authorCounts: {},
3456
3456
  lastTouch: 0
3457
3457
  };
3458
- this.nodes.set(path47, fresh);
3458
+ this.nodes.set(path48, fresh);
3459
3459
  return fresh;
3460
3460
  }
3461
3461
  };
@@ -3536,12 +3536,12 @@ var OwnershipIndex = class _OwnershipIndex {
3536
3536
  */
3537
3537
  snapshot() {
3538
3538
  const nodes = {};
3539
- for (const [path47, raw] of this.nodes) {
3539
+ for (const [path48, raw] of this.nodes) {
3540
3540
  const authorWeights = {};
3541
3541
  for (const [email, entry] of Object.entries(raw.authorWeights)) {
3542
3542
  authorWeights[email] = { ...entry };
3543
3543
  }
3544
- nodes[path47] = { authorWeights, lastTouch: raw.lastTouch };
3544
+ nodes[path48] = { authorWeights, lastTouch: raw.lastTouch };
3545
3545
  }
3546
3546
  return { version: 1, nodes };
3547
3547
  }
@@ -3550,23 +3550,23 @@ var OwnershipIndex = class _OwnershipIndex {
3550
3550
  */
3551
3551
  static load(s) {
3552
3552
  const idx = new _OwnershipIndex();
3553
- for (const [path47, raw] of Object.entries(s.nodes)) {
3553
+ for (const [path48, raw] of Object.entries(s.nodes)) {
3554
3554
  const authorWeights = {};
3555
3555
  for (const [email, entry] of Object.entries(raw.authorWeights)) {
3556
3556
  authorWeights[email] = { ...entry };
3557
3557
  }
3558
- idx.nodes.set(path47, { authorWeights, lastTouch: raw.lastTouch });
3558
+ idx.nodes.set(path48, { authorWeights, lastTouch: raw.lastTouch });
3559
3559
  }
3560
3560
  return idx;
3561
3561
  }
3562
3562
  // -------------------------------------------------------------------------
3563
3563
  // Private helpers
3564
3564
  // -------------------------------------------------------------------------
3565
- getOrCreate(path47) {
3566
- const existing = this.nodes.get(path47);
3565
+ getOrCreate(path48) {
3566
+ const existing = this.nodes.get(path48);
3567
3567
  if (existing !== void 0) return existing;
3568
3568
  const fresh = { authorWeights: {}, lastTouch: 0 };
3569
- this.nodes.set(path47, fresh);
3569
+ this.nodes.set(path48, fresh);
3570
3570
  return fresh;
3571
3571
  }
3572
3572
  };
@@ -4326,6 +4326,11 @@ ${methodLines.join("\n")}
4326
4326
  init_embedder();
4327
4327
  init_VectorStore();
4328
4328
 
4329
+ // ../../packages/core/src/db/vectorsCleanup.ts
4330
+ import fs16 from "fs";
4331
+ import path16 from "path";
4332
+ var VECTOR_DB_REL = path16.join(".ctxloom", "vectors.lancedb");
4333
+
4329
4334
  // ../../node_modules/zod/v3/external.js
4330
4335
  var external_exports = {};
4331
4336
  __export(external_exports, {
@@ -4804,8 +4809,8 @@ function getErrorMap() {
4804
4809
 
4805
4810
  // ../../node_modules/zod/v3/helpers/parseUtil.js
4806
4811
  var makeIssue = (params) => {
4807
- const { data, path: path47, errorMaps, issueData } = params;
4808
- const fullPath = [...path47, ...issueData.path || []];
4812
+ const { data, path: path48, errorMaps, issueData } = params;
4813
+ const fullPath = [...path48, ...issueData.path || []];
4809
4814
  const fullIssue = {
4810
4815
  ...issueData,
4811
4816
  path: fullPath
@@ -4921,11 +4926,11 @@ var errorUtil;
4921
4926
 
4922
4927
  // ../../node_modules/zod/v3/types.js
4923
4928
  var ParseInputLazyPath = class {
4924
- constructor(parent, value, path47, key) {
4929
+ constructor(parent, value, path48, key) {
4925
4930
  this._cachedPath = [];
4926
4931
  this.parent = parent;
4927
4932
  this.data = value;
4928
- this._path = path47;
4933
+ this._path = path48;
4929
4934
  this._key = key;
4930
4935
  }
4931
4936
  get path() {
@@ -8379,13 +8384,13 @@ init_logger();
8379
8384
 
8380
8385
  // ../../packages/core/src/budget/eventCollector.ts
8381
8386
  init_logger();
8382
- import fs16 from "fs";
8387
+ import fs17 from "fs";
8383
8388
  import os2 from "os";
8384
- import path16 from "path";
8385
- var DEFAULT_TELEMETRY_DIR = path16.join(os2.homedir(), ".ctxloom", "telemetry");
8389
+ import path17 from "path";
8390
+ var DEFAULT_TELEMETRY_DIR = path17.join(os2.homedir(), ".ctxloom", "telemetry");
8386
8391
  function telemetryDir() {
8387
8392
  const raw = process.env.CTXLOOM_TELEMETRY_DIR ?? DEFAULT_TELEMETRY_DIR;
8388
- if (raw.includes("..") || !path16.isAbsolute(raw)) {
8393
+ if (raw.includes("..") || !path17.isAbsolute(raw)) {
8389
8394
  if (!telemetryDirWarned) {
8390
8395
  telemetryDirWarned = true;
8391
8396
  logger.warn('CTXLOOM_TELEMETRY_DIR rejected \u2014 must be an absolute path with no ".." segments; using default', {
@@ -8395,7 +8400,7 @@ function telemetryDir() {
8395
8400
  }
8396
8401
  return DEFAULT_TELEMETRY_DIR;
8397
8402
  }
8398
- return path16.resolve(raw);
8403
+ return path17.resolve(raw);
8399
8404
  }
8400
8405
  var telemetryDirWarned = false;
8401
8406
  function filenameForDate(date) {
@@ -8408,12 +8413,12 @@ function readEvents(opts = {}) {
8408
8413
  const until = opts.until ?? /* @__PURE__ */ new Date();
8409
8414
  const since = opts.since ?? new Date(until.getTime() - 14 * 24 * 60 * 60 * 1e3);
8410
8415
  const dir = telemetryDir();
8411
- if (!fs16.existsSync(dir)) return [];
8416
+ if (!fs17.existsSync(dir)) return [];
8412
8417
  const out = [];
8413
8418
  for (let cursor = new Date(Date.UTC(since.getUTCFullYear(), since.getUTCMonth(), since.getUTCDate())); cursor.getTime() <= until.getTime(); cursor = new Date(cursor.getTime() + 24 * 60 * 60 * 1e3)) {
8414
- const file = path16.join(dir, filenameForDate(cursor));
8415
- if (!fs16.existsSync(file)) continue;
8416
- const text = fs16.readFileSync(file, "utf-8");
8419
+ const file = path17.join(dir, filenameForDate(cursor));
8420
+ if (!fs17.existsSync(file)) continue;
8421
+ const text = fs17.readFileSync(file, "utf-8");
8417
8422
  for (const line of text.split("\n")) {
8418
8423
  if (line.trim() === "") continue;
8419
8424
  let parsed;
@@ -8474,7 +8479,7 @@ var Schema2 = external_exports.object({
8474
8479
  });
8475
8480
 
8476
8481
  // ../../packages/core/src/tools/context-packet.ts
8477
- import path17 from "path";
8482
+ import path18 from "path";
8478
8483
  var Schema3 = external_exports.object({
8479
8484
  target_file: external_exports.string().describe("Relative path to the primary file"),
8480
8485
  mode: external_exports.enum(["edit", "read"]).optional().default("edit").describe("Context mode"),
@@ -8486,7 +8491,7 @@ var Schema3 = external_exports.object({
8486
8491
  });
8487
8492
 
8488
8493
  // ../../packages/core/src/tools/findCallers.ts
8489
- import path18 from "path";
8494
+ import path19 from "path";
8490
8495
 
8491
8496
  // ../../packages/core/src/tools/call-graph.ts
8492
8497
  var Schema4 = external_exports.object({
@@ -8587,7 +8592,7 @@ var Schema12 = external_exports.object({
8587
8592
  });
8588
8593
 
8589
8594
  // ../../packages/core/src/tools/knowledge-gaps.ts
8590
- import path19 from "path";
8595
+ import path20 from "path";
8591
8596
  var Schema13 = external_exports.object({
8592
8597
  min_importers: external_exports.number().min(1).max(50).optional().default(3).describe(
8593
8598
  "Minimum importers to qualify as an untested hub (default: 3)"
@@ -8616,7 +8621,7 @@ var Schema14 = external_exports.object({
8616
8621
  });
8617
8622
 
8618
8623
  // ../../packages/core/src/tools/wiki-generate.ts
8619
- import fs17 from "fs";
8624
+ import fs18 from "fs";
8620
8625
  var Schema15 = external_exports.object({
8621
8626
  force: external_exports.boolean().optional().default(false).describe(
8622
8627
  "Regenerate all pages even if content unchanged (default: false)"
@@ -8664,8 +8669,8 @@ var Schema17 = external_exports.object({
8664
8669
  });
8665
8670
 
8666
8671
  // ../../packages/core/src/tools/refactor-preview.ts
8667
- import fs18 from "fs";
8668
- import path20 from "path";
8672
+ import fs19 from "fs";
8673
+ import path21 from "path";
8669
8674
  var Schema18 = external_exports.object({
8670
8675
  symbol: external_exports.string().min(1).describe("Symbol name to rename (exact match, case-sensitive)"),
8671
8676
  new_name: external_exports.string().min(1).describe("New name for the symbol"),
@@ -8700,8 +8705,8 @@ var Schema19 = external_exports.object({
8700
8705
  init_embedder();
8701
8706
  init_VectorStore();
8702
8707
  init_logger();
8703
- import fs19 from "fs";
8704
- import path21 from "path";
8708
+ import fs20 from "fs";
8709
+ import path22 from "path";
8705
8710
  var Schema20 = external_exports.object({
8706
8711
  query: external_exports.string().min(1).describe("Search query \u2014 natural language or code fragment"),
8707
8712
  limit: external_exports.number().min(1).max(100).optional().default(10).describe(
@@ -8718,8 +8723,8 @@ var Schema20 = external_exports.object({
8718
8723
  });
8719
8724
 
8720
8725
  // ../../packages/core/src/tools/apply-refactor.ts
8721
- import fs20 from "fs";
8722
- import path22 from "path";
8726
+ import fs21 from "fs";
8727
+ import path23 from "path";
8723
8728
  var Schema21 = external_exports.object({
8724
8729
  symbol: external_exports.string().min(1).describe("Symbol name to rename (exact, case-sensitive)"),
8725
8730
  new_name: external_exports.string().min(1).describe("New name for the symbol"),
@@ -8752,8 +8757,8 @@ var Schema22 = external_exports.object({
8752
8757
  });
8753
8758
 
8754
8759
  // ../../packages/core/src/tools/full-text-search.ts
8755
- import fs21 from "fs";
8756
- import path23 from "path";
8760
+ import fs22 from "fs";
8761
+ import path24 from "path";
8757
8762
  var Schema23 = external_exports.object({
8758
8763
  query: external_exports.string().min(1).describe("Search term \u2014 literal or /regex/"),
8759
8764
  mode: external_exports.enum(["hybrid", "keyword", "semantic"]).optional().default("hybrid"),
@@ -8785,8 +8790,8 @@ var Schema25 = external_exports.object({
8785
8790
  });
8786
8791
 
8787
8792
  // ../../packages/core/src/tools/graph-snapshot.ts
8788
- import fs22 from "fs";
8789
- import path24 from "path";
8793
+ import fs23 from "fs";
8794
+ import path25 from "path";
8790
8795
  var schema = external_exports.object({
8791
8796
  name: external_exports.string().min(1).max(64).regex(/^[\w.-]+$/, "Name may only contain letters, digits, dots, underscores, hyphens").describe(
8792
8797
  'Snapshot name (e.g. "before-refactor", "v1.0"). Used as the filename.'
@@ -8798,8 +8803,8 @@ var schema = external_exports.object({
8798
8803
  });
8799
8804
 
8800
8805
  // ../../packages/core/src/tools/graph-diff.ts
8801
- import fs23 from "fs";
8802
- import path25 from "path";
8806
+ import fs24 from "fs";
8807
+ import path26 from "path";
8803
8808
  var schema2 = external_exports.object({
8804
8809
  baseline: external_exports.string().min(1).describe('Name of the baseline snapshot (the "before" state).'),
8805
8810
  current: external_exports.string().min(1).describe('Name of the current snapshot (the "after" state).'),
@@ -8840,8 +8845,8 @@ var Schema27 = external_exports.object({
8840
8845
  });
8841
8846
 
8842
8847
  // ../../packages/core/src/rules/loadConfig.ts
8843
- import fs24 from "fs/promises";
8844
- import path26 from "path";
8848
+ import fs25 from "fs/promises";
8849
+ import path27 from "path";
8845
8850
 
8846
8851
  // ../../node_modules/js-yaml/dist/js-yaml.mjs
8847
8852
  function isNothing(subject) {
@@ -11482,24 +11487,24 @@ var Schema30 = external_exports.object({
11482
11487
  });
11483
11488
 
11484
11489
  // ../../packages/core/src/tools/ruleManager.ts
11485
- import fs25 from "fs";
11486
- import path27 from "path";
11487
-
11488
- // ../../packages/core/src/review/AuthorResolver.ts
11489
- import fs26 from "fs/promises";
11490
+ import fs26 from "fs";
11490
11491
  import path28 from "path";
11491
11492
 
11492
- // ../../packages/core/src/review/CodeownersWriter.ts
11493
+ // ../../packages/core/src/review/AuthorResolver.ts
11493
11494
  import fs27 from "fs/promises";
11494
11495
  import path29 from "path";
11495
11496
 
11496
- // ../../packages/core/src/review/loadConfig.ts
11497
+ // ../../packages/core/src/review/CodeownersWriter.ts
11497
11498
  import fs28 from "fs/promises";
11498
11499
  import path30 from "path";
11499
11500
 
11500
- // ../../packages/core/src/security/PathValidator.ts
11501
+ // ../../packages/core/src/review/loadConfig.ts
11502
+ import fs29 from "fs/promises";
11501
11503
  import path31 from "path";
11502
- import fs29 from "fs";
11504
+
11505
+ // ../../packages/core/src/security/PathValidator.ts
11506
+ import path32 from "path";
11507
+ import fs30 from "fs";
11503
11508
  var MAX_FILE_SIZE = 5 * 1024 * 1024;
11504
11509
 
11505
11510
  // ../../packages/core/src/index.ts
@@ -11510,7 +11515,7 @@ init_logger();
11510
11515
 
11511
11516
  // ../../packages/core/src/license/LicenseStore.ts
11512
11517
  import { readFileSync, writeFileSync, unlinkSync, mkdirSync, chmodSync, existsSync } from "fs";
11513
- import path32 from "path";
11518
+ import path33 from "path";
11514
11519
 
11515
11520
  // ../../packages/core/src/license/types.ts
11516
11521
  var FINGERPRINT_RE = /^sha256:[0-9a-f]{64}$/;
@@ -11541,11 +11546,11 @@ import os6 from "os";
11541
11546
 
11542
11547
  // ../../packages/core/src/license/DistinctIdStore.ts
11543
11548
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
11544
- import path33 from "path";
11549
+ import path34 from "path";
11545
11550
  import os4 from "os";
11546
11551
  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;
11547
11552
  function distinctIdPath(home) {
11548
- return path33.join(home ?? os4.homedir(), ".ctxloom", "distinct_id");
11553
+ return path34.join(home ?? os4.homedir(), ".ctxloom", "distinct_id");
11549
11554
  }
11550
11555
  function isValidV4(id) {
11551
11556
  return typeof id === "string" && UUID_V4_REGEX.test(id);
@@ -11566,7 +11571,7 @@ function getOrCreateDistinctId(home) {
11566
11571
  id: crypto.randomUUID(),
11567
11572
  alias_pending: os4.hostname()
11568
11573
  };
11569
- mkdirSync2(path33.dirname(filePath), { recursive: true });
11574
+ mkdirSync2(path34.dirname(filePath), { recursive: true });
11570
11575
  writeFileSync2(filePath, JSON.stringify(record), { mode: 384 });
11571
11576
  return record;
11572
11577
  }
@@ -11592,7 +11597,7 @@ function resolveTelemetryLevel() {
11592
11597
  }
11593
11598
  var TELEMETRY_LEVEL = resolveTelemetryLevel();
11594
11599
  var TELEMETRY_DISABLED = TELEMETRY_LEVEL === "off";
11595
- var CTXLOOM_VERSION = "1.5.4".length > 0 ? "1.5.4" : "dev";
11600
+ var CTXLOOM_VERSION = "1.5.6".length > 0 ? "1.5.6" : "dev";
11596
11601
  var POSTHOG_HOST = "https://eu.i.posthog.com";
11597
11602
  var POSTHOG_KEY = process.env["POSTHOG_API_KEY"] ?? (true ? "phc_CiDkmFLcZ2K6uCpcoSUQLmFrnnUvsyXGhSxopX5TVKE6" : "");
11598
11603
  var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528\u2028" : "");
@@ -11725,32 +11730,32 @@ function parseStack(stack) {
11725
11730
 
11726
11731
  // ../../packages/core/src/license/FunnelMilestones.ts
11727
11732
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
11728
- import path34 from "path";
11733
+ import path35 from "path";
11729
11734
  import os5 from "os";
11730
11735
 
11731
11736
  // ../../packages/core/src/license/TelemetryNotice.ts
11732
11737
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
11733
- import path35 from "path";
11738
+ import path36 from "path";
11734
11739
  import os7 from "os";
11735
11740
 
11736
11741
  // ../../packages/core/src/server/ProjectState.ts
11737
- import path37 from "path";
11742
+ import path38 from "path";
11738
11743
 
11739
11744
  // ../../packages/core/src/server/projectId.ts
11740
11745
  import crypto5 from "crypto";
11741
- import path36 from "path";
11746
+ import path37 from "path";
11742
11747
 
11743
11748
  // ../../packages/core/src/server/ProjectStateManager.ts
11744
11749
  init_logger();
11745
11750
 
11746
11751
  // ../../packages/core/src/server/resolveProjectRoot.ts
11747
- import fs30 from "fs";
11748
- import path38 from "path";
11749
-
11750
- // ../../packages/core/src/install/installer.ts
11751
11752
  import fs31 from "fs";
11752
11753
  import path39 from "path";
11753
11754
 
11755
+ // ../../packages/core/src/install/installer.ts
11756
+ import fs32 from "fs";
11757
+ import path40 from "path";
11758
+
11754
11759
  // ../../packages/core/src/install/templates.ts
11755
11760
  var RULES_BLOCK_CONTENT = `## MCP Tools: ctxloom
11756
11761
 
@@ -11989,7 +11994,7 @@ function summarize(events, windowStart, windowEnd) {
11989
11994
 
11990
11995
  // server/loader.ts
11991
11996
  async function loadContext(root) {
11992
- const absRoot = path40.resolve(root);
11997
+ const absRoot = path41.resolve(root);
11993
11998
  const overlay = new GitOverlayStore(absRoot);
11994
11999
  const gitEnabled = await overlay.loadSnapshot();
11995
12000
  const graph = new DependencyGraph();
@@ -12242,21 +12247,21 @@ function buildOwnershipRouter(ctx) {
12242
12247
 
12243
12248
  // server/routes/file.ts
12244
12249
  import { Router as Router7 } from "express";
12245
- import fs32 from "fs/promises";
12246
- import path41 from "path";
12250
+ import fs33 from "fs/promises";
12251
+ import path42 from "path";
12247
12252
  function buildFileRouter(ctx) {
12248
12253
  const router = Router7();
12249
12254
  router.get("/", async (req, res) => {
12250
12255
  const rel = req.query.path;
12251
12256
  if (!rel) return res.status(400).json({ error: "missing path" });
12252
- const abs = path41.resolve(ctx.root, rel);
12253
- const rootBoundary = ctx.root.endsWith(path41.sep) ? ctx.root : ctx.root + path41.sep;
12257
+ const abs = path42.resolve(ctx.root, rel);
12258
+ const rootBoundary = ctx.root.endsWith(path42.sep) ? ctx.root : ctx.root + path42.sep;
12254
12259
  if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
12255
12260
  return res.status(403).json({ error: "forbidden" });
12256
12261
  }
12257
12262
  try {
12258
- const content = await fs32.readFile(abs, "utf-8");
12259
- const ext = path41.extname(abs).slice(1);
12263
+ const content = await fs33.readFile(abs, "utf-8");
12264
+ const ext = path42.extname(abs).slice(1);
12260
12265
  res.json({ content, lines: content.split("\n").length, ext });
12261
12266
  } catch {
12262
12267
  res.status(404).json({ error: "not found" });
@@ -12268,7 +12273,7 @@ function buildFileRouter(ctx) {
12268
12273
  // server/routes/open.ts
12269
12274
  import { Router as Router8 } from "express";
12270
12275
  import { execFile as execFile2 } from "child_process";
12271
- import path42 from "path";
12276
+ import path43 from "path";
12272
12277
  function tryOpen(bin, abs) {
12273
12278
  return new Promise((resolve) => {
12274
12279
  execFile2(bin, [abs], { timeout: 5e3 }, (err) => resolve(!err));
@@ -12279,8 +12284,8 @@ function buildOpenRouter(ctx) {
12279
12284
  router.post("/", async (req, res) => {
12280
12285
  const rel = req.body?.path;
12281
12286
  if (!rel || typeof rel !== "string") return res.status(400).json({ error: "missing path" });
12282
- const abs = path42.resolve(ctx.root, rel);
12283
- const rootBoundary = ctx.root.endsWith(path42.sep) ? ctx.root : ctx.root + path42.sep;
12287
+ const abs = path43.resolve(ctx.root, rel);
12288
+ const rootBoundary = ctx.root.endsWith(path43.sep) ? ctx.root : ctx.root + path43.sep;
12284
12289
  if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
12285
12290
  return res.status(403).json({ error: "forbidden" });
12286
12291
  }
@@ -12292,8 +12297,8 @@ function buildOpenRouter(ctx) {
12292
12297
 
12293
12298
  // server/routes/tokens.ts
12294
12299
  import { Router as Router9 } from "express";
12295
- import path43 from "path";
12296
- import fs33 from "fs";
12300
+ import path44 from "path";
12301
+ import fs34 from "fs";
12297
12302
  var CHARS_PER_TOKEN = 4;
12298
12303
  var cache = null;
12299
12304
  function buildTokensRouter(ctx) {
@@ -12308,9 +12313,9 @@ function buildTokensRouter(ctx) {
12308
12313
  let fullChars = 0;
12309
12314
  let skeletonChars = 0;
12310
12315
  for (const file of files) {
12311
- const absPath = path43.join(ctx.root, file);
12316
+ const absPath = path44.join(ctx.root, file);
12312
12317
  try {
12313
- const content = fs33.readFileSync(absPath, "utf-8");
12318
+ const content = fs34.readFileSync(absPath, "utf-8");
12314
12319
  fullChars += content.length;
12315
12320
  const skeleton = await skeletonizer.skeletonize(absPath);
12316
12321
  skeletonChars += skeleton.length;
@@ -12411,17 +12416,17 @@ function buildFileTrendsRouter(ctx) {
12411
12416
 
12412
12417
  // server/routes/projects.ts
12413
12418
  import { Router as Router12 } from "express";
12414
- import path45 from "path";
12419
+ import path46 from "path";
12415
12420
 
12416
12421
  // server/projects.ts
12417
12422
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
12418
12423
  import os8 from "os";
12419
- import path44 from "path";
12424
+ import path45 from "path";
12420
12425
  import crypto7 from "crypto";
12421
12426
  var HOME = os8.homedir();
12422
- var REGISTRY_PATH = path44.join(HOME, ".ctxloom", "repos.json");
12427
+ var REGISTRY_PATH = path45.join(HOME, ".ctxloom", "repos.json");
12423
12428
  function slugFor(root) {
12424
- const abs = path44.resolve(root);
12429
+ const abs = path45.resolve(root);
12425
12430
  return crypto7.createHash("sha1").update(abs).digest("hex").slice(0, 12);
12426
12431
  }
12427
12432
  function readRegistry() {
@@ -12436,27 +12441,27 @@ function readRegistry() {
12436
12441
  }
12437
12442
  }
12438
12443
  function listProjects(defaultRoot) {
12439
- const absDefault = path44.resolve(defaultRoot);
12444
+ const absDefault = path45.resolve(defaultRoot);
12440
12445
  const out = [
12441
12446
  {
12442
12447
  slug: slugFor(absDefault),
12443
- name: path44.basename(absDefault) || absDefault,
12448
+ name: path45.basename(absDefault) || absDefault,
12444
12449
  root: absDefault,
12445
12450
  isDefault: true,
12446
- hasSnapshot: existsSync5(path44.join(absDefault, ".ctxloom"))
12451
+ hasSnapshot: existsSync5(path45.join(absDefault, ".ctxloom"))
12447
12452
  }
12448
12453
  ];
12449
12454
  const seen = /* @__PURE__ */ new Set([absDefault]);
12450
12455
  for (const entry of readRegistry()) {
12451
- const abs = path44.resolve(entry.root);
12456
+ const abs = path45.resolve(entry.root);
12452
12457
  if (seen.has(abs)) continue;
12453
12458
  seen.add(abs);
12454
12459
  const item = {
12455
12460
  slug: slugFor(abs),
12456
- name: entry.name ?? (path44.basename(abs) || abs),
12461
+ name: entry.name ?? (path45.basename(abs) || abs),
12457
12462
  root: abs,
12458
12463
  isDefault: false,
12459
- hasSnapshot: existsSync5(path44.join(abs, ".ctxloom"))
12464
+ hasSnapshot: existsSync5(path45.join(abs, ".ctxloom"))
12460
12465
  };
12461
12466
  if (entry.alias !== void 0) item.alias = entry.alias;
12462
12467
  out.push(item);
@@ -12509,7 +12514,7 @@ function buildProjectsRouter(deps) {
12509
12514
  } catch (err) {
12510
12515
  const detail = err instanceof Error ? err.message : String(err);
12511
12516
  res.status(500).json({
12512
- error: `failed to switch to ${path45.basename(target.root)}: ${detail}`
12517
+ error: `failed to switch to ${path46.basename(target.root)}: ${detail}`
12513
12518
  });
12514
12519
  }
12515
12520
  });
@@ -12619,7 +12624,7 @@ function buildBudgetEventsRouter() {
12619
12624
  }
12620
12625
 
12621
12626
  // server/index.ts
12622
- var __dirname2 = path46.dirname(fileURLToPath2(import.meta.url));
12627
+ var __dirname2 = path47.dirname(fileURLToPath2(import.meta.url));
12623
12628
  async function startDashboard(options) {
12624
12629
  const { root, port, open } = options;
12625
12630
  console.log(`ctxloom dashboard \u2014 loading context from ${root}...`);
@@ -12679,9 +12684,9 @@ async function startDashboard(options) {
12679
12684
  }
12680
12685
  activeWatcher = null;
12681
12686
  }
12682
- const snapshotDir = path46.join(targetRoot, ".ctxloom");
12687
+ const snapshotDir = path47.join(targetRoot, ".ctxloom");
12683
12688
  try {
12684
- activeWatcher = fs34.watch(snapshotDir, (_event, filename) => {
12689
+ activeWatcher = fs35.watch(snapshotDir, (_event, filename) => {
12685
12690
  if (!filename || !filename.includes("snapshot")) return;
12686
12691
  if (debounce) clearTimeout(debounce);
12687
12692
  debounce = setTimeout(async () => {
@@ -12710,12 +12715,12 @@ async function startDashboard(options) {
12710
12715
  attachSnapshotWatcher(newRoot);
12711
12716
  }
12712
12717
  }));
12713
- const clientDist = path46.join(__dirname2, "../dashboard/client");
12714
- const clientDistExists = fs34.existsSync(path46.join(clientDist, "index.html"));
12718
+ const clientDist = path47.join(__dirname2, "../dashboard/client");
12719
+ const clientDistExists = fs35.existsSync(path47.join(clientDist, "index.html"));
12715
12720
  if (clientDistExists) {
12716
12721
  app.use(express.static(clientDist, { dotfiles: "allow" }));
12717
12722
  app.get(/.*/, (_req, res) => {
12718
- res.sendFile(path46.join(clientDist, "index.html"), { dotfiles: "allow" });
12723
+ res.sendFile(path47.join(clientDist, "index.html"), { dotfiles: "allow" });
12719
12724
  });
12720
12725
  } else {
12721
12726
  app.get(/^\/(?!api\/).*/, (_req, res) => {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  VectorStore
3
- } from "./chunk-DVI2RWJR.js";
3
+ } from "./chunk-JULFFD7O.js";
4
4
  import "./chunk-TYDMSHV7.js";
5
5
  export {
6
6
  VectorStore
7
7
  };
8
- //# sourceMappingURL=VectorStore-XYLGD37W.js.map
8
+ //# sourceMappingURL=VectorStore-2LVECRTY.js.map