@mmnto/totem 1.14.13 → 1.14.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile-lesson.d.ts +7 -0
- package/dist/compile-lesson.d.ts.map +1 -1
- package/dist/compile-lesson.js +49 -2
- package/dist/compile-lesson.js.map +1 -1
- package/dist/compile-lesson.test.js +211 -4
- package/dist/compile-lesson.test.js.map +1 -1
- package/dist/compile-smoke-gate.d.ts +10 -6
- package/dist/compile-smoke-gate.d.ts.map +1 -1
- package/dist/compile-smoke-gate.js +17 -13
- package/dist/compile-smoke-gate.js.map +1 -1
- package/dist/compile-smoke-gate.test.js +42 -0
- package/dist/compile-smoke-gate.test.js.map +1 -1
- package/dist/compiler-schema.d.ts +61 -16
- package/dist/compiler-schema.d.ts.map +1 -1
- package/dist/compiler-schema.js +56 -1
- package/dist/compiler-schema.js.map +1 -1
- package/dist/compiler-schema.test.js +113 -0
- package/dist/compiler-schema.test.js.map +1 -1
- package/dist/compiler.test.js +9 -2
- package/dist/compiler.test.js.map +1 -1
- package/dist/lesson-pattern.d.ts +12 -0
- package/dist/lesson-pattern.d.ts.map +1 -1
- package/dist/lesson-pattern.js +23 -0
- package/dist/lesson-pattern.js.map +1 -1
- package/dist/lesson-pattern.test.js +93 -1
- package/dist/lesson-pattern.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -488,6 +488,7 @@ describe('buildCompiledRule smoke gate (mmnto/totem#1408)', () => {
|
|
|
488
488
|
engine: 'ast-grep',
|
|
489
489
|
astGrepPattern: 'debugger',
|
|
490
490
|
badExample: 'const x = 1;\n',
|
|
491
|
+
goodExample: '// placeholder\n',
|
|
491
492
|
};
|
|
492
493
|
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
493
494
|
enforceSmokeGate: true,
|
|
@@ -517,6 +518,7 @@ describe('buildCompiledRule smoke gate (mmnto/totem#1408)', () => {
|
|
|
517
518
|
engine: 'ast-grep',
|
|
518
519
|
astGrepPattern: 'debugger',
|
|
519
520
|
badExample: 'debugger;\n',
|
|
521
|
+
goodExample: '// placeholder\n',
|
|
520
522
|
};
|
|
521
523
|
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
522
524
|
enforceSmokeGate: true,
|
|
@@ -531,6 +533,7 @@ describe('buildCompiledRule smoke gate (mmnto/totem#1408)', () => {
|
|
|
531
533
|
engine: 'regex',
|
|
532
534
|
pattern: 'console\\.log',
|
|
533
535
|
badExample: 'console.log("debug")',
|
|
536
|
+
goodExample: '// placeholder\n',
|
|
534
537
|
};
|
|
535
538
|
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
536
539
|
enforceSmokeGate: true,
|
|
@@ -549,9 +552,11 @@ describe('buildCompiledRule smoke gate (mmnto/totem#1408)', () => {
|
|
|
549
552
|
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
550
553
|
enforceSmokeGate: true,
|
|
551
554
|
badExampleOverride: 'console.log("bad")',
|
|
555
|
+
goodExampleOverride: 'logger.info("good")',
|
|
552
556
|
});
|
|
553
557
|
expect(result.rule).not.toBeNull();
|
|
554
558
|
expect(result.rule.badExample).toBe('console.log("bad")');
|
|
559
|
+
expect(result.rule.goodExample).toBe('logger.info("good")');
|
|
555
560
|
});
|
|
556
561
|
it('Pipeline 1 is unaffected (gate is opt-in via enforceSmokeGate)', () => {
|
|
557
562
|
// Without the option flag, buildCompiledRule must behave exactly as before.
|
|
@@ -593,6 +598,7 @@ describe('compound rule smoke gate (mmnto-ai/totem#1409)', () => {
|
|
|
593
598
|
},
|
|
594
599
|
},
|
|
595
600
|
badExample: 'for (let i = 0; i < 10; i++) {\n const inside = i * 2;\n}',
|
|
601
|
+
goodExample: '// placeholder\n',
|
|
596
602
|
};
|
|
597
603
|
const result = buildCompiledRule(parsed, compoundLesson, existingByHash, {
|
|
598
604
|
enforceSmokeGate: true,
|
|
@@ -622,6 +628,7 @@ describe('compound rule smoke gate (mmnto-ai/totem#1409)', () => {
|
|
|
622
628
|
},
|
|
623
629
|
},
|
|
624
630
|
badExample: 'for (let i = 0; i < 10; i++) {\n const inside = i * 2;\n}',
|
|
631
|
+
goodExample: '// placeholder\n',
|
|
625
632
|
};
|
|
626
633
|
const result = buildCompiledRule(parsed, compoundLesson, existingByHash, {
|
|
627
634
|
enforceSmokeGate: true,
|
|
@@ -654,6 +661,183 @@ describe('compound rule smoke gate (mmnto-ai/totem#1409)', () => {
|
|
|
654
661
|
expect(result.rejectReason).toContain('badExample');
|
|
655
662
|
});
|
|
656
663
|
});
|
|
664
|
+
// ─── over-matching check (mmnto-ai/totem#1580) ───────
|
|
665
|
+
describe('buildCompiledRule goodExample over-matching check', () => {
|
|
666
|
+
it('rejects a regex rule that fires on its goodExample', () => {
|
|
667
|
+
const parsed = {
|
|
668
|
+
compilable: true,
|
|
669
|
+
message: 'No console.log',
|
|
670
|
+
engine: 'regex',
|
|
671
|
+
pattern: 'console\\.log',
|
|
672
|
+
// badExample exercises the pattern (matches) — gate under-match passes.
|
|
673
|
+
badExample: 'console.log("debug")',
|
|
674
|
+
// goodExample also matches the pattern, which means the rule is
|
|
675
|
+
// over-broad and fires on known-correct code. The gate must reject.
|
|
676
|
+
goodExample: 'console.log("intentional system message")',
|
|
677
|
+
};
|
|
678
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
679
|
+
enforceSmokeGate: true,
|
|
680
|
+
});
|
|
681
|
+
expect(result.rule).toBeNull();
|
|
682
|
+
expect(result.rejectReason).toContain('smoke gate');
|
|
683
|
+
expect(result.rejectReason).toContain('matches goodExample');
|
|
684
|
+
expect(result.rejectReason).toContain('over-matching');
|
|
685
|
+
});
|
|
686
|
+
it('rejects an ast-grep rule that fires on its goodExample', () => {
|
|
687
|
+
const parsed = {
|
|
688
|
+
compilable: true,
|
|
689
|
+
message: 'No debugger',
|
|
690
|
+
engine: 'ast-grep',
|
|
691
|
+
astGrepPattern: 'debugger',
|
|
692
|
+
badExample: 'debugger;',
|
|
693
|
+
goodExample: 'debugger;\n// should have been removed before commit',
|
|
694
|
+
};
|
|
695
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
696
|
+
enforceSmokeGate: true,
|
|
697
|
+
});
|
|
698
|
+
expect(result.rule).toBeNull();
|
|
699
|
+
expect(result.rejectReason).toContain('matches goodExample');
|
|
700
|
+
});
|
|
701
|
+
it('accepts a regex rule whose pattern fires on badExample but not goodExample', () => {
|
|
702
|
+
const parsed = {
|
|
703
|
+
compilable: true,
|
|
704
|
+
message: 'No console.log',
|
|
705
|
+
engine: 'regex',
|
|
706
|
+
pattern: 'console\\.log',
|
|
707
|
+
badExample: 'console.log("debug")',
|
|
708
|
+
goodExample: 'logger.info("intentional")',
|
|
709
|
+
};
|
|
710
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
711
|
+
enforceSmokeGate: true,
|
|
712
|
+
});
|
|
713
|
+
expect(result.rule).not.toBeNull();
|
|
714
|
+
expect(result.rule.goodExample).toBe('logger.info("intentional")');
|
|
715
|
+
});
|
|
716
|
+
it('rejects a rule that is missing goodExample (required for Pipeline 2/3)', () => {
|
|
717
|
+
const parsed = {
|
|
718
|
+
compilable: true,
|
|
719
|
+
message: 'No console.log',
|
|
720
|
+
engine: 'regex',
|
|
721
|
+
pattern: 'console\\.log',
|
|
722
|
+
badExample: 'console.log("debug")',
|
|
723
|
+
// goodExample absent — caller did not supply it and schema
|
|
724
|
+
// layer was bypassed. Gate must still reject.
|
|
725
|
+
};
|
|
726
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
727
|
+
enforceSmokeGate: true,
|
|
728
|
+
});
|
|
729
|
+
expect(result.rule).toBeNull();
|
|
730
|
+
expect(result.rejectReason).toContain('smoke gate');
|
|
731
|
+
expect(result.rejectReason).toContain('missing goodExample');
|
|
732
|
+
});
|
|
733
|
+
it('honors goodExampleOverride so Pipeline 3 can reuse its Good snippet', () => {
|
|
734
|
+
const parsed = {
|
|
735
|
+
compilable: true,
|
|
736
|
+
message: 'No console.log',
|
|
737
|
+
engine: 'regex',
|
|
738
|
+
pattern: 'console\\.log',
|
|
739
|
+
badExample: 'console.log("bad")',
|
|
740
|
+
// No goodExample on parsed; caller supplies it via override.
|
|
741
|
+
};
|
|
742
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
743
|
+
enforceSmokeGate: true,
|
|
744
|
+
goodExampleOverride: 'logger.info("good")',
|
|
745
|
+
});
|
|
746
|
+
expect(result.rule).not.toBeNull();
|
|
747
|
+
expect(result.rule.goodExample).toBe('logger.info("good")');
|
|
748
|
+
});
|
|
749
|
+
it('persists goodExample on the CompiledRule when the gate accepts', () => {
|
|
750
|
+
const parsed = {
|
|
751
|
+
compilable: true,
|
|
752
|
+
message: 'No debugger',
|
|
753
|
+
engine: 'ast-grep',
|
|
754
|
+
astGrepPattern: 'debugger',
|
|
755
|
+
badExample: 'debugger;',
|
|
756
|
+
goodExample: 'const x = 1;',
|
|
757
|
+
};
|
|
758
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
759
|
+
enforceSmokeGate: true,
|
|
760
|
+
});
|
|
761
|
+
expect(result.rule).not.toBeNull();
|
|
762
|
+
expect(result.rule.goodExample).toBe('const x = 1;');
|
|
763
|
+
});
|
|
764
|
+
it('falls back to parsed.goodExample when goodExampleOverride is undefined', () => {
|
|
765
|
+
// Pins the Pipeline 3 contract: the call site passes `undefined`
|
|
766
|
+
// (not an empty string) when snippets.good is empty, so buildCompiledRule's
|
|
767
|
+
// `options.goodExampleOverride ?? parsed.goodExample` correctly resolves
|
|
768
|
+
// to the LLM-echoed value.
|
|
769
|
+
const parsed = {
|
|
770
|
+
compilable: true,
|
|
771
|
+
message: 'No console.log',
|
|
772
|
+
engine: 'regex',
|
|
773
|
+
pattern: 'console\\.log',
|
|
774
|
+
badExample: 'console.log("bad")',
|
|
775
|
+
goodExample: 'logger.info("from parsed")',
|
|
776
|
+
};
|
|
777
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
778
|
+
enforceSmokeGate: true,
|
|
779
|
+
goodExampleOverride: undefined,
|
|
780
|
+
});
|
|
781
|
+
expect(result.rule).not.toBeNull();
|
|
782
|
+
expect(result.rule.goodExample).toBe('logger.info("from parsed")');
|
|
783
|
+
});
|
|
784
|
+
it('rejects a whitespace-only goodExample with missing-goodexample (parity with schema refine)', () => {
|
|
785
|
+
// Shield flagged on mmnto-ai/totem#1591: `if (!effectiveGoodExample)`
|
|
786
|
+
// treats `' '` as truthy, and runSmokeGate's early-return on
|
|
787
|
+
// `trim().length === 0` then reports matched: false, so a
|
|
788
|
+
// whitespace-only goodExample would otherwise pass the gate with
|
|
789
|
+
// zero coverage. The `.trim().length > 0` guard closes the hole.
|
|
790
|
+
const parsed = {
|
|
791
|
+
compilable: true,
|
|
792
|
+
message: 'No console.log',
|
|
793
|
+
engine: 'regex',
|
|
794
|
+
pattern: 'console\\.log',
|
|
795
|
+
badExample: 'console.log("bad")',
|
|
796
|
+
goodExample: ' \t\n ',
|
|
797
|
+
};
|
|
798
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
799
|
+
enforceSmokeGate: true,
|
|
800
|
+
});
|
|
801
|
+
expect(result.rule).toBeNull();
|
|
802
|
+
expect(result.rejectReason).toContain('missing goodExample');
|
|
803
|
+
});
|
|
804
|
+
it('rejects a whitespace-only badExample with missing-badexample (symmetric guard)', () => {
|
|
805
|
+
const parsed = {
|
|
806
|
+
compilable: true,
|
|
807
|
+
message: 'No console.log',
|
|
808
|
+
engine: 'regex',
|
|
809
|
+
pattern: 'console\\.log',
|
|
810
|
+
badExample: ' \t\n ',
|
|
811
|
+
goodExample: 'logger.info("good")',
|
|
812
|
+
};
|
|
813
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
814
|
+
enforceSmokeGate: true,
|
|
815
|
+
});
|
|
816
|
+
expect(result.rule).toBeNull();
|
|
817
|
+
expect(result.rejectReason).toContain('missing badExample');
|
|
818
|
+
});
|
|
819
|
+
it('empty-string goodExampleOverride clobbers parsed.goodExample (the trap the Pipeline 3 guard exists to prevent)', () => {
|
|
820
|
+
// Nullish coalescing (`??`) treats `''` as defined, so passing an
|
|
821
|
+
// empty string override suppresses the parsed value. This test pins
|
|
822
|
+
// that behavior so the Pipeline 3 call site's .length guard in
|
|
823
|
+
// compile-lesson.ts (snippets.good.length > 0 ? ... : undefined)
|
|
824
|
+
// stays load-bearing.
|
|
825
|
+
const parsed = {
|
|
826
|
+
compilable: true,
|
|
827
|
+
message: 'No console.log',
|
|
828
|
+
engine: 'regex',
|
|
829
|
+
pattern: 'console\\.log',
|
|
830
|
+
badExample: 'console.log("bad")',
|
|
831
|
+
goodExample: 'logger.info("from parsed")',
|
|
832
|
+
};
|
|
833
|
+
const result = buildCompiledRule(parsed, lesson, existingByHash, {
|
|
834
|
+
enforceSmokeGate: true,
|
|
835
|
+
goodExampleOverride: '',
|
|
836
|
+
});
|
|
837
|
+
expect(result.rule).toBeNull();
|
|
838
|
+
expect(result.rejectReason).toContain('missing goodExample');
|
|
839
|
+
});
|
|
840
|
+
});
|
|
657
841
|
// ─── buildManualRule ────────────────────────────────
|
|
658
842
|
describe('buildManualRule', () => {
|
|
659
843
|
it('returns null rule for lessons without manual patterns', () => {
|
|
@@ -750,6 +934,7 @@ describe('compileLesson', () => {
|
|
|
750
934
|
// wants the rule to compile, so give the helper a known-good
|
|
751
935
|
// snippet that matches the pattern.
|
|
752
936
|
badExample: 'console.log("debug")',
|
|
937
|
+
goodExample: '// placeholder\n',
|
|
753
938
|
}
|
|
754
939
|
: null),
|
|
755
940
|
runOrchestrator: vi.fn().mockResolvedValue(response),
|
|
@@ -803,6 +988,7 @@ describe('compileLesson', () => {
|
|
|
803
988
|
message: 'No console.log',
|
|
804
989
|
engine: 'regex',
|
|
805
990
|
badExample: 'console.log("debug")',
|
|
991
|
+
goodExample: '// placeholder\n',
|
|
806
992
|
}),
|
|
807
993
|
runOrchestrator: vi.fn().mockResolvedValue('{"compilable": true}'),
|
|
808
994
|
existingByHash: new Map(),
|
|
@@ -863,6 +1049,7 @@ describe('compileLesson', () => {
|
|
|
863
1049
|
message: 'No console.log',
|
|
864
1050
|
engine: 'regex',
|
|
865
1051
|
badExample: 'console.log("debug")',
|
|
1052
|
+
goodExample: '// placeholder\n',
|
|
866
1053
|
}),
|
|
867
1054
|
runOrchestrator: vi.fn().mockResolvedValue('{"compilable": true}'),
|
|
868
1055
|
existingByHash: new Map(),
|
|
@@ -1108,6 +1295,7 @@ describe('compileLesson with inline examples', () => {
|
|
|
1108
1295
|
message: 'No console.log',
|
|
1109
1296
|
engine: 'regex',
|
|
1110
1297
|
badExample: 'console.log("debug")',
|
|
1298
|
+
goodExample: '// placeholder\n',
|
|
1111
1299
|
}
|
|
1112
1300
|
: null),
|
|
1113
1301
|
runOrchestrator: vi.fn().mockResolvedValue(response),
|
|
@@ -1353,6 +1541,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1353
1541
|
message: 'No console.log',
|
|
1354
1542
|
engine: 'regex',
|
|
1355
1543
|
badExample: 'console.log("debug")',
|
|
1544
|
+
goodExample: '// placeholder\n',
|
|
1356
1545
|
})
|
|
1357
1546
|
.mockReturnValueOnce({
|
|
1358
1547
|
compilable: true,
|
|
@@ -1360,6 +1549,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1360
1549
|
message: 'No console.log',
|
|
1361
1550
|
engine: 'regex',
|
|
1362
1551
|
badExample: 'console.log("debug")',
|
|
1552
|
+
goodExample: '// placeholder\n',
|
|
1363
1553
|
});
|
|
1364
1554
|
const orchestratorMock = vi
|
|
1365
1555
|
.fn()
|
|
@@ -1394,6 +1584,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1394
1584
|
message: 'No console.log',
|
|
1395
1585
|
engine: 'regex',
|
|
1396
1586
|
badExample: 'console.log("debug")',
|
|
1587
|
+
goodExample: '// placeholder\n',
|
|
1397
1588
|
});
|
|
1398
1589
|
const orchestratorMock = vi.fn().mockResolvedValue('always-bad');
|
|
1399
1590
|
const deps = {
|
|
@@ -1524,6 +1715,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1524
1715
|
message: 'No console.log',
|
|
1525
1716
|
engine: 'regex',
|
|
1526
1717
|
badExample: 'zzz_only_matches_itself',
|
|
1718
|
+
goodExample: '// placeholder\n',
|
|
1527
1719
|
})
|
|
1528
1720
|
.mockReturnValueOnce({
|
|
1529
1721
|
compilable: true,
|
|
@@ -1531,6 +1723,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1531
1723
|
message: 'No console.log',
|
|
1532
1724
|
engine: 'regex',
|
|
1533
1725
|
badExample: 'console.log("x")',
|
|
1726
|
+
goodExample: '// placeholder\n',
|
|
1534
1727
|
});
|
|
1535
1728
|
const orchestratorMock = vi
|
|
1536
1729
|
.fn()
|
|
@@ -1574,6 +1767,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1574
1767
|
message: 'No console.log',
|
|
1575
1768
|
engine: 'regex',
|
|
1576
1769
|
badExample: 'zzz_only_matches_itself',
|
|
1770
|
+
goodExample: '// placeholder\n',
|
|
1577
1771
|
});
|
|
1578
1772
|
const orchestratorMock = vi.fn().mockResolvedValue('always-misses');
|
|
1579
1773
|
const deps = {
|
|
@@ -1602,6 +1796,7 @@ describe('compileLesson Pipeline 2 verify-retry', () => {
|
|
|
1602
1796
|
message: 'Invalid regex test',
|
|
1603
1797
|
engine: 'regex',
|
|
1604
1798
|
badExample: 'any string',
|
|
1799
|
+
goodExample: '// placeholder\n',
|
|
1605
1800
|
});
|
|
1606
1801
|
const orchestratorMock = vi.fn().mockResolvedValue('invalid-regex-output');
|
|
1607
1802
|
const deps = {
|
|
@@ -1645,6 +1840,7 @@ describe('compileLesson unverified flag', () => {
|
|
|
1645
1840
|
engine: 'regex',
|
|
1646
1841
|
severity: 'error',
|
|
1647
1842
|
badExample: 'console.log(x)',
|
|
1843
|
+
goodExample: '// placeholder\n',
|
|
1648
1844
|
});
|
|
1649
1845
|
const orchestratorMock = vi.fn().mockResolvedValue('{"compilable": true}');
|
|
1650
1846
|
const deps = {
|
|
@@ -1674,6 +1870,7 @@ describe('compileLesson unverified flag', () => {
|
|
|
1674
1870
|
message: 'No console.log',
|
|
1675
1871
|
engine: 'regex',
|
|
1676
1872
|
badExample: 'console.log(x)',
|
|
1873
|
+
goodExample: '// placeholder\n',
|
|
1677
1874
|
});
|
|
1678
1875
|
const orchestratorMock = vi.fn().mockResolvedValue('{"compilable": true}');
|
|
1679
1876
|
const deps = {
|
|
@@ -1700,6 +1897,7 @@ describe('compileLesson unverified flag', () => {
|
|
|
1700
1897
|
message: 'No console.log',
|
|
1701
1898
|
engine: 'regex',
|
|
1702
1899
|
badExample: 'console.log(x)',
|
|
1900
|
+
goodExample: '// placeholder\n',
|
|
1703
1901
|
});
|
|
1704
1902
|
const orchestratorMock = vi.fn().mockResolvedValue('{"compilable": true}');
|
|
1705
1903
|
const deps = {
|
|
@@ -1730,13 +1928,18 @@ describe('compileLesson unverified flag', () => {
|
|
|
1730
1928
|
};
|
|
1731
1929
|
const parseMock = vi.fn().mockReturnValue({
|
|
1732
1930
|
compilable: true,
|
|
1733
|
-
// Pattern that matches
|
|
1734
|
-
//
|
|
1735
|
-
//
|
|
1736
|
-
|
|
1931
|
+
// Pattern that matches both the trimmed-empty Example Hit (via
|
|
1932
|
+
// `^$`) AND the badExample "anything" (via `\banything\b`) so
|
|
1933
|
+
// verifyRuleExamples passes without interference. The goodExample
|
|
1934
|
+
// `// placeholder` is constructed to not satisfy either alternative
|
|
1935
|
+
// so the mmnto-ai/totem#1580 over-matching check also passes.
|
|
1936
|
+
// No trailing newline on goodExample so the line-split doesn't
|
|
1937
|
+
// produce an empty trailing line that would match `^$`.
|
|
1938
|
+
pattern: '^$|\\banything\\b',
|
|
1737
1939
|
message: 'msg',
|
|
1738
1940
|
engine: 'regex',
|
|
1739
1941
|
badExample: 'anything',
|
|
1942
|
+
goodExample: '// placeholder',
|
|
1740
1943
|
});
|
|
1741
1944
|
const orchestratorMock = vi.fn().mockResolvedValue('{"compilable": true}');
|
|
1742
1945
|
const deps = {
|
|
@@ -1860,6 +2063,7 @@ describe('compileLesson trace events', () => {
|
|
|
1860
2063
|
message: 'No console.log',
|
|
1861
2064
|
engine: 'regex',
|
|
1862
2065
|
badExample: 'console.log("x")',
|
|
2066
|
+
goodExample: '// placeholder\n',
|
|
1863
2067
|
});
|
|
1864
2068
|
const orchestratorMock = vi.fn().mockResolvedValue('attempt-1');
|
|
1865
2069
|
const deps = {
|
|
@@ -1894,6 +2098,7 @@ describe('compileLesson trace events', () => {
|
|
|
1894
2098
|
message: 'No console.log',
|
|
1895
2099
|
engine: 'regex',
|
|
1896
2100
|
badExample: 'zzz_only_matches_itself',
|
|
2101
|
+
goodExample: '// placeholder\n',
|
|
1897
2102
|
});
|
|
1898
2103
|
const orchestratorMock = vi.fn().mockResolvedValue('always-misses');
|
|
1899
2104
|
const deps = {
|
|
@@ -1958,6 +2163,7 @@ describe('compileLesson trace events', () => {
|
|
|
1958
2163
|
message: 'bad regex',
|
|
1959
2164
|
engine: 'regex',
|
|
1960
2165
|
badExample: 'anything',
|
|
2166
|
+
goodExample: '// placeholder\n',
|
|
1961
2167
|
});
|
|
1962
2168
|
const orchestratorMock = vi.fn().mockResolvedValue('invalid-regex-output');
|
|
1963
2169
|
const deps = {
|
|
@@ -2007,6 +2213,7 @@ describe('compileLesson trace events', () => {
|
|
|
2007
2213
|
message: 'No console.log',
|
|
2008
2214
|
engine: 'regex',
|
|
2009
2215
|
badExample: 'console.log("x")',
|
|
2216
|
+
goodExample: '// placeholder\n',
|
|
2010
2217
|
});
|
|
2011
2218
|
const orchestratorMock = vi.fn().mockResolvedValue('pipeline-3-response');
|
|
2012
2219
|
const deps = {
|