@mmnto/cli 1.10.0 → 1.10.1

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 (35) hide show
  1. package/LICENSE +190 -190
  2. package/dist/commands/install-hooks.d.ts.map +1 -1
  3. package/dist/commands/install-hooks.js +28 -19
  4. package/dist/commands/install-hooks.js.map +1 -1
  5. package/dist/commands/install-hooks.test.js +4 -7
  6. package/dist/commands/install-hooks.test.js.map +1 -1
  7. package/dist/commands/review-alias.test.js +9 -15
  8. package/dist/commands/review-alias.test.js.map +1 -1
  9. package/dist/exemptions/__tests__/exemption-engine.test.js +9 -0
  10. package/dist/exemptions/__tests__/exemption-engine.test.js.map +1 -1
  11. package/dist/exemptions/exemption-engine.js +1 -1
  12. package/dist/exemptions/exemption-engine.js.map +1 -1
  13. package/dist/utils.test.js +7 -1
  14. package/dist/utils.test.js.map +1 -1
  15. package/package.json +4 -3
  16. package/dist/commands/anchor.d.ts +0 -2
  17. package/dist/commands/anchor.d.ts.map +0 -1
  18. package/dist/commands/anchor.js +0 -84
  19. package/dist/commands/anchor.js.map +0 -1
  20. package/dist/commands/config-cmd.d.ts +0 -4
  21. package/dist/commands/config-cmd.d.ts.map +0 -1
  22. package/dist/commands/config-cmd.js +0 -60
  23. package/dist/commands/config-cmd.js.map +0 -1
  24. package/dist/commands/learn.d.ts +0 -26
  25. package/dist/commands/learn.d.ts.map +0 -1
  26. package/dist/commands/learn.js +0 -325
  27. package/dist/commands/learn.js.map +0 -1
  28. package/dist/commands/learn.test.d.ts +0 -2
  29. package/dist/commands/learn.test.d.ts.map +0 -1
  30. package/dist/commands/learn.test.js +0 -169
  31. package/dist/commands/learn.test.js.map +0 -1
  32. package/dist/orchestrator.test.d.ts +0 -2
  33. package/dist/orchestrator.test.d.ts.map +0 -1
  34. package/dist/orchestrator.test.js +0 -130
  35. package/dist/orchestrator.test.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"anchor.d.ts","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"AAmBA,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ErE"}
@@ -1,84 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import * as fs from 'node:fs';
3
- import * as path from 'node:path';
4
- import { stdin as input, stdout as output } from 'node:process';
5
- import * as readline from 'node:readline/promises';
6
- import { log } from '../ui.js';
7
- import { IS_WIN, loadConfig, loadEnv, resolveConfigPath } from '../utils.js';
8
- function detectSyncCommand(cwd) {
9
- if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) {
10
- return { cmd: IS_WIN ? 'pnpm.cmd' : 'pnpm', args: ['exec', 'totem', 'sync', '--incremental'] };
11
- }
12
- if (fs.existsSync(path.join(cwd, 'yarn.lock'))) {
13
- return { cmd: IS_WIN ? 'yarn.cmd' : 'yarn', args: ['totem', 'sync', '--incremental'] };
14
- }
15
- return { cmd: IS_WIN ? 'npx.cmd' : 'npx', args: ['totem', 'sync', '--incremental'] };
16
- }
17
- export async function anchorCommand(lessonArg) {
18
- const cwd = process.cwd();
19
- const configPath = resolveConfigPath(cwd);
20
- loadEnv(cwd);
21
- const config = await loadConfig(configPath);
22
- const totemDir = path.join(cwd, config.totemDir);
23
- if (!fs.existsSync(totemDir)) {
24
- fs.mkdirSync(totemDir, { recursive: true });
25
- }
26
- const lessonsPath = path.join(totemDir, 'lessons.md');
27
- let lessonText = lessonArg;
28
- const tags = [];
29
- if (!lessonText) {
30
- const rl = readline.createInterface({ input, output });
31
- try {
32
- console.log('--- Proactive Anchoring ---');
33
- const context = await rl.question('> Context (e.g., Attempting to persist state...): ');
34
- const symptom = await rl.question('> Symptom (e.g., App crashes on reload...): ');
35
- const fix = await rl.question('> Fix/Rule (e.g., Use custom localStorage wrappers...): ');
36
- const tagStr = await rl.question('> Tags (comma separated): ');
37
- if (tagStr.trim()) {
38
- tags.push(...tagStr
39
- .split(',')
40
- .map((t) => t.trim())
41
- .filter(Boolean));
42
- }
43
- const parts = [];
44
- if (context.trim())
45
- parts.push(`**Context:** ${context.trim()}`);
46
- if (symptom.trim())
47
- parts.push(`**Symptom:** ${symptom.trim()}`);
48
- if (fix.trim())
49
- parts.push(`**Fix/Rule:** ${fix.trim()}`);
50
- lessonText = parts.join('\n');
51
- }
52
- finally {
53
- rl.close();
54
- }
55
- }
56
- if (!lessonText || !lessonText.trim()) {
57
- log.error('Totem', 'Lesson text cannot be empty.');
58
- return;
59
- }
60
- const timestamp = new Date().toISOString();
61
- const tagString = tags.length > 0 ? tags.join(', ') : 'manual';
62
- const entry = `\n## Lesson — ${timestamp}\n\n**Tags:** ${tagString}\n\n${lessonText.trim()}\n`;
63
- fs.appendFileSync(lessonsPath, entry, 'utf-8');
64
- log.success('Totem', `Lesson saved to ${config.totemDir}/lessons.md`);
65
- const logPath = path.join(totemDir, 'mcp-sync.log');
66
- log.dim('Totem', 'Triggering background re-index...');
67
- try {
68
- const { cmd, args } = detectSyncCommand(cwd);
69
- const logFd = fs.openSync(logPath, 'a');
70
- const child = spawn(cmd, args, {
71
- cwd,
72
- detached: true,
73
- stdio: ['ignore', logFd, logFd],
74
- shell: IS_WIN,
75
- windowsHide: true,
76
- });
77
- child.unref();
78
- }
79
- catch (err) {
80
- const message = err instanceof Error ? err.message : String(err);
81
- log.warn('Totem', `Failed to trigger background sync: ${message}`);
82
- }
83
- }
84
- //# sourceMappingURL=anchor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/commands/anchor.ts"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- export declare function configListCommand(): Promise<void>;
2
- export declare function configGetCommand(key: string): Promise<void>;
3
- export declare function configSetCommand(): Promise<void>;
4
- //# sourceMappingURL=config-cmd.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-cmd.d.ts","sourceRoot":"","sources":["../../src/commands/config-cmd.ts"],"names":[],"mappings":"AAqCA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAavD;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBjE;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD"}
@@ -1,60 +0,0 @@
1
- const TAG = 'Config';
2
- /**
3
- * Navigate an object by a dot-separated key path.
4
- * Returns `{ found: true, value }` or `{ found: false }`.
5
- */
6
- function getByDotPath(obj, key) {
7
- const parts = key.split('.');
8
- let current = obj;
9
- for (const part of parts) {
10
- if (current === null || current === undefined || typeof current !== 'object') {
11
- return { found: false };
12
- }
13
- if (!(part in current)) {
14
- return { found: false };
15
- }
16
- current = current[part];
17
- }
18
- return { found: true, value: current };
19
- }
20
- /**
21
- * Format a value for display — primitives raw, objects as indented JSON.
22
- */
23
- function formatValue(value) {
24
- if (value === null || value === undefined)
25
- return String(value);
26
- if (typeof value === 'object')
27
- return JSON.stringify(value, null, 2);
28
- return String(value);
29
- }
30
- // ─── Subcommands ───────────────────────────────────────
31
- export async function configListCommand() {
32
- const path = await import('node:path');
33
- const { log, dim } = await import('../ui.js');
34
- const { loadConfig, resolveConfigPath } = await import('../utils.js');
35
- const cwd = process.cwd();
36
- const configPath = resolveConfigPath(cwd);
37
- const config = await loadConfig(configPath);
38
- const relPath = path.relative(cwd, configPath) || configPath;
39
- log.info(TAG, `Config loaded from: ${dim(relPath)}`);
40
- console.error('');
41
- console.error(JSON.stringify(config, null, 2));
42
- }
43
- export async function configGetCommand(key) {
44
- const { log, dim } = await import('../ui.js');
45
- const { loadConfig, resolveConfigPath } = await import('../utils.js');
46
- const cwd = process.cwd();
47
- const configPath = resolveConfigPath(cwd);
48
- const config = await loadConfig(configPath);
49
- const result = getByDotPath(config, key);
50
- if (!result.found) {
51
- log.error('Totem Error', `Config key '${key}' not found. Run ${dim('`totem config list`')} to see available keys.`);
52
- return;
53
- }
54
- console.error(formatValue(result.value));
55
- }
56
- export async function configSetCommand() {
57
- const { log, dim } = await import('../ui.js');
58
- log.warn(TAG, `${dim('totem config set')} is not yet implemented. Edit totem.config.ts directly.`);
59
- }
60
- //# sourceMappingURL=config-cmd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-cmd.js","sourceRoot":"","sources":["../../src/commands/config-cmd.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- export interface ExtractedLesson {
2
- tags: string[];
3
- text: string;
4
- }
5
- export declare function parseLessons(llmOutput: string): ExtractedLesson[];
6
- export declare function appendLessons(lessons: ExtractedLesson[], lessonsPath: string): void;
7
- /**
8
- * Returns true if lessons should be written, false to abort.
9
- * Throws in non-interactive environments without --yes.
10
- */
11
- export declare function confirmLessons(count: number, opts: {
12
- yes?: boolean;
13
- isTTY?: boolean;
14
- input?: NodeJS.ReadableStream;
15
- output?: NodeJS.WritableStream;
16
- }): Promise<boolean>;
17
- export interface LearnOptions {
18
- raw?: boolean;
19
- out?: string;
20
- model?: string;
21
- fresh?: boolean;
22
- dryRun?: boolean;
23
- yes?: boolean;
24
- }
25
- export declare function learnCommand(prNumbers: string[], options: LearnOptions): Promise<void>;
26
- //# sourceMappingURL=learn.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"learn.d.ts","sourceRoot":"","sources":["../../src/commands/learn.ts"],"names":[],"mappings":"AAwLA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAID,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CAkBjE;AAID,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAenF;AAID;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IACJ,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC,GACA,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAID,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoK5F"}
@@ -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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=learn.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"learn.test.d.ts","sourceRoot":"","sources":["../../src/commands/learn.test.ts"],"names":[],"mappings":""}