@ddse/acm-aicoder 0.5.0 → 0.5.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.
Files changed (47) hide show
  1. package/dist/src/capability-map.d.ts +4 -0
  2. package/dist/src/capability-map.d.ts.map +1 -0
  3. package/dist/src/capability-map.js +289 -0
  4. package/dist/src/capability-map.js.map +1 -0
  5. package/dist/src/registries.d.ts +3 -0
  6. package/dist/src/registries.d.ts.map +1 -1
  7. package/dist/src/registries.js +11 -0
  8. package/dist/src/registries.js.map +1 -1
  9. package/dist/tsconfig.tsbuildinfo +1 -1
  10. package/package.json +21 -7
  11. package/.aicoder/index.json +0 -304
  12. package/AICODER_IMPLEMENTATION_PLAN_PHASE2.md +0 -284
  13. package/bin/interactive.tsx +0 -232
  14. package/docs/AICODER.png +0 -0
  15. package/docs/INTERACTIVE_CLI_GUIDE.md +0 -201
  16. package/docs/TUI_MOCKUP.md +0 -180
  17. package/src/config/providers.ts +0 -174
  18. package/src/config/session.ts +0 -143
  19. package/src/context/bm25.ts +0 -173
  20. package/src/context/code-search.ts +0 -188
  21. package/src/context/context-pack.ts +0 -133
  22. package/src/context/dependency-mapper.ts +0 -72
  23. package/src/context/index.ts +0 -8
  24. package/src/context/symbol-extractor.ts +0 -149
  25. package/src/context/test-mapper.ts +0 -77
  26. package/src/context/types.ts +0 -69
  27. package/src/context/workspace-indexer.ts +0 -249
  28. package/src/index.ts +0 -5
  29. package/src/registries.ts +0 -118
  30. package/src/runtime/budget-manager.ts +0 -118
  31. package/src/runtime/interactive-runtime.ts +0 -423
  32. package/src/tasks-v2/analysis-tasks.ts +0 -311
  33. package/src/tasks-v2/developer-tasks.ts +0 -437
  34. package/src/tasks-v2/index.ts +0 -3
  35. package/src/tools-v2/edit-tools.ts +0 -153
  36. package/src/tools-v2/index.ts +0 -6
  37. package/src/tools-v2/read-tools.ts +0 -286
  38. package/src/tools-v2/search-tools.ts +0 -175
  39. package/src/tools-v2/test-tools.ts +0 -147
  40. package/src/tools-v2/workspace-context.ts +0 -428
  41. package/src/ui/App.tsx +0 -392
  42. package/src/ui/components/ChatPane.tsx +0 -84
  43. package/src/ui/components/EventsPane.tsx +0 -81
  44. package/src/ui/components/GoalsTasksPane.tsx +0 -149
  45. package/src/ui/store.ts +0 -362
  46. package/tests/integration.test.ts +0 -537
  47. package/tsconfig.json +0 -22
@@ -1,428 +0,0 @@
1
- // Workspace Context Retrieval Tool
2
- import { Tool, type ContextRetrievalArtifact } from '@ddse/acm-sdk';
3
- import * as fs from 'fs/promises';
4
- import * as path from 'path';
5
- import { CodeSearch, WorkspaceIndexer, type WorkspaceIndex } from '../context/index.js';
6
- import { GrepTool } from './search-tools.js';
7
-
8
- export type WorkspaceContextOperation =
9
- | {
10
- type: 'search';
11
- query: string;
12
- k?: number;
13
- includeContext?: boolean;
14
- contextLines?: number;
15
- preferTypes?: string[];
16
- rationale?: string;
17
- }
18
- | {
19
- type: 'symbol';
20
- symbol: string;
21
- k?: number;
22
- rationale?: string;
23
- }
24
- | {
25
- type: 'grep';
26
- pattern: string;
27
- regex?: boolean;
28
- caseInsensitive?: boolean;
29
- maxResults?: number;
30
- rationale?: string;
31
- }
32
- | {
33
- type: 'file';
34
- path: string;
35
- startLine?: number;
36
- endLine?: number;
37
- maxBytes?: number;
38
- rationale?: string;
39
- }
40
- | {
41
- type: 'recent';
42
- limit?: number;
43
- languages?: string[];
44
- rationale?: string;
45
- }
46
- | {
47
- type: 'metadata';
48
- summary?: boolean;
49
- languages?: string[];
50
- rationale?: string;
51
- };
52
-
53
- export interface WorkspaceContextRequest {
54
- directive?: string;
55
- goal?: string;
56
- operations?: WorkspaceContextOperation[];
57
- }
58
-
59
- const DEFAULT_MAX_BYTES = 16_000;
60
-
61
- export class WorkspaceContextRetrievalTool extends Tool<
62
- WorkspaceContextRequest,
63
- ContextRetrievalArtifact[]
64
- > {
65
- private rootPath: string;
66
- private codeSearch?: CodeSearch;
67
- private indexer: WorkspaceIndexer;
68
- private index?: WorkspaceIndex;
69
- private grepTool: GrepTool;
70
- private indexingPromise?: Promise<void>;
71
-
72
- constructor(rootPath: string = process.cwd()) {
73
- super();
74
- this.rootPath = path.resolve(rootPath);
75
- this.indexer = new WorkspaceIndexer(this.rootPath);
76
- this.grepTool = new GrepTool(this.rootPath);
77
- }
78
-
79
- name(): string {
80
- return 'workspace_context';
81
- }
82
-
83
- async call(request: WorkspaceContextRequest): Promise<ContextRetrievalArtifact[]> {
84
- const operations = request.operations && request.operations.length > 0
85
- ? request.operations
86
- : this.deriveOperationsFromDirective(request.directive);
87
-
88
- if (!operations || operations.length === 0) {
89
- return [];
90
- }
91
-
92
- await this.ensureSearchIndex();
93
-
94
- const artifacts: ContextRetrievalArtifact[] = [];
95
- const seen = new Set<string>();
96
-
97
- for (const operation of operations) {
98
- try {
99
- if (operation.type === 'search') {
100
- const searchArtifacts = await this.handleSearch(operation);
101
- this.pushArtifacts(searchArtifacts, artifacts, seen);
102
- } else if (operation.type === 'symbol') {
103
- const symbolArtifacts = await this.handleSymbol(operation);
104
- this.pushArtifacts(symbolArtifacts, artifacts, seen);
105
- } else if (operation.type === 'grep') {
106
- const grepArtifacts = await this.handleGrep(operation);
107
- this.pushArtifacts(grepArtifacts, artifacts, seen);
108
- } else if (operation.type === 'file') {
109
- const fileArtifact = await this.handleFile(operation);
110
- this.pushArtifacts(fileArtifact, artifacts, seen);
111
- } else if (operation.type === 'recent') {
112
- const recentArtifact = await this.handleRecent(operation);
113
- this.pushArtifacts(recentArtifact, artifacts, seen);
114
- } else if (operation.type === 'metadata') {
115
- const metadataArtifact = await this.handleMetadata(operation);
116
- this.pushArtifacts(metadataArtifact, artifacts, seen);
117
- }
118
- } catch (error) {
119
- // Skip failing operation but surface metadata for debugging
120
- this.pushArtifacts(
121
- {
122
- type: 'workspace.debug',
123
- content: {
124
- operation,
125
- error: error instanceof Error ? error.message : String(error),
126
- },
127
- promote: false,
128
- provenance: {
129
- tool: this.name(),
130
- stage: 'operation-error',
131
- },
132
- },
133
- artifacts,
134
- seen
135
- );
136
- }
137
- }
138
-
139
- return artifacts;
140
- }
141
-
142
- private async ensureSearchIndex(): Promise<void> {
143
- if (this.index && this.codeSearch) {
144
- return;
145
- }
146
-
147
- if (!this.indexingPromise) {
148
- this.indexingPromise = (async () => {
149
- this.index = await this.indexer.buildIndex({ useCache: true });
150
- this.codeSearch = new CodeSearch(this.rootPath);
151
- await this.codeSearch.indexFiles(this.index);
152
- })();
153
- }
154
-
155
- await this.indexingPromise;
156
- }
157
-
158
- private deriveOperationsFromDirective(directive?: string): WorkspaceContextOperation[] {
159
- if (!directive) {
160
- return [];
161
- }
162
-
163
- const separatorIndex = directive.indexOf(':');
164
- const payload = separatorIndex >= 0 ? directive.slice(separatorIndex + 1).trim() : '';
165
-
166
- if (payload.startsWith('{')) {
167
- try {
168
- const parsed = JSON.parse(payload);
169
- if (Array.isArray(parsed.operations)) {
170
- return parsed.operations as WorkspaceContextOperation[];
171
- }
172
- if (typeof parsed.query === 'string' && parsed.query.length > 0) {
173
- return [
174
- {
175
- type: 'search',
176
- query: parsed.query,
177
- k: parsed.k,
178
- includeContext: parsed.includeContext ?? true,
179
- rationale: parsed.rationale,
180
- },
181
- ];
182
- }
183
- } catch {
184
- // fall back to text parsing
185
- }
186
- }
187
-
188
- if (payload.length > 0) {
189
- return [
190
- {
191
- type: 'search',
192
- query: payload,
193
- includeContext: true,
194
- },
195
- {
196
- type: 'grep',
197
- pattern: payload,
198
- maxResults: 20,
199
- },
200
- ];
201
- }
202
-
203
- return [];
204
- }
205
-
206
- private pushArtifacts(
207
- artifact: ContextRetrievalArtifact | ContextRetrievalArtifact[] | null | undefined,
208
- collection: ContextRetrievalArtifact[],
209
- seen: Set<string>
210
- ): void {
211
- if (!artifact) return;
212
- const artifacts = Array.isArray(artifact) ? artifact : [artifact];
213
-
214
- for (const entry of artifacts) {
215
- if (!entry || typeof entry.type !== 'string') continue;
216
-
217
- const provenance = entry.provenance ?? { tool: this.name() };
218
- const keySource = JSON.stringify([
219
- entry.type,
220
- provenance.tool,
221
- (entry.content && (entry.content.path || entry.content.id || entry.content.key)) ??
222
- JSON.stringify(entry.content),
223
- ]);
224
-
225
- if (seen.has(keySource)) {
226
- continue;
227
- }
228
-
229
- seen.add(keySource);
230
- collection.push({
231
- ...entry,
232
- provenance,
233
- });
234
- }
235
- }
236
-
237
- private async handleSearch(operation: Extract<WorkspaceContextOperation, { type: 'search' }>): Promise<ContextRetrievalArtifact[]> {
238
- if (!this.codeSearch) {
239
- return [];
240
- }
241
-
242
- const results = await this.codeSearch.search(operation.query, {
243
- k: Math.min(operation.k ?? 8, 20),
244
- includeContext: operation.includeContext ?? true,
245
- contextLines: operation.contextLines ?? 2,
246
- preferTypes: operation.preferTypes,
247
- });
248
-
249
- return results.map(result => ({
250
- type: 'workspace.snippet',
251
- promote: true,
252
- content: {
253
- path: result.path,
254
- line: result.line,
255
- snippet: result.snippet,
256
- score: result.score,
257
- operation: 'bm25-search',
258
- query: operation.query,
259
- rationale: operation.rationale,
260
- },
261
- provenance: {
262
- tool: this.name(),
263
- operation: 'search',
264
- },
265
- }));
266
- }
267
-
268
- private async handleSymbol(operation: Extract<WorkspaceContextOperation, { type: 'symbol' }>): Promise<ContextRetrievalArtifact[]> {
269
- if (!this.codeSearch) {
270
- return [];
271
- }
272
-
273
- const results = await this.codeSearch.searchSymbol(operation.symbol);
274
- return results.slice(0, Math.min(operation.k ?? 5, 10)).map(result => ({
275
- type: 'workspace.snippet',
276
- promote: true,
277
- content: {
278
- path: result.path,
279
- line: result.line,
280
- snippet: result.snippet,
281
- score: result.score,
282
- operation: 'symbol-search',
283
- symbol: operation.symbol,
284
- rationale: operation.rationale,
285
- },
286
- provenance: {
287
- tool: this.name(),
288
- operation: 'symbol',
289
- },
290
- }));
291
- }
292
-
293
- private async handleGrep(operation: Extract<WorkspaceContextOperation, { type: 'grep' }>): Promise<ContextRetrievalArtifact[]> {
294
- const result = await this.grepTool.call({
295
- pattern: operation.pattern,
296
- regex: operation.regex,
297
- caseInsensitive: operation.caseInsensitive,
298
- maxResults: Math.min(operation.maxResults ?? 30, 100),
299
- });
300
-
301
- return result.matches.map(match => ({
302
- type: 'workspace.match',
303
- promote: true,
304
- content: {
305
- path: match.path,
306
- line: match.line,
307
- column: match.column,
308
- preview: match.preview,
309
- operation: 'grep',
310
- pattern: operation.pattern,
311
- rationale: operation.rationale,
312
- },
313
- provenance: {
314
- tool: this.name(),
315
- operation: 'grep',
316
- },
317
- }));
318
- }
319
-
320
- private async handleFile(operation: Extract<WorkspaceContextOperation, { type: 'file' }>): Promise<ContextRetrievalArtifact | null> {
321
- const absolutePath = path.isAbsolute(operation.path)
322
- ? operation.path
323
- : path.join(this.rootPath, operation.path);
324
-
325
- const relativePath = path.relative(this.rootPath, absolutePath);
326
-
327
- try {
328
- let content = await fs.readFile(absolutePath, 'utf-8');
329
- const maxBytes = operation.maxBytes ?? DEFAULT_MAX_BYTES;
330
- if (content.length > maxBytes) {
331
- content = content.slice(0, maxBytes);
332
- }
333
-
334
- let snippet = content;
335
- let startLine = 1;
336
- let endLine = content.split('\n').length;
337
-
338
- if (operation.startLine || operation.endLine) {
339
- const lines = content.split('\n');
340
- startLine = Math.max(operation.startLine ?? 1, 1);
341
- endLine = Math.min(operation.endLine ?? lines.length, lines.length);
342
- snippet = lines.slice(startLine - 1, endLine).join('\n');
343
- }
344
-
345
- return {
346
- type: 'workspace.file',
347
- promote: true,
348
- content: {
349
- path: relativePath,
350
- snippet,
351
- startLine,
352
- endLine,
353
- rationale: operation.rationale,
354
- },
355
- provenance: {
356
- tool: this.name(),
357
- operation: 'file',
358
- },
359
- };
360
- } catch {
361
- return {
362
- type: 'workspace.debug',
363
- promote: false,
364
- content: {
365
- operation,
366
- error: `Failed to read file: ${relativePath}`,
367
- },
368
- provenance: {
369
- tool: this.name(),
370
- operation: 'file',
371
- },
372
- };
373
- }
374
- }
375
-
376
- private async handleRecent(operation: Extract<WorkspaceContextOperation, { type: 'recent' }>): Promise<ContextRetrievalArtifact | null> {
377
- if (!this.index) {
378
- return null;
379
- }
380
-
381
- const limit = Math.min(operation.limit ?? 5, 20);
382
- const files = WorkspaceIndexer.getRecentFiles(this.index, limit);
383
- const filtered = operation.languages && operation.languages.length > 0
384
- ? files.filter(file => operation.languages!.includes(file.language))
385
- : files;
386
-
387
- return {
388
- type: 'workspace.metadata',
389
- promote: true,
390
- content: {
391
- kind: 'recent-files',
392
- files: filtered.map(file => ({
393
- path: file.path,
394
- mtime: file.mtime,
395
- language: file.language,
396
- size: file.size,
397
- })),
398
- rationale: operation.rationale,
399
- },
400
- provenance: {
401
- tool: this.name(),
402
- operation: 'recent',
403
- },
404
- };
405
- }
406
-
407
- private async handleMetadata(operation: Extract<WorkspaceContextOperation, { type: 'metadata' }>): Promise<ContextRetrievalArtifact | null> {
408
- if (!this.index) {
409
- return null;
410
- }
411
-
412
- return {
413
- type: 'workspace.metadata',
414
- promote: true,
415
- content: {
416
- kind: 'summary',
417
- files: this.index.totalFiles,
418
- totalSize: this.index.totalSize,
419
- languages: Array.from(new Set(this.index.files.map(f => f.language))).slice(0, 32),
420
- rationale: operation.rationale,
421
- },
422
- provenance: {
423
- tool: this.name(),
424
- operation: 'metadata',
425
- },
426
- };
427
- }
428
- }