@sunilp-org/jam-cli 0.1.0 → 0.1.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 (103) hide show
  1. package/README.md +304 -52
  2. package/dist/commands/ask.d.ts +4 -0
  3. package/dist/commands/ask.d.ts.map +1 -1
  4. package/dist/commands/ask.js +202 -10
  5. package/dist/commands/ask.js.map +1 -1
  6. package/dist/commands/commit.d.ts +12 -0
  7. package/dist/commands/commit.d.ts.map +1 -0
  8. package/dist/commands/commit.js +135 -0
  9. package/dist/commands/commit.js.map +1 -0
  10. package/dist/commands/context.d.ts +12 -0
  11. package/dist/commands/context.d.ts.map +1 -0
  12. package/dist/commands/context.js +52 -0
  13. package/dist/commands/context.js.map +1 -0
  14. package/dist/commands/review.d.ts +25 -0
  15. package/dist/commands/review.d.ts.map +1 -0
  16. package/dist/commands/review.js +117 -0
  17. package/dist/commands/review.js.map +1 -0
  18. package/dist/commands/run.d.ts +1 -0
  19. package/dist/commands/run.d.ts.map +1 -1
  20. package/dist/commands/run.js +199 -197
  21. package/dist/commands/run.js.map +1 -1
  22. package/dist/config/loader.d.ts.map +1 -1
  23. package/dist/config/loader.js +3 -0
  24. package/dist/config/loader.js.map +1 -1
  25. package/dist/index.js +63 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/providers/base.d.ts +26 -0
  28. package/dist/providers/base.d.ts.map +1 -1
  29. package/dist/providers/factory.d.ts.map +1 -1
  30. package/dist/providers/factory.js +17 -1
  31. package/dist/providers/factory.js.map +1 -1
  32. package/dist/providers/groq.d.ts +16 -0
  33. package/dist/providers/groq.d.ts.map +1 -0
  34. package/dist/providers/groq.js +23 -0
  35. package/dist/providers/groq.js.map +1 -0
  36. package/dist/providers/ollama.d.ts +6 -1
  37. package/dist/providers/ollama.d.ts.map +1 -1
  38. package/dist/providers/ollama.js +77 -4
  39. package/dist/providers/ollama.js.map +1 -1
  40. package/dist/providers/openai.d.ts +18 -0
  41. package/dist/providers/openai.d.ts.map +1 -0
  42. package/dist/providers/openai.js +229 -0
  43. package/dist/providers/openai.js.map +1 -0
  44. package/dist/tools/all-tools.d.ts +18 -0
  45. package/dist/tools/all-tools.d.ts.map +1 -0
  46. package/dist/tools/all-tools.js +95 -0
  47. package/dist/tools/all-tools.js.map +1 -0
  48. package/dist/tools/apply_patch.js +1 -1
  49. package/dist/tools/apply_patch.js.map +1 -1
  50. package/dist/tools/context-tools.d.ts +14 -0
  51. package/dist/tools/context-tools.d.ts.map +1 -0
  52. package/dist/tools/context-tools.js +63 -0
  53. package/dist/tools/context-tools.js.map +1 -0
  54. package/dist/tools/git_diff.js +1 -1
  55. package/dist/tools/git_diff.js.map +1 -1
  56. package/dist/tools/git_status.js +1 -1
  57. package/dist/tools/git_status.js.map +1 -1
  58. package/dist/tools/registry.d.ts.map +1 -1
  59. package/dist/tools/registry.js +2 -0
  60. package/dist/tools/registry.js.map +1 -1
  61. package/dist/tools/run_command.d.ts +8 -3
  62. package/dist/tools/run_command.d.ts.map +1 -1
  63. package/dist/tools/run_command.js +90 -3
  64. package/dist/tools/run_command.js.map +1 -1
  65. package/dist/ui/chat.d.ts.map +1 -1
  66. package/dist/ui/chat.js +173 -1
  67. package/dist/ui/chat.js.map +1 -1
  68. package/dist/ui/logo.d.ts.map +1 -1
  69. package/dist/ui/logo.js +5 -1
  70. package/dist/ui/logo.js.map +1 -1
  71. package/dist/utils/agent.d.ts +130 -0
  72. package/dist/utils/agent.d.ts.map +1 -0
  73. package/dist/utils/agent.js +449 -0
  74. package/dist/utils/agent.js.map +1 -0
  75. package/dist/utils/cache.d.ts +30 -0
  76. package/dist/utils/cache.d.ts.map +1 -0
  77. package/dist/utils/cache.js +62 -0
  78. package/dist/utils/cache.js.map +1 -0
  79. package/dist/utils/context.d.ts +38 -0
  80. package/dist/utils/context.d.ts.map +1 -0
  81. package/dist/utils/context.js +383 -0
  82. package/dist/utils/context.js.map +1 -0
  83. package/dist/utils/critic.d.ts +31 -0
  84. package/dist/utils/critic.d.ts.map +1 -0
  85. package/dist/utils/critic.js +126 -0
  86. package/dist/utils/critic.js.map +1 -0
  87. package/dist/utils/index-builder.d.ts +53 -0
  88. package/dist/utils/index-builder.d.ts.map +1 -0
  89. package/dist/utils/index-builder.js +241 -0
  90. package/dist/utils/index-builder.js.map +1 -0
  91. package/dist/utils/memory.d.ts +104 -0
  92. package/dist/utils/memory.d.ts.map +1 -0
  93. package/dist/utils/memory.js +215 -0
  94. package/dist/utils/memory.js.map +1 -0
  95. package/dist/utils/past-sessions.d.ts +31 -0
  96. package/dist/utils/past-sessions.d.ts.map +1 -0
  97. package/dist/utils/past-sessions.js +126 -0
  98. package/dist/utils/past-sessions.js.map +1 -0
  99. package/dist/utils/tokens.d.ts +53 -0
  100. package/dist/utils/tokens.d.ts.map +1 -0
  101. package/dist/utils/tokens.js +138 -0
  102. package/dist/utils/tokens.js.map +1 -0
  103. package/package.json +4 -2
@@ -0,0 +1,383 @@
1
+ /**
2
+ * JAM.md — persistent project context file.
3
+ *
4
+ * Automatically discovers project details (language, structure, dependencies,
5
+ * patterns) and writes a `JAM.md` at the workspace root. This file is read
6
+ * by `jam ask` / `jam chat` and injected into the system prompt so the model
7
+ * starts every conversation with a deep understanding of the project.
8
+ *
9
+ * Users can (and should) edit JAM.md to add domain-specific notes, coding
10
+ * conventions, architectural decisions, etc.
11
+ */
12
+ import { readFile, writeFile, readdir, access, constants } from 'node:fs/promises';
13
+ import { basename, join } from 'node:path';
14
+ export const CONTEXT_FILENAME = 'JAM.md';
15
+ // ── Read existing JAM.md ──────────────────────────────────────────────────────
16
+ /**
17
+ * Load `JAM.md` from the workspace root. Returns `null` if not found.
18
+ */
19
+ export async function loadContextFile(workspaceRoot) {
20
+ const contextPath = join(workspaceRoot, CONTEXT_FILENAME);
21
+ try {
22
+ return await readFile(contextPath, 'utf-8');
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /** Recursively build a directory tree string (max depth). */
29
+ async function buildTree(dir, prefix, depth, maxDepth) {
30
+ if (depth > maxDepth)
31
+ return '';
32
+ let entries;
33
+ try {
34
+ entries = await readdir(dir, { withFileTypes: true });
35
+ }
36
+ catch {
37
+ return '';
38
+ }
39
+ // Filter out noise
40
+ const filtered = entries
41
+ .filter((e) => {
42
+ const name = String(e.name);
43
+ if (name.startsWith('.'))
44
+ return false;
45
+ if (['node_modules', 'dist', 'build', 'coverage', '__pycache__', '.next', '.nuxt', 'target', 'out'].includes(name))
46
+ return false;
47
+ return true;
48
+ })
49
+ .sort((a, b) => {
50
+ // Dirs first, then files
51
+ if (a.isDirectory() && !b.isDirectory())
52
+ return -1;
53
+ if (!a.isDirectory() && b.isDirectory())
54
+ return 1;
55
+ return String(a.name).localeCompare(String(b.name));
56
+ });
57
+ const lines = [];
58
+ for (let i = 0; i < filtered.length; i++) {
59
+ const entry = filtered[i];
60
+ const name = String(entry.name);
61
+ const isLast = i === filtered.length - 1;
62
+ const connector = isLast ? '└── ' : '├── ';
63
+ const childPrefix = isLast ? ' ' : '│ ';
64
+ if (entry.isDirectory()) {
65
+ lines.push(`${prefix}${connector}${name}/`);
66
+ const subtree = await buildTree(join(dir, name), prefix + childPrefix, depth + 1, maxDepth);
67
+ if (subtree)
68
+ lines.push(subtree);
69
+ }
70
+ else {
71
+ lines.push(`${prefix}${connector}${name}`);
72
+ }
73
+ }
74
+ return lines.join('\n');
75
+ }
76
+ /** Detect language, framework, and other details from filesystem. */
77
+ async function discoverProject(workspaceRoot) {
78
+ const info = {
79
+ name: basename(workspaceRoot),
80
+ language: 'unknown',
81
+ framework: 'none detected',
82
+ packageManager: 'unknown',
83
+ description: '',
84
+ entryPoint: '',
85
+ testFramework: '',
86
+ scripts: {},
87
+ dependencies: [],
88
+ devDependencies: [],
89
+ structure: '',
90
+ };
91
+ // ── package.json (Node / TS / JS) ──────────────────────────────────────────
92
+ try {
93
+ const pkgRaw = await readFile(join(workspaceRoot, 'package.json'), 'utf-8');
94
+ const pkg = JSON.parse(pkgRaw);
95
+ info.name = pkg['name'] ?? info.name;
96
+ info.description = pkg['description'] ?? '';
97
+ info.entryPoint = pkg['main'] ?? (pkg['bin'] ? JSON.stringify(pkg['bin']) : '');
98
+ const scripts = pkg['scripts'];
99
+ if (scripts)
100
+ info.scripts = scripts;
101
+ const deps = pkg['dependencies'];
102
+ if (deps)
103
+ info.dependencies = Object.keys(deps);
104
+ const devDeps = pkg['devDependencies'];
105
+ if (devDeps)
106
+ info.devDependencies = Object.keys(devDeps);
107
+ // Detect package manager
108
+ const lockFiles = [
109
+ ['bun.lockb', 'bun'],
110
+ ['pnpm-lock.yaml', 'pnpm'],
111
+ ['yarn.lock', 'yarn'],
112
+ ['package-lock.json', 'npm'],
113
+ ];
114
+ for (const [file, mgr] of lockFiles) {
115
+ try {
116
+ await access(join(workspaceRoot, file), constants.F_OK);
117
+ info.packageManager = mgr;
118
+ break;
119
+ }
120
+ catch { /* skip */ }
121
+ }
122
+ // Detect frameworks from deps
123
+ const allDeps = [...info.dependencies, ...info.devDependencies];
124
+ if (allDeps.includes('commander') || allDeps.includes('yargs') || allDeps.includes('oclif'))
125
+ info.framework = 'CLI application';
126
+ else if (allDeps.includes('next'))
127
+ info.framework = 'Next.js';
128
+ else if (allDeps.includes('nuxt'))
129
+ info.framework = 'Nuxt';
130
+ else if (allDeps.includes('svelte'))
131
+ info.framework = 'Svelte';
132
+ else if (allDeps.includes('vue'))
133
+ info.framework = 'Vue';
134
+ else if (allDeps.includes('react'))
135
+ info.framework = 'React';
136
+ else if (allDeps.includes('express'))
137
+ info.framework = 'Express';
138
+ else if (allDeps.includes('fastify'))
139
+ info.framework = 'Fastify';
140
+ // Detect test framework
141
+ if (allDeps.includes('vitest'))
142
+ info.testFramework = 'Vitest';
143
+ else if (allDeps.includes('jest'))
144
+ info.testFramework = 'Jest';
145
+ else if (allDeps.includes('mocha'))
146
+ info.testFramework = 'Mocha';
147
+ }
148
+ catch { /* not a node project */ }
149
+ // ── Language detection ──────────────────────────────────────────────────────
150
+ try {
151
+ await access(join(workspaceRoot, 'tsconfig.json'), constants.F_OK);
152
+ info.language = 'TypeScript';
153
+ }
154
+ catch {
155
+ try {
156
+ await access(join(workspaceRoot, 'package.json'), constants.F_OK);
157
+ info.language = 'JavaScript';
158
+ }
159
+ catch { /* fallthrough */ }
160
+ }
161
+ // Python detection
162
+ if (info.language === 'unknown') {
163
+ for (const marker of ['pyproject.toml', 'setup.py', 'requirements.txt', 'Pipfile']) {
164
+ try {
165
+ await access(join(workspaceRoot, marker), constants.F_OK);
166
+ info.language = 'Python';
167
+ break;
168
+ }
169
+ catch { /* skip */ }
170
+ }
171
+ }
172
+ // Go
173
+ if (info.language === 'unknown') {
174
+ try {
175
+ await access(join(workspaceRoot, 'go.mod'), constants.F_OK);
176
+ info.language = 'Go';
177
+ }
178
+ catch { /* skip */ }
179
+ }
180
+ // Rust
181
+ if (info.language === 'unknown') {
182
+ try {
183
+ await access(join(workspaceRoot, 'Cargo.toml'), constants.F_OK);
184
+ info.language = 'Rust';
185
+ }
186
+ catch { /* skip */ }
187
+ }
188
+ // ── Build directory tree ───────────────────────────────────────────────────
189
+ info.structure = await buildTree(workspaceRoot, '', 0, 3);
190
+ return info;
191
+ }
192
+ /** File extension hint for the language. */
193
+ function langFileHint(lang) {
194
+ switch (lang) {
195
+ case 'TypeScript': return '`.ts` / `.tsx`';
196
+ case 'JavaScript': return '`.js` / `.jsx`';
197
+ case 'Python': return '`.py`';
198
+ case 'Go': return '`.go`';
199
+ case 'Rust': return '`.rs`';
200
+ default: return '';
201
+ }
202
+ }
203
+ /**
204
+ * Generate JAM.md content by auto-discovering the project.
205
+ */
206
+ export async function generateContextContent(workspaceRoot) {
207
+ const info = await discoverProject(workspaceRoot);
208
+ const sections = [];
209
+ // Header
210
+ sections.push(`# ${info.name}`);
211
+ sections.push('');
212
+ sections.push('> This file was auto-generated by `jam context init`.');
213
+ sections.push('> Edit it freely — Jam reads it on every `ask` / `chat` invocation.');
214
+ sections.push('');
215
+ // Overview
216
+ sections.push('## Overview');
217
+ sections.push('');
218
+ if (info.description)
219
+ sections.push(info.description);
220
+ sections.push('');
221
+ sections.push(`| Property | Value |`);
222
+ sections.push(`|----------|-------|`);
223
+ sections.push(`| Language | ${info.language} |`);
224
+ if (langFileHint(info.language)) {
225
+ sections.push(`| File extensions | ${langFileHint(info.language)} |`);
226
+ }
227
+ if (info.framework !== 'none detected') {
228
+ sections.push(`| Framework | ${info.framework} |`);
229
+ }
230
+ if (info.packageManager !== 'unknown') {
231
+ sections.push(`| Package manager | ${info.packageManager} |`);
232
+ }
233
+ if (info.entryPoint) {
234
+ sections.push(`| Entry point | \`${info.entryPoint}\` |`);
235
+ }
236
+ if (info.testFramework) {
237
+ sections.push(`| Test framework | ${info.testFramework} |`);
238
+ }
239
+ sections.push('');
240
+ // Scripts
241
+ if (Object.keys(info.scripts).length > 0) {
242
+ sections.push('## Scripts');
243
+ sections.push('');
244
+ sections.push('```bash');
245
+ for (const [name, cmd] of Object.entries(info.scripts)) {
246
+ sections.push(`${info.packageManager !== 'unknown' ? info.packageManager : 'npm'} run ${name} # ${cmd}`);
247
+ }
248
+ sections.push('```');
249
+ sections.push('');
250
+ }
251
+ // Directory structure
252
+ if (info.structure) {
253
+ sections.push('## Directory Structure');
254
+ sections.push('');
255
+ sections.push('```');
256
+ sections.push(info.structure);
257
+ sections.push('```');
258
+ sections.push('');
259
+ }
260
+ // Key dependencies
261
+ if (info.dependencies.length > 0) {
262
+ sections.push('## Key Dependencies');
263
+ sections.push('');
264
+ for (const dep of info.dependencies) {
265
+ sections.push(`- \`${dep}\``);
266
+ }
267
+ sections.push('');
268
+ }
269
+ // Dev dependencies (abbreviated)
270
+ if (info.devDependencies.length > 0) {
271
+ sections.push('## Dev Dependencies');
272
+ sections.push('');
273
+ for (const dep of info.devDependencies) {
274
+ sections.push(`- \`${dep}\``);
275
+ }
276
+ sections.push('');
277
+ }
278
+ // User editable sections
279
+ sections.push('## Architecture Notes');
280
+ sections.push('');
281
+ sections.push('<!-- Add notes about the project architecture, key patterns, design decisions, etc. -->');
282
+ sections.push('');
283
+ sections.push('## Coding Conventions');
284
+ sections.push('');
285
+ sections.push('<!-- Add notes about coding style, naming conventions, import patterns, etc. -->');
286
+ sections.push('');
287
+ sections.push('## Important Context');
288
+ sections.push('');
289
+ sections.push('<!-- Add anything else Jam should know when answering questions about this project. -->');
290
+ sections.push('');
291
+ return sections.join('\n');
292
+ }
293
+ /**
294
+ * Write JAM.md to the workspace root. Returns the path written.
295
+ */
296
+ export async function writeContextFile(workspaceRoot, content) {
297
+ const contextPath = join(workspaceRoot, CONTEXT_FILENAME);
298
+ await writeFile(contextPath, content, 'utf-8');
299
+ return contextPath;
300
+ }
301
+ /**
302
+ * Check if JAM.md already exists.
303
+ */
304
+ export async function contextFileExists(workspaceRoot) {
305
+ try {
306
+ await access(join(workspaceRoot, CONTEXT_FILENAME), constants.F_OK);
307
+ return true;
308
+ }
309
+ catch {
310
+ return false;
311
+ }
312
+ }
313
+ // ── Auto-update JAM.md with usage patterns (P2-7) ────────────────────────────
314
+ const USAGE_SECTION_HEADER = '## Frequently Accessed Files';
315
+ const USAGE_SECTION_MARKER = '<!-- jam-auto-usage -->';
316
+ /**
317
+ * Update JAM.md with frequently accessed file patterns from the session.
318
+ * Appends or replaces a "Frequently Accessed Files" section.
319
+ *
320
+ * @param workspaceRoot Workspace root path
321
+ * @param readFiles Array of file paths accessed during sessions
322
+ * @param searchQueries Array of search queries used during sessions
323
+ */
324
+ export async function updateContextWithUsage(workspaceRoot, readFiles, searchQueries) {
325
+ const contextPath = join(workspaceRoot, CONTEXT_FILENAME);
326
+ let existing;
327
+ try {
328
+ existing = await readFile(contextPath, 'utf-8');
329
+ }
330
+ catch {
331
+ return; // No JAM.md — nothing to update
332
+ }
333
+ // Count file access frequency
334
+ const fileCounts = new Map();
335
+ for (const f of readFiles) {
336
+ fileCounts.set(f, (fileCounts.get(f) ?? 0) + 1);
337
+ }
338
+ // Sort by frequency
339
+ const topFiles = [...fileCounts.entries()]
340
+ .sort((a, b) => b[1] - a[1])
341
+ .slice(0, 15)
342
+ .map(([path, count]) => `- \`${path}\` (${count}x)`);
343
+ if (topFiles.length === 0)
344
+ return;
345
+ const usageSection = [
346
+ '',
347
+ USAGE_SECTION_HEADER,
348
+ '',
349
+ USAGE_SECTION_MARKER,
350
+ '',
351
+ '> Auto-updated by Jam based on your usage patterns. These are the files most frequently',
352
+ '> examined when answering questions. Jam will prioritize searching these locations.',
353
+ '',
354
+ ...topFiles,
355
+ '',
356
+ ...(searchQueries.length > 0 ? [
357
+ '### Common Search Patterns',
358
+ '',
359
+ ...searchQueries.slice(0, 10).map(q => `- \`${q}\``),
360
+ '',
361
+ ] : []),
362
+ USAGE_SECTION_MARKER,
363
+ '',
364
+ ].join('\n');
365
+ // Replace existing usage section or append
366
+ const markerStart = existing.indexOf(USAGE_SECTION_MARKER);
367
+ if (markerStart !== -1) {
368
+ const markerEnd = existing.indexOf(USAGE_SECTION_MARKER, markerStart + USAGE_SECTION_MARKER.length);
369
+ if (markerEnd !== -1) {
370
+ // Find the section header before first marker
371
+ const headerPos = existing.lastIndexOf(USAGE_SECTION_HEADER, markerStart);
372
+ const sectionStart = headerPos !== -1 ? headerPos : markerStart;
373
+ const sectionEnd = markerEnd + USAGE_SECTION_MARKER.length;
374
+ const updated = existing.slice(0, sectionStart) + usageSection + existing.slice(sectionEnd);
375
+ await writeFile(contextPath, updated, 'utf-8');
376
+ return;
377
+ }
378
+ }
379
+ // Append to end
380
+ const updated = existing.trimEnd() + '\n' + usageSection;
381
+ await writeFile(contextPath, updated, 'utf-8');
382
+ }
383
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Critic agent — evaluates the main agent's answer for quality and relevance.
3
+ *
4
+ * Replaces the naive keyword-matching `checkAnswerRelevance` with a real
5
+ * LLM-based evaluation. The critic runs as a separate, cheap LLM call
6
+ * with a focused system prompt.
7
+ */
8
+ import type { ProviderAdapter } from '../providers/base.js';
9
+ export interface CriticVerdict {
10
+ /** Whether the answer passes quality checks. */
11
+ pass: boolean;
12
+ /** Brief reason if it fails. */
13
+ reason: string;
14
+ /** Confidence 0-1 (from the critic's self-assessment). */
15
+ confidence: number;
16
+ }
17
+ /**
18
+ * Run the critic agent to evaluate an answer.
19
+ *
20
+ * Uses a low temperature and short max tokens for fast, focused evaluation.
21
+ * Falls back to PASS if the critic call fails (non-blocking).
22
+ */
23
+ export declare function criticEvaluate(provider: ProviderAdapter, question: string, answer: string, options?: {
24
+ model?: string;
25
+ }): Promise<CriticVerdict>;
26
+ /**
27
+ * Build a correction message from the critic's feedback.
28
+ * More specific than the generic buildCorrectionMessage.
29
+ */
30
+ export declare function buildCriticCorrection(verdict: CriticVerdict, originalQuestion: string): string;
31
+ //# sourceMappingURL=critic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"critic.d.ts","sourceRoot":"","sources":["../../src/utils/critic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;CACpB;AAiCD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAiCD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAgB9F"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Critic agent — evaluates the main agent's answer for quality and relevance.
3
+ *
4
+ * Replaces the naive keyword-matching `checkAnswerRelevance` with a real
5
+ * LLM-based evaluation. The critic runs as a separate, cheap LLM call
6
+ * with a focused system prompt.
7
+ */
8
+ // ── Critic prompt ─────────────────────────────────────────────────────────────
9
+ const CRITIC_SYSTEM_PROMPT = `You are a strict answer quality evaluator for a code assistant.
10
+
11
+ You will receive:
12
+ 1. The user's ORIGINAL QUESTION
13
+ 2. The assistant's PROPOSED ANSWER
14
+
15
+ Evaluate the answer on these criteria:
16
+ - RELEVANCE: Does the answer address the user's specific question?
17
+ - SPECIFICITY: Does the answer reference specific files, line numbers, or code?
18
+ - ACCURACY: Does the answer appear technically correct (no obvious hallucinations)?
19
+ - COMPLETENESS: Does the answer cover the main aspects of the question?
20
+ - FORMAT: Is the answer in clean Markdown (not raw JSON, not gibberish)?
21
+
22
+ Respond in EXACTLY this format (no extra text):
23
+ PASS or FAIL
24
+ CONFIDENCE: 0.0-1.0
25
+ REASON: one sentence explanation
26
+
27
+ Examples:
28
+ PASS
29
+ CONFIDENCE: 0.9
30
+ REASON: Answer correctly identifies the provider factory pattern in src/providers/factory.ts with specific line references.
31
+
32
+ FAIL
33
+ CONFIDENCE: 0.8
34
+ REASON: Answer describes the context.ts file but the user asked about LLM providers — completely off-topic.`;
35
+ // ── Critic execution ──────────────────────────────────────────────────────────
36
+ /**
37
+ * Run the critic agent to evaluate an answer.
38
+ *
39
+ * Uses a low temperature and short max tokens for fast, focused evaluation.
40
+ * Falls back to PASS if the critic call fails (non-blocking).
41
+ */
42
+ export async function criticEvaluate(provider, question, answer, options = {}) {
43
+ // Skip critic for very short answers (handled by basic validation)
44
+ if (answer.trim().length < 30) {
45
+ return { pass: false, reason: 'Answer is too short to be useful.', confidence: 1.0 };
46
+ }
47
+ try {
48
+ const request = {
49
+ messages: [{
50
+ role: 'user',
51
+ content: [
52
+ '## Original Question',
53
+ '',
54
+ question,
55
+ '',
56
+ '## Proposed Answer',
57
+ '',
58
+ answer.slice(0, 3000), // Cap answer length sent to critic
59
+ ].join('\n'),
60
+ }],
61
+ model: options.model,
62
+ temperature: 0.1,
63
+ maxTokens: 150,
64
+ systemPrompt: CRITIC_SYSTEM_PROMPT,
65
+ };
66
+ let response = '';
67
+ const stream = provider.streamCompletion(request);
68
+ for await (const chunk of stream) {
69
+ if (!chunk.done)
70
+ response += chunk.delta;
71
+ }
72
+ return parseCriticResponse(response.trim());
73
+ }
74
+ catch {
75
+ // Critic failure is non-fatal — default to pass
76
+ return { pass: true, reason: 'Critic evaluation failed, defaulting to pass.', confidence: 0.0 };
77
+ }
78
+ }
79
+ /**
80
+ * Parse the critic's structured response.
81
+ */
82
+ function parseCriticResponse(text) {
83
+ const lines = text.split('\n').map(l => l.trim()).filter(Boolean);
84
+ if (lines.length === 0) {
85
+ return { pass: true, reason: 'Empty critic response.', confidence: 0.0 };
86
+ }
87
+ const firstLine = lines[0].toUpperCase();
88
+ const pass = firstLine.includes('PASS');
89
+ // Extract confidence
90
+ let confidence = 0.5;
91
+ const confLine = lines.find(l => l.toUpperCase().startsWith('CONFIDENCE'));
92
+ if (confLine) {
93
+ const match = confLine.match(/[\d.]+/);
94
+ if (match)
95
+ confidence = Math.min(1, Math.max(0, parseFloat(match[0])));
96
+ }
97
+ // Extract reason
98
+ let reason = 'No reason provided.';
99
+ const reasonLine = lines.find(l => l.toUpperCase().startsWith('REASON'));
100
+ if (reasonLine) {
101
+ reason = reasonLine.replace(/^REASON:\s*/i, '').trim();
102
+ }
103
+ return { pass, reason, confidence };
104
+ }
105
+ /**
106
+ * Build a correction message from the critic's feedback.
107
+ * More specific than the generic buildCorrectionMessage.
108
+ */
109
+ export function buildCriticCorrection(verdict, originalQuestion) {
110
+ return [
111
+ `[CRITIC FEEDBACK: Your answer was rejected.]`,
112
+ '',
113
+ `Reason: ${verdict.reason}`,
114
+ '',
115
+ `The user's original question was: "${originalQuestion}"`,
116
+ '',
117
+ 'Provide a NEW answer that:',
118
+ '1. Directly addresses the question above',
119
+ '2. References specific file paths, line numbers, and code snippets',
120
+ '3. Is formatted in clean Markdown',
121
+ '4. Does NOT repeat your previous answer',
122
+ '',
123
+ 'If you need more information, use tools to search and read code first.',
124
+ ].join('\n');
125
+ }
126
+ //# sourceMappingURL=critic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"critic.js","sourceRoot":"","sources":["../../src/utils/critic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Symbol index builder — lightweight file→symbol mapping for faster retrieval.
3
+ *
4
+ * Scans source files for exported symbols (functions, classes, interfaces,
5
+ * types, constants) and builds an index file at `.jam/symbol-index.json`.
6
+ *
7
+ * The index is used by the planner and enrichment stages to suggest specific
8
+ * files to the model based on symbol names, reducing wasted search rounds.
9
+ */
10
+ export interface SymbolEntry {
11
+ /** Symbol name (function, class, interface, variable name). */
12
+ name: string;
13
+ /** Kind of symbol. */
14
+ kind: 'function' | 'class' | 'interface' | 'type' | 'const' | 'enum' | 'variable';
15
+ /** File path relative to workspace root. */
16
+ file: string;
17
+ /** 1-based line number where the symbol is defined. */
18
+ line: number;
19
+ }
20
+ export interface SymbolIndex {
21
+ /** When the index was built (ISO timestamp). */
22
+ builtAt: string;
23
+ /** Number of files scanned. */
24
+ filesScanned: number;
25
+ /** Total symbols found. */
26
+ totalSymbols: number;
27
+ /** All symbol entries. */
28
+ symbols: SymbolEntry[];
29
+ }
30
+ /**
31
+ * Build a symbol index for the workspace.
32
+ * Scans all source files and extracts exported symbols.
33
+ */
34
+ export declare function buildSymbolIndex(workspaceRoot: string): Promise<SymbolIndex>;
35
+ /**
36
+ * Load the cached symbol index from disk.
37
+ * Returns null if no index exists or it's too stale.
38
+ */
39
+ export declare function loadSymbolIndex(workspaceRoot: string, maxAge?: number): Promise<SymbolIndex | null>;
40
+ /**
41
+ * Load or build the symbol index (builds if missing/stale).
42
+ */
43
+ export declare function getOrBuildIndex(workspaceRoot: string): Promise<SymbolIndex>;
44
+ /**
45
+ * Search the symbol index for symbols matching a query.
46
+ * Returns matching symbols sorted by relevance.
47
+ */
48
+ export declare function searchSymbols(index: SymbolIndex, query: string, maxResults?: number): SymbolEntry[];
49
+ /**
50
+ * Format symbol search results for injection into context.
51
+ */
52
+ export declare function formatSymbolResults(symbols: SymbolEntry[]): string;
53
+ //# sourceMappingURL=index-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-builder.d.ts","sourceRoot":"","sources":["../../src/utils/index-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;IAClF,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAoJD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA6ClF;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,MAAuB,GAC9B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAa7B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAIjF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAW,GACtB,WAAW,EAAE,CAyBf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAUlE"}