@mmnto/totem 1.34.0 → 1.34.2
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/exporter.d.ts +12 -2
- package/dist/exporter.d.ts.map +1 -1
- package/dist/exporter.js +27 -6
- package/dist/exporter.js.map +1 -1
- package/dist/lesson-format.d.ts +3 -1
- package/dist/lesson-format.d.ts.map +1 -1
- package/dist/lesson-format.js +110 -22
- package/dist/lesson-format.js.map +1 -1
- package/dist/lesson-format.test.js +64 -0
- package/dist/lesson-format.test.js.map +1 -1
- package/package.json +1 -1
package/dist/exporter.d.ts
CHANGED
|
@@ -4,8 +4,14 @@ export declare const SENTINEL_END = "<!-- totem:generated:end -->";
|
|
|
4
4
|
/**
|
|
5
5
|
* Format parsed lessons as a markdown block for injection into AI config files.
|
|
6
6
|
* Always generates sentinel markers (even for empty lessons) to preserve idempotency.
|
|
7
|
+
*
|
|
8
|
+
* When `archivedReasonByHash` is provided, lessons whose content-hash is in the
|
|
9
|
+
* map get an `_(archived: <reason>)_` suffix so a reading agent can weight the
|
|
10
|
+
* guidance appropriately. Empty / missing reasons fall back to a plain bullet
|
|
11
|
+
* (Tenet 4 spirit — surface the rule loudly even with degraded metadata).
|
|
12
|
+
* Per mmnto-ai/totem#1873.
|
|
7
13
|
*/
|
|
8
|
-
export declare function formatLessonsAsMarkdown(lessons: ParsedLesson[]): string;
|
|
14
|
+
export declare function formatLessonsAsMarkdown(lessons: ParsedLesson[], archivedReasonByHash?: ReadonlyMap<string, string>): string;
|
|
9
15
|
/**
|
|
10
16
|
* Inject a generated block between sentinel markers in file content.
|
|
11
17
|
* - If sentinels exist: replaces content between them (inclusive)
|
|
@@ -16,6 +22,10 @@ export declare function injectSentinelBlock(existingContent: string, generatedBl
|
|
|
16
22
|
/**
|
|
17
23
|
* Export formatted lessons to a target file path.
|
|
18
24
|
* Creates directories if needed. Uses sentinel-based injection for idempotent updates.
|
|
25
|
+
*
|
|
26
|
+
* When `archivedReasonByHash` is provided, lessons whose content-hash appears
|
|
27
|
+
* in the map render with an `_(archived: <reason>)_` annotation suffix
|
|
28
|
+
* (mmnto-ai/totem#1873).
|
|
19
29
|
*/
|
|
20
|
-
export declare function exportLessons(lessons: ParsedLesson[], targetPath: string): void;
|
|
30
|
+
export declare function exportLessons(lessons: ParsedLesson[], targetPath: string, archivedReasonByHash?: ReadonlyMap<string, string>): void;
|
|
21
31
|
//# sourceMappingURL=exporter.d.ts.map
|
package/dist/exporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKxD,eAAO,MAAM,cAAc,mCAAmC,CAAC;AAC/D,eAAO,MAAM,YAAY,iCAAiC,CAAC;AAI3D;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EAAE,EACvB,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACjD,MAAM,CA6BR;AAID;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CA6B3F;AAID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,EAAE,MAAM,EAClB,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACjD,IAAI,CAeN"}
|
package/dist/exporter.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
+
import { hashLesson } from './compiler.js';
|
|
3
4
|
import { TotemParseError } from './errors.js';
|
|
4
5
|
// ─── Constants ─────────────────────────────────────────
|
|
5
6
|
export const SENTINEL_START = '<!-- totem:generated:start -->';
|
|
@@ -8,8 +9,14 @@ export const SENTINEL_END = '<!-- totem:generated:end -->';
|
|
|
8
9
|
/**
|
|
9
10
|
* Format parsed lessons as a markdown block for injection into AI config files.
|
|
10
11
|
* Always generates sentinel markers (even for empty lessons) to preserve idempotency.
|
|
12
|
+
*
|
|
13
|
+
* When `archivedReasonByHash` is provided, lessons whose content-hash is in the
|
|
14
|
+
* map get an `_(archived: <reason>)_` suffix so a reading agent can weight the
|
|
15
|
+
* guidance appropriately. Empty / missing reasons fall back to a plain bullet
|
|
16
|
+
* (Tenet 4 spirit — surface the rule loudly even with degraded metadata).
|
|
17
|
+
* Per mmnto-ai/totem#1873.
|
|
11
18
|
*/
|
|
12
|
-
export function formatLessonsAsMarkdown(lessons) {
|
|
19
|
+
export function formatLessonsAsMarkdown(lessons, archivedReasonByHash) {
|
|
13
20
|
const lines = [
|
|
14
21
|
SENTINEL_START,
|
|
15
22
|
'<!-- Auto-generated by `totem compile --export`. Do not edit between these markers. -->',
|
|
@@ -17,12 +24,22 @@ export function formatLessonsAsMarkdown(lessons) {
|
|
|
17
24
|
'## Totem Project Rules',
|
|
18
25
|
'',
|
|
19
26
|
];
|
|
27
|
+
const escapeMarkdown = (s) => s.replace(/[*_]/g, '\\$&');
|
|
28
|
+
// Strip C0 control bytes (incl. CR/LF/TAB) so an archivedReason copied
|
|
29
|
+
// from an operator's terminal session cannot break the bullet shape or
|
|
30
|
+
// bleed across lines. Mirrors the sanitizing discipline applied to
|
|
31
|
+
// lesson body content above (per CR mmnto-ai/totem#1878).
|
|
32
|
+
const sanitizeReason = (s) => escapeMarkdown(s.replace(/[\x00-\x1F\x7F]/g, ' ').trim());
|
|
20
33
|
for (const lesson of lessons) {
|
|
21
|
-
const escapeMarkdown = (s) => s.replace(/[*_]/g, '\\$&');
|
|
22
34
|
const heading = escapeMarkdown(lesson.heading);
|
|
23
35
|
const bodyOneLine = escapeMarkdown(lesson.body.replace(/\n+/g, ' ').trim());
|
|
24
|
-
const
|
|
25
|
-
|
|
36
|
+
const tagSuffix = lesson.tags.length > 0 ? ` _(${lesson.tags.join(', ')})_` : '';
|
|
37
|
+
const rawReason = archivedReasonByHash
|
|
38
|
+
? archivedReasonByHash.get(hashLesson(lesson.heading, lesson.body))
|
|
39
|
+
: undefined;
|
|
40
|
+
const cleanedReason = rawReason ? sanitizeReason(rawReason) : '';
|
|
41
|
+
const archivedSuffix = cleanedReason ? ` _(archived: ${cleanedReason})_` : '';
|
|
42
|
+
lines.push(`- **${heading}** - ` + bodyOneLine + tagSuffix + archivedSuffix);
|
|
26
43
|
}
|
|
27
44
|
lines.push('', SENTINEL_END);
|
|
28
45
|
return lines.join('\n');
|
|
@@ -60,13 +77,17 @@ export function injectSentinelBlock(existingContent, generatedBlock) {
|
|
|
60
77
|
/**
|
|
61
78
|
* Export formatted lessons to a target file path.
|
|
62
79
|
* Creates directories if needed. Uses sentinel-based injection for idempotent updates.
|
|
80
|
+
*
|
|
81
|
+
* When `archivedReasonByHash` is provided, lessons whose content-hash appears
|
|
82
|
+
* in the map render with an `_(archived: <reason>)_` annotation suffix
|
|
83
|
+
* (mmnto-ai/totem#1873).
|
|
63
84
|
*/
|
|
64
|
-
export function exportLessons(lessons, targetPath) {
|
|
85
|
+
export function exportLessons(lessons, targetPath, archivedReasonByHash) {
|
|
65
86
|
const dir = path.dirname(targetPath);
|
|
66
87
|
if (!fs.existsSync(dir)) {
|
|
67
88
|
fs.mkdirSync(dir, { recursive: true });
|
|
68
89
|
}
|
|
69
|
-
const generatedBlock = formatLessonsAsMarkdown(lessons);
|
|
90
|
+
const generatedBlock = formatLessonsAsMarkdown(lessons, archivedReasonByHash);
|
|
70
91
|
if (fs.existsSync(targetPath)) {
|
|
71
92
|
const existing = fs.readFileSync(targetPath, 'utf-8');
|
|
72
93
|
const updated = injectSentinelBlock(existing, generatedBlock);
|
package/dist/exporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"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"}
|
package/dist/lesson-format.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export declare const HEADING_MAX_CHARS = 60;
|
|
|
3
3
|
* Truncate a heading string to HEADING_MAX_CHARS at a word boundary.
|
|
4
4
|
* Strips trailing ellipsis/periods added by LLMs before enforcing the limit.
|
|
5
5
|
* Also trims dangling prepositions/articles/conjunctions that leave the
|
|
6
|
-
* heading feeling incomplete (e.g. "must be tested against the" → "must be tested")
|
|
6
|
+
* heading feeling incomplete (e.g. "must be tested against the" → "must be tested"),
|
|
7
|
+
* and clause-internal-cut tails where a verb/adjective follows a preposition
|
|
8
|
+
* (e.g. "to prevent" → drop both, per mmnto-ai/totem#1872).
|
|
7
9
|
*/
|
|
8
10
|
export declare function truncateHeading(heading: string): string;
|
|
9
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lesson-format.d.ts","sourceRoot":"","sources":["../src/lesson-format.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"lesson-format.d.ts","sourceRoot":"","sources":["../src/lesson-format.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAqHpC;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgBvD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkC1D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAW5F"}
|
package/dist/lesson-format.js
CHANGED
|
@@ -5,11 +5,118 @@ const MIN_WORD_BREAK = 20;
|
|
|
5
5
|
* Trimming past these produces cleaner, self-contained phrases.
|
|
6
6
|
*/
|
|
7
7
|
const DANGLING_TAIL_RE = /\s+(?:the|a|an|of|for|in|on|at|to|by|with|from|into|via|and|or|but|is|are|was|were|that|this|its|their|your|against|between|within|about|after|before|during|through|across|can|must|should|when|if|as|than|like|e\.g\.?)$/i;
|
|
8
|
+
/**
|
|
9
|
+
* Prepositions that, when they immediately precede an expectant-tail run,
|
|
10
|
+
* signal a mid-clause cut. The prep must be the IMMEDIATE anchor of the
|
|
11
|
+
* run — an article like "the" between the prep and the trailing word
|
|
12
|
+
* (as in "Pass the props to the component") stops the run at the noun and
|
|
13
|
+
* leaves the heading kept.
|
|
14
|
+
*/
|
|
15
|
+
const ANCHOR_PREPS = new Set([
|
|
16
|
+
'to',
|
|
17
|
+
'for',
|
|
18
|
+
'by',
|
|
19
|
+
'with',
|
|
20
|
+
'from',
|
|
21
|
+
'into',
|
|
22
|
+
'via',
|
|
23
|
+
'against',
|
|
24
|
+
'between',
|
|
25
|
+
'within',
|
|
26
|
+
'about',
|
|
27
|
+
'after',
|
|
28
|
+
'before',
|
|
29
|
+
'during',
|
|
30
|
+
'through',
|
|
31
|
+
'across',
|
|
32
|
+
'of',
|
|
33
|
+
'on',
|
|
34
|
+
'at',
|
|
35
|
+
'in',
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* Suffixes that strongly signal a trailing word is a verb or attributive
|
|
39
|
+
* adjective expecting a noun complement. Used to detect "expectant runs"
|
|
40
|
+
* — consecutive trailing words like "enable auditable" — that signal an
|
|
41
|
+
* incomplete clause when anchored to a preposition.
|
|
42
|
+
*
|
|
43
|
+
* Note: many common English nouns (component, client, state, environment,
|
|
44
|
+
* string) also match these suffixes. The walk-backwards-collect logic
|
|
45
|
+
* relies on the IMMEDIATE-anchor check (must be a preposition with no
|
|
46
|
+
* intervening article/noun) to avoid over-stripping those.
|
|
47
|
+
*/
|
|
48
|
+
const EXPECTANT_SUFFIX_RE = /(?:ate|ize|ise|ify|able|ible|ing|ent|ant)$/i;
|
|
49
|
+
function isExpectantWord(word) {
|
|
50
|
+
// Hyphenated words (fixed-size, real-time, multi-tenant) are almost
|
|
51
|
+
// always attributive adjectives — treat as expectant.
|
|
52
|
+
if (word.includes('-'))
|
|
53
|
+
return true;
|
|
54
|
+
return EXPECTANT_SUFFIX_RE.test(word);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Strip a trailing run of expectant words (one or more verb/adjective-shaped
|
|
58
|
+
* words at the end of the heading) when the run is IMMEDIATELY anchored to
|
|
59
|
+
* a preposition. Examples (mmnto-ai/totem#1872 regression evidence):
|
|
60
|
+
*
|
|
61
|
+
* "Validate ... to prevent" → strip "prevent" (anchored to "to")
|
|
62
|
+
* "RON tuple ... for fixed-size" → strip "fixed-size" (anchored to "for")
|
|
63
|
+
* "Snapshot ... to isolate" → strip "isolate" (anchored to "to")
|
|
64
|
+
* "Document ... to enable auditable" → strip "enable auditable" (anchored to "to")
|
|
65
|
+
*
|
|
66
|
+
* The run is collected by walking backwards from the end as long as each
|
|
67
|
+
* word is "expectant" (verb/adjective-shaped or hyphenated). The anchor is
|
|
68
|
+
* the word immediately before the run. If the anchor is in ANCHOR_PREPS,
|
|
69
|
+
* strip the run; the existing dangling-tail check then strips the preposition.
|
|
70
|
+
*
|
|
71
|
+
* False positives are avoided by the immediate-adjacency check: in "Pass
|
|
72
|
+
* the props to the component", the anchor before "component" is "the"
|
|
73
|
+
* (not a preposition), so the heading is kept.
|
|
74
|
+
*/
|
|
75
|
+
function trimIncompleteClause(text) {
|
|
76
|
+
const words = text.split(/\s+/);
|
|
77
|
+
if (words.length < 2)
|
|
78
|
+
return text;
|
|
79
|
+
let runStart = words.length;
|
|
80
|
+
while (runStart > 0 && isExpectantWord(words[runStart - 1])) {
|
|
81
|
+
runStart--;
|
|
82
|
+
}
|
|
83
|
+
if (runStart === words.length)
|
|
84
|
+
return text; // no trailing expectant run
|
|
85
|
+
if (runStart === 0)
|
|
86
|
+
return text; // entire heading is expectant — no anchor
|
|
87
|
+
const anchor = words[runStart - 1];
|
|
88
|
+
if (!ANCHOR_PREPS.has(anchor.toLowerCase()))
|
|
89
|
+
return text;
|
|
90
|
+
const trimmed = words.slice(0, runStart).join(' ').trimEnd();
|
|
91
|
+
if (trimmed.length < MIN_WORD_BREAK)
|
|
92
|
+
return text;
|
|
93
|
+
return trimmed;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Iteratively trim trailing fragments that leave a heading mid-clause.
|
|
97
|
+
* Chains the existing dangling-tail strip with the clause-incomplete strip
|
|
98
|
+
* so multi-word tails ("to enable auditable") collapse cleanly.
|
|
99
|
+
*/
|
|
100
|
+
function trimTrailingFragments(text) {
|
|
101
|
+
let prev = text;
|
|
102
|
+
for (;;) {
|
|
103
|
+
let next = prev;
|
|
104
|
+
if (DANGLING_TAIL_RE.test(next)) {
|
|
105
|
+
next = next.replace(DANGLING_TAIL_RE, '').trimEnd();
|
|
106
|
+
}
|
|
107
|
+
next = trimIncompleteClause(next);
|
|
108
|
+
if (next === prev || next.length < MIN_WORD_BREAK)
|
|
109
|
+
return next.length < MIN_WORD_BREAK ? prev : next;
|
|
110
|
+
prev = next;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
8
113
|
/**
|
|
9
114
|
* Truncate a heading string to HEADING_MAX_CHARS at a word boundary.
|
|
10
115
|
* Strips trailing ellipsis/periods added by LLMs before enforcing the limit.
|
|
11
116
|
* Also trims dangling prepositions/articles/conjunctions that leave the
|
|
12
|
-
* heading feeling incomplete (e.g. "must be tested against the" → "must be tested")
|
|
117
|
+
* heading feeling incomplete (e.g. "must be tested against the" → "must be tested"),
|
|
118
|
+
* and clause-internal-cut tails where a verb/adjective follows a preposition
|
|
119
|
+
* (e.g. "to prevent" → drop both, per mmnto-ai/totem#1872).
|
|
13
120
|
*/
|
|
14
121
|
export function truncateHeading(heading) {
|
|
15
122
|
// Strip trailing ellipsis (…) or triple-dot (...) that LLMs love to add
|
|
@@ -18,31 +125,12 @@ export function truncateHeading(heading) {
|
|
|
18
125
|
.replace(/\.{3,}$/, '')
|
|
19
126
|
.trim();
|
|
20
127
|
if (text.length <= HEADING_MAX_CHARS) {
|
|
21
|
-
|
|
22
|
-
let cleaned = text;
|
|
23
|
-
let prev = cleaned;
|
|
24
|
-
while (DANGLING_TAIL_RE.test(cleaned)) {
|
|
25
|
-
cleaned = cleaned.replace(DANGLING_TAIL_RE, '').trimEnd();
|
|
26
|
-
if (cleaned === prev || cleaned.length < MIN_WORD_BREAK)
|
|
27
|
-
return prev;
|
|
28
|
-
prev = cleaned;
|
|
29
|
-
}
|
|
30
|
-
return cleaned || text;
|
|
128
|
+
return trimTrailingFragments(text) || text;
|
|
31
129
|
}
|
|
32
130
|
const truncated = text.slice(0, HEADING_MAX_CHARS);
|
|
33
131
|
const lastSpace = truncated.lastIndexOf(' ');
|
|
34
132
|
text = (lastSpace > MIN_WORD_BREAK ? truncated.slice(0, lastSpace) : truncated).trimEnd();
|
|
35
|
-
|
|
36
|
-
let prev = text;
|
|
37
|
-
while (DANGLING_TAIL_RE.test(text)) {
|
|
38
|
-
text = text.replace(DANGLING_TAIL_RE, '').trimEnd();
|
|
39
|
-
if (text === prev || text.length < MIN_WORD_BREAK) {
|
|
40
|
-
text = prev;
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
prev = text;
|
|
44
|
-
}
|
|
45
|
-
return text;
|
|
133
|
+
return trimTrailingFragments(text);
|
|
46
134
|
}
|
|
47
135
|
/**
|
|
48
136
|
* Generate a descriptive lesson heading from the lesson body.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lesson-format.js","sourceRoot":"","sources":["../src/lesson-format.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B;;;GAGG;AACH,MAAM,gBAAgB,GACpB,6NAA6N,CAAC;AAEhO
|
|
1
|
+
{"version":3,"file":"lesson-format.js","sourceRoot":"","sources":["../src/lesson-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -106,6 +106,70 @@ describe('truncateHeading', () => {
|
|
|
106
106
|
// "in" at end is a dangling word
|
|
107
107
|
expect(truncateHeading('Guard reversed marker ordering in')).toBe('Guard reversed marker ordering');
|
|
108
108
|
});
|
|
109
|
+
// ─── Clause-internal truncation (mmnto-ai/totem#1872) ──
|
|
110
|
+
// Empirical regressions from mmnto-ai/liquid-city#229 / #234 / #238:
|
|
111
|
+
// headings ≤60 chars whose final word is a complete English word
|
|
112
|
+
// (prevent, fixed-size, isolate, auditable) but in context completes
|
|
113
|
+
// an incomplete prepositional/infinitival phrase. The trailing word
|
|
114
|
+
// alone passes the single-word dangling-tail check, but the phrase
|
|
115
|
+
// reads as mid-clause cut.
|
|
116
|
+
it('trims trailing infinitive after "to" (LC#229)', () => {
|
|
117
|
+
expect(truncateHeading('Validate const_name suffix before codegen to prevent')).toBe('Validate const_name suffix before codegen');
|
|
118
|
+
});
|
|
119
|
+
it('trims trailing hyphenated adjective after "for" (LC#229)', () => {
|
|
120
|
+
expect(truncateHeading('RON tuple syntax differs from array syntax for fixed-size')).toBe('RON tuple syntax differs from array syntax');
|
|
121
|
+
});
|
|
122
|
+
it('trims trailing -ate verb after "to" (LC#229)', () => {
|
|
123
|
+
expect(truncateHeading('Snapshot canonical form should exclude metadata to isolate')).toBe('Snapshot canonical form should exclude metadata');
|
|
124
|
+
});
|
|
125
|
+
it('trims chained trailing expectant words (LC#234)', () => {
|
|
126
|
+
// "to enable auditable" — strip "auditable" (-able), then "enable" (-able),
|
|
127
|
+
// then "to" (dangling prep) — three iterations
|
|
128
|
+
expect(truncateHeading('Document pre-resource call sites to enable auditable')).toBe('Document pre-resource call sites');
|
|
129
|
+
});
|
|
130
|
+
it('does NOT trim bare verb at end when no preceding preposition', () => {
|
|
131
|
+
// "validate" has -ate suffix but no preposition before it in heading
|
|
132
|
+
expect(truncateHeading('Always validate')).toBe('Always validate');
|
|
133
|
+
});
|
|
134
|
+
it('does NOT trim valid prepositional phrase ending in plain noun', () => {
|
|
135
|
+
// "from user" / "in CI" / "for tests" — trailing word is a plain noun
|
|
136
|
+
// (no expectant suffix, no hyphen), so the prep+noun pair is kept.
|
|
137
|
+
expect(truncateHeading('Sanitize input from user')).toBe('Sanitize input from user');
|
|
138
|
+
expect(truncateHeading('Run integration tests in CI')).toBe('Run integration tests in CI');
|
|
139
|
+
});
|
|
140
|
+
// ─── False-positive guards (totem review CRITICAL on this PR) ──
|
|
141
|
+
// The first iteration of the fix used a non-adjacent prep check
|
|
142
|
+
// ("does the heading contain ANY prep") and over-stripped common
|
|
143
|
+
// programming nouns ending in expectant suffixes. The walk-back-then-
|
|
144
|
+
// immediate-anchor approach should preserve all of these.
|
|
145
|
+
it('does NOT strip when anchor before expectant word is an article', () => {
|
|
146
|
+
// "component" matches -ent suffix but anchor "the" is an article (not a prep)
|
|
147
|
+
expect(truncateHeading('Pass the props to the component')).toBe('Pass the props to the component');
|
|
148
|
+
});
|
|
149
|
+
it('does NOT strip when consecutive expectant words have non-prep anchor', () => {
|
|
150
|
+
// "client state" — both -ent/-ate, anchor is "Restore" (verb, not prep)
|
|
151
|
+
expect(truncateHeading('Restore client state')).toBe('Restore client state');
|
|
152
|
+
});
|
|
153
|
+
it('does NOT strip hyphenated noun with non-prep anchor', () => {
|
|
154
|
+
// "load-balancer" hyphenated, but anchor "Configure" is not a prep
|
|
155
|
+
expect(truncateHeading('Configure load-balancer')).toBe('Configure load-balancer');
|
|
156
|
+
});
|
|
157
|
+
it('does NOT strip expectant-suffixed common nouns with article anchor', () => {
|
|
158
|
+
// "environment" / "variable" / "string" all match suffixes but anchor "the"
|
|
159
|
+
expect(truncateHeading('Detect the environment')).toBe('Detect the environment');
|
|
160
|
+
expect(truncateHeading('Reset the variable')).toBe('Reset the variable');
|
|
161
|
+
expect(truncateHeading('Parse the string')).toBe('Parse the string');
|
|
162
|
+
});
|
|
163
|
+
it('handles >60-char heading with mid-clause cut at word boundary', () => {
|
|
164
|
+
// After cutting to 60 chars at word boundary the heading should still
|
|
165
|
+
// strip trailing incomplete-clause tails.
|
|
166
|
+
const long = 'Ensure all consumer repos qualify cross-repo references to prevent broken links';
|
|
167
|
+
// Truncates to "Ensure all consumer repos qualify cross-repo references" (~54 chars)
|
|
168
|
+
// No trailing prep+verb after truncation, so it stays clean.
|
|
169
|
+
const result = truncateHeading(long);
|
|
170
|
+
expect(result.length).toBeLessThanOrEqual(HEADING_MAX_CHARS);
|
|
171
|
+
expect(result).not.toMatch(/\sto\s+prevent$/);
|
|
172
|
+
});
|
|
109
173
|
});
|
|
110
174
|
// ─── rewriteLessonHeadings ─────────────────────────────
|
|
111
175
|
describe('rewriteLessonHeadings', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lesson-format.test.js","sourceRoot":"","sources":["../src/lesson-format.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lesson-format.test.js","sourceRoot":"","sources":["../src/lesson-format.test.ts"],"names":[],"mappings":"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"}
|