@yawlabs/ctxlint 0.9.5 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +253 -536
  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;
@@ -34482,473 +34482,28 @@ var init_scanner = __esm({
34482
34482
  }
34483
34483
  });
34484
34484
 
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
34485
  // src/utils/tokens.ts
34945
- function getEncoder() {
34946
- if (!encoder && encodingForModel) {
34947
- encoder = encodingForModel("gpt-4");
34486
+ import { createRequire } from "node:module";
34487
+ function loadEncodingForModel() {
34488
+ if (loadAttempted) return encodingForModel;
34489
+ loadAttempted = true;
34490
+ try {
34491
+ const req = createRequire(import.meta.url);
34492
+ const tiktoken = req("tiktoken");
34493
+ encodingForModel = tiktoken.encoding_for_model;
34494
+ } catch {
34948
34495
  }
34496
+ return encodingForModel;
34497
+ }
34498
+ function getEncoder() {
34499
+ if (encoder) return encoder;
34500
+ const loader = loadEncodingForModel();
34501
+ if (!loader) return null;
34502
+ encoder = loader("gpt-4");
34949
34503
  return encoder;
34950
34504
  }
34951
34505
  function countTokens(text) {
34506
+ if (!text) return 0;
34952
34507
  const enc = getEncoder();
34953
34508
  if (!enc) {
34954
34509
  return Math.ceil(text.length / 4);
@@ -34968,16 +34523,12 @@ function freeEncoder() {
34968
34523
  function keepEncoderAlive(keep) {
34969
34524
  _keepAlive = keep;
34970
34525
  }
34971
- var encodingForModel, encoder, _keepAlive;
34526
+ var encodingForModel, loadAttempted, encoder, _keepAlive;
34972
34527
  var init_tokens = __esm({
34973
- async "src/utils/tokens.ts"() {
34528
+ "src/utils/tokens.ts"() {
34974
34529
  "use strict";
34975
34530
  encodingForModel = null;
34976
- try {
34977
- const tiktoken = await Promise.resolve().then(() => __toESM(require_tiktoken(), 1));
34978
- encodingForModel = tiktoken.encoding_for_model;
34979
- } catch {
34980
- }
34531
+ loadAttempted = false;
34981
34532
  encoder = null;
34982
34533
  _keepAlive = false;
34983
34534
  }
@@ -35067,6 +34618,10 @@ function extractPathReferences(lines, sections) {
35067
34618
  if (PATH_EXCLUDE.test(value)) continue;
35068
34619
  if (value.length < 3) continue;
35069
34620
  if (/^v?\d+\.\d+\//.test(value)) continue;
34621
+ if (/^\d+\/\d+$/.test(value)) continue;
34622
+ if (/^[A-Z][\w.-]*\/[A-Z][\w.-]*$/.test(value) && !value.includes(".")) {
34623
+ continue;
34624
+ }
35070
34625
  const column = match.index + match[0].length - match[1].length + 1;
35071
34626
  paths.push({
35072
34627
  value,
@@ -35171,10 +34726,10 @@ function extractCommandReferences(lines, sections) {
35171
34726
  }
35172
34727
  var PATH_PATTERN, PATH_EXCLUDE, COMMAND_PREFIXES, COMMON_COMMANDS;
35173
34728
  var init_parser = __esm({
35174
- async "src/core/parser.ts"() {
34729
+ "src/core/parser.ts"() {
35175
34730
  "use strict";
35176
34731
  init_fs();
35177
- await init_tokens();
34732
+ init_tokens();
35178
34733
  PATH_PATTERN = /(?:^|[\s`"'(])((\.{0,2}\/)?(?:[\w@.-]+\/)+[\w.*-]*(?:\.\w+)?)(?=[\s`"'),;:]|$)/gm;
35179
34734
  PATH_EXCLUDE = /^(https?:\/\/|ftp:\/\/|mailto:|n\/a|w\/o|I\/O|i\/o|e\.g\.|N\/A|\.deb\/|\.rpm[.\/]|\.tar[.\/]|\.zip[.\/])/i;
35180
34735
  COMMAND_PREFIXES = /^\s*[\$>]\s+(.+)$/;
@@ -41785,8 +41340,8 @@ function isAlwaysLoaded(file2) {
41785
41340
  if (rel.includes("/rules/")) {
41786
41341
  return !hasPathsFrontmatter(file2.content);
41787
41342
  }
41788
- const basename2 = rel.split("/").pop() ?? "";
41789
- return ALWAYS_LOADED_BASENAMES.has(basename2);
41343
+ const basename3 = rel.split("/").pop() ?? "";
41344
+ return ALWAYS_LOADED_BASENAMES.has(basename3);
41790
41345
  }
41791
41346
  function computeSectionCosts(file2) {
41792
41347
  if (file2.sections.length === 0) return [];
@@ -41814,16 +41369,21 @@ function loadSettingsSources(projectRoot) {
41814
41369
  }
41815
41370
  return sources;
41816
41371
  }
41372
+ function canonicalizeCommand(backticked) {
41373
+ const beforeFlags = backticked.trim().split(/\s+--?/, 1)[0];
41374
+ return beforeFlags.replace(/\s+/g, " ");
41375
+ }
41817
41376
  function commandIsEnforced(cmd, settings) {
41818
- const lower = cmd.toLowerCase();
41377
+ const escaped = cmd.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
41378
+ const pattern = new RegExp(`\\b${escaped}\\b`, "i");
41819
41379
  for (const s of settings) {
41820
41380
  for (const entry of s.permissions?.deny ?? []) {
41821
- if (entry.toLowerCase().includes(lower)) return true;
41381
+ if (pattern.test(entry)) return true;
41822
41382
  }
41823
41383
  for (const h2 of s.hooks?.PreToolUse ?? []) {
41824
- if ((h2.matcher || "").toLowerCase().includes(lower)) return true;
41384
+ if (pattern.test(h2.matcher || "")) return true;
41825
41385
  for (const sub of h2.hooks ?? []) {
41826
- if ((sub.command || "").toLowerCase().includes(lower)) return true;
41386
+ if (pattern.test(sub.command || "")) return true;
41827
41387
  }
41828
41388
  }
41829
41389
  }
@@ -41834,10 +41394,9 @@ function checkHardEnforcement(file2, settings) {
41834
41394
  const lines = file2.content.split("\n");
41835
41395
  for (let i2 = 0; i2 < lines.length; i2++) {
41836
41396
  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("/"));
41397
+ const match = line.match(INVIOLABLE_WITH_COMMAND);
41398
+ if (!match) continue;
41399
+ const cmd = canonicalizeCommand(match[2]);
41841
41400
  if (!cmd) continue;
41842
41401
  if (commandIsEnforced(cmd, settings)) continue;
41843
41402
  issues.push({
@@ -41846,7 +41405,7 @@ function checkHardEnforcement(file2, settings) {
41846
41405
  ruleId: "tier-tokens/hard-enforcement-missing",
41847
41406
  line: i2 + 1,
41848
41407
  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.`
41408
+ 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
41409
  });
41851
41410
  }
41852
41411
  return issues;
@@ -41894,11 +41453,11 @@ function checkAggregateTierTokens(files) {
41894
41453
  suggestion: "Consider moving the largest files or their heaviest sections to on-demand tiers (skills, subagents, memory)."
41895
41454
  };
41896
41455
  }
41897
- var ALWAYS_LOADED_BASENAMES, TOP_SECTIONS_TO_REPORT, INVIOLABLE_FRAMING, COMMAND_IN_BACKTICKS;
41456
+ var ALWAYS_LOADED_BASENAMES, TOP_SECTIONS_TO_REPORT, INVIOLABLE_WITH_COMMAND;
41898
41457
  var init_tier_tokens = __esm({
41899
- async "src/core/checks/tier-tokens.ts"() {
41458
+ "src/core/checks/tier-tokens.ts"() {
41900
41459
  "use strict";
41901
- await init_tokens();
41460
+ init_tokens();
41902
41461
  init_tokens2();
41903
41462
  ALWAYS_LOADED_BASENAMES = /* @__PURE__ */ new Set([
41904
41463
  "CLAUDE.md",
@@ -41920,8 +41479,7 @@ var init_tier_tokens = __esm({
41920
41479
  "instructions.md"
41921
41480
  ]);
41922
41481
  TOP_SECTIONS_TO_REPORT = 3;
41923
- INVIOLABLE_FRAMING = /\b(NEVER|ALWAYS|DON'?T|DO NOT|MUST NOT)\b/i;
41924
- COMMAND_IN_BACKTICKS = /`([^`]+)`/g;
41482
+ INVIOLABLE_WITH_COMMAND = /\b(NEVER|ALWAYS|DON'?T|DO NOT|MUST NOT)\b[^.!?`]{0,80}`([^`]+)`/i;
41925
41483
  }
41926
41484
  });
41927
41485
 
@@ -42044,10 +41602,10 @@ function escapeRegex2(str) {
42044
41602
  }
42045
41603
  var PACKAGE_TECH_MAP;
42046
41604
  var init_redundancy = __esm({
42047
- async "src/core/checks/redundancy.ts"() {
41605
+ "src/core/checks/redundancy.ts"() {
42048
41606
  "use strict";
42049
41607
  init_fs();
42050
- await init_tokens();
41608
+ init_tokens();
42051
41609
  PACKAGE_TECH_MAP = {
42052
41610
  react: ["React", "react"],
42053
41611
  "react-dom": ["React DOM", "ReactDOM"],
@@ -43203,22 +42761,70 @@ function checkMissingFromClient(configs) {
43203
42761
  }
43204
42762
  return issues;
43205
42763
  }
42764
+ function collectServerNameKeys(content, rootKey) {
42765
+ const names = [];
42766
+ let i2 = 0;
42767
+ let depth = 0;
42768
+ let inString = false;
42769
+ let escape2 = false;
42770
+ let rootKeyDepth = -1;
42771
+ let pendingKey = "";
42772
+ let collectingKey = false;
42773
+ while (i2 < content.length) {
42774
+ const c3 = content[i2];
42775
+ if (escape2) {
42776
+ escape2 = false;
42777
+ if (collectingKey) pendingKey += c3;
42778
+ i2++;
42779
+ continue;
42780
+ }
42781
+ if (c3 === "\\" && inString) {
42782
+ escape2 = true;
42783
+ if (collectingKey) pendingKey += c3;
42784
+ i2++;
42785
+ continue;
42786
+ }
42787
+ if (c3 === '"') {
42788
+ if (!inString) {
42789
+ inString = true;
42790
+ collectingKey = true;
42791
+ pendingKey = "";
42792
+ } else {
42793
+ inString = false;
42794
+ let j3 = i2 + 1;
42795
+ while (j3 < content.length && /\s/.test(content[j3])) j3++;
42796
+ if (content[j3] === ":") {
42797
+ if (pendingKey === rootKey && rootKeyDepth === -1) {
42798
+ rootKeyDepth = depth;
42799
+ } else if (rootKeyDepth !== -1 && depth === rootKeyDepth + 1) {
42800
+ names.push(pendingKey);
42801
+ }
42802
+ }
42803
+ collectingKey = false;
42804
+ pendingKey = "";
42805
+ }
42806
+ i2++;
42807
+ continue;
42808
+ }
42809
+ if (inString) {
42810
+ if (collectingKey) pendingKey += c3;
42811
+ i2++;
42812
+ continue;
42813
+ }
42814
+ if (c3 === "{" || c3 === "[") depth++;
42815
+ else if (c3 === "}" || c3 === "]") depth--;
42816
+ i2++;
42817
+ }
42818
+ return names;
42819
+ }
43206
42820
  function checkSingleFileIssues(configs) {
43207
42821
  const issues = [];
43208
42822
  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) {
42823
+ if (!config2.actualRootKey) continue;
42824
+ const serverKeys = collectServerNameKeys(config2.content, config2.actualRootKey);
42825
+ const counts = /* @__PURE__ */ new Map();
42826
+ for (const k3 of serverKeys) counts.set(k3, (counts.get(k3) ?? 0) + 1);
42827
+ for (const [name, count] of counts) {
43222
42828
  if (count > 1) {
43223
42829
  issues.push({
43224
42830
  severity: "warning",
@@ -43568,7 +43174,10 @@ var init_session_scanner = __esm({
43568
43174
  });
43569
43175
 
43570
43176
  // src/core/checks/session/missing-secret.ts
43571
- import { resolve as resolve5 } from "node:path";
43177
+ import { resolve as resolve5, basename as basename2 } from "node:path";
43178
+ function normalizePath(p2) {
43179
+ return resolve5(p2).replace(/\\/g, "/").toLowerCase();
43180
+ }
43572
43181
  async function checkMissingSecret(ctx) {
43573
43182
  const issues = [];
43574
43183
  const secrets = [];
@@ -43588,15 +43197,25 @@ async function checkMissingSecret(ctx) {
43588
43197
  byName.get(s.name).add(s.project);
43589
43198
  if (s.repo) byName.get(s.name).add(s.repo);
43590
43199
  }
43591
- const currentNorm = resolve5(ctx.currentProject).replace(/\\/g, "/");
43200
+ const currentNorm = normalizePath(ctx.currentProject);
43201
+ const currentBase = basename2(currentNorm);
43592
43202
  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
- );
43203
+ const normalizedProjects = [...projects].map(normalizePath);
43204
+ const currentHas = normalizedProjects.some((p2) => {
43205
+ if (p2 === currentNorm) return true;
43206
+ const lastSegment = p2.split("/").pop() || "";
43207
+ return lastSegment === currentBase;
43208
+ });
43596
43209
  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
- );
43210
+ const siblingMatches = ctx.siblings.filter((sib) => {
43211
+ const sibNorm = normalizePath(sib.path);
43212
+ const sibBase = basename2(sibNorm);
43213
+ return normalizedProjects.some((p2) => {
43214
+ if (p2 === sibNorm) return true;
43215
+ const lastSegment = p2.split("/").pop() || "";
43216
+ return lastSegment === sibBase;
43217
+ });
43218
+ });
43600
43219
  if (siblingMatches.length >= 2) {
43601
43220
  const sibNames = siblingMatches.map((s) => s.name).join(", ");
43602
43221
  issues.push({
@@ -43753,6 +43372,15 @@ var init_missing_workflow = __esm({
43753
43372
  // src/core/checks/session/stale-memory.ts
43754
43373
  import { existsSync as existsSync4 } from "node:fs";
43755
43374
  import { resolve as resolve6, isAbsolute } from "node:path";
43375
+ function resolveRef2(ref, projectRoot) {
43376
+ if (ref.startsWith("~/") || ref === "~") {
43377
+ const home2 = process.env.HOME || process.env.USERPROFILE;
43378
+ if (!home2) return null;
43379
+ return ref === "~" ? home2 : resolve6(home2, ref.slice(2));
43380
+ }
43381
+ if (isAbsolute(ref)) return ref;
43382
+ return resolve6(projectRoot, ref);
43383
+ }
43756
43384
  async function checkStaleMemory(ctx) {
43757
43385
  const issues = [];
43758
43386
  const projectMemories = ctx.memories.filter(
@@ -43761,7 +43389,8 @@ async function checkStaleMemory(ctx) {
43761
43389
  for (const mem of projectMemories) {
43762
43390
  const brokenPaths = [];
43763
43391
  for (const ref of mem.referencedPaths) {
43764
- const fullPath = isAbsolute(ref) ? ref : resolve6(ctx.currentProject, ref);
43392
+ const fullPath = resolveRef2(ref, ctx.currentProject);
43393
+ if (!fullPath) continue;
43765
43394
  if (!existsSync4(fullPath)) {
43766
43395
  brokenPaths.push(ref);
43767
43396
  }
@@ -44137,7 +43766,7 @@ import { readFileSync as readFileSync4 } from "node:fs";
44137
43766
  import { resolve as resolve8, dirname as dirname3 } from "node:path";
44138
43767
  import { fileURLToPath } from "node:url";
44139
43768
  function loadVersion() {
44140
- if (true) return "0.9.5";
43769
+ if (true) return "0.9.6";
44141
43770
  const __dir = dirname3(fileURLToPath(import.meta.url));
44142
43771
  const pkgPath = resolve8(__dir, "../package.json");
44143
43772
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
@@ -44349,18 +43978,18 @@ async function runAudit(projectRoot, activeChecks, options = {}) {
44349
43978
  }
44350
43979
  var ALL_CHECKS, ALL_MCP_CHECKS, ALL_SESSION_CHECKS;
44351
43980
  var init_audit = __esm({
44352
- async "src/core/audit.ts"() {
43981
+ "src/core/audit.ts"() {
44353
43982
  "use strict";
44354
43983
  init_scanner();
44355
- await init_parser();
43984
+ init_parser();
44356
43985
  init_mcp_parser();
44357
- await init_tokens();
43986
+ init_tokens();
44358
43987
  init_paths();
44359
43988
  init_commands();
44360
43989
  init_staleness();
44361
43990
  init_tokens2();
44362
- await init_tier_tokens();
44363
- await init_redundancy();
43991
+ init_tier_tokens();
43992
+ init_redundancy();
44364
43993
  init_contradictions();
44365
43994
  init_frontmatter();
44366
43995
  init_schema();
@@ -44959,16 +44588,32 @@ import * as fs7 from "node:fs";
44959
44588
  function applyFixes(result, options = {}) {
44960
44589
  const log = options.quiet ? () => {
44961
44590
  } : console.log.bind(console);
44591
+ const dryRun = options.dryRun ?? false;
44592
+ const skipSymlinks = options.skipSymlinks ?? true;
44593
+ const symlinkFiles = /* @__PURE__ */ new Set();
44594
+ if (skipSymlinks) {
44595
+ for (const f of result.files) {
44596
+ if (f.isSymlink) symlinkFiles.add(f.path);
44597
+ }
44598
+ }
44962
44599
  const fixesByFile = /* @__PURE__ */ new Map();
44600
+ const skippedSymlinks = /* @__PURE__ */ new Set();
44963
44601
  for (const file2 of result.files) {
44964
44602
  for (const issue2 of file2.issues) {
44965
44603
  if (issue2.fix) {
44604
+ if (skipSymlinks && file2.isSymlink) {
44605
+ skippedSymlinks.add(file2.path);
44606
+ continue;
44607
+ }
44966
44608
  const existing = fixesByFile.get(issue2.fix.file) || [];
44967
44609
  existing.push(issue2.fix);
44968
44610
  fixesByFile.set(issue2.fix.file, existing);
44969
44611
  }
44970
44612
  }
44971
44613
  }
44614
+ for (const p2 of skippedSymlinks) {
44615
+ log(source_default.yellow(" Skipped") + ` ${p2}: symlink (use --follow-symlinks to override)`);
44616
+ }
44972
44617
  let totalFixes = 0;
44973
44618
  const filesModified = [];
44974
44619
  for (const [filePath, fixes] of fixesByFile) {
@@ -44990,8 +44635,9 @@ function applyFixes(result, options = {}) {
44990
44635
  if (line.includes(fix.oldText)) {
44991
44636
  line = line.replace(fix.oldText, fix.newText);
44992
44637
  totalFixes++;
44638
+ const prefix = dryRun ? source_default.cyan(" Would fix") : source_default.green(" Fixed");
44993
44639
  log(
44994
- source_default.green(" Fixed") + ` Line ${fix.line}: ${source_default.dim(fix.oldText)} ${source_default.dim("\u2192")} ${fix.newText}`
44640
+ prefix + ` Line ${fix.line}: ${source_default.dim(fix.oldText)} ${source_default.dim("\u2192")} ${fix.newText}`
44995
44641
  );
44996
44642
  }
44997
44643
  }
@@ -45010,7 +44656,9 @@ function applyFixes(result, options = {}) {
45010
44656
  continue;
45011
44657
  }
45012
44658
  }
45013
- fs7.writeFileSync(filePath, newContent, "utf-8");
44659
+ if (!dryRun) {
44660
+ fs7.writeFileSync(filePath, newContent, "utf-8");
44661
+ }
45014
44662
  filesModified.push(filePath);
45015
44663
  }
45016
44664
  }
@@ -45034,12 +44682,12 @@ var init_server3 = __esm({
45034
44682
  init_stdio2();
45035
44683
  init_zod();
45036
44684
  init_scanner();
45037
- await init_parser();
45038
- await init_audit();
44685
+ init_parser();
44686
+ init_audit();
45039
44687
  init_fixer();
45040
44688
  init_fs();
45041
44689
  init_git();
45042
- await init_tokens();
44690
+ init_tokens();
45043
44691
  init_git();
45044
44692
  init_paths();
45045
44693
  init_version2();
@@ -51968,6 +51616,13 @@ function buildRuleDescriptors() {
51968
51616
  shortDescription: { text: "Context file token usage" },
51969
51617
  helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51970
51618
  },
51619
+ {
51620
+ id: "ctxlint/tier-tokens",
51621
+ shortDescription: {
51622
+ text: "Tier-aware token accounting for always-loaded context files"
51623
+ },
51624
+ helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51625
+ },
51971
51626
  {
51972
51627
  id: "ctxlint/redundancy",
51973
51628
  shortDescription: { text: "Content is redundant or inferable" },
@@ -52062,6 +51717,13 @@ function buildRuleDescriptors() {
52062
51717
  id: "ctxlint/session-loop-detection",
52063
51718
  shortDescription: { text: "Agent looping pattern detected in session history" },
52064
51719
  helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
51720
+ },
51721
+ {
51722
+ id: "ctxlint/session-memory-index-overflow",
51723
+ shortDescription: {
51724
+ text: "MEMORY.md exceeds Claude Code's 200-line / 25KB session-load cap"
51725
+ },
51726
+ helpUri: "https://github.com/yawlabs/ctxlint#what-it-checks"
52065
51727
  }
52066
51728
  ];
52067
51729
  }
@@ -52139,7 +51801,7 @@ async function runCli() {
52139
51801
  "Lint your AI agent context files and MCP server configs against your actual codebase"
52140
51802
  ).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
51803
  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) => {
51804
+ ).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
51805
  const resolvedPath = path11.resolve(projectPath);
52144
51806
  const configPath = opts.config ? path11.resolve(opts.config) : void 0;
52145
51807
  const config2 = configPath ? loadConfigFromPath(configPath) : loadConfig(resolvedPath);
@@ -52221,14 +51883,59 @@ async function runCli() {
52221
51883
  }
52222
51884
  if (!opts.watch) return;
52223
51885
  }
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" : ""}.
51886
+ const dryRunFlag = opts.fixDryRun || false;
51887
+ const yes = opts.yes || false;
51888
+ const followSymlinks = opts.followSymlinks || false;
51889
+ const isInteractive2 = !!process.stdout.isTTY && !options.quiet;
51890
+ if (dryRunFlag || options.fix) {
51891
+ const commonOpts = { quiet: options.quiet, skipSymlinks: !followSymlinks };
51892
+ if (dryRunFlag) {
51893
+ const preview = applyFixes(result, { ...commonOpts, dryRun: true });
51894
+ if (!options.quiet) {
51895
+ if (preview.totalFixes === 0) {
51896
+ console.log("\nNo auto-fixable issues.\n");
51897
+ } else {
51898
+ console.log(
51899
+ `
51900
+ 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
51901
  `
52231
- );
51902
+ );
51903
+ }
51904
+ }
51905
+ } else if (options.fix) {
51906
+ if (isInteractive2 && !yes) {
51907
+ const preview = applyFixes(result, { ...commonOpts, dryRun: true });
51908
+ if (preview.totalFixes === 0) {
51909
+ console.log("\nNo auto-fixable issues.\n");
51910
+ } else {
51911
+ console.log(
51912
+ `
51913
+ ${preview.totalFixes} fix${preview.totalFixes !== 1 ? "es" : ""} proposed across ${preview.filesModified.length} file${preview.filesModified.length !== 1 ? "s" : ""}.`
51914
+ );
51915
+ const confirmed = await promptYesNo(
51916
+ "Apply these fixes? Re-run with --yes to skip this prompt. [y/N] "
51917
+ );
51918
+ if (!confirmed) {
51919
+ console.log("Aborted. No files modified.\n");
51920
+ } else {
51921
+ const applied = applyFixes(result, commonOpts);
51922
+ console.log(
51923
+ `
51924
+ Fixed ${applied.totalFixes} issue${applied.totalFixes !== 1 ? "s" : ""} in ${applied.filesModified.length} file${applied.filesModified.length !== 1 ? "s" : ""}.
51925
+ `
51926
+ );
51927
+ }
51928
+ }
51929
+ } else {
51930
+ const applied = applyFixes(result, commonOpts);
51931
+ if (applied.totalFixes > 0 && !options.quiet) {
51932
+ console.log(
51933
+ `
51934
+ Fixed ${applied.totalFixes} issue${applied.totalFixes !== 1 ? "s" : ""} in ${applied.filesModified.length} file${applied.filesModified.length !== 1 ? "s" : ""}.
51935
+ `
51936
+ );
51937
+ }
51938
+ }
52232
51939
  }
52233
51940
  }
52234
51941
  if (!options.quiet) {
@@ -52380,6 +52087,16 @@ npx @yawlabs/ctxlint --strict
52380
52087
  });
52381
52088
  program2.parse();
52382
52089
  }
52090
+ async function promptYesNo(question) {
52091
+ const { createInterface: createInterface2 } = await import("node:readline/promises");
52092
+ const rl = createInterface2({ input: process.stdin, output: process.stdout });
52093
+ try {
52094
+ const answer = await rl.question(question);
52095
+ return /^\s*y(es)?\s*$/i.test(answer);
52096
+ } finally {
52097
+ rl.close();
52098
+ }
52099
+ }
52383
52100
  function loadConfigFromPath(configPath) {
52384
52101
  try {
52385
52102
  const content = fs9.readFileSync(configPath, "utf-8");
@@ -52392,7 +52109,7 @@ function loadConfigFromPath(configPath) {
52392
52109
  }
52393
52110
  var VALID_CHECKS;
52394
52111
  var init_cli = __esm({
52395
- async "src/cli.ts"() {
52112
+ "src/cli.ts"() {
52396
52113
  "use strict";
52397
52114
  init_esm3();
52398
52115
  init_ora();
@@ -52400,11 +52117,11 @@ var init_cli = __esm({
52400
52117
  init_tokens2();
52401
52118
  init_reporter();
52402
52119
  init_fixer();
52403
- await init_tokens();
52120
+ init_tokens();
52404
52121
  init_git();
52405
52122
  init_fs();
52406
52123
  init_config2();
52407
- await init_audit();
52124
+ init_audit();
52408
52125
  init_version2();
52409
52126
  VALID_CHECKS = /* @__PURE__ */ new Set([...ALL_CHECKS, ...ALL_MCP_CHECKS, ...ALL_SESSION_CHECKS]);
52410
52127
  }
@@ -52414,7 +52131,7 @@ var init_cli = __esm({
52414
52131
  if (process.argv.includes("--mcp-server")) {
52415
52132
  await init_server3().then(() => server_exports);
52416
52133
  } else {
52417
- const { runCli: runCli2 } = await init_cli().then(() => cli_exports);
52134
+ const { runCli: runCli2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
52418
52135
  await runCli2();
52419
52136
  }
52420
52137
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/ctxlint",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Lint your AI agent context files, MCP server configs, and session data against your actual codebase",
5
5
  "bin": {
6
6
  "ctxlint": "dist/index.js"