@sunilp-org/jam-cli 0.1.0 → 0.1.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/README.md +431 -63
- package/dist/commands/ask.d.ts +4 -0
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +202 -10
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/commit.d.ts +12 -0
- package/dist/commands/commit.d.ts.map +1 -0
- package/dist/commands/commit.js +135 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +2 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/context.d.ts +12 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +52 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/review.d.ts +25 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +117 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +199 -197
- package/dist/commands/run.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +39 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/index.js +63 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/base.d.ts +26 -0
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/embedded.d.ts +20 -0
- package/dist/providers/embedded.d.ts.map +1 -0
- package/dist/providers/embedded.js +302 -0
- package/dist/providers/embedded.js.map +1 -0
- package/dist/providers/factory.d.ts.map +1 -1
- package/dist/providers/factory.js +25 -1
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/groq.d.ts +16 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/groq.js +23 -0
- package/dist/providers/groq.js.map +1 -0
- package/dist/providers/ollama.d.ts +6 -1
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +77 -4
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +18 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +229 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/tools/all-tools.d.ts +18 -0
- package/dist/tools/all-tools.d.ts.map +1 -0
- package/dist/tools/all-tools.js +95 -0
- package/dist/tools/all-tools.js.map +1 -0
- package/dist/tools/apply_patch.js +1 -1
- package/dist/tools/apply_patch.js.map +1 -1
- package/dist/tools/context-tools.d.ts +14 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +63 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/git_diff.js +1 -1
- package/dist/tools/git_diff.js.map +1 -1
- package/dist/tools/git_status.js +1 -1
- package/dist/tools/git_status.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +2 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run_command.d.ts +8 -3
- package/dist/tools/run_command.d.ts.map +1 -1
- package/dist/tools/run_command.js +90 -3
- package/dist/tools/run_command.js.map +1 -1
- package/dist/ui/chat.d.ts.map +1 -1
- package/dist/ui/chat.js +173 -1
- package/dist/ui/chat.js.map +1 -1
- package/dist/ui/logo.d.ts.map +1 -1
- package/dist/ui/logo.js +5 -1
- package/dist/ui/logo.js.map +1 -1
- package/dist/utils/agent.d.ts +130 -0
- package/dist/utils/agent.d.ts.map +1 -0
- package/dist/utils/agent.js +449 -0
- package/dist/utils/agent.js.map +1 -0
- package/dist/utils/cache.d.ts +30 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +62 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/context.d.ts +38 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +383 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/critic.d.ts +31 -0
- package/dist/utils/critic.d.ts.map +1 -0
- package/dist/utils/critic.js +126 -0
- package/dist/utils/critic.js.map +1 -0
- package/dist/utils/index-builder.d.ts +53 -0
- package/dist/utils/index-builder.d.ts.map +1 -0
- package/dist/utils/index-builder.js +241 -0
- package/dist/utils/index-builder.js.map +1 -0
- package/dist/utils/memory.d.ts +104 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +215 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/past-sessions.d.ts +31 -0
- package/dist/utils/past-sessions.d.ts.map +1 -0
- package/dist/utils/past-sessions.js +126 -0
- package/dist/utils/past-sessions.js.map +1 -0
- package/dist/utils/tokens.d.ts +53 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +138 -0
- package/dist/utils/tokens.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result cache — avoids redundant file reads and searches within a session.
|
|
3
|
+
*
|
|
4
|
+
* Keyed by (toolName, JSON.stringify(args)). File reads are invalidated
|
|
5
|
+
* if a write_file or apply_patch call modifies the same path.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ToolResultCache {
|
|
8
|
+
private cache;
|
|
9
|
+
/** TTL in ms — stale results are evicted (default: 5 minutes). */
|
|
10
|
+
private ttl;
|
|
11
|
+
constructor(ttlMs?: number);
|
|
12
|
+
private key;
|
|
13
|
+
/**
|
|
14
|
+
* Get a cached result. Returns `null` if not found or expired.
|
|
15
|
+
*/
|
|
16
|
+
get(name: string, args: Record<string, unknown>): string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Store a tool result.
|
|
19
|
+
*/
|
|
20
|
+
set(name: string, args: Record<string, unknown>, output: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Invalidate cached reads for a file path (called after write/patch operations).
|
|
23
|
+
*/
|
|
24
|
+
invalidatePath(filePath: string): void;
|
|
25
|
+
/** Number of cached entries. */
|
|
26
|
+
get size(): number;
|
|
27
|
+
/** Clear all cached results. */
|
|
28
|
+
clear(): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAA4D;IAEzE,kEAAkE;IAClE,OAAO,CAAC,GAAG,CAAS;gBAER,KAAK,GAAE,MAAsB;IAIzC,OAAO,CAAC,GAAG;IAIX;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI;IAW/D;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKtE;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAatC,gCAAgC;IAChC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gCAAgC;IAChC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool result cache — avoids redundant file reads and searches within a session.
|
|
3
|
+
*
|
|
4
|
+
* Keyed by (toolName, JSON.stringify(args)). File reads are invalidated
|
|
5
|
+
* if a write_file or apply_patch call modifies the same path.
|
|
6
|
+
*/
|
|
7
|
+
export class ToolResultCache {
|
|
8
|
+
cache = new Map();
|
|
9
|
+
/** TTL in ms — stale results are evicted (default: 5 minutes). */
|
|
10
|
+
ttl;
|
|
11
|
+
constructor(ttlMs = 5 * 60 * 1000) {
|
|
12
|
+
this.ttl = ttlMs;
|
|
13
|
+
}
|
|
14
|
+
key(name, args) {
|
|
15
|
+
return `${name}:${JSON.stringify(args, Object.keys(args).sort())}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get a cached result. Returns `null` if not found or expired.
|
|
19
|
+
*/
|
|
20
|
+
get(name, args) {
|
|
21
|
+
const k = this.key(name, args);
|
|
22
|
+
const entry = this.cache.get(k);
|
|
23
|
+
if (!entry)
|
|
24
|
+
return null;
|
|
25
|
+
if (Date.now() - entry.timestamp > this.ttl) {
|
|
26
|
+
this.cache.delete(k);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return entry.output;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Store a tool result.
|
|
33
|
+
*/
|
|
34
|
+
set(name, args, output) {
|
|
35
|
+
const k = this.key(name, args);
|
|
36
|
+
this.cache.set(k, { output, timestamp: Date.now() });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Invalidate cached reads for a file path (called after write/patch operations).
|
|
40
|
+
*/
|
|
41
|
+
invalidatePath(filePath) {
|
|
42
|
+
for (const [k] of this.cache) {
|
|
43
|
+
// Invalidate any read_file cache entries that match this path
|
|
44
|
+
if (k.startsWith('read_file:') && k.includes(filePath)) {
|
|
45
|
+
this.cache.delete(k);
|
|
46
|
+
}
|
|
47
|
+
// Also invalidate search_text since file contents changed
|
|
48
|
+
if (k.startsWith('search_text:')) {
|
|
49
|
+
this.cache.delete(k);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Number of cached entries. */
|
|
54
|
+
get size() {
|
|
55
|
+
return this.cache.size;
|
|
56
|
+
}
|
|
57
|
+
/** Clear all cached results. */
|
|
58
|
+
clear() {
|
|
59
|
+
this.cache.clear();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,OAAO,eAAe;IAClB,KAAK,GAAG,IAAI,GAAG,EAAiD,CAAC;IAEzE,kEAAkE;IAC1D,GAAG,CAAS;IAEpB,YAAY,QAAgB,CAAC,GAAG,EAAE,GAAG,IAAI;QACvC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC;IACnB,CAAC;IAEO,GAAG,CAAC,IAAY,EAAE,IAA6B;QACrD,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY,EAAE,IAA6B;QAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY,EAAE,IAA6B,EAAE,MAAc;QAC7D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,QAAgB;QAC7B,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,8DAA8D;YAC9D,IAAI,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YACD,0DAA0D;YAC1D,IAAI,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,gCAAgC;IAChC,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
export declare const CONTEXT_FILENAME = "JAM.md";
|
|
13
|
+
/**
|
|
14
|
+
* Load `JAM.md` from the workspace root. Returns `null` if not found.
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadContextFile(workspaceRoot: string): Promise<string | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Generate JAM.md content by auto-discovering the project.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateContextContent(workspaceRoot: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Write JAM.md to the workspace root. Returns the path written.
|
|
23
|
+
*/
|
|
24
|
+
export declare function writeContextFile(workspaceRoot: string, content: string): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if JAM.md already exists.
|
|
27
|
+
*/
|
|
28
|
+
export declare function contextFileExists(workspaceRoot: string): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Update JAM.md with frequently accessed file patterns from the session.
|
|
31
|
+
* Appends or replaces a "Frequently Accessed Files" section.
|
|
32
|
+
*
|
|
33
|
+
* @param workspaceRoot Workspace root path
|
|
34
|
+
* @param readFiles Array of file paths accessed during sessions
|
|
35
|
+
* @param searchQueries Array of search queries used during sessions
|
|
36
|
+
*/
|
|
37
|
+
export declare function updateContextWithUsage(workspaceRoot: string, readFiles: string[], searchQueries: string[]): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAIzC;;GAEG;AACH,wBAAsB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOnF;AAgMD;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgGnF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/E;AAOD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
|
|
@@ -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"}
|