ctxloom-pro 1.5.2 → 1.5.4
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.
|
|
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.
|
|
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.3
|
|
365
365
|
- run: ctxloom index
|
|
366
366
|
- run: ctxloom rules check --json
|
|
367
367
|
```
|
|
@@ -676,6 +676,47 @@ var ASTParser = class {
|
|
|
676
676
|
processedIds.add(node.id);
|
|
677
677
|
return;
|
|
678
678
|
}
|
|
679
|
+
// ─── CommonJS require() calls ────────────────────────────────────
|
|
680
|
+
// ES6 import_statement above handles `import X from './foo'`. But
|
|
681
|
+
// pure CommonJS projects — express, most pre-2020 Node libs — use
|
|
682
|
+
// `require('./foo')` instead and never emit an import_statement
|
|
683
|
+
// node. Without this case, those projects produce a dependency
|
|
684
|
+
// graph with 0 edges and the blast-radius tool collapses to
|
|
685
|
+
// "just the seed file" because there's nothing to traverse.
|
|
686
|
+
//
|
|
687
|
+
// Mirrors the Ruby require pattern below (see the `case 'call'`
|
|
688
|
+
// branch later in the walker). Only literal-string arguments are
|
|
689
|
+
// resolvable; dynamic `require(varName)` is statically invisible
|
|
690
|
+
// and intentionally skipped.
|
|
691
|
+
//
|
|
692
|
+
// Patterns matched:
|
|
693
|
+
// require('./path')
|
|
694
|
+
// require('../path')
|
|
695
|
+
// require('./path.json') — JSON files emit edges too
|
|
696
|
+
// Patterns NOT matched:
|
|
697
|
+
// require(varName) — dynamic, can't resolve
|
|
698
|
+
// require.resolve('./path') — returns path string, not a load
|
|
699
|
+
// import('./path') — dynamic ESM, separate concern
|
|
700
|
+
case "call_expression": {
|
|
701
|
+
const fnNode = node.childForFieldName?.("function") ?? node.children.find((c) => c?.type === "identifier");
|
|
702
|
+
if (fnNode?.text === "require") {
|
|
703
|
+
const argsNode = node.childForFieldName?.("arguments") ?? node.children.find((c) => c?.type === "arguments");
|
|
704
|
+
const firstArg = argsNode?.children.find((c) => c?.type === "string");
|
|
705
|
+
if (firstArg) {
|
|
706
|
+
const spec = firstArg.text.replace(/^['"`]|['"`]$/g, "");
|
|
707
|
+
if (spec.length > 0) {
|
|
708
|
+
nodes.push({
|
|
709
|
+
type: "import",
|
|
710
|
+
name: spec,
|
|
711
|
+
source: spec,
|
|
712
|
+
startLine: node.startPosition.row + 1,
|
|
713
|
+
endLine: node.endPosition.row + 1
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
679
720
|
// ─── Export statements (export function, export default) ────────
|
|
680
721
|
case "export_statement": {
|
|
681
722
|
const hasDefault = node.children.some((c) => c?.type === "default");
|
|
@@ -804,6 +845,8 @@ var ASTParser = class {
|
|
|
804
845
|
startLine: declarator.startPosition.row + 1,
|
|
805
846
|
endLine: declarator.endPosition.row + 1
|
|
806
847
|
});
|
|
848
|
+
} else if (valueNode.type === "call_expression") {
|
|
849
|
+
walk(valueNode);
|
|
807
850
|
}
|
|
808
851
|
}
|
|
809
852
|
}
|
|
@@ -1956,29 +1999,54 @@ function resolveImport(fromAbs, raw, rootDir) {
|
|
|
1956
1999
|
}
|
|
1957
2000
|
function extractPythonImports(content) {
|
|
1958
2001
|
const results = [];
|
|
1959
|
-
const relFrom = /^from\s+(\.+[\w.]*)\s+import/gm;
|
|
1960
2002
|
let m;
|
|
2003
|
+
const relFrom = /^from\s+(\.+[\w.]*)\s+import/gm;
|
|
1961
2004
|
while ((m = relFrom.exec(content)) !== null) {
|
|
1962
2005
|
results.push({ specifier: m[1], isRelative: true });
|
|
1963
2006
|
}
|
|
2007
|
+
const absFrom = /^from\s+([A-Za-z_][\w.]*)\s+import/gm;
|
|
2008
|
+
while ((m = absFrom.exec(content)) !== null) {
|
|
2009
|
+
results.push({ specifier: m[1], isRelative: false });
|
|
2010
|
+
}
|
|
2011
|
+
const directImport = /^import\s+([A-Za-z_][\w.]*)/gm;
|
|
2012
|
+
while ((m = directImport.exec(content)) !== null) {
|
|
2013
|
+
results.push({ specifier: m[1], isRelative: false });
|
|
2014
|
+
}
|
|
1964
2015
|
return results;
|
|
1965
2016
|
}
|
|
1966
2017
|
function resolvePythonImport(fromAbs, fromDir, raw, rootDir) {
|
|
1967
2018
|
const dotsMatch = raw.specifier.match(/^(\.+)/);
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2019
|
+
if (dotsMatch) {
|
|
2020
|
+
const dots = dotsMatch[1];
|
|
2021
|
+
const modulePart = raw.specifier.slice(dots.length);
|
|
2022
|
+
let baseDir = fromDir;
|
|
2023
|
+
for (let i = 1; i < dots.length; i++) {
|
|
2024
|
+
baseDir = path5.dirname(baseDir);
|
|
2025
|
+
}
|
|
2026
|
+
const modulePath2 = modulePart.replace(/\./g, path5.sep);
|
|
2027
|
+
const candidates2 = modulePath2 ? [
|
|
2028
|
+
path5.join(baseDir, modulePath2 + ".py"),
|
|
2029
|
+
path5.join(baseDir, modulePath2, "__init__.py")
|
|
2030
|
+
] : [
|
|
2031
|
+
path5.join(fromDir, "__init__.py"),
|
|
2032
|
+
fromAbs
|
|
2033
|
+
// self — skip below
|
|
2034
|
+
];
|
|
2035
|
+
for (const c of candidates2) {
|
|
2036
|
+
if (c !== fromAbs && fs5.existsSync(c)) {
|
|
2037
|
+
return path5.relative(rootDir, c);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
return null;
|
|
2041
|
+
}
|
|
2042
|
+
const modulePath = raw.specifier.replace(/\./g, path5.sep);
|
|
2043
|
+
const candidates = [
|
|
2044
|
+
// <repoRoot>/<package>/foo.py or <repoRoot>/<package>/foo/__init__.py
|
|
2045
|
+
path5.join(rootDir, modulePath + ".py"),
|
|
2046
|
+
path5.join(rootDir, modulePath, "__init__.py"),
|
|
2047
|
+
// src/ layout (common for Python apps that follow PEP 518 src-layout)
|
|
2048
|
+
path5.join(rootDir, "src", modulePath + ".py"),
|
|
2049
|
+
path5.join(rootDir, "src", modulePath, "__init__.py")
|
|
1982
2050
|
];
|
|
1983
2051
|
for (const c of candidates) {
|
|
1984
2052
|
if (c !== fromAbs && fs5.existsSync(c)) {
|
|
@@ -2913,10 +2981,28 @@ var DependencyGraph = class {
|
|
|
2913
2981
|
}
|
|
2914
2982
|
resolveImport(fromAbs, specifier, rootDir) {
|
|
2915
2983
|
const dir = path7.dirname(fromAbs);
|
|
2916
|
-
|
|
2984
|
+
const extensions = [
|
|
2985
|
+
"",
|
|
2986
|
+
".ts",
|
|
2987
|
+
".tsx",
|
|
2988
|
+
".js",
|
|
2989
|
+
".jsx",
|
|
2990
|
+
".mjs",
|
|
2991
|
+
".cjs",
|
|
2992
|
+
"/index.ts",
|
|
2993
|
+
"/index.tsx",
|
|
2994
|
+
"/index.js",
|
|
2995
|
+
"/index.jsx",
|
|
2996
|
+
"/index.mjs",
|
|
2997
|
+
"/index.cjs"
|
|
2998
|
+
];
|
|
2999
|
+
for (const ext of extensions) {
|
|
2917
3000
|
const candidate = path7.resolve(dir, specifier.replace(/\.js$/, "") + ext);
|
|
2918
|
-
|
|
2919
|
-
|
|
3001
|
+
try {
|
|
3002
|
+
if (fs7.statSync(candidate).isFile()) {
|
|
3003
|
+
return path7.relative(rootDir, candidate);
|
|
3004
|
+
}
|
|
3005
|
+
} catch {
|
|
2920
3006
|
}
|
|
2921
3007
|
}
|
|
2922
3008
|
return null;
|
|
@@ -11506,10 +11592,10 @@ function resolveTelemetryLevel() {
|
|
|
11506
11592
|
}
|
|
11507
11593
|
var TELEMETRY_LEVEL = resolveTelemetryLevel();
|
|
11508
11594
|
var TELEMETRY_DISABLED = TELEMETRY_LEVEL === "off";
|
|
11509
|
-
var CTXLOOM_VERSION = "1.5.
|
|
11595
|
+
var CTXLOOM_VERSION = "1.5.4".length > 0 ? "1.5.4" : "dev";
|
|
11510
11596
|
var POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
11511
11597
|
var POSTHOG_KEY = process.env["POSTHOG_API_KEY"] ?? (true ? "phc_CiDkmFLcZ2K6uCpcoSUQLmFrnnUvsyXGhSxopX5TVKE6" : "");
|
|
11512
|
-
var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528" : "");
|
|
11598
|
+
var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528\u2028" : "");
|
|
11513
11599
|
var cachedDistinctId = null;
|
|
11514
11600
|
function resolveDistinctId() {
|
|
11515
11601
|
if (cachedDistinctId) return cachedDistinctId;
|
|
@@ -522,6 +522,47 @@ var ASTParser = class {
|
|
|
522
522
|
processedIds.add(node.id);
|
|
523
523
|
return;
|
|
524
524
|
}
|
|
525
|
+
// ─── CommonJS require() calls ────────────────────────────────────
|
|
526
|
+
// ES6 import_statement above handles `import X from './foo'`. But
|
|
527
|
+
// pure CommonJS projects — express, most pre-2020 Node libs — use
|
|
528
|
+
// `require('./foo')` instead and never emit an import_statement
|
|
529
|
+
// node. Without this case, those projects produce a dependency
|
|
530
|
+
// graph with 0 edges and the blast-radius tool collapses to
|
|
531
|
+
// "just the seed file" because there's nothing to traverse.
|
|
532
|
+
//
|
|
533
|
+
// Mirrors the Ruby require pattern below (see the `case 'call'`
|
|
534
|
+
// branch later in the walker). Only literal-string arguments are
|
|
535
|
+
// resolvable; dynamic `require(varName)` is statically invisible
|
|
536
|
+
// and intentionally skipped.
|
|
537
|
+
//
|
|
538
|
+
// Patterns matched:
|
|
539
|
+
// require('./path')
|
|
540
|
+
// require('../path')
|
|
541
|
+
// require('./path.json') — JSON files emit edges too
|
|
542
|
+
// Patterns NOT matched:
|
|
543
|
+
// require(varName) — dynamic, can't resolve
|
|
544
|
+
// require.resolve('./path') — returns path string, not a load
|
|
545
|
+
// import('./path') — dynamic ESM, separate concern
|
|
546
|
+
case "call_expression": {
|
|
547
|
+
const fnNode = node.childForFieldName?.("function") ?? node.children.find((c) => c?.type === "identifier");
|
|
548
|
+
if (fnNode?.text === "require") {
|
|
549
|
+
const argsNode = node.childForFieldName?.("arguments") ?? node.children.find((c) => c?.type === "arguments");
|
|
550
|
+
const firstArg = argsNode?.children.find((c) => c?.type === "string");
|
|
551
|
+
if (firstArg) {
|
|
552
|
+
const spec = firstArg.text.replace(/^['"`]|['"`]$/g, "");
|
|
553
|
+
if (spec.length > 0) {
|
|
554
|
+
nodes.push({
|
|
555
|
+
type: "import",
|
|
556
|
+
name: spec,
|
|
557
|
+
source: spec,
|
|
558
|
+
startLine: node.startPosition.row + 1,
|
|
559
|
+
endLine: node.endPosition.row + 1
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
525
566
|
// ─── Export statements (export function, export default) ────────
|
|
526
567
|
case "export_statement": {
|
|
527
568
|
const hasDefault = node.children.some((c) => c?.type === "default");
|
|
@@ -650,6 +691,8 @@ var ASTParser = class {
|
|
|
650
691
|
startLine: declarator.startPosition.row + 1,
|
|
651
692
|
endLine: declarator.endPosition.row + 1
|
|
652
693
|
});
|
|
694
|
+
} else if (valueNode.type === "call_expression") {
|
|
695
|
+
walk(valueNode);
|
|
653
696
|
}
|
|
654
697
|
}
|
|
655
698
|
}
|
|
@@ -1798,29 +1841,54 @@ function resolveImport(fromAbs, raw, rootDir) {
|
|
|
1798
1841
|
}
|
|
1799
1842
|
function extractPythonImports(content) {
|
|
1800
1843
|
const results = [];
|
|
1801
|
-
const relFrom = /^from\s+(\.+[\w.]*)\s+import/gm;
|
|
1802
1844
|
let m;
|
|
1845
|
+
const relFrom = /^from\s+(\.+[\w.]*)\s+import/gm;
|
|
1803
1846
|
while ((m = relFrom.exec(content)) !== null) {
|
|
1804
1847
|
results.push({ specifier: m[1], isRelative: true });
|
|
1805
1848
|
}
|
|
1849
|
+
const absFrom = /^from\s+([A-Za-z_][\w.]*)\s+import/gm;
|
|
1850
|
+
while ((m = absFrom.exec(content)) !== null) {
|
|
1851
|
+
results.push({ specifier: m[1], isRelative: false });
|
|
1852
|
+
}
|
|
1853
|
+
const directImport = /^import\s+([A-Za-z_][\w.]*)/gm;
|
|
1854
|
+
while ((m = directImport.exec(content)) !== null) {
|
|
1855
|
+
results.push({ specifier: m[1], isRelative: false });
|
|
1856
|
+
}
|
|
1806
1857
|
return results;
|
|
1807
1858
|
}
|
|
1808
1859
|
function resolvePythonImport(fromAbs, fromDir, raw, rootDir) {
|
|
1809
1860
|
const dotsMatch = raw.specifier.match(/^(\.+)/);
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1861
|
+
if (dotsMatch) {
|
|
1862
|
+
const dots = dotsMatch[1];
|
|
1863
|
+
const modulePart = raw.specifier.slice(dots.length);
|
|
1864
|
+
let baseDir = fromDir;
|
|
1865
|
+
for (let i = 1; i < dots.length; i++) {
|
|
1866
|
+
baseDir = path4.dirname(baseDir);
|
|
1867
|
+
}
|
|
1868
|
+
const modulePath2 = modulePart.replace(/\./g, path4.sep);
|
|
1869
|
+
const candidates2 = modulePath2 ? [
|
|
1870
|
+
path4.join(baseDir, modulePath2 + ".py"),
|
|
1871
|
+
path4.join(baseDir, modulePath2, "__init__.py")
|
|
1872
|
+
] : [
|
|
1873
|
+
path4.join(fromDir, "__init__.py"),
|
|
1874
|
+
fromAbs
|
|
1875
|
+
// self — skip below
|
|
1876
|
+
];
|
|
1877
|
+
for (const c of candidates2) {
|
|
1878
|
+
if (c !== fromAbs && fs4.existsSync(c)) {
|
|
1879
|
+
return path4.relative(rootDir, c);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
return null;
|
|
1883
|
+
}
|
|
1884
|
+
const modulePath = raw.specifier.replace(/\./g, path4.sep);
|
|
1885
|
+
const candidates = [
|
|
1886
|
+
// <repoRoot>/<package>/foo.py or <repoRoot>/<package>/foo/__init__.py
|
|
1887
|
+
path4.join(rootDir, modulePath + ".py"),
|
|
1888
|
+
path4.join(rootDir, modulePath, "__init__.py"),
|
|
1889
|
+
// src/ layout (common for Python apps that follow PEP 518 src-layout)
|
|
1890
|
+
path4.join(rootDir, "src", modulePath + ".py"),
|
|
1891
|
+
path4.join(rootDir, "src", modulePath, "__init__.py")
|
|
1824
1892
|
];
|
|
1825
1893
|
for (const c of candidates) {
|
|
1826
1894
|
if (c !== fromAbs && fs4.existsSync(c)) {
|
|
@@ -2755,10 +2823,28 @@ var DependencyGraph = class {
|
|
|
2755
2823
|
}
|
|
2756
2824
|
resolveImport(fromAbs, specifier, rootDir) {
|
|
2757
2825
|
const dir = path6.dirname(fromAbs);
|
|
2758
|
-
|
|
2826
|
+
const extensions = [
|
|
2827
|
+
"",
|
|
2828
|
+
".ts",
|
|
2829
|
+
".tsx",
|
|
2830
|
+
".js",
|
|
2831
|
+
".jsx",
|
|
2832
|
+
".mjs",
|
|
2833
|
+
".cjs",
|
|
2834
|
+
"/index.ts",
|
|
2835
|
+
"/index.tsx",
|
|
2836
|
+
"/index.js",
|
|
2837
|
+
"/index.jsx",
|
|
2838
|
+
"/index.mjs",
|
|
2839
|
+
"/index.cjs"
|
|
2840
|
+
];
|
|
2841
|
+
for (const ext of extensions) {
|
|
2759
2842
|
const candidate = path6.resolve(dir, specifier.replace(/\.js$/, "") + ext);
|
|
2760
|
-
|
|
2761
|
-
|
|
2843
|
+
try {
|
|
2844
|
+
if (fs6.statSync(candidate).isFile()) {
|
|
2845
|
+
return path6.relative(rootDir, candidate);
|
|
2846
|
+
}
|
|
2847
|
+
} catch {
|
|
2762
2848
|
}
|
|
2763
2849
|
}
|
|
2764
2850
|
return null;
|
|
@@ -10205,10 +10291,10 @@ var TELEMETRY_DISABLED = TELEMETRY_LEVEL === "off";
|
|
|
10205
10291
|
function getTelemetryLevel() {
|
|
10206
10292
|
return TELEMETRY_LEVEL;
|
|
10207
10293
|
}
|
|
10208
|
-
var CTXLOOM_VERSION = "1.5.
|
|
10294
|
+
var CTXLOOM_VERSION = "1.5.4".length > 0 ? "1.5.4" : "dev";
|
|
10209
10295
|
var POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
10210
10296
|
var POSTHOG_KEY = process.env["POSTHOG_API_KEY"] ?? (true ? "phc_CiDkmFLcZ2K6uCpcoSUQLmFrnnUvsyXGhSxopX5TVKE6" : "");
|
|
10211
|
-
var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528" : "");
|
|
10297
|
+
var SENTRY_DSN = process.env["SENTRY_DSN"] ?? (true ? "https://81c94a0f04a8e242dee493ac1e17f733@o4508531702497280.ingest.de.sentry.io/4511256875368528\u2028" : "");
|
|
10212
10298
|
var cachedDistinctId = null;
|
|
10213
10299
|
function resolveDistinctId() {
|
|
10214
10300
|
if (cachedDistinctId) return cachedDistinctId;
|
|
@@ -11803,4 +11889,4 @@ export {
|
|
|
11803
11889
|
skillFilePath,
|
|
11804
11890
|
installHarness
|
|
11805
11891
|
};
|
|
11806
|
-
//# sourceMappingURL=chunk-
|
|
11892
|
+
//# sourceMappingURL=chunk-4ZXFJSDG.js.map
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
validateDefaultRoot,
|
|
46
46
|
wrapWithIndexingEnvelope,
|
|
47
47
|
writeCODEOWNERS
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-4ZXFJSDG.js";
|
|
49
49
|
import {
|
|
50
50
|
addCtxloomToConfig,
|
|
51
51
|
detectInstalledClients
|
|
@@ -1020,7 +1020,7 @@ try {
|
|
|
1020
1020
|
} catch {
|
|
1021
1021
|
}
|
|
1022
1022
|
var args = process.argv.slice(2);
|
|
1023
|
-
var ctxloomVersion = "1.5.
|
|
1023
|
+
var ctxloomVersion = "1.5.4".length > 0 ? "1.5.4" : "dev";
|
|
1024
1024
|
if (args.includes("--version") || args.includes("-v")) {
|
|
1025
1025
|
process.stdout.write(`ctxloom ${ctxloomVersion}
|
|
1026
1026
|
`);
|
|
@@ -1093,7 +1093,7 @@ async function checkLicense() {
|
|
|
1093
1093
|
if (command !== void 0 && LICENSE_GATE_BYPASS_COMMANDS.has(command)) return;
|
|
1094
1094
|
const ciKey = process.env["CTXLOOM_LICENSE_KEY"];
|
|
1095
1095
|
if (ciKey) {
|
|
1096
|
-
const { ApiClient } = await import("./src-
|
|
1096
|
+
const { ApiClient } = await import("./src-AN6JHJMC.js");
|
|
1097
1097
|
const client = new ApiClient(process.env["CTXLOOM_API_BASE"]);
|
|
1098
1098
|
try {
|
|
1099
1099
|
const result = await client.validate(ciKey, "ci-ephemeral");
|
|
@@ -1471,7 +1471,7 @@ async function main() {
|
|
|
1471
1471
|
}
|
|
1472
1472
|
if (!skipHarness) {
|
|
1473
1473
|
process.stdout.write("\n");
|
|
1474
|
-
const { installHarness } = await import("./src-
|
|
1474
|
+
const { installHarness } = await import("./src-AN6JHJMC.js");
|
|
1475
1475
|
const h = installHarness({ cwd: initRoot, dryRun, force, extraHosts });
|
|
1476
1476
|
const harnessFiles = [
|
|
1477
1477
|
h.claudeMd,
|
|
@@ -1534,7 +1534,7 @@ async function main() {
|
|
|
1534
1534
|
process.exit(1);
|
|
1535
1535
|
}
|
|
1536
1536
|
if (alias !== void 0) {
|
|
1537
|
-
const { validateAlias } = await import("./src-
|
|
1537
|
+
const { validateAlias } = await import("./src-AN6JHJMC.js");
|
|
1538
1538
|
const v = validateAlias(alias);
|
|
1539
1539
|
if (!v.ok) {
|
|
1540
1540
|
console.error(`[ctxloom] Invalid alias: ${v.reason}`);
|
|
@@ -1798,7 +1798,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1798
1798
|
process.stderr.write("[ctxloom] --limit must be a non-negative integer (0 for unlimited)\n");
|
|
1799
1799
|
process.exit(2);
|
|
1800
1800
|
}
|
|
1801
|
-
const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-
|
|
1801
|
+
const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-AN6JHJMC.js");
|
|
1802
1802
|
let config;
|
|
1803
1803
|
try {
|
|
1804
1804
|
config = await loadRulesConfig(root);
|
|
@@ -1822,7 +1822,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1822
1822
|
}
|
|
1823
1823
|
let graph;
|
|
1824
1824
|
if (useSnapshot) {
|
|
1825
|
-
const { DependencyGraph: DG } = await import("./src-
|
|
1825
|
+
const { DependencyGraph: DG } = await import("./src-AN6JHJMC.js");
|
|
1826
1826
|
graph = new DG();
|
|
1827
1827
|
const loaded = await graph.loadSnapshotOnly(root);
|
|
1828
1828
|
if (!loaded) {
|
|
@@ -1831,7 +1831,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1831
1831
|
}
|
|
1832
1832
|
} else {
|
|
1833
1833
|
process.stderr.write("[ctxloom] Building dependency graph...\n");
|
|
1834
|
-
const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-
|
|
1834
|
+
const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-AN6JHJMC.js");
|
|
1835
1835
|
let parser;
|
|
1836
1836
|
try {
|
|
1837
1837
|
parser = new ASTParser2();
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
wrapBlock,
|
|
130
130
|
wrapWithIndexingEnvelope,
|
|
131
131
|
writeCODEOWNERS
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-4ZXFJSDG.js";
|
|
133
133
|
import {
|
|
134
134
|
VectorStore
|
|
135
135
|
} from "./chunk-DVI2RWJR.js";
|
|
@@ -294,4 +294,4 @@ export {
|
|
|
294
294
|
wrapWithIndexingEnvelope,
|
|
295
295
|
writeCODEOWNERS
|
|
296
296
|
};
|
|
297
|
-
//# sourceMappingURL=src-
|
|
297
|
+
//# sourceMappingURL=src-AN6JHJMC.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ctxloom-pro",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "ctxloom — The Universal Code Context Engine. A local-first MCP server providing intelligent code context via hybrid Vector + AST + Graph search with Skeletonization (92% token reduction).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
"lint": "tsc --noEmit",
|
|
44
44
|
"postinstall": "node dist/setup/postinstall.js || true",
|
|
45
45
|
"bench:repos": "tsx benchmarks/benchmark-public-repos.ts",
|
|
46
|
+
"bench:spike": "tsx scripts/bench/eval.ts spike",
|
|
47
|
+
"bench:full": "tsx scripts/bench/eval.ts full",
|
|
46
48
|
"e2e:corpus": "node e2e-corpus/run.mjs"
|
|
47
49
|
},
|
|
48
50
|
"keywords": [
|