ctxloom-pro 1.0.29 → 1.1.0
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 +33 -1
- package/apps/dashboard/dist/dashboard/client/assets/{index-Ci5_ZKGm.js → index-Bfa2_GyA.js} +1 -1
- package/apps/dashboard/dist/dashboard/client/assets/index-MBoNDzdn.css +1 -0
- package/apps/dashboard/dist/dashboard/client/index.html +2 -2
- package/apps/dashboard/dist/server/index.js +167 -108
- package/apps/dashboard/package.json +1 -0
- package/bin/ctxloom.cjs +85 -0
- package/dist/{chunk-WQMLQTFY.js → chunk-FFSSKDV4.js} +838 -364
- package/dist/index.js +360 -165
- package/dist/{src-YPSOSNW5.js → src-XX7SUUMW.js} +32 -2
- package/package.json +3 -2
- package/apps/dashboard/dist/dashboard/client/assets/index-BvSIeKR7.css +0 -1
|
@@ -169,12 +169,12 @@ var init_VectorStore = __esm({
|
|
|
169
169
|
// server/index.ts
|
|
170
170
|
import express from "express";
|
|
171
171
|
import cors from "cors";
|
|
172
|
-
import
|
|
173
|
-
import
|
|
172
|
+
import path40 from "path";
|
|
173
|
+
import fs32 from "fs";
|
|
174
174
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
175
175
|
|
|
176
176
|
// server/loader.ts
|
|
177
|
-
import
|
|
177
|
+
import path34 from "path";
|
|
178
178
|
|
|
179
179
|
// ../../packages/core/src/graph/DependencyGraph.ts
|
|
180
180
|
import fs7 from "fs";
|
|
@@ -3133,8 +3133,8 @@ var CoChangeIndex = class _CoChangeIndex {
|
|
|
3133
3133
|
if (event.isBulk || event.isMerge) return;
|
|
3134
3134
|
const paths = event.files.map((f) => f.path);
|
|
3135
3135
|
if (paths.length === 0) return;
|
|
3136
|
-
for (const
|
|
3137
|
-
this.nodeCounts.set(
|
|
3136
|
+
for (const path41 of paths) {
|
|
3137
|
+
this.nodeCounts.set(path41, (this.nodeCounts.get(path41) ?? 0) + 1);
|
|
3138
3138
|
}
|
|
3139
3139
|
for (let i = 0; i < paths.length; i++) {
|
|
3140
3140
|
for (let j = i + 1; j < paths.length; j++) {
|
|
@@ -3281,8 +3281,8 @@ var ChurnIndex = class _ChurnIndex {
|
|
|
3281
3281
|
*/
|
|
3282
3282
|
snapshot() {
|
|
3283
3283
|
const nodes = {};
|
|
3284
|
-
for (const [
|
|
3285
|
-
nodes[
|
|
3284
|
+
for (const [path41, raw] of this.nodes) {
|
|
3285
|
+
nodes[path41] = {
|
|
3286
3286
|
commits: raw.commits,
|
|
3287
3287
|
churnLines: raw.churnLines,
|
|
3288
3288
|
bugCommits: raw.bugCommits,
|
|
@@ -3297,8 +3297,8 @@ var ChurnIndex = class _ChurnIndex {
|
|
|
3297
3297
|
*/
|
|
3298
3298
|
static load(s) {
|
|
3299
3299
|
const idx = new _ChurnIndex();
|
|
3300
|
-
for (const [
|
|
3301
|
-
idx.nodes.set(
|
|
3300
|
+
for (const [path41, raw] of Object.entries(s.nodes)) {
|
|
3301
|
+
idx.nodes.set(path41, {
|
|
3302
3302
|
commits: raw.commits,
|
|
3303
3303
|
churnLines: raw.churnLines,
|
|
3304
3304
|
bugCommits: raw.bugCommits,
|
|
@@ -3311,8 +3311,8 @@ var ChurnIndex = class _ChurnIndex {
|
|
|
3311
3311
|
// -------------------------------------------------------------------------
|
|
3312
3312
|
// Private helpers
|
|
3313
3313
|
// -------------------------------------------------------------------------
|
|
3314
|
-
getOrCreate(
|
|
3315
|
-
const existing = this.nodes.get(
|
|
3314
|
+
getOrCreate(path41) {
|
|
3315
|
+
const existing = this.nodes.get(path41);
|
|
3316
3316
|
if (existing !== void 0) return existing;
|
|
3317
3317
|
const fresh = {
|
|
3318
3318
|
commits: 0,
|
|
@@ -3321,7 +3321,7 @@ var ChurnIndex = class _ChurnIndex {
|
|
|
3321
3321
|
authorCounts: {},
|
|
3322
3322
|
lastTouch: 0
|
|
3323
3323
|
};
|
|
3324
|
-
this.nodes.set(
|
|
3324
|
+
this.nodes.set(path41, fresh);
|
|
3325
3325
|
return fresh;
|
|
3326
3326
|
}
|
|
3327
3327
|
};
|
|
@@ -3402,12 +3402,12 @@ var OwnershipIndex = class _OwnershipIndex {
|
|
|
3402
3402
|
*/
|
|
3403
3403
|
snapshot() {
|
|
3404
3404
|
const nodes = {};
|
|
3405
|
-
for (const [
|
|
3405
|
+
for (const [path41, raw] of this.nodes) {
|
|
3406
3406
|
const authorWeights = {};
|
|
3407
3407
|
for (const [email, entry] of Object.entries(raw.authorWeights)) {
|
|
3408
3408
|
authorWeights[email] = { ...entry };
|
|
3409
3409
|
}
|
|
3410
|
-
nodes[
|
|
3410
|
+
nodes[path41] = { authorWeights, lastTouch: raw.lastTouch };
|
|
3411
3411
|
}
|
|
3412
3412
|
return { version: 1, nodes };
|
|
3413
3413
|
}
|
|
@@ -3416,23 +3416,23 @@ var OwnershipIndex = class _OwnershipIndex {
|
|
|
3416
3416
|
*/
|
|
3417
3417
|
static load(s) {
|
|
3418
3418
|
const idx = new _OwnershipIndex();
|
|
3419
|
-
for (const [
|
|
3419
|
+
for (const [path41, raw] of Object.entries(s.nodes)) {
|
|
3420
3420
|
const authorWeights = {};
|
|
3421
3421
|
for (const [email, entry] of Object.entries(raw.authorWeights)) {
|
|
3422
3422
|
authorWeights[email] = { ...entry };
|
|
3423
3423
|
}
|
|
3424
|
-
idx.nodes.set(
|
|
3424
|
+
idx.nodes.set(path41, { authorWeights, lastTouch: raw.lastTouch });
|
|
3425
3425
|
}
|
|
3426
3426
|
return idx;
|
|
3427
3427
|
}
|
|
3428
3428
|
// -------------------------------------------------------------------------
|
|
3429
3429
|
// Private helpers
|
|
3430
3430
|
// -------------------------------------------------------------------------
|
|
3431
|
-
getOrCreate(
|
|
3432
|
-
const existing = this.nodes.get(
|
|
3431
|
+
getOrCreate(path41) {
|
|
3432
|
+
const existing = this.nodes.get(path41);
|
|
3433
3433
|
if (existing !== void 0) return existing;
|
|
3434
3434
|
const fresh = { authorWeights: {}, lastTouch: 0 };
|
|
3435
|
-
this.nodes.set(
|
|
3435
|
+
this.nodes.set(path41, fresh);
|
|
3436
3436
|
return fresh;
|
|
3437
3437
|
}
|
|
3438
3438
|
};
|
|
@@ -4670,8 +4670,8 @@ function getErrorMap() {
|
|
|
4670
4670
|
|
|
4671
4671
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
4672
4672
|
var makeIssue = (params) => {
|
|
4673
|
-
const { data, path:
|
|
4674
|
-
const fullPath = [...
|
|
4673
|
+
const { data, path: path41, errorMaps, issueData } = params;
|
|
4674
|
+
const fullPath = [...path41, ...issueData.path || []];
|
|
4675
4675
|
const fullIssue = {
|
|
4676
4676
|
...issueData,
|
|
4677
4677
|
path: fullPath
|
|
@@ -4787,11 +4787,11 @@ var errorUtil;
|
|
|
4787
4787
|
|
|
4788
4788
|
// ../../node_modules/zod/v3/types.js
|
|
4789
4789
|
var ParseInputLazyPath = class {
|
|
4790
|
-
constructor(parent, value,
|
|
4790
|
+
constructor(parent, value, path41, key) {
|
|
4791
4791
|
this._cachedPath = [];
|
|
4792
4792
|
this.parent = parent;
|
|
4793
4793
|
this.data = value;
|
|
4794
|
-
this._path =
|
|
4794
|
+
this._path = path41;
|
|
4795
4795
|
this._key = key;
|
|
4796
4796
|
}
|
|
4797
4797
|
get path() {
|
|
@@ -8233,21 +8233,33 @@ var coerce = {
|
|
|
8233
8233
|
};
|
|
8234
8234
|
var NEVER = INVALID;
|
|
8235
8235
|
|
|
8236
|
+
// ../../packages/core/src/tools/projectRootParam.ts
|
|
8237
|
+
var PROJECT_ROOT_DESCRIPTION = "Absolute path or registered alias of the project to operate on. Falls back to CTXLOOM_ROOT env, then server cwd. Register aliases with `ctxloom register <path> --alias <name>`.";
|
|
8238
|
+
var ProjectRootField = external_exports.string().optional().describe(PROJECT_ROOT_DESCRIPTION);
|
|
8239
|
+
|
|
8240
|
+
// ../../packages/core/src/tools/registry.ts
|
|
8241
|
+
init_logger();
|
|
8242
|
+
|
|
8236
8243
|
// ../../packages/core/src/tools/search.ts
|
|
8237
8244
|
init_embedder();
|
|
8238
8245
|
var Schema = external_exports.object({
|
|
8239
8246
|
query: external_exports.string().describe("Search query \u2014 natural language or code fragment"),
|
|
8240
|
-
limit: external_exports.number().max(100).optional().default(10).describe("Maximum results to return")
|
|
8247
|
+
limit: external_exports.number().max(100).optional().default(10).describe("Maximum results to return"),
|
|
8248
|
+
project_root: ProjectRootField
|
|
8241
8249
|
});
|
|
8242
8250
|
|
|
8243
8251
|
// ../../packages/core/src/tools/file.ts
|
|
8244
|
-
var Schema2 = external_exports.object({
|
|
8252
|
+
var Schema2 = external_exports.object({
|
|
8253
|
+
path: external_exports.string().describe("Relative path to the file"),
|
|
8254
|
+
project_root: ProjectRootField
|
|
8255
|
+
});
|
|
8245
8256
|
|
|
8246
8257
|
// ../../packages/core/src/tools/context-packet.ts
|
|
8247
8258
|
import path16 from "path";
|
|
8248
8259
|
var Schema3 = external_exports.object({
|
|
8249
8260
|
target_file: external_exports.string().describe("Relative path to the primary file"),
|
|
8250
|
-
mode: external_exports.enum(["edit", "read"]).optional().default("edit").describe("Context mode")
|
|
8261
|
+
mode: external_exports.enum(["edit", "read"]).optional().default("edit").describe("Context mode"),
|
|
8262
|
+
project_root: ProjectRootField
|
|
8251
8263
|
});
|
|
8252
8264
|
|
|
8253
8265
|
// ../../packages/core/src/tools/findCallers.ts
|
|
@@ -8258,17 +8270,25 @@ var Schema4 = external_exports.object({
|
|
|
8258
8270
|
symbol: external_exports.string().describe("Symbol name to search for"),
|
|
8259
8271
|
direction: external_exports.enum(["callers", "callees"]).optional().default("callers").describe("Traversal direction"),
|
|
8260
8272
|
depth: external_exports.number().max(10).optional().default(1).describe("Transitive traversal depth (max 10)"),
|
|
8261
|
-
target_file: external_exports.string().optional().describe("Optional: relative file path to start from")
|
|
8273
|
+
target_file: external_exports.string().optional().describe("Optional: relative file path to start from"),
|
|
8274
|
+
project_root: ProjectRootField
|
|
8262
8275
|
});
|
|
8263
8276
|
|
|
8264
8277
|
// ../../packages/core/src/tools/definition.ts
|
|
8265
|
-
var Schema5 = external_exports.object({
|
|
8278
|
+
var Schema5 = external_exports.object({
|
|
8279
|
+
symbol: external_exports.string().describe("Symbol name to look up"),
|
|
8280
|
+
project_root: ProjectRootField
|
|
8281
|
+
});
|
|
8282
|
+
|
|
8283
|
+
// ../../packages/core/src/tools/rules.ts
|
|
8284
|
+
var Schema6 = external_exports.object({ project_root: ProjectRootField });
|
|
8266
8285
|
|
|
8267
8286
|
// ../../packages/core/src/tools/similar-files.ts
|
|
8268
8287
|
init_embedder();
|
|
8269
|
-
var
|
|
8288
|
+
var Schema7 = external_exports.object({
|
|
8270
8289
|
target_file: external_exports.string().describe("Relative path to the file to find similar files for"),
|
|
8271
|
-
limit: external_exports.number().max(100).optional().default(10).describe("Maximum results to return")
|
|
8290
|
+
limit: external_exports.number().max(100).optional().default(10).describe("Maximum results to return"),
|
|
8291
|
+
project_root: ProjectRootField
|
|
8272
8292
|
});
|
|
8273
8293
|
|
|
8274
8294
|
// ../../packages/core/src/tools/blast-radius.ts
|
|
@@ -8276,37 +8296,40 @@ import { exec } from "child_process";
|
|
|
8276
8296
|
import { promisify } from "util";
|
|
8277
8297
|
init_logger();
|
|
8278
8298
|
var execAsync = promisify(exec);
|
|
8279
|
-
var
|
|
8299
|
+
var Schema8 = external_exports.object({
|
|
8280
8300
|
changed_files: external_exports.array(external_exports.string()).optional().describe("Changed file paths (relative). Defaults to git diff HEAD~1."),
|
|
8281
8301
|
depth: external_exports.number().min(1).max(10).optional().default(3).describe("Traversal depth (default: 3)"),
|
|
8282
8302
|
use_git: external_exports.boolean().optional().default(true).describe("Auto-detect changed files from git diff HEAD~1"),
|
|
8283
8303
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8284
8304
|
'"standard" (default) returns full per-file listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8285
|
-
)
|
|
8305
|
+
),
|
|
8306
|
+
project_root: ProjectRootField
|
|
8286
8307
|
});
|
|
8287
8308
|
|
|
8288
8309
|
// ../../packages/core/src/tools/hub-nodes.ts
|
|
8289
|
-
var
|
|
8310
|
+
var Schema9 = external_exports.object({
|
|
8290
8311
|
limit: external_exports.number().min(1).max(100).optional().default(20).describe("Number of hub nodes to return (default: 20)"),
|
|
8291
8312
|
min_degree: external_exports.number().min(0).optional().default(2).describe("Minimum total degree to include (default: 2)"),
|
|
8292
8313
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8293
8314
|
'"standard" (default) returns full per-file listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8294
|
-
)
|
|
8315
|
+
),
|
|
8316
|
+
project_root: ProjectRootField
|
|
8295
8317
|
});
|
|
8296
8318
|
|
|
8297
8319
|
// ../../packages/core/src/tools/bridge-nodes.ts
|
|
8298
|
-
var
|
|
8320
|
+
var Schema10 = external_exports.object({
|
|
8299
8321
|
limit: external_exports.number().min(1).max(100).optional().default(20).describe("Number of bridge nodes to return (default: 20)"),
|
|
8300
8322
|
sample: external_exports.number().min(10).max(1e3).optional().default(200).describe(
|
|
8301
8323
|
"Max source nodes for BFS sampling (default: 200). Lower = faster but approximate."
|
|
8302
8324
|
),
|
|
8303
8325
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8304
8326
|
'"standard" (default) returns full per-file listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8305
|
-
)
|
|
8327
|
+
),
|
|
8328
|
+
project_root: ProjectRootField
|
|
8306
8329
|
});
|
|
8307
8330
|
|
|
8308
8331
|
// ../../packages/core/src/tools/community-list.ts
|
|
8309
|
-
var
|
|
8332
|
+
var Schema11 = external_exports.object({
|
|
8310
8333
|
show_files: external_exports.boolean().optional().default(false).describe(
|
|
8311
8334
|
"Include member file paths in output (default: false for compact output)"
|
|
8312
8335
|
),
|
|
@@ -8321,22 +8344,24 @@ var Schema10 = external_exports.object({
|
|
|
8321
8344
|
),
|
|
8322
8345
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8323
8346
|
'"standard" (default) returns paged community list. "minimal" returns counts only \u2014 useful for a quick size check before paging.'
|
|
8324
|
-
)
|
|
8347
|
+
),
|
|
8348
|
+
project_root: ProjectRootField
|
|
8325
8349
|
});
|
|
8326
8350
|
|
|
8327
8351
|
// ../../packages/core/src/tools/architecture-overview.ts
|
|
8328
|
-
var
|
|
8352
|
+
var Schema12 = external_exports.object({
|
|
8329
8353
|
hub_limit: external_exports.number().min(1).max(10).optional().default(3).describe(
|
|
8330
8354
|
"Number of top hub files to show per community (default: 3)"
|
|
8331
8355
|
),
|
|
8332
8356
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8333
8357
|
'"standard" (default) returns full per-community listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8334
|
-
)
|
|
8358
|
+
),
|
|
8359
|
+
project_root: ProjectRootField
|
|
8335
8360
|
});
|
|
8336
8361
|
|
|
8337
8362
|
// ../../packages/core/src/tools/knowledge-gaps.ts
|
|
8338
8363
|
import path18 from "path";
|
|
8339
|
-
var
|
|
8364
|
+
var Schema13 = external_exports.object({
|
|
8340
8365
|
min_importers: external_exports.number().min(1).max(50).optional().default(3).describe(
|
|
8341
8366
|
"Minimum importers to qualify as an untested hub (default: 3)"
|
|
8342
8367
|
),
|
|
@@ -8345,11 +8370,12 @@ var Schema12 = external_exports.object({
|
|
|
8345
8370
|
),
|
|
8346
8371
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8347
8372
|
'"standard" (default) returns full per-file listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8348
|
-
)
|
|
8373
|
+
),
|
|
8374
|
+
project_root: ProjectRootField
|
|
8349
8375
|
});
|
|
8350
8376
|
|
|
8351
8377
|
// ../../packages/core/src/tools/surprising-connections.ts
|
|
8352
|
-
var
|
|
8378
|
+
var Schema14 = external_exports.object({
|
|
8353
8379
|
max_cycles: external_exports.number().min(1).max(100).optional().default(20).describe(
|
|
8354
8380
|
"Max circular dependency cycles to report (default: 20)"
|
|
8355
8381
|
),
|
|
@@ -8358,25 +8384,28 @@ var Schema13 = external_exports.object({
|
|
|
8358
8384
|
),
|
|
8359
8385
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8360
8386
|
'"standard" (default) returns full per-item listings. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8361
|
-
)
|
|
8387
|
+
),
|
|
8388
|
+
project_root: ProjectRootField
|
|
8362
8389
|
});
|
|
8363
8390
|
|
|
8364
8391
|
// ../../packages/core/src/tools/wiki-generate.ts
|
|
8365
8392
|
import fs16 from "fs";
|
|
8366
|
-
var
|
|
8393
|
+
var Schema15 = external_exports.object({
|
|
8367
8394
|
force: external_exports.boolean().optional().default(false).describe(
|
|
8368
8395
|
"Regenerate all pages even if content unchanged (default: false)"
|
|
8369
8396
|
),
|
|
8370
8397
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8371
8398
|
'"standard" (default) lists each written page with size. "minimal" returns counts only.'
|
|
8372
|
-
)
|
|
8399
|
+
),
|
|
8400
|
+
project_root: ProjectRootField
|
|
8373
8401
|
});
|
|
8374
8402
|
|
|
8375
8403
|
// ../../packages/core/src/tools/graph-export.ts
|
|
8376
|
-
var
|
|
8404
|
+
var Schema16 = external_exports.object({
|
|
8377
8405
|
format: external_exports.enum(["graphml", "dot", "obsidian", "svg", "html"]).describe(
|
|
8378
8406
|
"Output format: graphml (Gephi/yEd), dot (Graphviz), obsidian (wikilink vault), svg (inline, no dependencies), html (interactive D3.js browser view)"
|
|
8379
|
-
)
|
|
8407
|
+
),
|
|
8408
|
+
project_root: ProjectRootField
|
|
8380
8409
|
});
|
|
8381
8410
|
|
|
8382
8411
|
// ../../packages/core/src/tools/git-diff-review.ts
|
|
@@ -8384,7 +8413,7 @@ import { execFile } from "child_process";
|
|
|
8384
8413
|
import { promisify as promisify2 } from "util";
|
|
8385
8414
|
init_logger();
|
|
8386
8415
|
var execFileAsync = promisify2(execFile);
|
|
8387
|
-
var
|
|
8416
|
+
var Schema17 = external_exports.object({
|
|
8388
8417
|
changed_files: external_exports.array(external_exports.string()).optional().describe(
|
|
8389
8418
|
"Changed file paths (relative to project root). Omit to auto-detect from git diff HEAD~1."
|
|
8390
8419
|
),
|
|
@@ -8395,22 +8424,24 @@ var Schema16 = external_exports.object({
|
|
|
8395
8424
|
),
|
|
8396
8425
|
max_diff_lines: external_exports.number().min(10).max(2e3).optional().default(300).describe(
|
|
8397
8426
|
"Max diff lines to include per file (default: 300)"
|
|
8398
|
-
)
|
|
8427
|
+
),
|
|
8428
|
+
project_root: ProjectRootField
|
|
8399
8429
|
});
|
|
8400
8430
|
|
|
8401
8431
|
// ../../packages/core/src/tools/refactor-preview.ts
|
|
8402
8432
|
import fs17 from "fs";
|
|
8403
8433
|
import path19 from "path";
|
|
8404
|
-
var
|
|
8434
|
+
var Schema18 = external_exports.object({
|
|
8405
8435
|
symbol: external_exports.string().min(1).describe("Symbol name to rename (exact match, case-sensitive)"),
|
|
8406
8436
|
new_name: external_exports.string().min(1).describe("New name for the symbol"),
|
|
8407
8437
|
max_files: external_exports.number().min(1).max(200).optional().default(50).describe(
|
|
8408
8438
|
"Maximum number of files to scan for occurrences (default: 50)"
|
|
8409
|
-
)
|
|
8439
|
+
),
|
|
8440
|
+
project_root: ProjectRootField
|
|
8410
8441
|
});
|
|
8411
8442
|
|
|
8412
8443
|
// ../../packages/core/src/tools/execution-flow.ts
|
|
8413
|
-
var
|
|
8444
|
+
var Schema19 = external_exports.object({
|
|
8414
8445
|
entry_point: external_exports.string().min(1).describe("Symbol name to start the execution flow from"),
|
|
8415
8446
|
entry_file: external_exports.string().optional().describe(
|
|
8416
8447
|
"File path containing the entry symbol (relative). Disambiguates when the same symbol name appears in multiple files."
|
|
@@ -8418,7 +8449,8 @@ var Schema18 = external_exports.object({
|
|
|
8418
8449
|
depth: external_exports.number().min(1).max(20).optional().default(10).describe("Max traversal depth (default: 10)"),
|
|
8419
8450
|
max_nodes: external_exports.number().min(1).max(200).optional().default(50).describe(
|
|
8420
8451
|
"Max total steps to include in output (default: 50)"
|
|
8421
|
-
)
|
|
8452
|
+
),
|
|
8453
|
+
project_root: ProjectRootField
|
|
8422
8454
|
});
|
|
8423
8455
|
|
|
8424
8456
|
// ../../packages/core/src/tools/cross-repo-search.ts
|
|
@@ -8427,20 +8459,21 @@ init_VectorStore();
|
|
|
8427
8459
|
init_logger();
|
|
8428
8460
|
import fs18 from "fs";
|
|
8429
8461
|
import path20 from "path";
|
|
8430
|
-
var
|
|
8462
|
+
var Schema20 = external_exports.object({
|
|
8431
8463
|
query: external_exports.string().min(1).describe("Search query \u2014 natural language or code fragment"),
|
|
8432
8464
|
limit: external_exports.number().min(1).max(100).optional().default(10).describe(
|
|
8433
8465
|
"Maximum total results across all repos (default: 10)"
|
|
8434
8466
|
),
|
|
8435
8467
|
repos: external_exports.array(external_exports.string()).optional().describe(
|
|
8436
8468
|
"Specific repo root paths to search. Omit to search all registered repos."
|
|
8437
|
-
)
|
|
8469
|
+
),
|
|
8470
|
+
project_root: ProjectRootField
|
|
8438
8471
|
});
|
|
8439
8472
|
|
|
8440
8473
|
// ../../packages/core/src/tools/apply-refactor.ts
|
|
8441
8474
|
import fs19 from "fs";
|
|
8442
8475
|
import path21 from "path";
|
|
8443
|
-
var
|
|
8476
|
+
var Schema21 = external_exports.object({
|
|
8444
8477
|
symbol: external_exports.string().min(1).describe("Symbol name to rename (exact, case-sensitive)"),
|
|
8445
8478
|
new_name: external_exports.string().min(1).describe("New name for the symbol"),
|
|
8446
8479
|
dry_run: external_exports.boolean().optional().default(false).describe(
|
|
@@ -8448,7 +8481,8 @@ var Schema20 = external_exports.object({
|
|
|
8448
8481
|
),
|
|
8449
8482
|
max_files: external_exports.number().min(1).max(200).optional().default(50).describe(
|
|
8450
8483
|
"Maximum candidate files to process (default: 50)"
|
|
8451
|
-
)
|
|
8484
|
+
),
|
|
8485
|
+
project_root: ProjectRootField
|
|
8452
8486
|
});
|
|
8453
8487
|
|
|
8454
8488
|
// ../../packages/core/src/tools/detect-changes.ts
|
|
@@ -8456,24 +8490,26 @@ import { exec as exec2 } from "child_process";
|
|
|
8456
8490
|
import { promisify as promisify3 } from "util";
|
|
8457
8491
|
init_logger();
|
|
8458
8492
|
var execAsync2 = promisify3(exec2);
|
|
8459
|
-
var
|
|
8493
|
+
var Schema22 = external_exports.object({
|
|
8460
8494
|
changed_files: external_exports.array(external_exports.string()).optional(),
|
|
8461
8495
|
use_git: external_exports.boolean().optional().default(true),
|
|
8462
8496
|
depth: external_exports.number().min(1).max(10).optional().default(3),
|
|
8463
8497
|
detail_level: external_exports.enum(["standard", "minimal"]).default("standard").describe(
|
|
8464
8498
|
'"standard" (default) returns full per-file risk details. "minimal" returns counts only \u2014 ~60% fewer tokens.'
|
|
8465
|
-
)
|
|
8499
|
+
),
|
|
8500
|
+
project_root: ProjectRootField
|
|
8466
8501
|
});
|
|
8467
8502
|
|
|
8468
8503
|
// ../../packages/core/src/tools/full-text-search.ts
|
|
8469
8504
|
import fs20 from "fs";
|
|
8470
8505
|
import path22 from "path";
|
|
8471
|
-
var
|
|
8506
|
+
var Schema23 = external_exports.object({
|
|
8472
8507
|
query: external_exports.string().min(1).describe("Search term \u2014 literal or /regex/"),
|
|
8473
8508
|
mode: external_exports.enum(["hybrid", "keyword", "semantic"]).optional().default("hybrid"),
|
|
8474
8509
|
case_sensitive: external_exports.boolean().optional().default(false),
|
|
8475
8510
|
limit: external_exports.number().min(1).max(100).optional().default(20),
|
|
8476
|
-
context_lines: external_exports.number().min(0).max(5).optional().default(1)
|
|
8511
|
+
context_lines: external_exports.number().min(0).max(5).optional().default(1),
|
|
8512
|
+
project_root: ProjectRootField
|
|
8477
8513
|
});
|
|
8478
8514
|
|
|
8479
8515
|
// ../../packages/core/src/tools/suggested-questions.ts
|
|
@@ -8481,14 +8517,16 @@ init_logger();
|
|
|
8481
8517
|
import { exec as exec3 } from "child_process";
|
|
8482
8518
|
import { promisify as promisify4 } from "util";
|
|
8483
8519
|
var execAsync3 = promisify4(exec3);
|
|
8484
|
-
var
|
|
8520
|
+
var Schema24 = external_exports.object({
|
|
8485
8521
|
changed_files: external_exports.array(external_exports.string()).optional(),
|
|
8486
|
-
use_git: external_exports.boolean().optional().default(true)
|
|
8522
|
+
use_git: external_exports.boolean().optional().default(true),
|
|
8523
|
+
project_root: ProjectRootField
|
|
8487
8524
|
});
|
|
8488
8525
|
|
|
8489
8526
|
// ../../packages/core/src/tools/get-workflow.ts
|
|
8490
|
-
var
|
|
8491
|
-
workflow: external_exports.enum(["review", "debug", "onboard", "refactor", "audit"])
|
|
8527
|
+
var Schema25 = external_exports.object({
|
|
8528
|
+
workflow: external_exports.enum(["review", "debug", "onboard", "refactor", "audit"]),
|
|
8529
|
+
project_root: ProjectRootField
|
|
8492
8530
|
});
|
|
8493
8531
|
|
|
8494
8532
|
// ../../packages/core/src/tools/graph-snapshot.ts
|
|
@@ -8500,7 +8538,8 @@ var schema = external_exports.object({
|
|
|
8500
8538
|
),
|
|
8501
8539
|
overwrite: external_exports.boolean().default(false).describe(
|
|
8502
8540
|
"If true, overwrite an existing snapshot with the same name."
|
|
8503
|
-
)
|
|
8541
|
+
),
|
|
8542
|
+
project_root: ProjectRootField
|
|
8504
8543
|
});
|
|
8505
8544
|
|
|
8506
8545
|
// ../../packages/core/src/tools/graph-diff.ts
|
|
@@ -8508,7 +8547,8 @@ import fs22 from "fs";
|
|
|
8508
8547
|
import path24 from "path";
|
|
8509
8548
|
var schema2 = external_exports.object({
|
|
8510
8549
|
baseline: external_exports.string().min(1).describe('Name of the baseline snapshot (the "before" state).'),
|
|
8511
|
-
current: external_exports.string().min(1).describe('Name of the current snapshot (the "after" state).')
|
|
8550
|
+
current: external_exports.string().min(1).describe('Name of the current snapshot (the "after" state).'),
|
|
8551
|
+
project_root: ProjectRootField
|
|
8512
8552
|
});
|
|
8513
8553
|
|
|
8514
8554
|
// ../../packages/core/src/tools/find-large-functions.ts
|
|
@@ -8521,20 +8561,23 @@ var schema3 = external_exports.object({
|
|
|
8521
8561
|
),
|
|
8522
8562
|
limit: external_exports.number().int().min(1).max(200).default(30).describe(
|
|
8523
8563
|
"Maximum results to return (default: 30)."
|
|
8524
|
-
)
|
|
8564
|
+
),
|
|
8565
|
+
project_root: ProjectRootField
|
|
8525
8566
|
});
|
|
8526
8567
|
|
|
8527
8568
|
// ../../packages/core/src/tools/git-coupling.ts
|
|
8528
|
-
var
|
|
8569
|
+
var Schema26 = external_exports.object({
|
|
8529
8570
|
file: external_exports.string().describe("File path to look up co-changed siblings for"),
|
|
8530
8571
|
limit: external_exports.number().int().min(1).max(50).default(10),
|
|
8531
8572
|
min_confidence: external_exports.number().min(0).max(1).default(0.05),
|
|
8532
|
-
half_life_days: external_exports.number().int().min(1).max(3650).default(90)
|
|
8573
|
+
half_life_days: external_exports.number().int().min(1).max(3650).default(90),
|
|
8574
|
+
project_root: ProjectRootField
|
|
8533
8575
|
});
|
|
8534
8576
|
|
|
8535
8577
|
// ../../packages/core/src/tools/risk-overlay.ts
|
|
8536
|
-
var
|
|
8537
|
-
nodes: external_exports.array(external_exports.string()).min(1).max(200).describe("File paths to score")
|
|
8578
|
+
var Schema27 = external_exports.object({
|
|
8579
|
+
nodes: external_exports.array(external_exports.string()).min(1).max(200).describe("File paths to score"),
|
|
8580
|
+
project_root: ProjectRootField
|
|
8538
8581
|
});
|
|
8539
8582
|
|
|
8540
8583
|
// ../../packages/core/src/rules/loadConfig.ts
|
|
@@ -11140,12 +11183,15 @@ var RulesConfigSchema = external_exports.object({
|
|
|
11140
11183
|
rules: external_exports.array(RuleSchema).default([])
|
|
11141
11184
|
});
|
|
11142
11185
|
|
|
11186
|
+
// ../../packages/core/src/tools/rules-check.ts
|
|
11187
|
+
var Schema28 = external_exports.object({ project_root: ProjectRootField });
|
|
11188
|
+
|
|
11143
11189
|
// ../../packages/core/src/tools/get-affected-flows.ts
|
|
11144
11190
|
init_logger();
|
|
11145
11191
|
import { exec as exec4 } from "child_process";
|
|
11146
11192
|
import { promisify as promisify5 } from "util";
|
|
11147
11193
|
var execAsync4 = promisify5(exec4);
|
|
11148
|
-
var
|
|
11194
|
+
var Schema29 = external_exports.object({
|
|
11149
11195
|
changed_files: external_exports.array(external_exports.string()).optional().describe(
|
|
11150
11196
|
"Changed file paths (relative). Defaults to auto-detection from git diff HEAD~1."
|
|
11151
11197
|
),
|
|
@@ -11160,7 +11206,8 @@ var Schema27 = external_exports.object({
|
|
|
11160
11206
|
),
|
|
11161
11207
|
max_steps_per_flow: external_exports.number().min(1).max(100).optional().default(30).describe(
|
|
11162
11208
|
"Max call chain steps per flow (default: 30)"
|
|
11163
|
-
)
|
|
11209
|
+
),
|
|
11210
|
+
project_root: ProjectRootField
|
|
11164
11211
|
});
|
|
11165
11212
|
|
|
11166
11213
|
// ../../packages/core/src/tools/ruleManager.ts
|
|
@@ -11226,9 +11273,19 @@ var TELEMETRY_DISABLED = process.env["CTXLOOM_NO_TELEMETRY"] === "1" || process.
|
|
|
11226
11273
|
var POSTHOG_KEY = process.env["POSTHOG_API_KEY"] ?? (typeof __TELEMETRY_POSTHOG_KEY__ === "string" ? __TELEMETRY_POSTHOG_KEY__ : "");
|
|
11227
11274
|
var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (typeof __TELEMETRY_SENTRY_DSN__ === "string" ? __TELEMETRY_SENTRY_DSN__ : "");
|
|
11228
11275
|
|
|
11276
|
+
// ../../packages/core/src/server/ProjectState.ts
|
|
11277
|
+
import path32 from "path";
|
|
11278
|
+
|
|
11279
|
+
// ../../packages/core/src/server/ProjectStateManager.ts
|
|
11280
|
+
init_logger();
|
|
11281
|
+
|
|
11282
|
+
// ../../packages/core/src/server/resolveProjectRoot.ts
|
|
11283
|
+
import fs29 from "fs";
|
|
11284
|
+
import path33 from "path";
|
|
11285
|
+
|
|
11229
11286
|
// server/loader.ts
|
|
11230
11287
|
async function loadContext(root) {
|
|
11231
|
-
const absRoot =
|
|
11288
|
+
const absRoot = path34.resolve(root);
|
|
11232
11289
|
const overlay = new GitOverlayStore(absRoot);
|
|
11233
11290
|
const gitEnabled = await overlay.loadSnapshot();
|
|
11234
11291
|
const graph = new DependencyGraph();
|
|
@@ -11481,21 +11538,21 @@ function buildOwnershipRouter(ctx) {
|
|
|
11481
11538
|
|
|
11482
11539
|
// server/routes/file.ts
|
|
11483
11540
|
import { Router as Router7 } from "express";
|
|
11484
|
-
import
|
|
11485
|
-
import
|
|
11541
|
+
import fs30 from "fs/promises";
|
|
11542
|
+
import path35 from "path";
|
|
11486
11543
|
function buildFileRouter(ctx) {
|
|
11487
11544
|
const router = Router7();
|
|
11488
11545
|
router.get("/", async (req, res) => {
|
|
11489
11546
|
const rel = req.query.path;
|
|
11490
11547
|
if (!rel) return res.status(400).json({ error: "missing path" });
|
|
11491
|
-
const abs =
|
|
11492
|
-
const rootBoundary = ctx.root.endsWith(
|
|
11548
|
+
const abs = path35.resolve(ctx.root, rel);
|
|
11549
|
+
const rootBoundary = ctx.root.endsWith(path35.sep) ? ctx.root : ctx.root + path35.sep;
|
|
11493
11550
|
if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
|
|
11494
11551
|
return res.status(403).json({ error: "forbidden" });
|
|
11495
11552
|
}
|
|
11496
11553
|
try {
|
|
11497
|
-
const content = await
|
|
11498
|
-
const ext =
|
|
11554
|
+
const content = await fs30.readFile(abs, "utf-8");
|
|
11555
|
+
const ext = path35.extname(abs).slice(1);
|
|
11499
11556
|
res.json({ content, lines: content.split("\n").length, ext });
|
|
11500
11557
|
} catch {
|
|
11501
11558
|
res.status(404).json({ error: "not found" });
|
|
@@ -11507,7 +11564,7 @@ function buildFileRouter(ctx) {
|
|
|
11507
11564
|
// server/routes/open.ts
|
|
11508
11565
|
import { Router as Router8 } from "express";
|
|
11509
11566
|
import { execFile as execFile2 } from "child_process";
|
|
11510
|
-
import
|
|
11567
|
+
import path36 from "path";
|
|
11511
11568
|
function tryOpen(bin, abs) {
|
|
11512
11569
|
return new Promise((resolve) => {
|
|
11513
11570
|
execFile2(bin, [abs], { timeout: 5e3 }, (err) => resolve(!err));
|
|
@@ -11518,8 +11575,8 @@ function buildOpenRouter(ctx) {
|
|
|
11518
11575
|
router.post("/", async (req, res) => {
|
|
11519
11576
|
const rel = req.body?.path;
|
|
11520
11577
|
if (!rel || typeof rel !== "string") return res.status(400).json({ error: "missing path" });
|
|
11521
|
-
const abs =
|
|
11522
|
-
const rootBoundary = ctx.root.endsWith(
|
|
11578
|
+
const abs = path36.resolve(ctx.root, rel);
|
|
11579
|
+
const rootBoundary = ctx.root.endsWith(path36.sep) ? ctx.root : ctx.root + path36.sep;
|
|
11523
11580
|
if (abs !== ctx.root && !abs.startsWith(rootBoundary)) {
|
|
11524
11581
|
return res.status(403).json({ error: "forbidden" });
|
|
11525
11582
|
}
|
|
@@ -11531,8 +11588,8 @@ function buildOpenRouter(ctx) {
|
|
|
11531
11588
|
|
|
11532
11589
|
// server/routes/tokens.ts
|
|
11533
11590
|
import { Router as Router9 } from "express";
|
|
11534
|
-
import
|
|
11535
|
-
import
|
|
11591
|
+
import path37 from "path";
|
|
11592
|
+
import fs31 from "fs";
|
|
11536
11593
|
var CHARS_PER_TOKEN = 4;
|
|
11537
11594
|
var cache = null;
|
|
11538
11595
|
function buildTokensRouter(ctx) {
|
|
@@ -11547,9 +11604,9 @@ function buildTokensRouter(ctx) {
|
|
|
11547
11604
|
let fullChars = 0;
|
|
11548
11605
|
let skeletonChars = 0;
|
|
11549
11606
|
for (const file of files) {
|
|
11550
|
-
const absPath =
|
|
11607
|
+
const absPath = path37.join(ctx.root, file);
|
|
11551
11608
|
try {
|
|
11552
|
-
const content =
|
|
11609
|
+
const content = fs31.readFileSync(absPath, "utf-8");
|
|
11553
11610
|
fullChars += content.length;
|
|
11554
11611
|
const skeleton = await skeletonizer.skeletonize(absPath);
|
|
11555
11612
|
skeletonChars += skeleton.length;
|
|
@@ -11650,17 +11707,17 @@ function buildFileTrendsRouter(ctx) {
|
|
|
11650
11707
|
|
|
11651
11708
|
// server/routes/projects.ts
|
|
11652
11709
|
import { Router as Router12 } from "express";
|
|
11653
|
-
import
|
|
11710
|
+
import path39 from "path";
|
|
11654
11711
|
|
|
11655
11712
|
// server/projects.ts
|
|
11656
11713
|
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
|
|
11657
11714
|
import os4 from "os";
|
|
11658
|
-
import
|
|
11715
|
+
import path38 from "path";
|
|
11659
11716
|
import crypto5 from "crypto";
|
|
11660
11717
|
var HOME = os4.homedir();
|
|
11661
|
-
var REGISTRY_PATH =
|
|
11718
|
+
var REGISTRY_PATH = path38.join(HOME, ".ctxloom", "repos.json");
|
|
11662
11719
|
function slugFor(root) {
|
|
11663
|
-
const abs =
|
|
11720
|
+
const abs = path38.resolve(root);
|
|
11664
11721
|
return crypto5.createHash("sha1").update(abs).digest("hex").slice(0, 12);
|
|
11665
11722
|
}
|
|
11666
11723
|
function readRegistry() {
|
|
@@ -11675,28 +11732,30 @@ function readRegistry() {
|
|
|
11675
11732
|
}
|
|
11676
11733
|
}
|
|
11677
11734
|
function listProjects(defaultRoot) {
|
|
11678
|
-
const absDefault =
|
|
11735
|
+
const absDefault = path38.resolve(defaultRoot);
|
|
11679
11736
|
const out = [
|
|
11680
11737
|
{
|
|
11681
11738
|
slug: slugFor(absDefault),
|
|
11682
|
-
name:
|
|
11739
|
+
name: path38.basename(absDefault) || absDefault,
|
|
11683
11740
|
root: absDefault,
|
|
11684
11741
|
isDefault: true,
|
|
11685
|
-
hasSnapshot: existsSync2(
|
|
11742
|
+
hasSnapshot: existsSync2(path38.join(absDefault, ".ctxloom"))
|
|
11686
11743
|
}
|
|
11687
11744
|
];
|
|
11688
11745
|
const seen = /* @__PURE__ */ new Set([absDefault]);
|
|
11689
11746
|
for (const entry of readRegistry()) {
|
|
11690
|
-
const abs =
|
|
11747
|
+
const abs = path38.resolve(entry.root);
|
|
11691
11748
|
if (seen.has(abs)) continue;
|
|
11692
11749
|
seen.add(abs);
|
|
11693
|
-
|
|
11750
|
+
const item = {
|
|
11694
11751
|
slug: slugFor(abs),
|
|
11695
|
-
name: entry.name ?? (
|
|
11752
|
+
name: entry.name ?? (path38.basename(abs) || abs),
|
|
11696
11753
|
root: abs,
|
|
11697
11754
|
isDefault: false,
|
|
11698
|
-
hasSnapshot: existsSync2(
|
|
11699
|
-
}
|
|
11755
|
+
hasSnapshot: existsSync2(path38.join(abs, ".ctxloom"))
|
|
11756
|
+
};
|
|
11757
|
+
if (entry.alias !== void 0) item.alias = entry.alias;
|
|
11758
|
+
out.push(item);
|
|
11700
11759
|
}
|
|
11701
11760
|
return out;
|
|
11702
11761
|
}
|
|
@@ -11746,7 +11805,7 @@ function buildProjectsRouter(deps) {
|
|
|
11746
11805
|
} catch (err) {
|
|
11747
11806
|
const detail = err instanceof Error ? err.message : String(err);
|
|
11748
11807
|
res.status(500).json({
|
|
11749
|
-
error: `failed to switch to ${
|
|
11808
|
+
error: `failed to switch to ${path39.basename(target.root)}: ${detail}`
|
|
11750
11809
|
});
|
|
11751
11810
|
}
|
|
11752
11811
|
});
|
|
@@ -11754,7 +11813,7 @@ function buildProjectsRouter(deps) {
|
|
|
11754
11813
|
}
|
|
11755
11814
|
|
|
11756
11815
|
// server/index.ts
|
|
11757
|
-
var __dirname2 =
|
|
11816
|
+
var __dirname2 = path40.dirname(fileURLToPath2(import.meta.url));
|
|
11758
11817
|
async function startDashboard(options) {
|
|
11759
11818
|
const { root, port, open } = options;
|
|
11760
11819
|
console.log(`ctxloom dashboard \u2014 loading context from ${root}...`);
|
|
@@ -11813,9 +11872,9 @@ async function startDashboard(options) {
|
|
|
11813
11872
|
}
|
|
11814
11873
|
activeWatcher = null;
|
|
11815
11874
|
}
|
|
11816
|
-
const snapshotDir =
|
|
11875
|
+
const snapshotDir = path40.join(targetRoot, ".ctxloom");
|
|
11817
11876
|
try {
|
|
11818
|
-
activeWatcher =
|
|
11877
|
+
activeWatcher = fs32.watch(snapshotDir, (_event, filename) => {
|
|
11819
11878
|
if (!filename || !filename.includes("snapshot")) return;
|
|
11820
11879
|
if (debounce) clearTimeout(debounce);
|
|
11821
11880
|
debounce = setTimeout(async () => {
|
|
@@ -11843,12 +11902,12 @@ async function startDashboard(options) {
|
|
|
11843
11902
|
attachSnapshotWatcher(newRoot);
|
|
11844
11903
|
}
|
|
11845
11904
|
}));
|
|
11846
|
-
const clientDist =
|
|
11847
|
-
const clientDistExists =
|
|
11905
|
+
const clientDist = path40.join(__dirname2, "../dashboard/client");
|
|
11906
|
+
const clientDistExists = fs32.existsSync(path40.join(clientDist, "index.html"));
|
|
11848
11907
|
if (clientDistExists) {
|
|
11849
11908
|
app.use(express.static(clientDist, { dotfiles: "allow" }));
|
|
11850
11909
|
app.get(/.*/, (_req, res) => {
|
|
11851
|
-
res.sendFile(
|
|
11910
|
+
res.sendFile(path40.join(clientDist, "index.html"), { dotfiles: "allow" });
|
|
11852
11911
|
});
|
|
11853
11912
|
} else {
|
|
11854
11913
|
app.get(/^\/(?!api\/).*/, (_req, res) => {
|