@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.
- package/LICENSE +190 -190
- 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/utils.test.js +7 -1
- 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
|
@@ -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"}
|
package/dist/commands/anchor.js
DELETED
|
@@ -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 +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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"}
|
package/dist/commands/learn.d.ts
DELETED
|
@@ -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"}
|
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":""}
|