@mmnto/cli 1.10.0 → 1.10.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/LICENSE +190 -190
- package/dist/commands/extract-shared.d.ts.map +1 -1
- package/dist/commands/extract-shared.js +18 -1
- package/dist/commands/extract-shared.js.map +1 -1
- package/dist/commands/init-detect.js +4 -4
- package/dist/commands/init-detect.js.map +1 -1
- package/dist/commands/install-hooks.d.ts.map +1 -1
- package/dist/commands/install-hooks.js +28 -19
- package/dist/commands/install-hooks.js.map +1 -1
- package/dist/commands/install-hooks.test.js +4 -7
- package/dist/commands/install-hooks.test.js.map +1 -1
- package/dist/commands/review-alias.test.js +9 -15
- package/dist/commands/review-alias.test.js.map +1 -1
- package/dist/exemptions/__tests__/exemption-engine.test.js +9 -0
- package/dist/exemptions/__tests__/exemption-engine.test.js.map +1 -1
- package/dist/exemptions/exemption-engine.js +1 -1
- package/dist/exemptions/exemption-engine.js.map +1 -1
- package/dist/orchestrators/orchestrator.test.js +5 -5
- package/dist/orchestrators/orchestrator.test.js.map +1 -1
- package/dist/utils.test.js +8 -2
- package/dist/utils.test.js.map +1 -1
- package/package.json +4 -3
- package/dist/commands/anchor.d.ts +0 -2
- package/dist/commands/anchor.d.ts.map +0 -1
- package/dist/commands/anchor.js +0 -84
- package/dist/commands/anchor.js.map +0 -1
- package/dist/commands/config-cmd.d.ts +0 -4
- package/dist/commands/config-cmd.d.ts.map +0 -1
- package/dist/commands/config-cmd.js +0 -60
- package/dist/commands/config-cmd.js.map +0 -1
- package/dist/commands/learn.d.ts +0 -26
- package/dist/commands/learn.d.ts.map +0 -1
- package/dist/commands/learn.js +0 -325
- package/dist/commands/learn.js.map +0 -1
- package/dist/commands/learn.test.d.ts +0 -2
- package/dist/commands/learn.test.d.ts.map +0 -1
- package/dist/commands/learn.test.js +0 -169
- package/dist/commands/learn.test.js.map +0 -1
- package/dist/orchestrator.test.d.ts +0 -2
- package/dist/orchestrator.test.d.ts.map +0 -1
- package/dist/orchestrator.test.js +0 -130
- package/dist/orchestrator.test.js.map +0 -1
package/dist/commands/learn.js
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import * as readline from 'node:readline/promises';
|
|
4
|
-
import { createEmbedder, LanceStore, runSync } from '@mmnto/totem';
|
|
5
|
-
import { GitHubCliPrAdapter } from '../adapters/github-cli-pr.js';
|
|
6
|
-
import { log } from '../ui.js';
|
|
7
|
-
import { formatResults, getSystemPrompt, loadConfig, loadEnv, resolveConfigPath, runOrchestrator, sanitize, wrapXml, } from '../utils.js';
|
|
8
|
-
// ─── Constants ──────────────────────────────────────────
|
|
9
|
-
const TAG = 'Learn';
|
|
10
|
-
const MAX_EXISTING_LESSONS = 10;
|
|
11
|
-
const MAX_REVIEW_BODY_CHARS = 50_000;
|
|
12
|
-
const MAX_INPUTS = 5;
|
|
13
|
-
// ─── System prompt ──────────────────────────────────────
|
|
14
|
-
const SYSTEM_PROMPT = `# Learn System Prompt — PR Lesson Extraction
|
|
15
|
-
|
|
16
|
-
## Purpose
|
|
17
|
-
Extract tactical lessons from a pull request's review comments and discussion.
|
|
18
|
-
|
|
19
|
-
## Role
|
|
20
|
-
You are a knowledge curator analyzing a PR's review threads. Your job is to distill non-obvious lessons — traps, patterns, decisions with rationale — that will prevent future mistakes.
|
|
21
|
-
|
|
22
|
-
## Rules
|
|
23
|
-
- Extract ONLY non-obvious lessons (traps, surprising behaviors, pattern decisions with rationale)
|
|
24
|
-
- Ignore GCA boilerplate, simple acknowledgments, nits, and formatting suggestions
|
|
25
|
-
- When a suggestion was DECLINED, the author's rationale is often the most valuable lesson
|
|
26
|
-
- Each lesson should be 1-2 sentences capturing WHAT happened and WHY it matters
|
|
27
|
-
- Tags should be lowercase, comma-separated, reflecting the technical domain
|
|
28
|
-
- If existing lessons are provided, do NOT extract duplicates or near-duplicates
|
|
29
|
-
- If no lessons are worth extracting, output exactly: NONE
|
|
30
|
-
|
|
31
|
-
## Output Format
|
|
32
|
-
For each lesson, use this exact delimiter format:
|
|
33
|
-
|
|
34
|
-
---LESSON---
|
|
35
|
-
Tags: tag1, tag2, tag3
|
|
36
|
-
The lesson text. One or two sentences capturing the trap/pattern and WHY it matters.
|
|
37
|
-
---END---
|
|
38
|
-
|
|
39
|
-
If no lessons found, output exactly: NONE
|
|
40
|
-
`;
|
|
41
|
-
function groupIntoThreads(comments) {
|
|
42
|
-
const byId = new Map();
|
|
43
|
-
for (const c of comments)
|
|
44
|
-
byId.set(c.id, c);
|
|
45
|
-
const threadMap = new Map();
|
|
46
|
-
for (const c of comments) {
|
|
47
|
-
const rootId = c.inReplyToId ?? c.id;
|
|
48
|
-
const thread = threadMap.get(rootId) ?? [];
|
|
49
|
-
thread.push(c);
|
|
50
|
-
threadMap.set(rootId, thread);
|
|
51
|
-
}
|
|
52
|
-
const threads = [];
|
|
53
|
-
for (const [rootId, threadComments] of threadMap) {
|
|
54
|
-
threadComments.sort((a, b) => {
|
|
55
|
-
if (!a.createdAt || !b.createdAt)
|
|
56
|
-
return 0;
|
|
57
|
-
return a.createdAt.localeCompare(b.createdAt);
|
|
58
|
-
});
|
|
59
|
-
const root = byId.get(rootId) ?? threadComments[0];
|
|
60
|
-
threads.push({
|
|
61
|
-
path: root.path,
|
|
62
|
-
diffHunk: root.diffHunk,
|
|
63
|
-
comments: threadComments.map((c) => ({ author: c.author, body: c.body })),
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return threads;
|
|
67
|
-
}
|
|
68
|
-
// ─── LanceDB retrieval ─────────────────────────────────
|
|
69
|
-
async function retrieveExistingLessons(store) {
|
|
70
|
-
return store.search({
|
|
71
|
-
query: 'lesson trap pattern decision',
|
|
72
|
-
typeFilter: 'spec',
|
|
73
|
-
maxResults: MAX_EXISTING_LESSONS,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
// ─── Prompt assembly ────────────────────────────────────
|
|
77
|
-
const GCA_MARKERS = ['Using Gemini Code Assist', 'Gemini Code Assist'];
|
|
78
|
-
function isGcaBoilerplate(body) {
|
|
79
|
-
return GCA_MARKERS.some((marker) => body.includes(marker));
|
|
80
|
-
}
|
|
81
|
-
function assemblePrompt(pr, threads, existingLessons, systemPrompt) {
|
|
82
|
-
const sections = [systemPrompt];
|
|
83
|
-
// PR metadata
|
|
84
|
-
sections.push('=== PR METADATA ===');
|
|
85
|
-
sections.push(`PR #${pr.number}: ${pr.title}`);
|
|
86
|
-
sections.push(`State: ${pr.state}`);
|
|
87
|
-
if (pr.body) {
|
|
88
|
-
sections.push('');
|
|
89
|
-
sections.push(wrapXml('pr_body', pr.body));
|
|
90
|
-
}
|
|
91
|
-
// Review summaries (non-empty review bodies)
|
|
92
|
-
const reviewBodies = pr.reviews.filter((r) => r.body.trim());
|
|
93
|
-
if (reviewBodies.length > 0) {
|
|
94
|
-
sections.push('\n=== REVIEW SUMMARIES ===');
|
|
95
|
-
for (const r of reviewBodies) {
|
|
96
|
-
sections.push(`[${r.author} — ${r.state}]`);
|
|
97
|
-
sections.push(wrapXml('review_body', r.body));
|
|
98
|
-
sections.push('');
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Regular PR comments (filter GCA boilerplate)
|
|
102
|
-
const prComments = pr.comments.filter((c) => !isGcaBoilerplate(c.body));
|
|
103
|
-
if (prComments.length > 0) {
|
|
104
|
-
sections.push('\n=== PR COMMENTS ===');
|
|
105
|
-
for (const c of prComments) {
|
|
106
|
-
sections.push(`[${c.author}]`);
|
|
107
|
-
sections.push(wrapXml('comment_body', c.body));
|
|
108
|
-
sections.push('');
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Inline review comment threads
|
|
112
|
-
if (threads.length > 0) {
|
|
113
|
-
sections.push('\n=== INLINE REVIEW THREADS ===');
|
|
114
|
-
for (const thread of threads) {
|
|
115
|
-
sections.push(`--- ${thread.path} ---`);
|
|
116
|
-
sections.push(wrapXml('diff_hunk', thread.diffHunk));
|
|
117
|
-
for (const c of thread.comments) {
|
|
118
|
-
sections.push(`[${c.author}]:\n${wrapXml('comment_body', c.body)}`);
|
|
119
|
-
}
|
|
120
|
-
sections.push('');
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// Existing lessons for dedup context
|
|
124
|
-
const lessonSection = formatResults(existingLessons, 'EXISTING LESSONS (do NOT duplicate)');
|
|
125
|
-
if (lessonSection) {
|
|
126
|
-
sections.push('\n=== DEDUP CONTEXT ===');
|
|
127
|
-
sections.push(lessonSection);
|
|
128
|
-
}
|
|
129
|
-
// Truncate if needed
|
|
130
|
-
let prompt = sections.join('\n');
|
|
131
|
-
if (prompt.length > MAX_REVIEW_BODY_CHARS) {
|
|
132
|
-
prompt = prompt.slice(0, MAX_REVIEW_BODY_CHARS) + '\n\n... [content truncated] ...';
|
|
133
|
-
}
|
|
134
|
-
return prompt;
|
|
135
|
-
}
|
|
136
|
-
const LESSON_RE = /---LESSON---\s*\nTags:\s*(.+)\n([\s\S]+?)---END---/g;
|
|
137
|
-
export function parseLessons(llmOutput) {
|
|
138
|
-
if (llmOutput.trim() === 'NONE')
|
|
139
|
-
return [];
|
|
140
|
-
const lessons = [];
|
|
141
|
-
let match;
|
|
142
|
-
while ((match = LESSON_RE.exec(llmOutput)) !== null) {
|
|
143
|
-
const tags = match[1]
|
|
144
|
-
.split(',')
|
|
145
|
-
.map((t) => t.trim())
|
|
146
|
-
.filter(Boolean);
|
|
147
|
-
const text = match[2].trim();
|
|
148
|
-
if (text) {
|
|
149
|
-
lessons.push({ tags, text });
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return lessons;
|
|
153
|
-
}
|
|
154
|
-
// ─── Lesson writer ──────────────────────────────────────
|
|
155
|
-
export function appendLessons(lessons, lessonsPath) {
|
|
156
|
-
const dir = path.dirname(lessonsPath);
|
|
157
|
-
if (!fs.existsSync(dir)) {
|
|
158
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
159
|
-
}
|
|
160
|
-
const entries = lessons
|
|
161
|
-
.map((l) => {
|
|
162
|
-
const timestamp = new Date().toISOString();
|
|
163
|
-
const tags = l.tags.join(', ');
|
|
164
|
-
return `\n## Lesson — ${timestamp}\n\n**Tags:** ${tags}\n\n${l.text}\n`;
|
|
165
|
-
})
|
|
166
|
-
.join('');
|
|
167
|
-
fs.appendFileSync(lessonsPath, entries, 'utf-8');
|
|
168
|
-
}
|
|
169
|
-
// ─── Confirmation gate ──────────────────────────────────
|
|
170
|
-
/**
|
|
171
|
-
* Returns true if lessons should be written, false to abort.
|
|
172
|
-
* Throws in non-interactive environments without --yes.
|
|
173
|
-
*/
|
|
174
|
-
export async function confirmLessons(count, opts) {
|
|
175
|
-
if (opts.yes)
|
|
176
|
-
return true;
|
|
177
|
-
if (!opts.isTTY) {
|
|
178
|
-
throw new Error(`[Totem Error] Refusing to write lessons in non-interactive mode. Use --yes to bypass confirmation.`);
|
|
179
|
-
}
|
|
180
|
-
const rl = readline.createInterface({
|
|
181
|
-
input: opts.input ?? process.stdin,
|
|
182
|
-
output: opts.output ?? process.stderr,
|
|
183
|
-
});
|
|
184
|
-
try {
|
|
185
|
-
const answer = await rl.question(`[${TAG}] Write ${count} lesson(s) to lessons.md? [Y/n] `);
|
|
186
|
-
if (answer.trim().toLowerCase() === 'n') {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
finally {
|
|
192
|
-
rl.close();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
export async function learnCommand(prNumbers, options) {
|
|
196
|
-
// Validate and deduplicate PR numbers
|
|
197
|
-
const unique = [...new Set(prNumbers)];
|
|
198
|
-
if (unique.length > MAX_INPUTS) {
|
|
199
|
-
throw new Error(`[Totem Error] Too many PR numbers (${unique.length}). Maximum is ${MAX_INPUTS}.`);
|
|
200
|
-
}
|
|
201
|
-
const nums = [];
|
|
202
|
-
for (const prNumber of unique) {
|
|
203
|
-
const num = parseInt(prNumber, 10);
|
|
204
|
-
if (isNaN(num) || num <= 0) {
|
|
205
|
-
throw new Error(`[Totem Error] Invalid PR number: '${prNumber}'. Must be a positive integer.`);
|
|
206
|
-
}
|
|
207
|
-
nums.push(num);
|
|
208
|
-
}
|
|
209
|
-
const cwd = process.cwd();
|
|
210
|
-
const configPath = resolveConfigPath(cwd);
|
|
211
|
-
loadEnv(cwd);
|
|
212
|
-
const config = await loadConfig(configPath);
|
|
213
|
-
// Connect to LanceDB for dedup context
|
|
214
|
-
const embedder = createEmbedder(config.embedding);
|
|
215
|
-
const store = new LanceStore(path.join(cwd, config.lanceDir), embedder);
|
|
216
|
-
await store.connect();
|
|
217
|
-
log.info(TAG, 'Querying existing lessons for dedup...');
|
|
218
|
-
const existingLessons = await retrieveExistingLessons(store);
|
|
219
|
-
log.info(TAG, `Found ${existingLessons.length} existing lessons for context`);
|
|
220
|
-
// Resolve system prompt (allow .totem/prompts/learn.md override)
|
|
221
|
-
const systemPrompt = getSystemPrompt('learn', SYSTEM_PROMPT, cwd, config.totemDir);
|
|
222
|
-
// Process each PR sequentially, accumulating lessons
|
|
223
|
-
const allLessons = [];
|
|
224
|
-
const adapter = new GitHubCliPrAdapter(cwd);
|
|
225
|
-
for (const num of nums) {
|
|
226
|
-
// Fetch PR data
|
|
227
|
-
log.info(TAG, `Fetching PR #${num}...`);
|
|
228
|
-
const pr = adapter.fetchPr(num);
|
|
229
|
-
log.info(TAG, `Title: ${pr.title}`);
|
|
230
|
-
// Fetch inline review comments
|
|
231
|
-
log.info(TAG, 'Fetching review comments...');
|
|
232
|
-
const reviewComments = adapter.fetchReviewComments(num);
|
|
233
|
-
log.info(TAG, `Found ${reviewComments.length} inline review comments`);
|
|
234
|
-
// Filter GCA boilerplate from inline comments
|
|
235
|
-
const filteredComments = reviewComments.filter((c) => !isGcaBoilerplate(c.body));
|
|
236
|
-
// Skip if no review content
|
|
237
|
-
const hasReviewContent = pr.reviews.some((r) => r.body.trim()) ||
|
|
238
|
-
pr.comments.some((c) => !isGcaBoilerplate(c.body)) ||
|
|
239
|
-
filteredComments.length > 0;
|
|
240
|
-
if (!hasReviewContent) {
|
|
241
|
-
log.dim(TAG, `No review content found in PR #${num}. Skipping.`);
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
// Group inline comments into threads
|
|
245
|
-
const threads = groupIntoThreads(filteredComments);
|
|
246
|
-
log.info(TAG, `Grouped into ${threads.length} review threads`);
|
|
247
|
-
// Assemble prompt
|
|
248
|
-
const prompt = assemblePrompt(pr, threads, existingLessons, systemPrompt);
|
|
249
|
-
log.dim(TAG, `Prompt: ${(prompt.length / 1024).toFixed(0)}KB`);
|
|
250
|
-
// Run orchestrator (handles --raw mode, validation, invocation, telemetry)
|
|
251
|
-
const content = runOrchestrator({ prompt, tag: TAG, options, config, cwd });
|
|
252
|
-
if (content == null)
|
|
253
|
-
continue; // --raw mode — prompt already output, process next PR
|
|
254
|
-
// Parse lessons from LLM output
|
|
255
|
-
const lessons = parseLessons(content);
|
|
256
|
-
if (lessons.length === 0) {
|
|
257
|
-
log.dim(TAG, `No lessons extracted from PR #${num}.`);
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
log.success(TAG, `Extracted ${lessons.length} lesson(s) from PR #${num}`);
|
|
261
|
-
allLessons.push(...lessons);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
// In --raw mode, prompts were already output during the loop
|
|
265
|
-
if (options.raw)
|
|
266
|
-
return;
|
|
267
|
-
if (allLessons.length === 0) {
|
|
268
|
-
log.dim(TAG, 'No lessons extracted from any PR.');
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
log.success(TAG, `Total: ${allLessons.length} lesson(s) from ${nums.length} PR(s)`);
|
|
272
|
-
// Display extracted lessons for review
|
|
273
|
-
console.error('');
|
|
274
|
-
log.warn(TAG, 'WARNING: These lessons were extracted from PR comments, which may include content from untrusted contributors.');
|
|
275
|
-
log.warn(TAG, 'Review each lesson carefully before accepting.\n');
|
|
276
|
-
for (let i = 0; i < allLessons.length; i++) {
|
|
277
|
-
const lesson = allLessons[i];
|
|
278
|
-
console.error(` [${i + 1}] Tags: ${sanitize(lesson.tags.join(', ')).replace(/\n/g, ' ')}`);
|
|
279
|
-
console.error(` ${sanitize(lesson.text).replace(/\n/g, '\n ')}`);
|
|
280
|
-
console.error('');
|
|
281
|
-
}
|
|
282
|
-
// --dry-run mode: preview lessons to stdout (pipeable) without writing
|
|
283
|
-
if (options.dryRun) {
|
|
284
|
-
log.dim(TAG, 'Dry run — lessons not written.');
|
|
285
|
-
for (const lesson of allLessons) {
|
|
286
|
-
console.log(`\n Tags: ${sanitize(lesson.tags.join(', ')).replace(/\n/g, ' ')}`);
|
|
287
|
-
console.log(` ${sanitize(lesson.text).replace(/\n/g, '\n ')}`);
|
|
288
|
-
}
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
// Confirmation gate
|
|
292
|
-
const confirmed = await confirmLessons(allLessons.length, {
|
|
293
|
-
yes: options.yes,
|
|
294
|
-
isTTY: !!process.stdin.isTTY,
|
|
295
|
-
});
|
|
296
|
-
if (!confirmed) {
|
|
297
|
-
log.dim(TAG, 'Aborted — no lessons written.');
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
// Sanitize before persisting — strip any terminal injection from stored lessons
|
|
301
|
-
const sanitizedLessons = allLessons.map((l) => ({
|
|
302
|
-
tags: l.tags.map((t) => sanitize(t)),
|
|
303
|
-
text: sanitize(l.text),
|
|
304
|
-
}));
|
|
305
|
-
// Append lessons to .totem/lessons.md
|
|
306
|
-
const lessonsPath = path.join(cwd, config.totemDir, 'lessons.md');
|
|
307
|
-
appendLessons(sanitizedLessons, lessonsPath);
|
|
308
|
-
log.success(TAG, `Appended ${allLessons.length} lesson(s) to ${config.totemDir}/lessons.md`);
|
|
309
|
-
// Run incremental sync so lessons are immediately searchable
|
|
310
|
-
log.info(TAG, 'Running incremental sync...');
|
|
311
|
-
const syncResult = await runSync(config, {
|
|
312
|
-
projectRoot: cwd,
|
|
313
|
-
incremental: true,
|
|
314
|
-
onProgress: (msg) => log.dim(TAG, msg),
|
|
315
|
-
});
|
|
316
|
-
log.success(TAG, `Sync complete: ${syncResult.chunksProcessed} chunks from ${syncResult.filesProcessed} files`);
|
|
317
|
-
// Print summary
|
|
318
|
-
const prLabel = nums.length === 1 ? `PR #${nums[0]}` : `${nums.length} PRs`;
|
|
319
|
-
console.log(`\nExtracted ${sanitizedLessons.length} lesson(s) from ${prLabel}:`);
|
|
320
|
-
for (const lesson of sanitizedLessons) {
|
|
321
|
-
console.log(`\n Tags: ${lesson.tags.join(', ').replace(/\n/g, ' ')}`);
|
|
322
|
-
console.log(` ${lesson.text.replace(/\n/g, '\n ')}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
//# sourceMappingURL=learn.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"learn.js","sourceRoot":"","sources":["../../src/commands/learn.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"learn.test.d.ts","sourceRoot":"","sources":["../../src/commands/learn.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs';
|
|
2
|
-
import * as os from 'node:os';
|
|
3
|
-
import * as path from 'node:path';
|
|
4
|
-
import { Readable, Writable } from 'node:stream';
|
|
5
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
-
import { appendLessons, confirmLessons, parseLessons } from './learn.js';
|
|
7
|
-
// ─── parseLessons ───────────────────────────────────────
|
|
8
|
-
describe('parseLessons', () => {
|
|
9
|
-
it('extracts a single lesson', () => {
|
|
10
|
-
const output = `---LESSON---
|
|
11
|
-
Tags: git, cli, trap
|
|
12
|
-
Always check for ENOENT separately from other errors.
|
|
13
|
-
---END---`;
|
|
14
|
-
const lessons = parseLessons(output);
|
|
15
|
-
expect(lessons).toHaveLength(1);
|
|
16
|
-
expect(lessons[0]).toEqual({
|
|
17
|
-
tags: ['git', 'cli', 'trap'],
|
|
18
|
-
text: 'Always check for ENOENT separately from other errors.',
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
it('extracts multiple lessons', () => {
|
|
22
|
-
const output = `---LESSON---
|
|
23
|
-
Tags: adapter, DRY
|
|
24
|
-
Extract shared fetch logic into a helper immediately.
|
|
25
|
-
---END---
|
|
26
|
-
|
|
27
|
-
---LESSON---
|
|
28
|
-
Tags: security, input
|
|
29
|
-
Sanitize all user input before writing to files.
|
|
30
|
-
---END---`;
|
|
31
|
-
const lessons = parseLessons(output);
|
|
32
|
-
expect(lessons).toHaveLength(2);
|
|
33
|
-
expect(lessons[0].tags).toEqual(['adapter', 'DRY']);
|
|
34
|
-
expect(lessons[1].tags).toEqual(['security', 'input']);
|
|
35
|
-
});
|
|
36
|
-
it('returns empty array for NONE', () => {
|
|
37
|
-
expect(parseLessons('NONE')).toEqual([]);
|
|
38
|
-
});
|
|
39
|
-
it('returns empty array for NONE with whitespace', () => {
|
|
40
|
-
expect(parseLessons(' NONE ')).toEqual([]);
|
|
41
|
-
});
|
|
42
|
-
it('handles multi-line lesson text', () => {
|
|
43
|
-
const output = `---LESSON---
|
|
44
|
-
Tags: architecture
|
|
45
|
-
First line of the lesson.
|
|
46
|
-
Second line with more detail.
|
|
47
|
-
---END---`;
|
|
48
|
-
const lessons = parseLessons(output);
|
|
49
|
-
expect(lessons).toHaveLength(1);
|
|
50
|
-
expect(lessons[0].text).toBe('First line of the lesson.\nSecond line with more detail.');
|
|
51
|
-
});
|
|
52
|
-
it('strips empty tags', () => {
|
|
53
|
-
const output = `---LESSON---
|
|
54
|
-
Tags: git, , cli,
|
|
55
|
-
A lesson about git.
|
|
56
|
-
---END---`;
|
|
57
|
-
const lessons = parseLessons(output);
|
|
58
|
-
expect(lessons[0].tags).toEqual(['git', 'cli']);
|
|
59
|
-
});
|
|
60
|
-
it('skips lessons with empty text', () => {
|
|
61
|
-
const output = `---LESSON---
|
|
62
|
-
Tags: empty
|
|
63
|
-
---END---`;
|
|
64
|
-
const lessons = parseLessons(output);
|
|
65
|
-
expect(lessons).toEqual([]);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
// sanitize tests are in utils.test.ts (sanitize now lives in utils.ts)
|
|
69
|
-
// ─── appendLessons ──────────────────────────────────────
|
|
70
|
-
describe('appendLessons', () => {
|
|
71
|
-
let tmpDir;
|
|
72
|
-
let lessonsPath;
|
|
73
|
-
beforeEach(() => {
|
|
74
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-learn-'));
|
|
75
|
-
lessonsPath = path.join(tmpDir, '.totem', 'lessons.md');
|
|
76
|
-
});
|
|
77
|
-
afterEach(() => {
|
|
78
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
79
|
-
});
|
|
80
|
-
it('creates directory and file if they do not exist', () => {
|
|
81
|
-
appendLessons([{ tags: ['test'], text: 'A test lesson.' }], lessonsPath);
|
|
82
|
-
expect(fs.existsSync(lessonsPath)).toBe(true);
|
|
83
|
-
const content = fs.readFileSync(lessonsPath, 'utf-8');
|
|
84
|
-
expect(content).toContain('**Tags:** test');
|
|
85
|
-
expect(content).toContain('A test lesson.');
|
|
86
|
-
});
|
|
87
|
-
it('appends to existing file', () => {
|
|
88
|
-
fs.mkdirSync(path.dirname(lessonsPath), { recursive: true });
|
|
89
|
-
fs.writeFileSync(lessonsPath, '# Existing content\n');
|
|
90
|
-
appendLessons([{ tags: ['new'], text: 'New lesson.' }], lessonsPath);
|
|
91
|
-
const content = fs.readFileSync(lessonsPath, 'utf-8');
|
|
92
|
-
expect(content).toContain('# Existing content');
|
|
93
|
-
expect(content).toContain('New lesson.');
|
|
94
|
-
});
|
|
95
|
-
it('writes multiple lessons', () => {
|
|
96
|
-
appendLessons([
|
|
97
|
-
{ tags: ['a', 'b'], text: 'First.' },
|
|
98
|
-
{ tags: ['c'], text: 'Second.' },
|
|
99
|
-
], lessonsPath);
|
|
100
|
-
const content = fs.readFileSync(lessonsPath, 'utf-8');
|
|
101
|
-
expect(content).toContain('**Tags:** a, b');
|
|
102
|
-
expect(content).toContain('First.');
|
|
103
|
-
expect(content).toContain('**Tags:** c');
|
|
104
|
-
expect(content).toContain('Second.');
|
|
105
|
-
});
|
|
106
|
-
it('includes ISO timestamp in heading', () => {
|
|
107
|
-
appendLessons([{ tags: ['test'], text: 'Timestamped.' }], lessonsPath);
|
|
108
|
-
const content = fs.readFileSync(lessonsPath, 'utf-8');
|
|
109
|
-
// Match ISO 8601 pattern in heading
|
|
110
|
-
expect(content).toMatch(/## Lesson — \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
// ─── confirmLessons ─────────────────────────────────────
|
|
114
|
-
function makeInput(response) {
|
|
115
|
-
const input = new Readable({ read() { } });
|
|
116
|
-
// Push response after a tick so readline can consume it
|
|
117
|
-
setImmediate(() => {
|
|
118
|
-
input.push(response + '\n');
|
|
119
|
-
input.push(null);
|
|
120
|
-
});
|
|
121
|
-
return input;
|
|
122
|
-
}
|
|
123
|
-
const nullOutput = new Writable({
|
|
124
|
-
write(_chunk, _enc, cb) {
|
|
125
|
-
cb();
|
|
126
|
-
},
|
|
127
|
-
});
|
|
128
|
-
describe('confirmLessons', () => {
|
|
129
|
-
it('returns true when --yes is set', async () => {
|
|
130
|
-
const result = await confirmLessons(3, { yes: true, isTTY: false });
|
|
131
|
-
expect(result).toBe(true);
|
|
132
|
-
});
|
|
133
|
-
it('throws in non-TTY without --yes', async () => {
|
|
134
|
-
await expect(confirmLessons(3, { isTTY: false })).rejects.toThrow('[Totem Error] Refusing to write lessons in non-interactive mode. Use --yes to bypass confirmation.');
|
|
135
|
-
});
|
|
136
|
-
it('returns true when user confirms with empty input (default Y)', async () => {
|
|
137
|
-
const result = await confirmLessons(2, {
|
|
138
|
-
isTTY: true,
|
|
139
|
-
input: makeInput(''),
|
|
140
|
-
output: nullOutput,
|
|
141
|
-
});
|
|
142
|
-
expect(result).toBe(true);
|
|
143
|
-
});
|
|
144
|
-
it('returns true when user types y', async () => {
|
|
145
|
-
const result = await confirmLessons(2, {
|
|
146
|
-
isTTY: true,
|
|
147
|
-
input: makeInput('y'),
|
|
148
|
-
output: nullOutput,
|
|
149
|
-
});
|
|
150
|
-
expect(result).toBe(true);
|
|
151
|
-
});
|
|
152
|
-
it('returns false when user types n', async () => {
|
|
153
|
-
const result = await confirmLessons(2, {
|
|
154
|
-
isTTY: true,
|
|
155
|
-
input: makeInput('n'),
|
|
156
|
-
output: nullOutput,
|
|
157
|
-
});
|
|
158
|
-
expect(result).toBe(false);
|
|
159
|
-
});
|
|
160
|
-
it('returns false when user types N', async () => {
|
|
161
|
-
const result = await confirmLessons(1, {
|
|
162
|
-
isTTY: true,
|
|
163
|
-
input: makeInput('N'),
|
|
164
|
-
output: nullOutput,
|
|
165
|
-
});
|
|
166
|
-
expect(result).toBe(false);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
//# sourceMappingURL=learn.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"learn.test.js","sourceRoot":"","sources":["../../src/commands/learn.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.test.d.ts","sourceRoot":"","sources":["../src/orchestrator.test.ts"],"names":[],"mappings":""}
|