@ddse/acm-aicoder 0.5.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.
Files changed (165) hide show
  1. package/.aicoder/index.json +304 -0
  2. package/AICODER_IMPLEMENTATION_PLAN_PHASE2.md +284 -0
  3. package/LICENSE +21 -0
  4. package/README.md +490 -0
  5. package/bin/interactive.tsx +232 -0
  6. package/dist/bin/interactive.d.ts +3 -0
  7. package/dist/bin/interactive.d.ts.map +1 -0
  8. package/dist/bin/interactive.js +155 -0
  9. package/dist/bin/interactive.js.map +1 -0
  10. package/dist/src/config/providers.d.ts +15 -0
  11. package/dist/src/config/providers.d.ts.map +1 -0
  12. package/dist/src/config/providers.js +142 -0
  13. package/dist/src/config/providers.js.map +1 -0
  14. package/dist/src/config/session.d.ts +25 -0
  15. package/dist/src/config/session.d.ts.map +1 -0
  16. package/dist/src/config/session.js +97 -0
  17. package/dist/src/config/session.js.map +1 -0
  18. package/dist/src/context/bm25.d.ts +68 -0
  19. package/dist/src/context/bm25.d.ts.map +1 -0
  20. package/dist/src/context/bm25.js +131 -0
  21. package/dist/src/context/bm25.js.map +1 -0
  22. package/dist/src/context/code-search.d.ts +30 -0
  23. package/dist/src/context/code-search.d.ts.map +1 -0
  24. package/dist/src/context/code-search.js +150 -0
  25. package/dist/src/context/code-search.js.map +1 -0
  26. package/dist/src/context/context-pack.d.ts +25 -0
  27. package/dist/src/context/context-pack.d.ts.map +1 -0
  28. package/dist/src/context/context-pack.js +92 -0
  29. package/dist/src/context/context-pack.js.map +1 -0
  30. package/dist/src/context/dependency-mapper.d.ts +10 -0
  31. package/dist/src/context/dependency-mapper.d.ts.map +1 -0
  32. package/dist/src/context/dependency-mapper.js +62 -0
  33. package/dist/src/context/dependency-mapper.js.map +1 -0
  34. package/dist/src/context/index.d.ts +8 -0
  35. package/dist/src/context/index.d.ts.map +1 -0
  36. package/dist/src/context/index.js +9 -0
  37. package/dist/src/context/index.js.map +1 -0
  38. package/dist/src/context/symbol-extractor.d.ts +26 -0
  39. package/dist/src/context/symbol-extractor.d.ts.map +1 -0
  40. package/dist/src/context/symbol-extractor.js +129 -0
  41. package/dist/src/context/symbol-extractor.js.map +1 -0
  42. package/dist/src/context/test-mapper.d.ts +16 -0
  43. package/dist/src/context/test-mapper.d.ts.map +1 -0
  44. package/dist/src/context/test-mapper.js +66 -0
  45. package/dist/src/context/test-mapper.js.map +1 -0
  46. package/dist/src/context/types.d.ts +61 -0
  47. package/dist/src/context/types.d.ts.map +1 -0
  48. package/dist/src/context/types.js +3 -0
  49. package/dist/src/context/types.js.map +1 -0
  50. package/dist/src/context/workspace-indexer.d.ts +39 -0
  51. package/dist/src/context/workspace-indexer.d.ts.map +1 -0
  52. package/dist/src/context/workspace-indexer.js +222 -0
  53. package/dist/src/context/workspace-indexer.js.map +1 -0
  54. package/dist/src/index.d.ts +5 -0
  55. package/dist/src/index.d.ts.map +1 -0
  56. package/dist/src/index.js +6 -0
  57. package/dist/src/index.js.map +1 -0
  58. package/dist/src/registries.d.ts +34 -0
  59. package/dist/src/registries.d.ts.map +1 -0
  60. package/dist/src/registries.js +87 -0
  61. package/dist/src/registries.js.map +1 -0
  62. package/dist/src/runtime/budget-manager.d.ts +42 -0
  63. package/dist/src/runtime/budget-manager.d.ts.map +1 -0
  64. package/dist/src/runtime/budget-manager.js +82 -0
  65. package/dist/src/runtime/budget-manager.js.map +1 -0
  66. package/dist/src/runtime/interactive-runtime.d.ts +39 -0
  67. package/dist/src/runtime/interactive-runtime.d.ts.map +1 -0
  68. package/dist/src/runtime/interactive-runtime.js +321 -0
  69. package/dist/src/runtime/interactive-runtime.js.map +1 -0
  70. package/dist/src/tasks-v2/analysis-tasks.d.ts +117 -0
  71. package/dist/src/tasks-v2/analysis-tasks.d.ts.map +1 -0
  72. package/dist/src/tasks-v2/analysis-tasks.js +209 -0
  73. package/dist/src/tasks-v2/analysis-tasks.js.map +1 -0
  74. package/dist/src/tasks-v2/developer-tasks.d.ts +226 -0
  75. package/dist/src/tasks-v2/developer-tasks.d.ts.map +1 -0
  76. package/dist/src/tasks-v2/developer-tasks.js +322 -0
  77. package/dist/src/tasks-v2/developer-tasks.js.map +1 -0
  78. package/dist/src/tasks-v2/index.d.ts +3 -0
  79. package/dist/src/tasks-v2/index.d.ts.map +1 -0
  80. package/dist/src/tasks-v2/index.js +4 -0
  81. package/dist/src/tasks-v2/index.js.map +1 -0
  82. package/dist/src/tools-v2/edit-tools.d.ts +67 -0
  83. package/dist/src/tools-v2/edit-tools.d.ts.map +1 -0
  84. package/dist/src/tools-v2/edit-tools.js +117 -0
  85. package/dist/src/tools-v2/edit-tools.js.map +1 -0
  86. package/dist/src/tools-v2/index.d.ts +6 -0
  87. package/dist/src/tools-v2/index.d.ts.map +1 -0
  88. package/dist/src/tools-v2/index.js +7 -0
  89. package/dist/src/tools-v2/index.js.map +1 -0
  90. package/dist/src/tools-v2/read-tools.d.ts +129 -0
  91. package/dist/src/tools-v2/read-tools.d.ts.map +1 -0
  92. package/dist/src/tools-v2/read-tools.js +216 -0
  93. package/dist/src/tools-v2/read-tools.js.map +1 -0
  94. package/dist/src/tools-v2/search-tools.d.ts +73 -0
  95. package/dist/src/tools-v2/search-tools.d.ts.map +1 -0
  96. package/dist/src/tools-v2/search-tools.js +132 -0
  97. package/dist/src/tools-v2/search-tools.js.map +1 -0
  98. package/dist/src/tools-v2/test-tools.d.ts +59 -0
  99. package/dist/src/tools-v2/test-tools.d.ts.map +1 -0
  100. package/dist/src/tools-v2/test-tools.js +111 -0
  101. package/dist/src/tools-v2/test-tools.js.map +1 -0
  102. package/dist/src/tools-v2/workspace-context.d.ts +65 -0
  103. package/dist/src/tools-v2/workspace-context.d.ts.map +1 -0
  104. package/dist/src/tools-v2/workspace-context.js +336 -0
  105. package/dist/src/tools-v2/workspace-context.js.map +1 -0
  106. package/dist/src/ui/App.d.ts +9 -0
  107. package/dist/src/ui/App.d.ts.map +1 -0
  108. package/dist/src/ui/App.js +257 -0
  109. package/dist/src/ui/App.js.map +1 -0
  110. package/dist/src/ui/components/ChatPane.d.ts +12 -0
  111. package/dist/src/ui/components/ChatPane.d.ts.map +1 -0
  112. package/dist/src/ui/components/ChatPane.js +41 -0
  113. package/dist/src/ui/components/ChatPane.js.map +1 -0
  114. package/dist/src/ui/components/EventsPane.d.ts +12 -0
  115. package/dist/src/ui/components/EventsPane.d.ts.map +1 -0
  116. package/dist/src/ui/components/EventsPane.js +48 -0
  117. package/dist/src/ui/components/EventsPane.js.map +1 -0
  118. package/dist/src/ui/components/GoalsTasksPane.d.ts +18 -0
  119. package/dist/src/ui/components/GoalsTasksPane.d.ts.map +1 -0
  120. package/dist/src/ui/components/GoalsTasksPane.js +83 -0
  121. package/dist/src/ui/components/GoalsTasksPane.js.map +1 -0
  122. package/dist/src/ui/store.d.ts +74 -0
  123. package/dist/src/ui/store.d.ts.map +1 -0
  124. package/dist/src/ui/store.js +260 -0
  125. package/dist/src/ui/store.js.map +1 -0
  126. package/dist/tests/integration.test.d.ts +2 -0
  127. package/dist/tests/integration.test.d.ts.map +1 -0
  128. package/dist/tests/integration.test.js +415 -0
  129. package/dist/tests/integration.test.js.map +1 -0
  130. package/dist/tsconfig.tsbuildinfo +1 -0
  131. package/docs/AICODER.png +0 -0
  132. package/docs/INTERACTIVE_CLI_GUIDE.md +201 -0
  133. package/docs/TUI_MOCKUP.md +180 -0
  134. package/package.json +52 -0
  135. package/src/config/providers.ts +174 -0
  136. package/src/config/session.ts +143 -0
  137. package/src/context/bm25.ts +173 -0
  138. package/src/context/code-search.ts +188 -0
  139. package/src/context/context-pack.ts +133 -0
  140. package/src/context/dependency-mapper.ts +72 -0
  141. package/src/context/index.ts +8 -0
  142. package/src/context/symbol-extractor.ts +149 -0
  143. package/src/context/test-mapper.ts +77 -0
  144. package/src/context/types.ts +69 -0
  145. package/src/context/workspace-indexer.ts +249 -0
  146. package/src/index.ts +5 -0
  147. package/src/registries.ts +118 -0
  148. package/src/runtime/budget-manager.ts +118 -0
  149. package/src/runtime/interactive-runtime.ts +423 -0
  150. package/src/tasks-v2/analysis-tasks.ts +311 -0
  151. package/src/tasks-v2/developer-tasks.ts +437 -0
  152. package/src/tasks-v2/index.ts +3 -0
  153. package/src/tools-v2/edit-tools.ts +153 -0
  154. package/src/tools-v2/index.ts +6 -0
  155. package/src/tools-v2/read-tools.ts +286 -0
  156. package/src/tools-v2/search-tools.ts +175 -0
  157. package/src/tools-v2/test-tools.ts +147 -0
  158. package/src/tools-v2/workspace-context.ts +428 -0
  159. package/src/ui/App.tsx +392 -0
  160. package/src/ui/components/ChatPane.tsx +84 -0
  161. package/src/ui/components/EventsPane.tsx +81 -0
  162. package/src/ui/components/GoalsTasksPane.tsx +149 -0
  163. package/src/ui/store.ts +362 -0
  164. package/tests/integration.test.ts +537 -0
  165. package/tsconfig.json +22 -0
@@ -0,0 +1,311 @@
1
+ // Analysis and Utility Tasks
2
+ import { Task, type RunContext } from '@ddse/acm-sdk';
3
+ import path from 'path';
4
+ import {
5
+ WorkspaceIndexer,
6
+ SymbolExtractor,
7
+ DependencyMapper,
8
+ TestMapper,
9
+ CodeSearch,
10
+ ContextPackGenerator,
11
+ type ContextPack,
12
+ } from '../context/index.js';
13
+
14
+ /**
15
+ * AnalyzeWorkspaceTask - Deep workspace analysis with context
16
+ */
17
+ export class AnalyzeWorkspaceTask extends Task<
18
+ {
19
+ path?: string;
20
+ includeTests?: boolean;
21
+ includeDeps?: boolean;
22
+ runBuild?: boolean;
23
+ runTests?: boolean;
24
+ buildCommand?: string;
25
+ testCommand?: string;
26
+ },
27
+ {
28
+ summary: string;
29
+ totalFiles: number;
30
+ codeFiles: number;
31
+ symbols: number;
32
+ dependencies: number;
33
+ testFiles: number;
34
+ build?: { success: boolean; errors: string[]; duration: number };
35
+ tests?: { success: boolean; exitCode: number; duration: number };
36
+ contextPack?: ContextPack;
37
+ }
38
+ > {
39
+ constructor() {
40
+ super('analyze-workspace', 'analyze_workspace');
41
+ }
42
+
43
+ async execute(
44
+ ctx: RunContext,
45
+ input: {
46
+ path?: string;
47
+ includeTests?: boolean;
48
+ includeDeps?: boolean;
49
+ runBuild?: boolean;
50
+ runTests?: boolean;
51
+ buildCommand?: string;
52
+ testCommand?: string;
53
+ }
54
+ ): Promise<{
55
+ summary: string;
56
+ totalFiles: number;
57
+ codeFiles: number;
58
+ symbols: number;
59
+ dependencies: number;
60
+ testFiles: number;
61
+ build?: { success: boolean; errors: string[]; duration: number };
62
+ tests?: { success: boolean; exitCode: number; duration: number };
63
+ contextPack?: ContextPack;
64
+ }> {
65
+ const workspaceRoot = getWorkspaceRoot(ctx);
66
+ const rootPath = resolveRootPath(input.path, workspaceRoot);
67
+
68
+ // Build index
69
+ ctx.stream?.emit('task', { taskId: this.id, step: 'indexing_workspace' });
70
+ const indexer = new WorkspaceIndexer(rootPath);
71
+ const index = await indexer.buildIndex({ useCache: true });
72
+
73
+ ctx.stream?.emit('task', {
74
+ taskId: this.id,
75
+ step: 'index_complete',
76
+ totalFiles: index.totalFiles,
77
+ });
78
+
79
+ // Extract symbols
80
+ ctx.stream?.emit('task', { taskId: this.id, step: 'extracting_symbols' });
81
+ const symbolExtractor = new SymbolExtractor(rootPath);
82
+ const symbols = await symbolExtractor.extractSymbols(index);
83
+
84
+ // Extract dependencies
85
+ const depMapper = new DependencyMapper(rootPath);
86
+ const dependencies = await depMapper.extractDependencies(index);
87
+
88
+ // Map tests
89
+ const testMappings = TestMapper.mapTests(index);
90
+
91
+ // Count code files
92
+ const codeFiles = index.files.filter(f =>
93
+ ['typescript', 'javascript'].includes(f.language)
94
+ ).length;
95
+
96
+ ctx.stream?.emit('task', {
97
+ taskId: this.id,
98
+ step: 'analysis_complete',
99
+ symbols: symbols.length,
100
+ dependencies: dependencies.length,
101
+ tests: testMappings.length,
102
+ });
103
+
104
+ // Optionally run build and tests using registered tools
105
+ let buildSummary: { success: boolean; errors: string[]; duration: number } | undefined;
106
+ if (input.runBuild) {
107
+ ctx.stream?.emit('task', { taskId: this.id, step: 'running_build' });
108
+ const buildTool = ctx.getTool('build');
109
+ if (buildTool) {
110
+ const buildRes = await buildTool.call({
111
+ command: input.buildCommand || 'npm run build',
112
+ cwd: rootPath,
113
+ });
114
+ buildSummary = {
115
+ success: !!buildRes.success,
116
+ errors: Array.isArray(buildRes.errors) ? buildRes.errors : [],
117
+ duration: Number(buildRes.duration) || 0,
118
+ };
119
+ ctx.stream?.emit('task', {
120
+ taskId: this.id,
121
+ step: 'build_complete',
122
+ success: buildSummary.success,
123
+ errors: buildSummary.errors.length,
124
+ duration: buildSummary.duration,
125
+ });
126
+ } else {
127
+ ctx.stream?.emit('task', { taskId: this.id, step: 'build_tool_missing' });
128
+ }
129
+ }
130
+
131
+ let testSummary: { success: boolean; exitCode: number; duration: number } | undefined;
132
+ if (input.runTests) {
133
+ ctx.stream?.emit('task', { taskId: this.id, step: 'running_tests' });
134
+ const testTool = ctx.getTool('run_tests_v2');
135
+ if (testTool) {
136
+ const testRes = await testTool.call({
137
+ command: input.testCommand || 'npm test',
138
+ cwd: rootPath,
139
+ });
140
+ testSummary = {
141
+ success: !!testRes.success,
142
+ exitCode: Number(testRes.exitCode) || (testRes.success ? 0 : 1),
143
+ duration: Number(testRes.duration) || 0,
144
+ };
145
+ ctx.stream?.emit('task', {
146
+ taskId: this.id,
147
+ step: 'tests_complete',
148
+ success: testSummary.success,
149
+ exitCode: testSummary.exitCode,
150
+ duration: testSummary.duration,
151
+ });
152
+ } else {
153
+ ctx.stream?.emit('task', { taskId: this.id, step: 'test_tool_missing' });
154
+ }
155
+ }
156
+
157
+ const summaryParts = [
158
+ `Analyzed ${index.totalFiles} files`,
159
+ `${codeFiles} code files`,
160
+ `${symbols.length} symbols`,
161
+ `${dependencies.length} dependencies`,
162
+ `${testMappings.length} test files`,
163
+ ];
164
+ if (buildSummary) {
165
+ summaryParts.push(`build: ${buildSummary.success ? 'ok' : `${buildSummary.errors.length} errors`}`);
166
+ }
167
+ if (testSummary) {
168
+ summaryParts.push(`tests: ${testSummary.success ? 'ok' : `exit ${testSummary.exitCode}`}`);
169
+ }
170
+ const summary = summaryParts.join(', ');
171
+
172
+ return {
173
+ summary,
174
+ totalFiles: index.totalFiles,
175
+ codeFiles,
176
+ symbols: symbols.length,
177
+ dependencies: dependencies.length,
178
+ testFiles: testMappings.length,
179
+ build: buildSummary,
180
+ tests: testSummary,
181
+ };
182
+ }
183
+
184
+ verification(): string[] {
185
+ return ['output.totalFiles > 0', 'output.summary !== undefined'];
186
+ }
187
+ }
188
+
189
+ /**
190
+ * CollectContextPackTask - Generate context for planning
191
+ */
192
+ export class CollectContextPackTask extends Task<
193
+ { goal: string; path?: string; maxFiles?: number; maxSymbols?: number },
194
+ { contextPack: ContextPack }
195
+ > {
196
+ constructor() {
197
+ super('collect-context-pack', 'collect_context_pack');
198
+ }
199
+
200
+ async execute(
201
+ ctx: RunContext,
202
+ input: { goal: string; path?: string; maxFiles?: number; maxSymbols?: number }
203
+ ): Promise<{ contextPack: ContextPack }> {
204
+ const workspaceRoot = getWorkspaceRoot(ctx);
205
+ const rootPath = resolveRootPath(input.path, workspaceRoot);
206
+ const goalText = (input.goal && input.goal.trim().length > 0)
207
+ ? input.goal
208
+ : (ctx.goal?.intent || ctx.goal?.id || '');
209
+
210
+ // Build index and search
211
+ ctx.stream?.emit('task', { taskId: this.id, step: 'indexing' });
212
+ const indexer = new WorkspaceIndexer(rootPath);
213
+ const index = await indexer.buildIndex({ useCache: true });
214
+
215
+ const search = new CodeSearch(rootPath);
216
+ await search.indexFiles(index);
217
+
218
+ // Extract symbols and dependencies
219
+ const symbolExtractor = new SymbolExtractor(rootPath);
220
+ const symbols = await symbolExtractor.extractSymbols(index);
221
+
222
+ const depMapper = new DependencyMapper(rootPath);
223
+ const dependencies = await depMapper.extractDependencies(index);
224
+
225
+ const testMappings = TestMapper.mapTests(index);
226
+
227
+ // Generate context pack
228
+ ctx.stream?.emit('task', { taskId: this.id, step: 'generating_context' });
229
+ const packGenerator = new ContextPackGenerator(search);
230
+ const contextPack = await packGenerator.generate(
231
+ goalText,
232
+ index,
233
+ symbols,
234
+ dependencies,
235
+ testMappings,
236
+ {
237
+ maxFiles: input.maxFiles ?? 8,
238
+ maxSymbols: input.maxSymbols ?? 20,
239
+ includeTests: true,
240
+ includeDependencies: true,
241
+ }
242
+ );
243
+
244
+ ctx.stream?.emit('task', {
245
+ taskId: this.id,
246
+ step: 'context_ready',
247
+ files: contextPack.files.length,
248
+ symbols: contextPack.symbols.length,
249
+ });
250
+
251
+ return { contextPack };
252
+ }
253
+
254
+ verification(): string[] {
255
+ return ['output.contextPack !== undefined', 'output.contextPack.files.length > 0'];
256
+ }
257
+ }
258
+
259
+ function getWorkspaceRoot(ctx: RunContext): string {
260
+ const workspace = (ctx.context?.facts?.workspace as string) ?? process.cwd();
261
+ return path.resolve(workspace);
262
+ }
263
+
264
+ function resolveRootPath(inputPath: string | undefined, workspaceRoot: string): string {
265
+ if (!inputPath) {
266
+ return workspaceRoot;
267
+ }
268
+
269
+ return path.isAbsolute(inputPath) ? inputPath : path.resolve(workspaceRoot, inputPath);
270
+ }
271
+
272
+ /**
273
+ * SearchCodeTask - Search for code with context
274
+ */
275
+ export class SearchCodeTask extends Task<
276
+ { query: string; k?: number; preferTypes?: string[]; path?: string },
277
+ { results: Array<{ path: string; score: number; snippet: string; line: number }> }
278
+ > {
279
+ constructor() {
280
+ super('search-code', 'search_code');
281
+ }
282
+
283
+ async execute(
284
+ ctx: RunContext,
285
+ input: { query: string; k?: number; preferTypes?: string[]; path?: string }
286
+ ): Promise<{ results: Array<{ path: string; score: number; snippet: string; line: number }> }> {
287
+ const searchTool = ctx.getTool('code_search');
288
+ if (!searchTool) throw new Error('CodeSearchTool not found');
289
+
290
+ ctx.stream?.emit('task', { taskId: this.id, step: 'searching', query: input.query });
291
+
292
+ const result = await searchTool.call({
293
+ query: input.query,
294
+ k: input.k ?? 10,
295
+ preferTypes: input.preferTypes,
296
+ includeContext: true,
297
+ });
298
+
299
+ ctx.stream?.emit('task', {
300
+ taskId: this.id,
301
+ step: 'search_complete',
302
+ resultsFound: result.results.length,
303
+ });
304
+
305
+ return { results: result.results };
306
+ }
307
+
308
+ verification(): string[] {
309
+ return ['output.results !== undefined'];
310
+ }
311
+ }