ctxloom-pro 1.5.5 → 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 +2 -2
- package/apps/dashboard/dist/server/index.js +110 -105
- package/dist/{VectorStore-4VWT2ZMW.js → VectorStore-2LVECRTY.js} +2 -2
- package/dist/{chunk-5R4P7VEE.js → chunk-FPMNXF4D.js} +234 -177
- package/dist/{chunk-R56D54Y7.js → chunk-JULFFD7O.js} +10 -2
- package/dist/{chunk-COH5WYZS.js → chunk-WDX4PJGL.js} +2 -2
- package/dist/{embedder-7YOG4DFN.js → embedder-3AE4CSR7.js} +2 -2
- package/dist/index.js +138 -21
- package/dist/{src-QMDQDATD.js → src-DL44T55H.js} +8 -4
- package/dist/workers/indexerWorker.js +2 -2
- package/package.json +1 -1
- package/README.md.bak +0 -832
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.
|
|
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.
|
|
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
|
|
170
|
-
import
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3271
|
-
this.nodeCounts.set(
|
|
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 [
|
|
3419
|
-
nodes[
|
|
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 [
|
|
3435
|
-
idx.nodes.set(
|
|
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(
|
|
3449
|
-
const existing = this.nodes.get(
|
|
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(
|
|
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 [
|
|
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[
|
|
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 [
|
|
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(
|
|
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(
|
|
3566
|
-
const existing = this.nodes.get(
|
|
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(
|
|
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:
|
|
4808
|
-
const fullPath = [...
|
|
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,
|
|
4929
|
+
constructor(parent, value, path48, key) {
|
|
4925
4930
|
this._cachedPath = [];
|
|
4926
4931
|
this.parent = parent;
|
|
4927
4932
|
this.data = value;
|
|
4928
|
-
this._path =
|
|
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
|
|
8387
|
+
import fs17 from "fs";
|
|
8383
8388
|
import os2 from "os";
|
|
8384
|
-
import
|
|
8385
|
-
var DEFAULT_TELEMETRY_DIR =
|
|
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("..") || !
|
|
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
|
|
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 (!
|
|
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 =
|
|
8415
|
-
if (!
|
|
8416
|
-
const text =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
8668
|
-
import
|
|
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
|
|
8704
|
-
import
|
|
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
|
|
8722
|
-
import
|
|
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
|
|
8756
|
-
import
|
|
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
|
|
8789
|
-
import
|
|
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
|
|
8802
|
-
import
|
|
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
|
|
8844
|
-
import
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
11501
|
+
// ../../packages/core/src/review/loadConfig.ts
|
|
11502
|
+
import fs29 from "fs/promises";
|
|
11501
11503
|
import path31 from "path";
|
|
11502
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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.
|
|
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
|
|
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
|
|
11738
|
+
import path36 from "path";
|
|
11734
11739
|
import os7 from "os";
|
|
11735
11740
|
|
|
11736
11741
|
// ../../packages/core/src/server/ProjectState.ts
|
|
11737
|
-
import
|
|
11742
|
+
import path38 from "path";
|
|
11738
11743
|
|
|
11739
11744
|
// ../../packages/core/src/server/projectId.ts
|
|
11740
11745
|
import crypto5 from "crypto";
|
|
11741
|
-
import
|
|
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 =
|
|
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
|
|
12246
|
-
import
|
|
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 =
|
|
12253
|
-
const rootBoundary = ctx.root.endsWith(
|
|
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
|
|
12259
|
-
const ext =
|
|
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
|
|
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 =
|
|
12283
|
-
const rootBoundary = ctx.root.endsWith(
|
|
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
|
|
12296
|
-
import
|
|
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 =
|
|
12316
|
+
const absPath = path44.join(ctx.root, file);
|
|
12312
12317
|
try {
|
|
12313
|
-
const content =
|
|
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
|
|
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
|
|
12424
|
+
import path45 from "path";
|
|
12420
12425
|
import crypto7 from "crypto";
|
|
12421
12426
|
var HOME = os8.homedir();
|
|
12422
|
-
var REGISTRY_PATH =
|
|
12427
|
+
var REGISTRY_PATH = path45.join(HOME, ".ctxloom", "repos.json");
|
|
12423
12428
|
function slugFor(root) {
|
|
12424
|
-
const abs =
|
|
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 =
|
|
12444
|
+
const absDefault = path45.resolve(defaultRoot);
|
|
12440
12445
|
const out = [
|
|
12441
12446
|
{
|
|
12442
12447
|
slug: slugFor(absDefault),
|
|
12443
|
-
name:
|
|
12448
|
+
name: path45.basename(absDefault) || absDefault,
|
|
12444
12449
|
root: absDefault,
|
|
12445
12450
|
isDefault: true,
|
|
12446
|
-
hasSnapshot: existsSync5(
|
|
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 =
|
|
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 ?? (
|
|
12461
|
+
name: entry.name ?? (path45.basename(abs) || abs),
|
|
12457
12462
|
root: abs,
|
|
12458
12463
|
isDefault: false,
|
|
12459
|
-
hasSnapshot: existsSync5(
|
|
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 ${
|
|
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 =
|
|
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 =
|
|
12687
|
+
const snapshotDir = path47.join(targetRoot, ".ctxloom");
|
|
12683
12688
|
try {
|
|
12684
|
-
activeWatcher =
|
|
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 =
|
|
12714
|
-
const clientDistExists =
|
|
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(
|
|
12723
|
+
res.sendFile(path47.join(clientDist, "index.html"), { dotfiles: "allow" });
|
|
12719
12724
|
});
|
|
12720
12725
|
} else {
|
|
12721
12726
|
app.get(/^\/(?!api\/).*/, (_req, res) => {
|