@yawlabs/ctxlint 0.9.5 → 0.9.7

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.
Files changed (2) hide show
  1. package/dist/index.js +499 -612
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -25639,7 +25639,7 @@ var require_compile = __commonJS({
25639
25639
  }
25640
25640
  }
25641
25641
  exports.compileSchema = compileSchema;
25642
- function resolveRef2(root, baseId, ref) {
25642
+ function resolveRef3(root, baseId, ref) {
25643
25643
  var _a3;
25644
25644
  ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
25645
25645
  const schOrFunc = root.refs[ref];
@@ -25656,7 +25656,7 @@ var require_compile = __commonJS({
25656
25656
  return;
25657
25657
  return root.refs[ref] = inlineOrCompile.call(this, _sch);
25658
25658
  }
25659
- exports.resolveRef = resolveRef2;
25659
+ exports.resolveRef = resolveRef3;
25660
25660
  function inlineOrCompile(sch) {
25661
25661
  if ((0, resolve_1.inlineRef)(sch.schema, this.opts.inlineRefs))
25662
25662
  return sch.schema;
@@ -34322,29 +34322,24 @@ async function scanForContextFiles(projectRoot, options = {}) {
34322
34322
  }
34323
34323
  }
34324
34324
  collectDirs(projectRoot, 0);
34325
- for (const dir of dirsToScan) {
34326
- for (const pattern of patterns) {
34327
- const matches = await Ze(pattern, {
34328
- cwd: dir,
34329
- absolute: true,
34330
- nodir: true,
34331
- dot: true
34325
+ const perDirMatches = await Promise.all(
34326
+ dirsToScan.map((dir) => Ze(patterns, { cwd: dir, absolute: true, nodir: true, dot: true }))
34327
+ );
34328
+ for (const matches of perDirMatches) {
34329
+ for (const match of matches) {
34330
+ const normalized = path2.normalize(match);
34331
+ if (seen.has(normalized)) continue;
34332
+ seen.add(normalized);
34333
+ const relativePath = path2.relative(projectRoot, normalized);
34334
+ const symlink = isSymlink(normalized);
34335
+ const target = symlink ? readSymlinkTarget(normalized) : void 0;
34336
+ found.push({
34337
+ absolutePath: normalized,
34338
+ relativePath: relativePath.replace(/\\/g, "/"),
34339
+ isSymlink: symlink,
34340
+ symlinkTarget: target,
34341
+ type: "context"
34332
34342
  });
34333
- for (const match of matches) {
34334
- const normalized = path2.normalize(match);
34335
- if (seen.has(normalized)) continue;
34336
- seen.add(normalized);
34337
- const relativePath = path2.relative(projectRoot, normalized);
34338
- const symlink = isSymlink(normalized);
34339
- const target = symlink ? readSymlinkTarget(normalized) : void 0;
34340
- found.push({
34341
- absolutePath: normalized,
34342
- relativePath: relativePath.replace(/\\/g, "/"),
34343
- isSymlink: symlink,
34344
- symlinkTarget: target,
34345
- type: "context"
34346
- });
34347
- }
34348
34343
  }
34349
34344
  }
34350
34345
  return found.sort((a, b2) => a.relativePath.localeCompare(b2.relativePath));
@@ -34482,473 +34477,28 @@ var init_scanner = __esm({
34482
34477
  }
34483
34478
  });
34484
34479
 
34485
- // node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken_bg.cjs
34486
- var require_tiktoken_bg = __commonJS({
34487
- "node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken_bg.cjs"(exports, module) {
34488
- var wasm;
34489
- module.exports.__wbg_set_wasm = function(val) {
34490
- wasm = val;
34491
- };
34492
- var lTextDecoder = typeof TextDecoder === "undefined" ? (0, module.require)("util").TextDecoder : TextDecoder;
34493
- var cachedTextDecoder = new lTextDecoder("utf-8", { ignoreBOM: true, fatal: true });
34494
- cachedTextDecoder.decode();
34495
- var cachedUint8ArrayMemory0 = null;
34496
- function getUint8ArrayMemory0() {
34497
- if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
34498
- cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
34499
- }
34500
- return cachedUint8ArrayMemory0;
34501
- }
34502
- function getStringFromWasm0(ptr, len) {
34503
- ptr = ptr >>> 0;
34504
- return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
34505
- }
34506
- var heap = new Array(128).fill(void 0);
34507
- heap.push(void 0, null, true, false);
34508
- var heap_next = heap.length;
34509
- function addHeapObject(obj) {
34510
- if (heap_next === heap.length) heap.push(heap.length + 1);
34511
- const idx = heap_next;
34512
- heap_next = heap[idx];
34513
- heap[idx] = obj;
34514
- return idx;
34515
- }
34516
- function handleError(f, args) {
34517
- try {
34518
- return f.apply(this, args);
34519
- } catch (e) {
34520
- wasm.__wbindgen_export_0(addHeapObject(e));
34521
- }
34522
- }
34523
- function getObject(idx) {
34524
- return heap[idx];
34525
- }
34526
- function dropObject(idx) {
34527
- if (idx < 132) return;
34528
- heap[idx] = heap_next;
34529
- heap_next = idx;
34530
- }
34531
- function takeObject(idx) {
34532
- const ret = getObject(idx);
34533
- dropObject(idx);
34534
- return ret;
34535
- }
34536
- var WASM_VECTOR_LEN = 0;
34537
- var lTextEncoder = typeof TextEncoder === "undefined" ? (0, module.require)("util").TextEncoder : TextEncoder;
34538
- var cachedTextEncoder = new lTextEncoder("utf-8");
34539
- var encodeString = typeof cachedTextEncoder.encodeInto === "function" ? function(arg, view) {
34540
- return cachedTextEncoder.encodeInto(arg, view);
34541
- } : function(arg, view) {
34542
- const buf = cachedTextEncoder.encode(arg);
34543
- view.set(buf);
34544
- return {
34545
- read: arg.length,
34546
- written: buf.length
34547
- };
34548
- };
34549
- function passStringToWasm0(arg, malloc, realloc) {
34550
- if (realloc === void 0) {
34551
- const buf = cachedTextEncoder.encode(arg);
34552
- const ptr2 = malloc(buf.length, 1) >>> 0;
34553
- getUint8ArrayMemory0().subarray(ptr2, ptr2 + buf.length).set(buf);
34554
- WASM_VECTOR_LEN = buf.length;
34555
- return ptr2;
34556
- }
34557
- let len = arg.length;
34558
- let ptr = malloc(len, 1) >>> 0;
34559
- const mem = getUint8ArrayMemory0();
34560
- let offset = 0;
34561
- for (; offset < len; offset++) {
34562
- const code = arg.charCodeAt(offset);
34563
- if (code > 127) break;
34564
- mem[ptr + offset] = code;
34565
- }
34566
- if (offset !== len) {
34567
- if (offset !== 0) {
34568
- arg = arg.slice(offset);
34569
- }
34570
- ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
34571
- const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
34572
- const ret = encodeString(arg, view);
34573
- offset += ret.written;
34574
- ptr = realloc(ptr, len, offset, 1) >>> 0;
34575
- }
34576
- WASM_VECTOR_LEN = offset;
34577
- return ptr;
34578
- }
34579
- function isLikeNone(x3) {
34580
- return x3 === void 0 || x3 === null;
34581
- }
34582
- var cachedDataViewMemory0 = null;
34583
- function getDataViewMemory0() {
34584
- if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {
34585
- cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
34586
- }
34587
- return cachedDataViewMemory0;
34588
- }
34589
- var cachedUint32ArrayMemory0 = null;
34590
- function getUint32ArrayMemory0() {
34591
- if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
34592
- cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
34593
- }
34594
- return cachedUint32ArrayMemory0;
34595
- }
34596
- function getArrayU32FromWasm0(ptr, len) {
34597
- ptr = ptr >>> 0;
34598
- return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
34599
- }
34600
- function passArray8ToWasm0(arg, malloc) {
34601
- const ptr = malloc(arg.length * 1, 1) >>> 0;
34602
- getUint8ArrayMemory0().set(arg, ptr / 1);
34603
- WASM_VECTOR_LEN = arg.length;
34604
- return ptr;
34605
- }
34606
- function passArray32ToWasm0(arg, malloc) {
34607
- const ptr = malloc(arg.length * 4, 4) >>> 0;
34608
- getUint32ArrayMemory0().set(arg, ptr / 4);
34609
- WASM_VECTOR_LEN = arg.length;
34610
- return ptr;
34611
- }
34612
- function getArrayU8FromWasm0(ptr, len) {
34613
- ptr = ptr >>> 0;
34614
- return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
34615
- }
34616
- module.exports.get_encoding = function(encoding, extend_special_tokens) {
34617
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34618
- try {
34619
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34620
- const ptr0 = passStringToWasm0(encoding, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34621
- const len0 = WASM_VECTOR_LEN;
34622
- wasm.get_encoding(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
34623
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34624
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34625
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
34626
- if (r2) {
34627
- throw takeObject(r1);
34628
- }
34629
- return Tiktoken.__wrap(r0);
34630
- } finally {
34631
- wasm.__wbindgen_add_to_stack_pointer(16);
34632
- }
34633
- };
34634
- module.exports.encoding_for_model = function(model, extend_special_tokens) {
34635
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34636
- try {
34637
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34638
- const ptr0 = passStringToWasm0(model, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34639
- const len0 = WASM_VECTOR_LEN;
34640
- wasm.encoding_for_model(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
34641
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34642
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34643
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
34644
- if (r2) {
34645
- throw takeObject(r1);
34646
- }
34647
- return Tiktoken.__wrap(r0);
34648
- } finally {
34649
- wasm.__wbindgen_add_to_stack_pointer(16);
34650
- }
34651
- };
34652
- module.exports.get_encoding_name_for_model = function(model) {
34653
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34654
- let deferred3_0;
34655
- let deferred3_1;
34656
- try {
34657
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34658
- const ptr0 = passStringToWasm0(model, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34659
- const len0 = WASM_VECTOR_LEN;
34660
- wasm.get_encoding_name_for_model(retptr, ptr0, len0);
34661
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34662
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34663
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
34664
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
34665
- var ptr2 = r0;
34666
- var len2 = r1;
34667
- if (r3) {
34668
- ptr2 = 0;
34669
- len2 = 0;
34670
- throw takeObject(r2);
34671
- }
34672
- deferred3_0 = ptr2;
34673
- deferred3_1 = len2;
34674
- return getStringFromWasm0(ptr2, len2);
34675
- } finally {
34676
- wasm.__wbindgen_add_to_stack_pointer(16);
34677
- wasm.__wbindgen_export_3(deferred3_0, deferred3_1, 1);
34678
- }
34679
- };
34680
- var TiktokenFinalization = typeof FinalizationRegistry === "undefined" ? { register: () => {
34681
- }, unregister: () => {
34682
- } } : new FinalizationRegistry((ptr) => wasm.__wbg_tiktoken_free(ptr >>> 0, 1));
34683
- var Tiktoken = class _Tiktoken {
34684
- /**
34685
- * @param {string} tiktoken_bfe
34686
- * @param {any} special_tokens
34687
- * @param {string} pat_str
34688
- */
34689
- constructor(tiktoken_bfe, special_tokens, pat_str) {
34690
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34691
- const ptr0 = passStringToWasm0(tiktoken_bfe, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34692
- const len0 = WASM_VECTOR_LEN;
34693
- const ptr1 = passStringToWasm0(pat_str, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34694
- const len1 = WASM_VECTOR_LEN;
34695
- const ret = wasm.tiktoken_new(ptr0, len0, addHeapObject(special_tokens), ptr1, len1);
34696
- this.__wbg_ptr = ret >>> 0;
34697
- TiktokenFinalization.register(this, this.__wbg_ptr, this);
34698
- return this;
34699
- }
34700
- /** @returns {string | undefined} */
34701
- get name() {
34702
- try {
34703
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34704
- wasm.tiktoken_name(retptr, this.__wbg_ptr);
34705
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34706
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34707
- let v1;
34708
- if (r0 !== 0) {
34709
- v1 = getStringFromWasm0(r0, r1).slice();
34710
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
34711
- }
34712
- return v1;
34713
- } finally {
34714
- wasm.__wbindgen_add_to_stack_pointer(16);
34715
- }
34716
- }
34717
- static __wrap(ptr) {
34718
- ptr = ptr >>> 0;
34719
- const obj = Object.create(_Tiktoken.prototype);
34720
- obj.__wbg_ptr = ptr;
34721
- TiktokenFinalization.register(obj, obj.__wbg_ptr, obj);
34722
- return obj;
34723
- }
34724
- __destroy_into_raw() {
34725
- const ptr = this.__wbg_ptr;
34726
- this.__wbg_ptr = 0;
34727
- TiktokenFinalization.unregister(this);
34728
- return ptr;
34729
- }
34730
- free() {
34731
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34732
- const ptr = this.__destroy_into_raw();
34733
- wasm.__wbg_tiktoken_free(ptr, 0);
34734
- }
34735
- /**
34736
- * @param {string} text
34737
- * @param {any} allowed_special
34738
- * @param {any} disallowed_special
34739
- * @returns {Uint32Array}
34740
- */
34741
- encode(text, allowed_special, disallowed_special) {
34742
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34743
- try {
34744
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34745
- const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34746
- const len0 = WASM_VECTOR_LEN;
34747
- wasm.tiktoken_encode(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
34748
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34749
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34750
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
34751
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
34752
- if (r3) {
34753
- throw takeObject(r2);
34754
- }
34755
- var v2 = getArrayU32FromWasm0(r0, r1).slice();
34756
- wasm.__wbindgen_export_3(r0, r1 * 4, 4);
34757
- return v2;
34758
- } finally {
34759
- wasm.__wbindgen_add_to_stack_pointer(16);
34760
- }
34761
- }
34762
- /**
34763
- * @param {string} text
34764
- * @returns {Uint32Array}
34765
- */
34766
- encode_ordinary(text) {
34767
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34768
- try {
34769
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34770
- const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34771
- const len0 = WASM_VECTOR_LEN;
34772
- wasm.tiktoken_encode_ordinary(retptr, this.__wbg_ptr, ptr0, len0);
34773
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34774
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34775
- var v2 = getArrayU32FromWasm0(r0, r1).slice();
34776
- wasm.__wbindgen_export_3(r0, r1 * 4, 4);
34777
- return v2;
34778
- } finally {
34779
- wasm.__wbindgen_add_to_stack_pointer(16);
34780
- }
34781
- }
34782
- /**
34783
- * @param {string} text
34784
- * @param {any} allowed_special
34785
- * @param {any} disallowed_special
34786
- * @returns {any}
34787
- */
34788
- encode_with_unstable(text, allowed_special, disallowed_special) {
34789
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34790
- try {
34791
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34792
- const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34793
- const len0 = WASM_VECTOR_LEN;
34794
- wasm.tiktoken_encode_with_unstable(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
34795
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34796
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34797
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
34798
- if (r2) {
34799
- throw takeObject(r1);
34800
- }
34801
- return takeObject(r0);
34802
- } finally {
34803
- wasm.__wbindgen_add_to_stack_pointer(16);
34804
- }
34805
- }
34806
- /**
34807
- * @param {Uint8Array} bytes
34808
- * @returns {number}
34809
- */
34810
- encode_single_token(bytes) {
34811
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34812
- const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export_1);
34813
- const len0 = WASM_VECTOR_LEN;
34814
- const ret = wasm.tiktoken_encode_single_token(this.__wbg_ptr, ptr0, len0);
34815
- return ret >>> 0;
34816
- }
34817
- /**
34818
- * @param {Uint32Array} tokens
34819
- * @returns {Uint8Array}
34820
- */
34821
- decode(tokens) {
34822
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34823
- try {
34824
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34825
- const ptr0 = passArray32ToWasm0(tokens, wasm.__wbindgen_export_1);
34826
- const len0 = WASM_VECTOR_LEN;
34827
- wasm.tiktoken_decode(retptr, this.__wbg_ptr, ptr0, len0);
34828
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34829
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34830
- var v2 = getArrayU8FromWasm0(r0, r1).slice();
34831
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
34832
- return v2;
34833
- } finally {
34834
- wasm.__wbindgen_add_to_stack_pointer(16);
34835
- }
34836
- }
34837
- /**
34838
- * @param {number} token
34839
- * @returns {Uint8Array}
34840
- */
34841
- decode_single_token_bytes(token) {
34842
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34843
- try {
34844
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
34845
- wasm.tiktoken_decode_single_token_bytes(retptr, this.__wbg_ptr, token);
34846
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
34847
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
34848
- var v1 = getArrayU8FromWasm0(r0, r1).slice();
34849
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
34850
- return v1;
34851
- } finally {
34852
- wasm.__wbindgen_add_to_stack_pointer(16);
34853
- }
34854
- }
34855
- /** @returns {any} */
34856
- token_byte_values() {
34857
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34858
- const ret = wasm.tiktoken_token_byte_values(this.__wbg_ptr);
34859
- return takeObject(ret);
34860
- }
34861
- };
34862
- module.exports.Tiktoken = Tiktoken;
34863
- module.exports.__wbg_parse_def2e24ef1252aff = function() {
34864
- return handleError(function(arg0, arg1) {
34865
- const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
34866
- return addHeapObject(ret);
34867
- }, arguments);
34868
- };
34869
- module.exports.__wbg_stringify_f7ed6987935b4a24 = function() {
34870
- return handleError(function(arg0) {
34871
- const ret = JSON.stringify(getObject(arg0));
34872
- return addHeapObject(ret);
34873
- }, arguments);
34874
- };
34875
- module.exports.__wbindgen_error_new = function(arg0, arg1) {
34876
- const ret = new Error(getStringFromWasm0(arg0, arg1));
34877
- return addHeapObject(ret);
34878
- };
34879
- module.exports.__wbindgen_is_undefined = function(arg0) {
34880
- const ret = getObject(arg0) === void 0;
34881
- return ret;
34882
- };
34883
- module.exports.__wbindgen_object_drop_ref = function(arg0) {
34884
- takeObject(arg0);
34885
- };
34886
- module.exports.__wbindgen_string_get = function(arg0, arg1) {
34887
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
34888
- const obj = getObject(arg1);
34889
- const ret = typeof obj === "string" ? obj : void 0;
34890
- var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
34891
- var len1 = WASM_VECTOR_LEN;
34892
- getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
34893
- getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
34894
- };
34895
- module.exports.__wbindgen_throw = function(arg0, arg1) {
34896
- throw new Error(getStringFromWasm0(arg0, arg1));
34897
- };
34898
- }
34899
- });
34900
-
34901
- // node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken.cjs
34902
- var require_tiktoken = __commonJS({
34903
- "node_modules/.pnpm/tiktoken@1.0.22/node_modules/tiktoken/tiktoken.cjs"(exports) {
34904
- var wasm = require_tiktoken_bg();
34905
- var imports = {};
34906
- imports["./tiktoken_bg.js"] = wasm;
34907
- var path12 = __require("path");
34908
- var fs10 = __require("fs");
34909
- var candidates = __dirname.split(path12.sep).reduce((memo, _3, index, array2) => {
34910
- const prefix = array2.slice(0, index + 1).join(path12.sep) + path12.sep;
34911
- if (!prefix.includes("node_modules" + path12.sep)) {
34912
- memo.unshift(
34913
- path12.join(
34914
- prefix,
34915
- "node_modules",
34916
- "tiktoken",
34917
- "",
34918
- "./tiktoken_bg.wasm"
34919
- )
34920
- );
34921
- }
34922
- return memo;
34923
- }, []);
34924
- candidates.unshift(path12.join(__dirname, "./tiktoken_bg.wasm"));
34925
- var bytes = null;
34926
- for (const candidate of candidates) {
34927
- try {
34928
- bytes = fs10.readFileSync(candidate);
34929
- break;
34930
- } catch {
34931
- }
34932
- }
34933
- if (bytes == null) throw new Error("Missing tiktoken_bg.wasm");
34934
- var wasmModule = new WebAssembly.Module(bytes);
34935
- var wasmInstance = new WebAssembly.Instance(wasmModule, imports);
34936
- wasm.__wbg_set_wasm(wasmInstance.exports);
34937
- exports["get_encoding"] = wasm["get_encoding"];
34938
- exports["encoding_for_model"] = wasm["encoding_for_model"];
34939
- exports["get_encoding_name_for_model"] = wasm["get_encoding_name_for_model"];
34940
- exports["Tiktoken"] = wasm["Tiktoken"];
34941
- }
34942
- });
34943
-
34944
34480
  // src/utils/tokens.ts
34945
- function getEncoder() {
34946
- if (!encoder && encodingForModel) {
34947
- encoder = encodingForModel("gpt-4");
34481
+ import { createRequire } from "node:module";
34482
+ function loadEncodingForModel() {
34483
+ if (loadAttempted) return encodingForModel;
34484
+ loadAttempted = true;
34485
+ try {
34486
+ const req = createRequire(import.meta.url);
34487
+ const tiktoken = req("tiktoken");
34488
+ encodingForModel = tiktoken.encoding_for_model;
34489
+ } catch {
34948
34490
  }
34491
+ return encodingForModel;
34492
+ }
34493
+ function getEncoder() {
34494
+ if (encoder) return encoder;
34495
+ const loader = loadEncodingForModel();
34496
+ if (!loader) return null;
34497
+ encoder = loader("gpt-4");
34949
34498
  return encoder;
34950
34499
  }
34951
34500
  function countTokens(text) {
34501
+ if (!text) return 0;
34952
34502
  const enc = getEncoder();
34953
34503
  if (!enc) {
34954
34504
  return Math.ceil(text.length / 4);
@@ -34968,16 +34518,12 @@ function freeEncoder() {
34968
34518
  function keepEncoderAlive(keep) {
34969
34519
  _keepAlive = keep;
34970
34520
  }
34971
- var encodingForModel, encoder, _keepAlive;
34521
+ var encodingForModel, loadAttempted, encoder, _keepAlive;
34972
34522
  var init_tokens = __esm({
34973
- async "src/utils/tokens.ts"() {
34523
+ "src/utils/tokens.ts"() {
34974
34524
  "use strict";
34975
34525
  encodingForModel = null;
34976
- try {
34977
- const tiktoken = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
34978
- encodingForModel = tiktoken.encoding_for_model;
34979
- } catch {
34980
- }
34526
+ loadAttempted = false;
34981
34527
  encoder = null;
34982
34528
  _keepAlive = false;
34983
34529
  }
@@ -35067,6 +34613,10 @@ function extractPathReferences(lines, sections) {
35067
34613
  if (PATH_EXCLUDE.test(value)) continue;
35068
34614
  if (value.length < 3) continue;
35069
34615
  if (/^v?\d+\.\d+\//.test(value)) continue;
34616
+ if (/^\d+\/\d+$/.test(value)) continue;
34617
+ if (/^[A-Z][\w.-]*\/[A-Z][\w.-]*$/.test(value) && !value.includes(".")) {
34618
+ continue;
34619
+ }
35070
34620
  const column = match.index + match[0].length - match[1].length + 1;
35071
34621
  paths.push({
35072
34622
  value,
@@ -35171,10 +34721,10 @@ function extractCommandReferences(lines, sections) {
35171
34721
  }
35172
34722
  var PATH_PATTERN, PATH_EXCLUDE, COMMAND_PREFIXES, COMMON_COMMANDS;
35173
34723
  var init_parser = __esm({
35174
- async "src/core/parser.ts"() {
34724
+ "src/core/parser.ts"() {
35175
34725
  "use strict";
35176
34726
  init_fs();
35177
- await init_tokens();
34727
+ init_tokens();
35178
34728
  PATH_PATTERN = /(?:^|[\s`"'(])((\.{0,2}\/)?(?:[\w@.-]+\/)+[\w.*-]*(?:\.\w+)?)(?=[\s`"'),;:]|$)/gm;
35179
34729
  PATH_EXCLUDE = /^(https?:\/\/|ftp:\/\/|mailto:|n\/a|w\/o|I\/O|i\/o|e\.g\.|N\/A|\.deb\/|\.rpm[.\/]|\.tar[.\/]|\.zip[.\/])/i;
35180
34730
  COMMAND_PREFIXES = /^\s*[\$>]\s+(.+)$/;
@@ -40946,17 +40496,54 @@ async function getFileLastModified(projectRoot, filePath) {
40946
40496
  return null;
40947
40497
  }
40948
40498
  }
40949
- async function getCommitsSince(projectRoot, filePath, since) {
40499
+ async function getCommitsSinceBatch(projectRoot, paths, since) {
40500
+ const counts = /* @__PURE__ */ new Map();
40501
+ for (const p2 of paths) counts.set(p2, 0);
40502
+ if (paths.length === 0) return counts;
40950
40503
  try {
40951
40504
  const git = getGit(projectRoot);
40952
- const log = await git.log({
40953
- file: filePath,
40954
- "--since": since.toISOString()
40955
- });
40956
- return log.total;
40505
+ const SENTINEL = "___CTXLINT_COMMIT___";
40506
+ const raw = await git.raw([
40507
+ "log",
40508
+ `--since=${since.toISOString()}`,
40509
+ "--name-only",
40510
+ `--format=${SENTINEL}`
40511
+ ]);
40512
+ const normalize3 = (p2) => p2.replace(/\\/g, "/");
40513
+ const requested = new Set(paths.map(normalize3));
40514
+ const lines = raw.split("\n");
40515
+ let inCommit = false;
40516
+ const seenThisCommit = /* @__PURE__ */ new Set();
40517
+ const flush = () => {
40518
+ for (const p2 of seenThisCommit) {
40519
+ counts.set(p2, (counts.get(p2) ?? 0) + 1);
40520
+ }
40521
+ seenThisCommit.clear();
40522
+ };
40523
+ for (const line of lines) {
40524
+ if (line === SENTINEL) {
40525
+ if (inCommit) flush();
40526
+ inCommit = true;
40527
+ continue;
40528
+ }
40529
+ if (!inCommit) continue;
40530
+ const trimmed2 = line.trim();
40531
+ if (!trimmed2) continue;
40532
+ const changed = normalize3(trimmed2);
40533
+ for (const req of requested) {
40534
+ if (changed === req || changed.startsWith(req.endsWith("/") ? req : req + "/")) {
40535
+ seenThisCommit.add(req);
40536
+ }
40537
+ }
40538
+ }
40539
+ if (inCommit) flush();
40957
40540
  } catch {
40958
- return 0;
40959
40541
  }
40542
+ const out = /* @__PURE__ */ new Map();
40543
+ for (const p2 of paths) {
40544
+ out.set(p2, counts.get(p2.replace(/\\/g, "/")) ?? 0);
40545
+ }
40546
+ return out;
40960
40547
  }
40961
40548
  async function findRenames(projectRoot, filePath) {
40962
40549
  try {
@@ -41298,7 +40885,7 @@ var require_levenshtein = __commonJS({
41298
40885
  } catch (err) {
41299
40886
  console.log("Collator could not be initialized and wouldn't be used");
41300
40887
  }
41301
- var levenshtein2 = require_mod();
40888
+ var levenshtein3 = require_mod();
41302
40889
  var prevRow = [], str2Char = [];
41303
40890
  var Levenshtein = {
41304
40891
  /**
@@ -41343,7 +40930,7 @@ var require_levenshtein = __commonJS({
41343
40930
  }
41344
40931
  return nextCol;
41345
40932
  }
41346
- return levenshtein2.distance(str1, str2);
40933
+ return levenshtein3.distance(str1, str2);
41347
40934
  }
41348
40935
  };
41349
40936
  if (typeof define !== "undefined" && define !== null && define.amd) {
@@ -41638,11 +41225,14 @@ async function checkStaleness(file2, projectRoot) {
41638
41225
  for (const ref of file2.references.paths) {
41639
41226
  referencedPaths.add(ref.value);
41640
41227
  }
41228
+ if (referencedPaths.size === 0) {
41229
+ return issues;
41230
+ }
41231
+ const counts = await getCommitsSinceBatch(projectRoot, [...referencedPaths], lastModified);
41641
41232
  let totalCommits = 0;
41642
41233
  let mostActiveRef = "";
41643
41234
  let mostActiveCommits = 0;
41644
- for (const refPath of referencedPaths) {
41645
- const commits = await getCommitsSince(projectRoot, refPath, lastModified);
41235
+ for (const [refPath, commits] of counts) {
41646
41236
  totalCommits += commits;
41647
41237
  if (commits > mostActiveCommits) {
41648
41238
  mostActiveCommits = commits;
@@ -41785,8 +41375,8 @@ function isAlwaysLoaded(file2) {
41785
41375
  if (rel.includes("/rules/")) {
41786
41376
  return !hasPathsFrontmatter(file2.content);
41787
41377
  }
41788
- const basename2 = rel.split("/").pop() ?? "";
41789
- return ALWAYS_LOADED_BASENAMES.has(basename2);
41378
+ const basename3 = rel.split("/").pop() ?? "";
41379
+ return ALWAYS_LOADED_BASENAMES.has(basename3);
41790
41380
  }
41791
41381
  function computeSectionCosts(file2) {
41792
41382
  if (file2.sections.length === 0) return [];
@@ -41814,16 +41404,21 @@ function loadSettingsSources(projectRoot) {
41814
41404
  }
41815
41405
  return sources;
41816
41406
  }
41407
+ function canonicalizeCommand(backticked) {
41408
+ const beforeFlags = backticked.trim().split(/\s+--?/, 1)[0];
41409
+ return beforeFlags.replace(/\s+/g, " ");
41410
+ }
41817
41411
  function commandIsEnforced(cmd, settings) {
41818
- const lower = cmd.toLowerCase();
41412
+ const escaped = cmd.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
41413
+ const pattern = new RegExp(`\\b${escaped}\\b`, "i");
41819
41414
  for (const s of settings) {
41820
41415
  for (const entry of s.permissions?.deny ?? []) {
41821
- if (entry.toLowerCase().includes(lower)) return true;
41416
+ if (pattern.test(entry)) return true;
41822
41417
  }
41823
41418
  for (const h2 of s.hooks?.PreToolUse ?? []) {
41824
- if ((h2.matcher || "").toLowerCase().includes(lower)) return true;
41419
+ if (pattern.test(h2.matcher || "")) return true;
41825
41420
  for (const sub of h2.hooks ?? []) {
41826
- if ((sub.command || "").toLowerCase().includes(lower)) return true;
41421
+ if (pattern.test(sub.command || "")) return true;
41827
41422
  }
41828
41423
  }
41829
41424
  }
@@ -41834,10 +41429,9 @@ function checkHardEnforcement(file2, settings) {
41834
41429
  const lines = file2.content.split("\n");
41835
41430
  for (let i2 = 0; i2 < lines.length; i2++) {
41836
41431
  const line = lines[i2];
41837
- if (!INVIOLABLE_FRAMING.test(line)) continue;
41838
- COMMAND_IN_BACKTICKS.lastIndex = 0;
41839
- const matches = [...line.matchAll(COMMAND_IN_BACKTICKS)].map((m) => m[1]);
41840
- const cmd = matches.find((m) => /^[\w.-][\w\s.-]*/.test(m) && !m.includes("/"));
41432
+ const match = line.match(INVIOLABLE_WITH_COMMAND);
41433
+ if (!match) continue;
41434
+ const cmd = canonicalizeCommand(match[2]);
41841
41435
  if (!cmd) continue;
41842
41436
  if (commandIsEnforced(cmd, settings)) continue;
41843
41437
  issues.push({
@@ -41846,7 +41440,7 @@ function checkHardEnforcement(file2, settings) {
41846
41440
  ruleId: "tier-tokens/hard-enforcement-missing",
41847
41441
  line: i2 + 1,
41848
41442
  message: `Inviolable framing ("${line.trim().slice(0, 80)}") without a hook to back it up`,
41849
- suggestion: `Rules in always-loaded files are advisory. For "${cmd}", add a PreToolUse hook (or permissions.deny entry) in .claude/settings.json so the command is physically blocked.`
41443
+ suggestion: `Rules in always-loaded files are advisory. For \`${cmd}\`, add a PreToolUse hook (or permissions.deny entry) in .claude/settings.json so the command is physically blocked.`
41850
41444
  });
41851
41445
  }
41852
41446
  return issues;
@@ -41894,11 +41488,11 @@ function checkAggregateTierTokens(files) {
41894
41488
  suggestion: "Consider moving the largest files or their heaviest sections to on-demand tiers (skills, subagents, memory)."
41895
41489
  };
41896
41490
  }
41897
- var ALWAYS_LOADED_BASENAMES, TOP_SECTIONS_TO_REPORT, INVIOLABLE_FRAMING, COMMAND_IN_BACKTICKS;
41491
+ var ALWAYS_LOADED_BASENAMES, TOP_SECTIONS_TO_REPORT, INVIOLABLE_WITH_COMMAND;
41898
41492
  var init_tier_tokens = __esm({
41899
- async "src/core/checks/tier-tokens.ts"() {
41493
+ "src/core/checks/tier-tokens.ts"() {
41900
41494
  "use strict";
41901
- await init_tokens();
41495
+ init_tokens();
41902
41496
  init_tokens2();
41903
41497
  ALWAYS_LOADED_BASENAMES = /* @__PURE__ */ new Set([
41904
41498
  "CLAUDE.md",
@@ -41920,8 +41514,7 @@ var init_tier_tokens = __esm({
41920
41514
  "instructions.md"
41921
41515
  ]);
41922
41516
  TOP_SECTIONS_TO_REPORT = 3;
41923
- INVIOLABLE_FRAMING = /\b(NEVER|ALWAYS|DON'?T|DO NOT|MUST NOT)\b/i;
41924
- COMMAND_IN_BACKTICKS = /`([^`]+)`/g;
41517
+ INVIOLABLE_WITH_COMMAND = /\b(NEVER|ALWAYS|DON'?T|DO NOT|MUST NOT)\b[^.!?`]{0,80}`([^`]+)`/i;
41925
41518
  }
41926
41519
  });
41927
41520
 
@@ -42044,10 +41637,10 @@ function escapeRegex2(str) {
42044
41637
  }
42045
41638
  var PACKAGE_TECH_MAP;
42046
41639
  var init_redundancy = __esm({
42047
- async "src/core/checks/redundancy.ts"() {
41640
+ "src/core/checks/redundancy.ts"() {
42048
41641
  "use strict";
42049
41642
  init_fs();
42050
- await init_tokens();
41643
+ init_tokens();
42051
41644
  PACKAGE_TECH_MAP = {
42052
41645
  react: ["React", "react"],
42053
41646
  "react-dom": ["React DOM", "ReactDOM"],
@@ -42130,54 +41723,88 @@ function detectDirectives(file2) {
42130
41723
  function checkContradictions(files) {
42131
41724
  if (files.length < 2) return [];
42132
41725
  const issues = [];
42133
- const allDirectives = [];
42134
- for (const file2 of files) {
42135
- allDirectives.push(...detectDirectives(file2));
42136
- }
42137
41726
  const byCategory = /* @__PURE__ */ new Map();
42138
- for (const d of allDirectives) {
42139
- const existing = byCategory.get(d.category) || [];
42140
- existing.push(d);
42141
- byCategory.set(d.category, existing);
41727
+ const directiveIndex = /* @__PURE__ */ new Map();
41728
+ for (const file2 of files) {
41729
+ for (const d of detectDirectives(file2)) {
41730
+ let list = byCategory.get(d.category);
41731
+ if (!list) {
41732
+ list = [];
41733
+ byCategory.set(d.category, list);
41734
+ }
41735
+ list.push(d);
41736
+ let idx = directiveIndex.get(d.category);
41737
+ if (!idx) {
41738
+ idx = /* @__PURE__ */ new Map();
41739
+ directiveIndex.set(d.category, idx);
41740
+ }
41741
+ const key = `${d.file}::${d.label}`;
41742
+ if (!idx.has(key)) idx.set(key, d);
41743
+ }
42142
41744
  }
42143
41745
  for (const [category, directives] of byCategory) {
42144
- const byFile = /* @__PURE__ */ new Map();
42145
- for (const d of directives) {
42146
- const existing = byFile.get(d.file) || [];
42147
- existing.push(d);
42148
- byFile.set(d.file, existing);
42149
- }
42150
41746
  const labels = new Set(directives.map((d) => d.label));
42151
41747
  if (labels.size <= 1) continue;
42152
41748
  const fileLabels = /* @__PURE__ */ new Map();
42153
41749
  for (const d of directives) {
42154
- const existing = fileLabels.get(d.file) || /* @__PURE__ */ new Set();
41750
+ let existing = fileLabels.get(d.file);
41751
+ if (!existing) {
41752
+ existing = /* @__PURE__ */ new Set();
41753
+ fileLabels.set(d.file, existing);
41754
+ }
42155
41755
  existing.add(d.label);
42156
- fileLabels.set(d.file, existing);
42157
- }
42158
- const fileEntries = [...fileLabels.entries()];
42159
- for (let i2 = 0; i2 < fileEntries.length; i2++) {
42160
- for (let j3 = i2 + 1; j3 < fileEntries.length; j3++) {
42161
- const [fileA, labelsA] = fileEntries[i2];
42162
- const [fileB, labelsB] = fileEntries[j3];
42163
- for (const labelA of labelsA) {
42164
- for (const labelB of labelsB) {
42165
- if (labelA !== labelB) {
42166
- const directiveA = directives.find((d) => d.file === fileA && d.label === labelA);
42167
- const directiveB = directives.find((d) => d.file === fileB && d.label === labelB);
42168
- issues.push({
42169
- severity: "warning",
42170
- check: "contradictions",
42171
- ruleId: "contradictions/conflict",
42172
- line: directiveA.line,
42173
- message: `${category} conflict: "${directiveA.label}" in ${fileA} vs "${directiveB.label}" in ${fileB}`,
42174
- suggestion: `Align on one ${category} across all context files`,
42175
- detail: `${fileA}:${directiveA.line} says "${directiveA.text}" but ${fileB}:${directiveB.line} says "${directiveB.text}"`
42176
- });
42177
- }
42178
- }
41756
+ }
41757
+ const conflictingFiles = [...fileLabels.keys()].filter((f) => {
41758
+ const myLabels = fileLabels.get(f);
41759
+ for (const [otherFile, otherLabels] of fileLabels) {
41760
+ if (otherFile === f) continue;
41761
+ for (const l of myLabels) {
41762
+ if (!otherLabels.has(l)) return true;
42179
41763
  }
42180
41764
  }
41765
+ return false;
41766
+ });
41767
+ if (conflictingFiles.length < 2) continue;
41768
+ const idx = directiveIndex.get(category);
41769
+ if (conflictingFiles.length === 2) {
41770
+ const [fileA, fileB] = conflictingFiles;
41771
+ const labelsA = fileLabels.get(fileA);
41772
+ const labelsB = fileLabels.get(fileB);
41773
+ for (const labelA of labelsA) {
41774
+ for (const labelB of labelsB) {
41775
+ if (labelA === labelB) continue;
41776
+ const directiveA = idx.get(`${fileA}::${labelA}`);
41777
+ const directiveB = idx.get(`${fileB}::${labelB}`);
41778
+ issues.push({
41779
+ severity: "warning",
41780
+ check: "contradictions",
41781
+ ruleId: "contradictions/conflict",
41782
+ line: directiveA.line,
41783
+ message: `${category} conflict: "${directiveA.label}" in ${fileA} vs "${directiveB.label}" in ${fileB}`,
41784
+ suggestion: `Align on one ${category} across all context files`,
41785
+ detail: `${fileA}:${directiveA.line} says "${directiveA.text}" but ${fileB}:${directiveB.line} says "${directiveB.text}"`
41786
+ });
41787
+ }
41788
+ }
41789
+ } else {
41790
+ const entries = [];
41791
+ for (const f of conflictingFiles) {
41792
+ for (const l of fileLabels.get(f)) {
41793
+ entries.push(idx.get(`${f}::${l}`));
41794
+ }
41795
+ }
41796
+ const firstEntry = entries[0];
41797
+ const summary = entries.map((e) => `"${e.label}" in ${e.file}`).join(", ");
41798
+ const detail = entries.map((e) => `${e.file}:${e.line} says "${e.text}"`).join("\n");
41799
+ issues.push({
41800
+ severity: "warning",
41801
+ check: "contradictions",
41802
+ ruleId: "contradictions/conflict",
41803
+ line: firstEntry.line,
41804
+ message: `${category} conflict across ${conflictingFiles.length} files: ${summary}`,
41805
+ suggestion: `Align on one ${category} across all context files`,
41806
+ detail
41807
+ });
42181
41808
  }
42182
41809
  }
42183
41810
  return issues;
@@ -42855,6 +42482,7 @@ async function checkMcpCommands(config2, projectRoot) {
42855
42482
  }
42856
42483
  if (server2.args) {
42857
42484
  for (const arg of server2.args) {
42485
+ if (URL_PREFIX.test(arg)) continue;
42858
42486
  if (LOCAL_PATH_PATTERN.test(arg) || FILE_PATH_PATTERN.test(arg)) {
42859
42487
  const resolved = path8.resolve(projectRoot, arg);
42860
42488
  if (!fileExistsSafe(resolved)) {
@@ -42880,12 +42508,13 @@ function fileExistsSafe(filePath) {
42880
42508
  return false;
42881
42509
  }
42882
42510
  }
42883
- var LOCAL_PATH_PATTERN, FILE_PATH_PATTERN;
42511
+ var LOCAL_PATH_PATTERN, FILE_PATH_PATTERN, URL_PREFIX;
42884
42512
  var init_commands2 = __esm({
42885
42513
  "src/core/checks/mcp/commands.ts"() {
42886
42514
  "use strict";
42887
42515
  LOCAL_PATH_PATTERN = /^\.\.?\//;
42888
42516
  FILE_PATH_PATTERN = /^[^-].*\/.*\.\w+$/;
42517
+ URL_PREFIX = /^(https?|file|s3|gs|ssh|git):\/\//i;
42889
42518
  }
42890
42519
  });
42891
42520
 
@@ -43203,22 +42832,70 @@ function checkMissingFromClient(configs) {
43203
42832
  }
43204
42833
  return issues;
43205
42834
  }
42835
+ function collectServerNameKeys(content, rootKey) {
42836
+ const names = [];
42837
+ let i2 = 0;
42838
+ let depth = 0;
42839
+ let inString = false;
42840
+ let escape2 = false;
42841
+ let rootKeyDepth = -1;
42842
+ let pendingKey = "";
42843
+ let collectingKey = false;
42844
+ while (i2 < content.length) {
42845
+ const c3 = content[i2];
42846
+ if (escape2) {
42847
+ escape2 = false;
42848
+ if (collectingKey) pendingKey += c3;
42849
+ i2++;
42850
+ continue;
42851
+ }
42852
+ if (c3 === "\\" && inString) {
42853
+ escape2 = true;
42854
+ if (collectingKey) pendingKey += c3;
42855
+ i2++;
42856
+ continue;
42857
+ }
42858
+ if (c3 === '"') {
42859
+ if (!inString) {
42860
+ inString = true;
42861
+ collectingKey = true;
42862
+ pendingKey = "";
42863
+ } else {
42864
+ inString = false;
42865
+ let j3 = i2 + 1;
42866
+ while (j3 < content.length && /\s/.test(content[j3])) j3++;
42867
+ if (content[j3] === ":") {
42868
+ if (pendingKey === rootKey && rootKeyDepth === -1) {
42869
+ rootKeyDepth = depth;
42870
+ } else if (rootKeyDepth !== -1 && depth === rootKeyDepth + 1) {
42871
+ names.push(pendingKey);
42872
+ }
42873
+ }
42874
+ collectingKey = false;
42875
+ pendingKey = "";
42876
+ }
42877
+ i2++;
42878
+ continue;
42879
+ }
42880
+ if (inString) {
42881
+ if (collectingKey) pendingKey += c3;
42882
+ i2++;
42883
+ continue;
42884
+ }
42885
+ if (c3 === "{" || c3 === "[") depth++;
42886
+ else if (c3 === "}" || c3 === "]") depth--;
42887
+ i2++;
42888
+ }
42889
+ return names;
42890
+ }
43206
42891
  function checkSingleFileIssues(configs) {
43207
42892
  const issues = [];
43208
42893
  for (const config2 of configs) {
43209
- const nameCount = /* @__PURE__ */ new Map();
43210
- const lines = config2.content.split("\n");
43211
- for (const server2 of config2.servers) {
43212
- const escaped = server2.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
43213
- const pattern = new RegExp(`"${escaped}"\\s*:`, "g");
43214
- let count = 0;
43215
- for (const line of lines) {
43216
- if (pattern.test(line)) count++;
43217
- pattern.lastIndex = 0;
43218
- }
43219
- nameCount.set(server2.name, count);
43220
- }
43221
- for (const [name, count] of nameCount) {
42894
+ if (!config2.actualRootKey) continue;
42895
+ const serverKeys = collectServerNameKeys(config2.content, config2.actualRootKey);
42896
+ const counts = /* @__PURE__ */ new Map();
42897
+ for (const k3 of serverKeys) counts.set(k3, (counts.get(k3) ?? 0) + 1);
42898
+ for (const [name, count] of counts) {
43222
42899
  if (count > 1) {
43223
42900
  issues.push({
43224
42901
  severity: "warning",
@@ -43568,7 +43245,10 @@ var init_session_scanner = __esm({
43568
43245
  });
43569
43246
 
43570
43247
  // src/core/checks/session/missing-secret.ts
43571
- import { resolve as resolve5 } from "node:path";
43248
+ import { resolve as resolve5, basename as basename2 } from "node:path";
43249
+ function normalizePath(p2) {
43250
+ return resolve5(p2).replace(/\\/g, "/").toLowerCase();
43251
+ }
43572
43252
  async function checkMissingSecret(ctx) {
43573
43253
  const issues = [];
43574
43254
  const secrets = [];
@@ -43588,15 +43268,25 @@ async function checkMissingSecret(ctx) {
43588
43268
  byName.get(s.name).add(s.project);
43589
43269
  if (s.repo) byName.get(s.name).add(s.repo);
43590
43270
  }
43591
- const currentNorm = resolve5(ctx.currentProject).replace(/\\/g, "/");
43271
+ const currentNorm = normalizePath(ctx.currentProject);
43272
+ const currentBase = basename2(currentNorm);
43592
43273
  for (const [secretName, projects] of byName) {
43593
- const currentHas = [...projects].some(
43594
- (p2) => p2.includes(currentNorm) || currentNorm.includes(p2.replace(/\\/g, "/")) || p2.includes(resolve5(ctx.currentProject).split(/[/\\]/).pop() || "")
43595
- );
43274
+ const normalizedProjects = [...projects].map(normalizePath);
43275
+ const currentHas = normalizedProjects.some((p2) => {
43276
+ if (p2 === currentNorm) return true;
43277
+ const lastSegment = p2.split("/").pop() || "";
43278
+ return lastSegment === currentBase;
43279
+ });
43596
43280
  if (currentHas) continue;
43597
- const siblingMatches = ctx.siblings.filter(
43598
- (sib) => [...projects].some((p2) => p2.replace(/\\/g, "/").includes(sib.name) || p2.includes(sib.path))
43599
- );
43281
+ const siblingMatches = ctx.siblings.filter((sib) => {
43282
+ const sibNorm = normalizePath(sib.path);
43283
+ const sibBase = basename2(sibNorm);
43284
+ return normalizedProjects.some((p2) => {
43285
+ if (p2 === sibNorm) return true;
43286
+ const lastSegment = p2.split("/").pop() || "";
43287
+ return lastSegment === sibBase;
43288
+ });
43289
+ });
43600
43290
  if (siblingMatches.length >= 2) {
43601
43291
  const sibNames = siblingMatches.map((s) => s.name).join(", ");
43602
43292
  issues.push({
@@ -43753,6 +43443,15 @@ var init_missing_workflow = __esm({
43753
43443
  // src/core/checks/session/stale-memory.ts
43754
43444
  import { existsSync as existsSync4 } from "node:fs";
43755
43445
  import { resolve as resolve6, isAbsolute } from "node:path";
43446
+ function resolveRef2(ref, projectRoot) {
43447
+ if (ref.startsWith("~/") || ref === "~") {
43448
+ const home2 = process.env.HOME || process.env.USERPROFILE;
43449
+ if (!home2) return null;
43450
+ return ref === "~" ? home2 : resolve6(home2, ref.slice(2));
43451
+ }
43452
+ if (isAbsolute(ref)) return ref;
43453
+ return resolve6(projectRoot, ref);
43454
+ }
43756
43455
  async function checkStaleMemory(ctx) {
43757
43456
  const issues = [];
43758
43457
  const projectMemories = ctx.memories.filter(
@@ -43761,7 +43460,8 @@ async function checkStaleMemory(ctx) {
43761
43460
  for (const mem of projectMemories) {
43762
43461
  const brokenPaths = [];
43763
43462
  for (const ref of mem.referencedPaths) {
43764
- const fullPath = isAbsolute(ref) ? ref : resolve6(ctx.currentProject, ref);
43463
+ const fullPath = resolveRef2(ref, ctx.currentProject);
43464
+ if (!fullPath) continue;
43765
43465
  if (!existsSync4(fullPath)) {
43766
43466
  brokenPaths.push(ref);
43767
43467
  }
@@ -44137,7 +43837,7 @@ import { readFileSync as readFileSync4 } from "node:fs";
44137
43837
  import { resolve as resolve8, dirname as dirname3 } from "node:path";
44138
43838
  import { fileURLToPath } from "node:url";
44139
43839
  function loadVersion() {
44140
- if (true) return "0.9.5";
43840
+ if (true) return "0.9.7";
44141
43841
  const __dir = dirname3(fileURLToPath(import.meta.url));
44142
43842
  const pkgPath = resolve8(__dir, "../package.json");
44143
43843
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
@@ -44349,18 +44049,18 @@ async function runAudit(projectRoot, activeChecks, options = {}) {
44349
44049
  }
44350
44050
  var ALL_CHECKS, ALL_MCP_CHECKS, ALL_SESSION_CHECKS;
44351
44051
  var init_audit = __esm({
44352
- async "src/core/audit.ts"() {
44052
+ "src/core/audit.ts"() {
44353
44053
  "use strict";
44354
44054
  init_scanner();
44355
- await init_parser();
44055
+ init_parser();
44356
44056
  init_mcp_parser();
44357
- await init_tokens();
44057
+ init_tokens();
44358
44058
  init_paths();
44359
44059
  init_commands();
44360
44060
  init_staleness();
44361
44061
  init_tokens2();
44362
- await init_tier_tokens();
44363
- await init_redundancy();
44062
+ init_tier_tokens();
44063
+ init_redundancy();
44364
44064
  init_contradictions();
44365
44065
  init_frontmatter();
44366
44066
  init_schema();
@@ -44959,16 +44659,41 @@ import * as fs7 from "node:fs";
44959
44659
  function applyFixes(result, options = {}) {
44960
44660
  const log = options.quiet ? () => {
44961
44661
  } : console.log.bind(console);
44662
+ const dryRun = options.dryRun ?? false;
44663
+ const skipSymlinks = options.skipSymlinks ?? true;
44664
+ const symlinkFiles = /* @__PURE__ */ new Set();
44665
+ if (skipSymlinks) {
44666
+ for (const f of result.files) {
44667
+ if (f.isSymlink) symlinkFiles.add(f.path);
44668
+ }
44669
+ }
44962
44670
  const fixesByFile = /* @__PURE__ */ new Map();
44671
+ const dedupeKeys = /* @__PURE__ */ new Map();
44672
+ const skippedSymlinks = /* @__PURE__ */ new Set();
44963
44673
  for (const file2 of result.files) {
44964
44674
  for (const issue2 of file2.issues) {
44965
44675
  if (issue2.fix) {
44676
+ if (skipSymlinks && file2.isSymlink) {
44677
+ skippedSymlinks.add(file2.path);
44678
+ continue;
44679
+ }
44680
+ const key = `${issue2.fix.line}:${issue2.fix.oldText}:${issue2.fix.newText}`;
44681
+ let seenInFile = dedupeKeys.get(issue2.fix.file);
44682
+ if (!seenInFile) {
44683
+ seenInFile = /* @__PURE__ */ new Set();
44684
+ dedupeKeys.set(issue2.fix.file, seenInFile);
44685
+ }
44686
+ if (seenInFile.has(key)) continue;
44687
+ seenInFile.add(key);
44966
44688
  const existing = fixesByFile.get(issue2.fix.file) || [];
44967
44689
  existing.push(issue2.fix);
44968
44690
  fixesByFile.set(issue2.fix.file, existing);
44969
44691
  }
44970
44692
  }
44971
44693
  }
44694
+ for (const p2 of skippedSymlinks) {
44695
+ log(source_default.yellow(" Skipped") + ` ${p2}: symlink (use --follow-symlinks to override)`);
44696
+ }
44972
44697
  let totalFixes = 0;
44973
44698
  const filesModified = [];
44974
44699
  for (const [filePath, fixes] of fixesByFile) {
@@ -44990,8 +44715,9 @@ function applyFixes(result, options = {}) {
44990
44715
  if (line.includes(fix.oldText)) {
44991
44716
  line = line.replace(fix.oldText, fix.newText);
44992
44717
  totalFixes++;
44718
+ const prefix = dryRun ? source_default.cyan(" Would fix") : source_default.green(" Fixed");
44993
44719
  log(
44994
- source_default.green(" Fixed") + ` Line ${fix.line}: ${source_default.dim(fix.oldText)} ${source_default.dim("\u2192")} ${fix.newText}`
44720
+ prefix + ` Line ${fix.line}: ${source_default.dim(fix.oldText)} ${source_default.dim("\u2192")} ${fix.newText}`
44995
44721
  );
44996
44722
  }
44997
44723
  }
@@ -45010,7 +44736,9 @@ function applyFixes(result, options = {}) {
45010
44736
  continue;
45011
44737
  }
45012
44738
  }
45013
- fs7.writeFileSync(filePath, newContent, "utf-8");
44739
+ if (!dryRun) {
44740
+ fs7.writeFileSync(filePath, newContent, "utf-8");
44741
+ }
45014
44742
  filesModified.push(filePath);
45015
44743
  }
45016
44744
  }
@@ -45034,12 +44762,12 @@ var init_server3 = __esm({
45034
44762
  init_stdio2();
45035
44763
  init_zod();
45036
44764
  init_scanner();
45037
- await init_parser();
45038
- await init_audit();
44765
+ init_parser();
44766
+ init_audit();
45039
44767
  init_fixer();
45040
44768
  init_fs();
45041
44769
  init_git();
45042
- await init_tokens();
44770
+ init_tokens();
45043
44771
  init_git();
45044
44772
  init_paths();
45045
44773
  init_version2();
@@ -51968,6 +51696,13 @@ function buildRuleDescriptors() {
51968
51696
  shortDescription: { text: "Context file token usage" },
51969
51697
  helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51970
51698
  },
51699
+ {
51700
+ id: "ctxlint/tier-tokens",
51701
+ shortDescription: {
51702
+ text: "Tier-aware token accounting for always-loaded context files"
51703
+ },
51704
+ helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51705
+ },
51971
51706
  {
51972
51707
  id: "ctxlint/redundancy",
51973
51708
  shortDescription: { text: "Content is redundant or inferable" },
@@ -52062,6 +51797,13 @@ function buildRuleDescriptors() {
52062
51797
  id: "ctxlint/session-loop-detection",
52063
51798
  shortDescription: { text: "Agent looping pattern detected in session history" },
52064
51799
  helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51800
+ },
51801
+ {
51802
+ id: "ctxlint/session-memory-index-overflow",
51803
+ shortDescription: {
51804
+ text: "MEMORY.md exceeds Claude Code's 200-line / 25KB session-load cap"
51805
+ },
51806
+ helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
52065
51807
  }
52066
51808
  ];
52067
51809
  }
@@ -52089,6 +51831,76 @@ var init_reporter = __esm({
52089
51831
  // src/core/config.ts
52090
51832
  import * as fs8 from "node:fs";
52091
51833
  import * as path10 from "node:path";
51834
+ function formatJsonError(content, err) {
51835
+ const msg = err instanceof Error ? err.message : String(err);
51836
+ const posMatch = msg.match(/position (\d+)/);
51837
+ if (posMatch) {
51838
+ return `${msg} (${posToLineCol(content, Number(posMatch[1]))})`;
51839
+ }
51840
+ if (/line \d+/.test(msg)) return msg;
51841
+ const pos = findFirstErrorPos(content, msg);
51842
+ if (pos !== null) {
51843
+ return `${msg} (${posToLineCol(content, pos)})`;
51844
+ }
51845
+ return msg;
51846
+ }
51847
+ function posToLineCol(content, pos) {
51848
+ let line = 1;
51849
+ let col = 1;
51850
+ for (let i2 = 0; i2 < pos && i2 < content.length; i2++) {
51851
+ if (content[i2] === "\n") {
51852
+ line++;
51853
+ col = 1;
51854
+ } else {
51855
+ col++;
51856
+ }
51857
+ }
51858
+ return `line ${line}, column ${col}`;
51859
+ }
51860
+ function findFirstErrorPos(content, errMsg) {
51861
+ const snippetMatch = errMsg.match(/\.\.\."([^"]+(?:"[^"]*)*?)"\s+is not valid JSON/);
51862
+ if (snippetMatch) {
51863
+ const snippet = snippetMatch[1];
51864
+ const needle = snippet.split(/\s/).find((s) => s.length > 1);
51865
+ if (needle) {
51866
+ const idx = content.indexOf(needle);
51867
+ if (idx !== -1) return idx;
51868
+ }
51869
+ }
51870
+ const tokenMatch = errMsg.match(/Unexpected token\s+['"]?([^'",]+?)['"]?,/);
51871
+ if (tokenMatch) {
51872
+ const tok = tokenMatch[1];
51873
+ const idx = content.indexOf(tok);
51874
+ if (idx !== -1) return idx;
51875
+ }
51876
+ return null;
51877
+ }
51878
+ function suggestKey(unknown2) {
51879
+ let best = null;
51880
+ let bestDist = Infinity;
51881
+ for (const known of KNOWN_CONFIG_KEYS) {
51882
+ const d = levenshtein2(unknown2, known);
51883
+ if (d < bestDist) {
51884
+ bestDist = d;
51885
+ best = known;
51886
+ }
51887
+ }
51888
+ if (best && bestDist <= Math.max(2, Math.floor(unknown2.length / 3))) {
51889
+ return best;
51890
+ }
51891
+ return null;
51892
+ }
51893
+ function warnUnknownKeys(config2, source) {
51894
+ if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) return;
51895
+ const keys = Object.keys(config2);
51896
+ const known = new Set(KNOWN_CONFIG_KEYS);
51897
+ for (const k3 of keys) {
51898
+ if (known.has(k3)) continue;
51899
+ const hint = suggestKey(k3);
51900
+ const suggestion = hint ? ` \u2014 did you mean "${hint}"?` : "";
51901
+ console.error(`Warning: unknown config key "${k3}" in ${source}${suggestion}`);
51902
+ }
51903
+ }
52092
51904
  function loadConfig(projectRoot) {
52093
51905
  for (const filename of CONFIG_FILENAMES) {
52094
51906
  const filePath = path10.join(projectRoot, filename);
@@ -52098,19 +51910,39 @@ function loadConfig(projectRoot) {
52098
51910
  } catch {
52099
51911
  continue;
52100
51912
  }
51913
+ let parsed;
52101
51914
  try {
52102
- return JSON.parse(content);
51915
+ parsed = JSON.parse(content);
52103
51916
  } catch (err) {
52104
- const msg = err instanceof Error ? err.message : String(err);
52105
- throw new Error(`Invalid JSON in ${filePath}: ${msg}`, { cause: err });
51917
+ throw new Error(`Invalid JSON in ${filePath}: ${formatJsonError(content, err)}`, {
51918
+ cause: err
51919
+ });
52106
51920
  }
51921
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
51922
+ throw new Error(
51923
+ `Invalid config in ${filePath}: expected a JSON object at the root, got ${Array.isArray(parsed) ? "an array" : typeof parsed}`
51924
+ );
51925
+ }
51926
+ warnUnknownKeys(parsed, filePath);
51927
+ return parsed;
52107
51928
  }
52108
51929
  return null;
52109
51930
  }
52110
- var CONFIG_FILENAMES;
51931
+ var import_fast_levenshtein2, levenshtein2, KNOWN_CONFIG_KEYS, CONFIG_FILENAMES;
52111
51932
  var init_config2 = __esm({
52112
51933
  "src/core/config.ts"() {
52113
51934
  "use strict";
51935
+ import_fast_levenshtein2 = __toESM(require_levenshtein(), 1);
51936
+ levenshtein2 = import_fast_levenshtein2.default.get;
51937
+ KNOWN_CONFIG_KEYS = [
51938
+ "checks",
51939
+ "ignore",
51940
+ "strict",
51941
+ "tokenThresholds",
51942
+ "contextFiles",
51943
+ "mcp",
51944
+ "mcpGlobal"
51945
+ ];
52114
51946
  CONFIG_FILENAMES = [".ctxlintrc", ".ctxlintrc.json"];
52115
51947
  }
52116
51948
  });
@@ -52139,7 +51971,7 @@ async function runCli() {
52139
51971
  "Lint your AI agent context files and MCP server configs against your actual codebase"
52140
51972
  ).version(VERSION).argument("[path]", "Project directory to scan", ".").option("--strict", "Exit code 1 on any warning or error (for CI)", false).option("--checks <checks>", "Comma-separated list of checks to run", "").addOption(
52141
51973
  new Option("--format <format>", "Output format: text, json, or sarif").choices(["text", "json", "sarif"]).default("text")
52142
- ).option("--tokens", "Show token breakdown per file", false).option("--verbose", "Show passing checks too", false).option("--fix", "Auto-fix broken paths using git history and fuzzy matching", false).option("--ignore <checks>", "Comma-separated list of checks to ignore", "").option("--quiet", "Suppress all output except errors (exit code only)", false).option("--config <path>", "Path to config file (default: .ctxlintrc in project root)").option("--depth <n>", "Max subdirectory depth to scan (default: 2)", "2").option("--mcp", "Enable MCP config linting alongside context file checks", false).option("--mcp-only", "Run only MCP config checks, skip context file checks", false).option("--mcp-global", "Also scan user/global MCP config files (implies --mcp)", false).option("--mcp-server", "Start the MCP server (for IDE/agent integration)").option("--session", "Run session audit checks (cross-project consistency)", false).option("--session-only", "Run only session checks, skip context and MCP checks", false).option("--watch", "Re-lint on context file changes", false).action(async (projectPath, opts) => {
51974
+ ).option("--tokens", "Show token breakdown per file", false).option("--verbose", "Show passing checks too", false).option("--fix", "Auto-fix broken paths using git history and fuzzy matching", false).option("--fix-dry-run", "Preview --fix changes without writing", false).option("--yes", "Skip interactive confirmation prompts (required for --fix in TTY)", false).option("--follow-symlinks", "Allow --fix to write through symlinks (default: skip)", false).option("--ignore <checks>", "Comma-separated list of checks to ignore", "").option("--quiet", "Suppress all output except errors (exit code only)", false).option("--config <path>", "Path to config file (default: .ctxlintrc in project root)").option("--depth <n>", "Max subdirectory depth to scan (default: 2)", "2").option("--mcp", "Enable MCP config linting alongside context file checks", false).option("--mcp-only", "Run only MCP config checks, skip context file checks", false).option("--mcp-global", "Also scan user/global MCP config files (implies --mcp)", false).option("--mcp-server", "Start the MCP server (for IDE/agent integration)").option("--session", "Run session audit checks (cross-project consistency)", false).option("--session-only", "Run only session checks, skip context and MCP checks", false).option("--watch", "Re-lint on context file changes", false).action(async (projectPath, opts) => {
52143
51975
  const resolvedPath = path11.resolve(projectPath);
52144
51976
  const configPath = opts.config ? path11.resolve(opts.config) : void 0;
52145
51977
  const config2 = configPath ? loadConfigFromPath(configPath) : loadConfig(resolvedPath);
@@ -52221,14 +52053,59 @@ async function runCli() {
52221
52053
  }
52222
52054
  if (!opts.watch) return;
52223
52055
  }
52224
- if (options.fix) {
52225
- const fixSummary = applyFixes(result, { quiet: options.quiet });
52226
- if (fixSummary.totalFixes > 0 && !options.quiet) {
52227
- console.log(
52228
- `
52229
- Fixed ${fixSummary.totalFixes} issue${fixSummary.totalFixes !== 1 ? "s" : ""} in ${fixSummary.filesModified.length} file${fixSummary.filesModified.length !== 1 ? "s" : ""}.
52056
+ const dryRunFlag = opts.fixDryRun || false;
52057
+ const yes = opts.yes || false;
52058
+ const followSymlinks = opts.followSymlinks || false;
52059
+ const isInteractive2 = !!process.stdout.isTTY && !options.quiet;
52060
+ if (dryRunFlag || options.fix) {
52061
+ const commonOpts = { quiet: options.quiet, skipSymlinks: !followSymlinks };
52062
+ if (dryRunFlag) {
52063
+ const preview = applyFixes(result, { ...commonOpts, dryRun: true });
52064
+ if (!options.quiet) {
52065
+ if (preview.totalFixes === 0) {
52066
+ console.log("\nNo auto-fixable issues.\n");
52067
+ } else {
52068
+ console.log(
52069
+ `
52070
+ Would fix ${preview.totalFixes} issue${preview.totalFixes !== 1 ? "s" : ""} in ${preview.filesModified.length} file${preview.filesModified.length !== 1 ? "s" : ""}. (dry-run \u2014 no files modified)
52230
52071
  `
52231
- );
52072
+ );
52073
+ }
52074
+ }
52075
+ } else if (options.fix) {
52076
+ if (isInteractive2 && !yes) {
52077
+ const preview = applyFixes(result, { ...commonOpts, dryRun: true });
52078
+ if (preview.totalFixes === 0) {
52079
+ console.log("\nNo auto-fixable issues.\n");
52080
+ } else {
52081
+ console.log(
52082
+ `
52083
+ ${preview.totalFixes} fix${preview.totalFixes !== 1 ? "es" : ""} proposed across ${preview.filesModified.length} file${preview.filesModified.length !== 1 ? "s" : ""}.`
52084
+ );
52085
+ const confirmed = await promptYesNo(
52086
+ "Apply these fixes? Re-run with --yes to skip this prompt. [y/N] "
52087
+ );
52088
+ if (!confirmed) {
52089
+ console.log("Aborted. No files modified.\n");
52090
+ } else {
52091
+ const applied = applyFixes(result, commonOpts);
52092
+ console.log(
52093
+ `
52094
+ Fixed ${applied.totalFixes} issue${applied.totalFixes !== 1 ? "s" : ""} in ${applied.filesModified.length} file${applied.filesModified.length !== 1 ? "s" : ""}.
52095
+ `
52096
+ );
52097
+ }
52098
+ }
52099
+ } else {
52100
+ const applied = applyFixes(result, commonOpts);
52101
+ if (applied.totalFixes > 0 && !options.quiet) {
52102
+ console.log(
52103
+ `
52104
+ Fixed ${applied.totalFixes} issue${applied.totalFixes !== 1 ? "s" : ""} in ${applied.filesModified.length} file${applied.filesModified.length !== 1 ? "s" : ""}.
52105
+ `
52106
+ );
52107
+ }
52108
+ }
52232
52109
  }
52233
52110
  }
52234
52111
  if (!options.quiet) {
@@ -52380,6 +52257,16 @@ npx @yawlabs/ctxlint --strict
52380
52257
  });
52381
52258
  program2.parse();
52382
52259
  }
52260
+ async function promptYesNo(question) {
52261
+ const { createInterface: createInterface2 } = await import("node:readline/promises");
52262
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
52263
+ try {
52264
+ const answer = await rl.question(question);
52265
+ return /^\s*y(es)?\s*$/i.test(answer);
52266
+ } finally {
52267
+ rl.close();
52268
+ }
52269
+ }
52383
52270
  function loadConfigFromPath(configPath) {
52384
52271
  try {
52385
52272
  const content = fs9.readFileSync(configPath, "utf-8");
@@ -52392,7 +52279,7 @@ function loadConfigFromPath(configPath) {
52392
52279
  }
52393
52280
  var VALID_CHECKS;
52394
52281
  var init_cli = __esm({
52395
- async "src/cli.ts"() {
52282
+ "src/cli.ts"() {
52396
52283
  "use strict";
52397
52284
  init_esm3();
52398
52285
  init_ora();
@@ -52400,11 +52287,11 @@ var init_cli = __esm({
52400
52287
  init_tokens2();
52401
52288
  init_reporter();
52402
52289
  init_fixer();
52403
- await init_tokens();
52290
+ init_tokens();
52404
52291
  init_git();
52405
52292
  init_fs();
52406
52293
  init_config2();
52407
- await init_audit();
52294
+ init_audit();
52408
52295
  init_version2();
52409
52296
  VALID_CHECKS = /* @__PURE__ */ new Set([...ALL_CHECKS, ...ALL_MCP_CHECKS, ...ALL_SESSION_CHECKS]);
52410
52297
  }
@@ -52414,7 +52301,7 @@ var init_cli = __esm({
52414
52301
  if (process.argv.includes("--mcp-server")) {
52415
52302
  await init_server3().then(() => server_exports);
52416
52303
  } else {
52417
- const { runCli: runCli2 } = await init_cli().then(() => cli_exports);
52304
+ const { runCli: runCli2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
52418
52305
  await runCli2();
52419
52306
  }
52420
52307
  //# sourceMappingURL=index.js.map