openplanr 0.1.0 → 0.3.0
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 +23 -5
- package/dist/agents/agent-factory.d.ts +7 -0
- package/dist/agents/agent-factory.d.ts.map +1 -0
- package/dist/agents/agent-factory.js +22 -0
- package/dist/agents/agent-factory.js.map +1 -0
- package/dist/agents/claude-agent.d.ts +13 -0
- package/dist/agents/claude-agent.d.ts.map +1 -0
- package/dist/agents/claude-agent.js +48 -0
- package/dist/agents/claude-agent.js.map +1 -0
- package/dist/agents/codex-agent.d.ts +13 -0
- package/dist/agents/codex-agent.d.ts.map +1 -0
- package/dist/agents/codex-agent.js +47 -0
- package/dist/agents/codex-agent.js.map +1 -0
- package/dist/agents/cursor-agent.d.ts +13 -0
- package/dist/agents/cursor-agent.d.ts.map +1 -0
- package/dist/agents/cursor-agent.js +40 -0
- package/dist/agents/cursor-agent.js.map +1 -0
- package/dist/agents/implementation-bridge.d.ts +21 -0
- package/dist/agents/implementation-bridge.d.ts.map +1 -0
- package/dist/agents/implementation-bridge.js +173 -0
- package/dist/agents/implementation-bridge.js.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/prompt-composer.d.ts +30 -0
- package/dist/agents/prompt-composer.d.ts.map +1 -0
- package/dist/agents/prompt-composer.js +81 -0
- package/dist/agents/prompt-composer.js.map +1 -0
- package/dist/agents/task-parser.d.ts +38 -0
- package/dist/agents/task-parser.d.ts.map +1 -0
- package/dist/agents/task-parser.js +83 -0
- package/dist/agents/task-parser.js.map +1 -0
- package/dist/agents/types.d.ts +23 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +8 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/utils.d.ts +9 -0
- package/dist/agents/utils.d.ts.map +1 -0
- package/dist/agents/utils.js +21 -0
- package/dist/agents/utils.js.map +1 -0
- package/dist/ai/codebase/context-builder.d.ts +31 -0
- package/dist/ai/codebase/context-builder.d.ts.map +1 -0
- package/dist/ai/codebase/context-builder.js +93 -0
- package/dist/ai/codebase/context-builder.js.map +1 -0
- package/dist/ai/codebase/file-reader.d.ts +22 -0
- package/dist/ai/codebase/file-reader.d.ts.map +1 -0
- package/dist/ai/codebase/file-reader.js +111 -0
- package/dist/ai/codebase/file-reader.js.map +1 -0
- package/dist/ai/codebase/index.d.ts +5 -0
- package/dist/ai/codebase/index.d.ts.map +1 -0
- package/dist/ai/codebase/index.js +5 -0
- package/dist/ai/codebase/index.js.map +1 -0
- package/dist/ai/codebase/stack-detector.d.ts +18 -0
- package/dist/ai/codebase/stack-detector.d.ts.map +1 -0
- package/dist/ai/codebase/stack-detector.js +147 -0
- package/dist/ai/codebase/stack-detector.js.map +1 -0
- package/dist/ai/codebase/tree-generator.d.ts +8 -0
- package/dist/ai/codebase/tree-generator.d.ts.map +1 -0
- package/dist/ai/codebase/tree-generator.js +85 -0
- package/dist/ai/codebase/tree-generator.js.map +1 -0
- package/dist/ai/errors.d.ts +22 -0
- package/dist/ai/errors.d.ts.map +1 -0
- package/dist/ai/errors.js +70 -0
- package/dist/ai/errors.js.map +1 -0
- package/dist/ai/index.d.ts +11 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +10 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts/prompt-builder.d.ts +42 -0
- package/dist/ai/prompts/prompt-builder.d.ts.map +1 -0
- package/dist/ai/prompts/prompt-builder.js +96 -0
- package/dist/ai/prompts/prompt-builder.js.map +1 -0
- package/dist/ai/prompts/system-prompts.d.ts +13 -0
- package/dist/ai/prompts/system-prompts.d.ts.map +1 -0
- package/dist/ai/prompts/system-prompts.js +124 -0
- package/dist/ai/prompts/system-prompts.js.map +1 -0
- package/dist/ai/provider-factory.d.ts +10 -0
- package/dist/ai/provider-factory.d.ts.map +1 -0
- package/dist/ai/provider-factory.js +33 -0
- package/dist/ai/provider-factory.js.map +1 -0
- package/dist/ai/providers/anthropic-provider.d.ts +22 -0
- package/dist/ai/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/ai/providers/anthropic-provider.js +82 -0
- package/dist/ai/providers/anthropic-provider.js.map +1 -0
- package/dist/ai/providers/ollama-provider.d.ts +13 -0
- package/dist/ai/providers/ollama-provider.d.ts.map +1 -0
- package/dist/ai/providers/ollama-provider.js +16 -0
- package/dist/ai/providers/ollama-provider.js.map +1 -0
- package/dist/ai/providers/openai-provider.d.ts +17 -0
- package/dist/ai/providers/openai-provider.d.ts.map +1 -0
- package/dist/ai/providers/openai-provider.js +58 -0
- package/dist/ai/providers/openai-provider.js.map +1 -0
- package/dist/ai/schemas/ai-response-schemas.d.ts +425 -0
- package/dist/ai/schemas/ai-response-schemas.d.ts.map +1 -0
- package/dist/ai/schemas/ai-response-schemas.js +87 -0
- package/dist/ai/schemas/ai-response-schemas.js.map +1 -0
- package/dist/ai/types.d.ts +40 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +16 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/commands/checklist.d.ts.map +1 -1
- package/dist/cli/commands/checklist.js +60 -1
- package/dist/cli/commands/checklist.js.map +1 -1
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +112 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/epic.d.ts +7 -0
- package/dist/cli/commands/epic.d.ts.map +1 -1
- package/dist/cli/commands/epic.js +161 -31
- package/dist/cli/commands/epic.js.map +1 -1
- package/dist/cli/commands/feature.d.ts +6 -0
- package/dist/cli/commands/feature.d.ts.map +1 -1
- package/dist/cli/commands/feature.js +143 -30
- package/dist/cli/commands/feature.js.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +48 -6
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +15 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +259 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/refine.d.ts +9 -0
- package/dist/cli/commands/refine.d.ts.map +1 -0
- package/dist/cli/commands/refine.js +101 -0
- package/dist/cli/commands/refine.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +150 -18
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/story.d.ts +6 -0
- package/dist/cli/commands/story.d.ts.map +1 -1
- package/dist/cli/commands/story.js +259 -45
- package/dist/cli/commands/story.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +12 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +227 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/task.d.ts +9 -0
- package/dist/cli/commands/task.d.ts.map +1 -1
- package/dist/cli/commands/task.js +350 -35
- package/dist/cli/commands/task.js.map +1 -1
- package/dist/cli/index.js +16 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/models/schema.d.ts +41 -0
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +9 -0
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +9 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/ai-service.d.ts +40 -0
- package/dist/services/ai-service.d.ts.map +1 -0
- package/dist/services/ai-service.js +150 -0
- package/dist/services/ai-service.js.map +1 -0
- package/dist/services/artifact-gathering.d.ts +49 -0
- package/dist/services/artifact-gathering.d.ts.map +1 -0
- package/dist/services/artifact-gathering.js +128 -0
- package/dist/services/artifact-gathering.js.map +1 -0
- package/dist/services/artifact-service.d.ts +47 -0
- package/dist/services/artifact-service.d.ts.map +1 -1
- package/dist/services/artifact-service.js +169 -0
- package/dist/services/artifact-service.js.map +1 -1
- package/dist/services/checklist-service.d.ts +23 -0
- package/dist/services/checklist-service.d.ts.map +1 -1
- package/dist/services/checklist-service.js +44 -0
- package/dist/services/checklist-service.js.map +1 -1
- package/dist/services/credentials-service.d.ts +22 -0
- package/dist/services/credentials-service.d.ts.map +1 -0
- package/dist/services/credentials-service.js +58 -0
- package/dist/services/credentials-service.js.map +1 -0
- package/dist/services/id-service.d.ts.map +1 -1
- package/dist/services/id-service.js +8 -5
- package/dist/services/id-service.js.map +1 -1
- package/dist/services/prompt-service.d.ts +6 -0
- package/dist/services/prompt-service.d.ts.map +1 -1
- package/dist/services/prompt-service.js +7 -1
- package/dist/services/prompt-service.js.map +1 -1
- package/dist/services/template-service.d.ts.map +1 -1
- package/dist/services/template-service.js +6 -0
- package/dist/services/template-service.js.map +1 -1
- package/dist/templates/checklists/agile-checklist.md.hbs +8 -8
- package/dist/templates/epics/epic.md.hbs +8 -2
- package/dist/templates/features/feature.md.hbs +3 -3
- package/dist/templates/rules/cursor/2001-agile-create-epic.mdc.hbs +1 -1
- package/dist/templates/rules/cursor/2002-agile-create-features.mdc.hbs +1 -1
- package/dist/templates/rules/cursor/2003-agile-create-user-story.mdc.hbs +1 -1
- package/dist/templates/stories/user-story.md.hbs +2 -2
- package/dist/templates/tasks/task-list.md.hbs +26 -3
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +12 -0
- package/dist/utils/logger.js.map +1 -1
- package/package.json +12 -5
- package/dist/templates/templates/adrs/adr-general.md.hbs +0 -46
- package/dist/templates/templates/checklists/agile-checklist.md.hbs +0 -49
- package/dist/templates/templates/epics/epic.md.hbs +0 -46
- package/dist/templates/templates/features/feature.md.hbs +0 -42
- package/dist/templates/templates/rules/claude/CLAUDE.md.hbs +0 -63
- package/dist/templates/templates/rules/codex/AGENTS.md.hbs +0 -28
- package/dist/templates/templates/rules/cursor/2000-agile-checklist.mdc.hbs +0 -33
- package/dist/templates/templates/rules/cursor/2001-agile-create-epic.mdc.hbs +0 -35
- package/dist/templates/templates/rules/cursor/2002-agile-create-features.mdc.hbs +0 -35
- package/dist/templates/templates/rules/cursor/2003-agile-create-user-story.mdc.hbs +0 -31
- package/dist/templates/templates/rules/cursor/2100-create-task-list.mdc.hbs +0 -36
- package/dist/templates/templates/rules/cursor/2101-implement-task-list.mdc.hbs +0 -28
- package/dist/templates/templates/stories/gherkin.feature.hbs +0 -13
- package/dist/templates/templates/stories/user-story.md.hbs +0 -28
- package/dist/templates/templates/tasks/task-list.md.hbs +0 -24
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composes rich implementation prompts for coding agents.
|
|
3
|
+
*
|
|
4
|
+
* Assembles a structured prompt from:
|
|
5
|
+
* 1. Target subtask details
|
|
6
|
+
* 2. Full task list context (what's done, what's next)
|
|
7
|
+
* 3. Parent story and feature context
|
|
8
|
+
* 4. Codebase context (tech stack, folder tree, related files)
|
|
9
|
+
*
|
|
10
|
+
* The output is a detailed markdown prompt that any coding agent
|
|
11
|
+
* (Claude, Cursor, Codex) can understand and act on.
|
|
12
|
+
*/
|
|
13
|
+
import { formatSubtaskList } from './task-parser.js';
|
|
14
|
+
/**
|
|
15
|
+
* Compose a complete implementation prompt from gathered context.
|
|
16
|
+
* Returns a markdown string ready to be sent to a coding agent.
|
|
17
|
+
*/
|
|
18
|
+
export function composeImplementationPrompt(ctx) {
|
|
19
|
+
const sections = [];
|
|
20
|
+
// Header
|
|
21
|
+
sections.push(`# Implementation Task: ${ctx.taskId}`);
|
|
22
|
+
// Target subtask(s)
|
|
23
|
+
if (ctx.targetSubtasks.length > 0) {
|
|
24
|
+
sections.push('## Target Subtask(s)\n');
|
|
25
|
+
sections.push('Implement ONLY the following subtask(s):');
|
|
26
|
+
sections.push('');
|
|
27
|
+
for (const st of ctx.targetSubtasks) {
|
|
28
|
+
sections.push(`- **${st.id}**: ${st.title}`);
|
|
29
|
+
}
|
|
30
|
+
// Parent group context
|
|
31
|
+
const parentId = ctx.targetSubtasks[0]?.parentId;
|
|
32
|
+
if (parentId) {
|
|
33
|
+
const parentGroup = ctx.allSubtasks.find((t) => t.id === parentId);
|
|
34
|
+
if (parentGroup) {
|
|
35
|
+
sections.push(`\nParent task group: **${parentGroup.id}** ${parentGroup.title}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Full task list (shows what's done and what's pending)
|
|
40
|
+
sections.push('\n## Full Task List\n');
|
|
41
|
+
sections.push('```');
|
|
42
|
+
const targetIds = new Set(ctx.targetSubtasks.map((t) => t.id));
|
|
43
|
+
const firstTargetId = ctx.targetSubtasks[0]?.id;
|
|
44
|
+
sections.push(formatSubtaskList(ctx.allSubtasks, firstTargetId));
|
|
45
|
+
sections.push('```');
|
|
46
|
+
// Parent story context
|
|
47
|
+
if (ctx.storyContent) {
|
|
48
|
+
sections.push('\n## User Story Context\n');
|
|
49
|
+
sections.push(truncate(ctx.storyContent, 3000));
|
|
50
|
+
}
|
|
51
|
+
// Parent feature context
|
|
52
|
+
if (ctx.featureContent) {
|
|
53
|
+
sections.push('\n## Feature Context\n');
|
|
54
|
+
sections.push(truncate(ctx.featureContent, 2000));
|
|
55
|
+
}
|
|
56
|
+
// Parent epic context (brief)
|
|
57
|
+
if (ctx.epicContent) {
|
|
58
|
+
sections.push('\n## Epic Context (summary)\n');
|
|
59
|
+
sections.push(truncate(ctx.epicContent, 1000));
|
|
60
|
+
}
|
|
61
|
+
// Codebase context
|
|
62
|
+
if (ctx.codebaseContext) {
|
|
63
|
+
sections.push('\n## Codebase Context\n');
|
|
64
|
+
sections.push(ctx.codebaseContext);
|
|
65
|
+
}
|
|
66
|
+
// Instructions
|
|
67
|
+
sections.push('\n## Instructions\n');
|
|
68
|
+
sections.push('1. Implement ONLY the target subtask(s) listed above.');
|
|
69
|
+
sections.push('2. Follow existing code patterns and conventions in the codebase.');
|
|
70
|
+
sections.push('3. Write clean, well-documented code.');
|
|
71
|
+
sections.push('4. Include appropriate error handling.');
|
|
72
|
+
sections.push('5. Add or update tests for the changes.');
|
|
73
|
+
sections.push('6. Do NOT modify code unrelated to the target subtask(s).');
|
|
74
|
+
return sections.join('\n');
|
|
75
|
+
}
|
|
76
|
+
function truncate(text, maxChars) {
|
|
77
|
+
if (text.length <= maxChars)
|
|
78
|
+
return text;
|
|
79
|
+
return text.slice(0, maxChars) + '\n\n... (truncated)';
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=prompt-composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-composer.js","sourceRoot":"","sources":["../../src/agents/prompt-composer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses task list markdown files to extract subtask structure.
|
|
3
|
+
*
|
|
4
|
+
* Supports addressing subtasks by:
|
|
5
|
+
* - ID (e.g., "2.1")
|
|
6
|
+
* - Group ID (e.g., "2.0" returns the group + all subtasks)
|
|
7
|
+
* - Keyword search (e.g., "auth" fuzzy-matches against titles)
|
|
8
|
+
* - Next pending (returns the first unchecked subtask)
|
|
9
|
+
*/
|
|
10
|
+
export interface ParsedSubtask {
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
done: boolean;
|
|
14
|
+
parentId: string | null;
|
|
15
|
+
depth: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse a task list markdown file into structured subtasks.
|
|
19
|
+
* Expected format: `- [x] 1.0 Task title` or ` - [ ] 1.1 Subtask title`
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseTaskMarkdown(content: string): ParsedSubtask[];
|
|
22
|
+
/**
|
|
23
|
+
* Find subtasks matching a query.
|
|
24
|
+
*
|
|
25
|
+
* - Exact ID match: "2.1" → single subtask
|
|
26
|
+
* - Group match: "2.0" → group + all its subtasks
|
|
27
|
+
* - Keyword search: "auth" → fuzzy match on titles
|
|
28
|
+
*/
|
|
29
|
+
export declare function findSubtasks(tasks: ParsedSubtask[], query: string): ParsedSubtask[];
|
|
30
|
+
/**
|
|
31
|
+
* Get the next pending (unchecked) subtask.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getNextPending(tasks: ParsedSubtask[]): ParsedSubtask | null;
|
|
34
|
+
/**
|
|
35
|
+
* Format subtasks for display in the terminal.
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatSubtaskList(tasks: ParsedSubtask[], highlightId?: string): string;
|
|
38
|
+
//# sourceMappingURL=task-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-parser.d.ts","sourceRoot":"","sources":["../../src/agents/task-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CA+BlE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAgBnF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,GAAG,IAAI,CAE3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAStF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses task list markdown files to extract subtask structure.
|
|
3
|
+
*
|
|
4
|
+
* Supports addressing subtasks by:
|
|
5
|
+
* - ID (e.g., "2.1")
|
|
6
|
+
* - Group ID (e.g., "2.0" returns the group + all subtasks)
|
|
7
|
+
* - Keyword search (e.g., "auth" fuzzy-matches against titles)
|
|
8
|
+
* - Next pending (returns the first unchecked subtask)
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parse a task list markdown file into structured subtasks.
|
|
12
|
+
* Expected format: `- [x] 1.0 Task title` or ` - [ ] 1.1 Subtask title`
|
|
13
|
+
*/
|
|
14
|
+
export function parseTaskMarkdown(content) {
|
|
15
|
+
const tasks = [];
|
|
16
|
+
const lines = content.split('\n');
|
|
17
|
+
let currentGroupId = null;
|
|
18
|
+
for (const line of lines) {
|
|
19
|
+
// Match: - [x] 1.0 Task title OR - [ ] 1.1 Subtask title
|
|
20
|
+
const match = line.match(/^(\s*)- \[(x| )\]\s+(\d+\.\d+)\s+(.+)$/);
|
|
21
|
+
if (!match)
|
|
22
|
+
continue;
|
|
23
|
+
const indent = match[1].length;
|
|
24
|
+
const done = match[2] === 'x';
|
|
25
|
+
const id = match[3];
|
|
26
|
+
const title = match[4].trim();
|
|
27
|
+
const depth = indent > 0 ? 1 : 0;
|
|
28
|
+
if (depth === 0) {
|
|
29
|
+
currentGroupId = id;
|
|
30
|
+
}
|
|
31
|
+
tasks.push({
|
|
32
|
+
id,
|
|
33
|
+
title,
|
|
34
|
+
done,
|
|
35
|
+
parentId: depth === 0 ? null : currentGroupId,
|
|
36
|
+
depth,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return tasks;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Find subtasks matching a query.
|
|
43
|
+
*
|
|
44
|
+
* - Exact ID match: "2.1" → single subtask
|
|
45
|
+
* - Group match: "2.0" → group + all its subtasks
|
|
46
|
+
* - Keyword search: "auth" → fuzzy match on titles
|
|
47
|
+
*/
|
|
48
|
+
export function findSubtasks(tasks, query) {
|
|
49
|
+
// Try exact ID match
|
|
50
|
+
const exactMatch = tasks.filter((t) => t.id === query);
|
|
51
|
+
if (exactMatch.length > 0) {
|
|
52
|
+
// If it's a group (x.0), include its children
|
|
53
|
+
const isGroup = query.endsWith('.0');
|
|
54
|
+
if (isGroup) {
|
|
55
|
+
const groupNum = query.split('.')[0];
|
|
56
|
+
return tasks.filter((t) => t.id.startsWith(groupNum + '.'));
|
|
57
|
+
}
|
|
58
|
+
return exactMatch;
|
|
59
|
+
}
|
|
60
|
+
// Fuzzy keyword search
|
|
61
|
+
const lowerQuery = query.toLowerCase();
|
|
62
|
+
return tasks.filter((t) => t.title.toLowerCase().includes(lowerQuery));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the next pending (unchecked) subtask.
|
|
66
|
+
*/
|
|
67
|
+
export function getNextPending(tasks) {
|
|
68
|
+
return tasks.find((t) => !t.done && t.depth > 0) || tasks.find((t) => !t.done) || null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Format subtasks for display in the terminal.
|
|
72
|
+
*/
|
|
73
|
+
export function formatSubtaskList(tasks, highlightId) {
|
|
74
|
+
return tasks
|
|
75
|
+
.map((t) => {
|
|
76
|
+
const checkbox = t.done ? '[x]' : '[ ]';
|
|
77
|
+
const indent = t.depth > 0 ? ' ' : '';
|
|
78
|
+
const marker = t.id === highlightId ? ' ← TARGET' : '';
|
|
79
|
+
return `${indent}- ${checkbox} ${t.id} ${t.title}${marker}`;
|
|
80
|
+
})
|
|
81
|
+
.join('\n');
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=task-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-parser.js","sourceRoot":"","sources":["../../src/agents/task-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coding agent abstraction types.
|
|
3
|
+
*
|
|
4
|
+
* Each supported coding agent (Claude CLI, Cursor, Codex) implements
|
|
5
|
+
* the CodingAgent interface for unified task implementation dispatch.
|
|
6
|
+
*/
|
|
7
|
+
export interface AgentOptions {
|
|
8
|
+
cwd: string;
|
|
9
|
+
stream: boolean;
|
|
10
|
+
dryRun: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface AgentResult {
|
|
13
|
+
output: string;
|
|
14
|
+
exitCode: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CodingAgent {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** Check if the coding agent CLI/tool is available on this machine. */
|
|
19
|
+
isAvailable(): Promise<boolean>;
|
|
20
|
+
/** Execute an implementation prompt via the coding agent. */
|
|
21
|
+
execute(prompt: string, options: AgentOptions): Promise<AgentResult>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,uEAAuE;IACvE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhC,6DAA6D;IAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACtE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for the agents module.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if a command exists on the system PATH.
|
|
6
|
+
* Returns the path to the command or null.
|
|
7
|
+
*/
|
|
8
|
+
export declare function which(command: string): Promise<string | null>;
|
|
9
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/agents/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH;;;GAGG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for the agents module.
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
/**
|
|
8
|
+
* Check if a command exists on the system PATH.
|
|
9
|
+
* Returns the path to the command or null.
|
|
10
|
+
*/
|
|
11
|
+
export async function which(command) {
|
|
12
|
+
try {
|
|
13
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
14
|
+
const { stdout } = await execFileAsync(cmd, [command]);
|
|
15
|
+
return stdout.trim() || null;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/agents/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAe;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAC7D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrates codebase awareness into a single context string.
|
|
3
|
+
*
|
|
4
|
+
* Combines tech stack detection, folder tree, and related file snippets
|
|
5
|
+
* into a formatted block for inclusion in AI prompts. Respects a token
|
|
6
|
+
* budget (~8K tokens ≈ 32K chars) to avoid prompt overflow.
|
|
7
|
+
*/
|
|
8
|
+
import { type TechStack } from './stack-detector.js';
|
|
9
|
+
export interface CodebaseContext {
|
|
10
|
+
techStack: TechStack | null;
|
|
11
|
+
folderTree: string;
|
|
12
|
+
relatedFiles: Map<string, string>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build a complete codebase context for AI prompt enrichment.
|
|
16
|
+
*
|
|
17
|
+
* @param projectDir - Project root directory
|
|
18
|
+
* @param keywords - Keywords to find related files (extracted from task/story)
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildCodebaseContext(projectDir: string, keywords?: string[]): Promise<CodebaseContext>;
|
|
21
|
+
/**
|
|
22
|
+
* Format the codebase context into a prompt-friendly string.
|
|
23
|
+
* Applies token budget by progressively dropping lower-priority sections.
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatCodebaseContext(ctx: CodebaseContext): string;
|
|
26
|
+
/**
|
|
27
|
+
* Extract keywords from artifact content for file searching.
|
|
28
|
+
* Looks for capitalized terms, technical words, and file paths.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractKeywords(content: string): string[];
|
|
31
|
+
//# sourceMappingURL=context-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../src/ai/codebase/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAMvF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAM,EAAO,GACtB,OAAO,CAAC,eAAe,CAAC,CAU1B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAwClE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BzD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrates codebase awareness into a single context string.
|
|
3
|
+
*
|
|
4
|
+
* Combines tech stack detection, folder tree, and related file snippets
|
|
5
|
+
* into a formatted block for inclusion in AI prompts. Respects a token
|
|
6
|
+
* budget (~8K tokens ≈ 32K chars) to avoid prompt overflow.
|
|
7
|
+
*/
|
|
8
|
+
import { detectTechStack, formatTechStack } from './stack-detector.js';
|
|
9
|
+
import { generateFolderTree } from './tree-generator.js';
|
|
10
|
+
import { findRelatedFiles, readFileSnippets } from './file-reader.js';
|
|
11
|
+
const MAX_CONTEXT_CHARS = 32_000; // ~8K tokens
|
|
12
|
+
/**
|
|
13
|
+
* Build a complete codebase context for AI prompt enrichment.
|
|
14
|
+
*
|
|
15
|
+
* @param projectDir - Project root directory
|
|
16
|
+
* @param keywords - Keywords to find related files (extracted from task/story)
|
|
17
|
+
*/
|
|
18
|
+
export async function buildCodebaseContext(projectDir, keywords = []) {
|
|
19
|
+
const [techStack, folderTree, relatedPaths] = await Promise.all([
|
|
20
|
+
detectTechStack(projectDir),
|
|
21
|
+
generateFolderTree(projectDir, 3),
|
|
22
|
+
findRelatedFiles(projectDir, keywords, 8),
|
|
23
|
+
]);
|
|
24
|
+
const relatedFiles = await readFileSnippets(projectDir, relatedPaths, 12_000);
|
|
25
|
+
return { techStack, folderTree, relatedFiles };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format the codebase context into a prompt-friendly string.
|
|
29
|
+
* Applies token budget by progressively dropping lower-priority sections.
|
|
30
|
+
*/
|
|
31
|
+
export function formatCodebaseContext(ctx) {
|
|
32
|
+
const sections = [];
|
|
33
|
+
// Priority 1: Tech stack (always included, small)
|
|
34
|
+
if (ctx.techStack) {
|
|
35
|
+
sections.push(`## Tech Stack\n${formatTechStack(ctx.techStack)}`);
|
|
36
|
+
}
|
|
37
|
+
// Priority 2: Folder tree (truncated if needed)
|
|
38
|
+
if (ctx.folderTree) {
|
|
39
|
+
const treeLines = ctx.folderTree.split('\n');
|
|
40
|
+
const maxLines = 60;
|
|
41
|
+
const truncatedTree = treeLines.length > maxLines
|
|
42
|
+
? treeLines.slice(0, maxLines).join('\n') + '\n... (truncated)'
|
|
43
|
+
: ctx.folderTree;
|
|
44
|
+
sections.push(`## Project Structure\n\`\`\`\n${truncatedTree}\n\`\`\``);
|
|
45
|
+
}
|
|
46
|
+
// Priority 3: Related file snippets (dropped if over budget)
|
|
47
|
+
if (ctx.relatedFiles.size > 0) {
|
|
48
|
+
const fileBlocks = [];
|
|
49
|
+
for (const [filePath, content] of ctx.relatedFiles) {
|
|
50
|
+
fileBlocks.push(`### ${filePath}\n\`\`\`\n${content}\n\`\`\``);
|
|
51
|
+
}
|
|
52
|
+
sections.push(`## Related Files\n${fileBlocks.join('\n\n')}`);
|
|
53
|
+
}
|
|
54
|
+
// Apply budget
|
|
55
|
+
let result = sections.join('\n\n');
|
|
56
|
+
if (result.length > MAX_CONTEXT_CHARS) {
|
|
57
|
+
// Drop file snippets first, keep stack + tree
|
|
58
|
+
result = sections.slice(0, 2).join('\n\n');
|
|
59
|
+
}
|
|
60
|
+
if (result.length > MAX_CONTEXT_CHARS) {
|
|
61
|
+
// Even tree is too large, truncate aggressively
|
|
62
|
+
result = result.slice(0, MAX_CONTEXT_CHARS) + '\n... (context truncated)';
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract keywords from artifact content for file searching.
|
|
68
|
+
* Looks for capitalized terms, technical words, and file paths.
|
|
69
|
+
*/
|
|
70
|
+
export function extractKeywords(content) {
|
|
71
|
+
const keywords = new Set();
|
|
72
|
+
// Extract file paths
|
|
73
|
+
const pathMatches = content.match(/[\w/-]+\.\w+/g) || [];
|
|
74
|
+
for (const p of pathMatches) {
|
|
75
|
+
const parts = p.split('/');
|
|
76
|
+
keywords.add(parts[parts.length - 1].replace(/\.\w+$/, ''));
|
|
77
|
+
}
|
|
78
|
+
// Extract technical terms (CamelCase or hyphenated)
|
|
79
|
+
const termMatches = content.match(/[A-Z][a-z]+(?:[A-Z][a-z]+)+|[a-z]+-[a-z]+/g) || [];
|
|
80
|
+
for (const term of termMatches) {
|
|
81
|
+
keywords.add(term.toLowerCase());
|
|
82
|
+
}
|
|
83
|
+
// Extract quoted terms
|
|
84
|
+
const quotedMatches = content.match(/"([^"]+)"|'([^']+)'/g) || [];
|
|
85
|
+
for (const q of quotedMatches) {
|
|
86
|
+
const clean = q.replace(/['"]/g, '').trim();
|
|
87
|
+
if (clean.length > 2 && clean.length < 30) {
|
|
88
|
+
keywords.add(clean.toLowerCase());
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return [...keywords].slice(0, 10);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=context-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../../src/ai/codebase/context-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight codebase file reading utilities.
|
|
3
|
+
*
|
|
4
|
+
* NOT a full indexer — just smart file reading for enriching AI prompts
|
|
5
|
+
* with relevant code context. Files larger than MAX_FILE_SIZE are skipped.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Read a single project file with size guard.
|
|
9
|
+
* Returns null if file is too large or doesn't exist.
|
|
10
|
+
*/
|
|
11
|
+
export declare function readProjectFile(projectDir: string, relativePath: string): Promise<string | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Find files whose names or paths match any of the given keywords.
|
|
14
|
+
* Returns relative paths, limited to maxResults.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findRelatedFiles(projectDir: string, keywords: string[], maxResults?: number): Promise<string[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Read multiple files and return a map of relative paths to truncated content.
|
|
19
|
+
* Respects a total character budget across all files.
|
|
20
|
+
*/
|
|
21
|
+
export declare function readFileSnippets(projectDir: string, relativePaths: string[], totalBudget?: number): Promise<Map<string, string>>;
|
|
22
|
+
//# sourceMappingURL=file-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-reader.d.ts","sourceRoot":"","sources":["../../../src/ai/codebase/file-reader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH;;;GAGG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,GAAE,MAAW,GACtB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAqDD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EAAE,EACvB,WAAW,GAAE,MAAe,GAC3B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgB9B"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight codebase file reading utilities.
|
|
3
|
+
*
|
|
4
|
+
* NOT a full indexer — just smart file reading for enriching AI prompts
|
|
5
|
+
* with relevant code context. Files larger than MAX_FILE_SIZE are skipped.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import fse from 'fs-extra';
|
|
9
|
+
const MAX_FILE_SIZE = 50_000; // 50KB per file
|
|
10
|
+
const MAX_SNIPPET_CHARS = 3_000; // Truncate snippets to this length
|
|
11
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
12
|
+
'.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
13
|
+
'.py', '.go', '.rs', '.java', '.kt', '.swift',
|
|
14
|
+
'.vue', '.svelte', '.astro',
|
|
15
|
+
'.sql', '.graphql', '.gql',
|
|
16
|
+
'.css', '.scss', '.less',
|
|
17
|
+
'.json', '.yaml', '.yml', '.toml',
|
|
18
|
+
'.md', '.mdx',
|
|
19
|
+
]);
|
|
20
|
+
const IGNORED_DIRS = new Set([
|
|
21
|
+
'node_modules', '.git', 'dist', 'build', 'out', '.next',
|
|
22
|
+
'__pycache__', 'vendor', 'target', '.venv', 'coverage',
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Read a single project file with size guard.
|
|
26
|
+
* Returns null if file is too large or doesn't exist.
|
|
27
|
+
*/
|
|
28
|
+
export async function readProjectFile(projectDir, relativePath) {
|
|
29
|
+
const fullPath = path.join(projectDir, relativePath);
|
|
30
|
+
try {
|
|
31
|
+
const stat = await fse.stat(fullPath);
|
|
32
|
+
if (stat.size > MAX_FILE_SIZE)
|
|
33
|
+
return null;
|
|
34
|
+
return await fse.readFile(fullPath, 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Find files whose names or paths match any of the given keywords.
|
|
42
|
+
* Returns relative paths, limited to maxResults.
|
|
43
|
+
*/
|
|
44
|
+
export async function findRelatedFiles(projectDir, keywords, maxResults = 10) {
|
|
45
|
+
if (keywords.length === 0)
|
|
46
|
+
return [];
|
|
47
|
+
const lowerKeywords = keywords.map((k) => k.toLowerCase());
|
|
48
|
+
const matches = [];
|
|
49
|
+
await searchDir(projectDir, projectDir, lowerKeywords, matches, maxResults, 0);
|
|
50
|
+
return matches;
|
|
51
|
+
}
|
|
52
|
+
async function searchDir(rootDir, currentDir, keywords, matches, maxResults, depth) {
|
|
53
|
+
if (depth > 5 || matches.length >= maxResults)
|
|
54
|
+
return;
|
|
55
|
+
let entries;
|
|
56
|
+
try {
|
|
57
|
+
entries = await fse.readdir(currentDir);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (matches.length >= maxResults)
|
|
64
|
+
return;
|
|
65
|
+
if (IGNORED_DIRS.has(entry) || entry.startsWith('.'))
|
|
66
|
+
continue;
|
|
67
|
+
const fullPath = path.join(currentDir, entry);
|
|
68
|
+
try {
|
|
69
|
+
const stat = await fse.stat(fullPath);
|
|
70
|
+
if (stat.isDirectory()) {
|
|
71
|
+
await searchDir(rootDir, fullPath, keywords, matches, maxResults, depth + 1);
|
|
72
|
+
}
|
|
73
|
+
else if (isSourceFile(entry)) {
|
|
74
|
+
const lowerEntry = entry.toLowerCase();
|
|
75
|
+
const relativePath = path.relative(rootDir, fullPath);
|
|
76
|
+
const lowerPath = relativePath.toLowerCase();
|
|
77
|
+
const isMatch = keywords.some((kw) => lowerEntry.includes(kw) || lowerPath.includes(kw));
|
|
78
|
+
if (isMatch) {
|
|
79
|
+
matches.push(relativePath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Skip inaccessible entries
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function isSourceFile(filename) {
|
|
89
|
+
const ext = path.extname(filename).toLowerCase();
|
|
90
|
+
return SOURCE_EXTENSIONS.has(ext);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Read multiple files and return a map of relative paths to truncated content.
|
|
94
|
+
* Respects a total character budget across all files.
|
|
95
|
+
*/
|
|
96
|
+
export async function readFileSnippets(projectDir, relativePaths, totalBudget = 12_000) {
|
|
97
|
+
const result = new Map();
|
|
98
|
+
let remaining = totalBudget;
|
|
99
|
+
for (const relPath of relativePaths) {
|
|
100
|
+
if (remaining <= 0)
|
|
101
|
+
break;
|
|
102
|
+
const content = await readProjectFile(projectDir, relPath);
|
|
103
|
+
if (!content)
|
|
104
|
+
continue;
|
|
105
|
+
const truncated = content.slice(0, Math.min(MAX_SNIPPET_CHARS, remaining));
|
|
106
|
+
result.set(relPath, truncated);
|
|
107
|
+
remaining -= truncated.length;
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=file-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-reader.js","sourceRoot":"","sources":["../../../src/ai/codebase/file-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { detectTechStack, formatTechStack, type TechStack } from './stack-detector.js';
|
|
2
|
+
export { generateFolderTree } from './tree-generator.js';
|
|
3
|
+
export { readProjectFile, findRelatedFiles, readFileSnippets } from './file-reader.js';
|
|
4
|
+
export { buildCodebaseContext, formatCodebaseContext, extractKeywords, type CodebaseContext, } from './context-builder.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/codebase/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { detectTechStack, formatTechStack } from './stack-detector.js';
|
|
2
|
+
export { generateFolderTree } from './tree-generator.js';
|
|
3
|
+
export { readProjectFile, findRelatedFiles, readFileSnippets } from './file-reader.js';
|
|
4
|
+
export { buildCodebaseContext, formatCodebaseContext, extractKeywords, } from './context-builder.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai/codebase/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,GAEhB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects the tech stack of a project by reading manifest files.
|
|
3
|
+
*
|
|
4
|
+
* Looks for package.json (Node.js), go.mod (Go), requirements.txt / pyproject.toml
|
|
5
|
+
* (Python), Cargo.toml (Rust), and more. Returns a structured TechStack object
|
|
6
|
+
* used to enrich AI prompts with codebase awareness.
|
|
7
|
+
*/
|
|
8
|
+
export interface TechStack {
|
|
9
|
+
language: string;
|
|
10
|
+
framework?: string;
|
|
11
|
+
packageManager?: string;
|
|
12
|
+
dependencies: string[];
|
|
13
|
+
devDependencies: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function detectTechStack(projectDir: string): Promise<TechStack | null>;
|
|
16
|
+
/** Format tech stack as a human-readable string for prompt injection. */
|
|
17
|
+
export declare function formatTechStack(stack: TechStack): string;
|
|
18
|
+
//# sourceMappingURL=stack-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../../src/ai/codebase/stack-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA4GD,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAanF;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CASxD"}
|