@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
package/README.md ADDED
@@ -0,0 +1,490 @@
1
+ # ACM AI Coder - Phase 2
2
+
3
+ <!-- markdownlint-disable MD024 MD032 -->
4
+
5
+ An advanced AI-powered developer workflow automation tool with an interactive full-screen TUI that showcases the complete ACM (Agentic Contract Model) framework v0.5.
6
+
7
+ ## Overview
8
+
9
+ The ACM AI Coder Phase 2 introduces an **interactive-only experience** with a three-column terminal UI:
10
+
11
+ - **Left Column**: Chat interface with streaming planner and nucleus reasoning
12
+ - **Middle Column**: Current goal, tasks with live status, and budget metrics
13
+ - **Right Column**: Event stream showing ledger entries, tool calls, and context updates
14
+
15
+ ### Key Features
16
+
17
+ - ✅ **Interactive-Only TUI**: Full-screen terminal interface with real-time updates
18
+ - ✅ **Mandatory Configuration**: Requires `--provider`, `--model`, and `--workspace` flags with optional `--base-url`
19
+ - ✅ **Budget Governance**: Pre-inference cost checks with live spend tracking
20
+ - ✅ **Streaming Reasoning**: Watch planner and nucleus think in real-time
21
+ - ✅ **File Mentions**: Reference workspace files with `#path/to/file` syntax
22
+ - ✅ **Memory Lifecycle**: Automatic cleanup and replay bundle persistence
23
+ - ✅ **ACM Framework Integration**: Built entirely on ACM primitives (planner, runtime, nucleus, ledger)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ # From the workspace root
29
+ pnpm install
30
+
31
+ # Build the package
32
+ pnpm --filter @ddse/acm-aicoder build
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ### Phase 2 Interactive Mode (Recommended)
38
+
39
+ ```bash
40
+ # Start the interactive AI Coder
41
+ acm-aicoder \
42
+ --provider vllm \
43
+ --model Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8 \
44
+ --base-url http://localhost:8001/v1 \
45
+ --workspace /path/to/your/project
46
+ ```
47
+
48
+ **Required Parameters:**
49
+
50
+ - `--provider <ollama|vllm>` - LLM provider (default: ollama)
51
+ - `--model <name>` - Model identifier provided by the selected provider
52
+ - `--workspace <path>` - Project workspace root directory (must exist and be a readable directory)
53
+
54
+ **Optional Parameters:**
55
+
56
+ - `--base-url <url>` - Override provider base URL when using a custom endpoint
57
+ - `--temperature <0-2>` - LLM temperature (default: 0.7)
58
+ - `--seed <number>` - Random seed for reproducibility
59
+ - `--plans <1|2>` - Number of alternative plans to generate (default: 1)
60
+
61
+ ### Commands in Interactive Mode
62
+
63
+ Once running, you can use these commands:
64
+
65
+ - `/exit`, `/quit` - Exit the application
66
+ - `/help` - Show available commands
67
+ - `/budget` - Display detailed budget information
68
+ - `/context` - Show current context information
69
+ - `/reset` - Reset the session (clear goal and tasks)
70
+ - `#path/to/file` - Mention files from your workspace in chat
71
+
72
+ **Example Session:**
73
+
74
+ ```text
75
+ > Analyze the src/index.ts file and find potential bugs
76
+
77
+ [Planner will reason about the task, select appropriate capabilities]
78
+ [Tasks will execute with live status updates]
79
+ [Events will stream in the right column]
80
+ ```
81
+
82
+ ## ACM Framework Integration
83
+
84
+ Phase 2 is built strictly on ACM v0.5 components:
85
+
86
+ ### Planner & Nucleus
87
+
88
+ - Chat pane visualizes ACM planner tool-call loops and nucleus inferences in real-time
89
+ - Streaming tokens show reasoning as it happens
90
+ - Budget checks run before each inference
91
+
92
+ #### Nucleus configuration requirements
93
+
94
+ - Every runtime invocation now passes a `nucleusFactory` and `nucleusConfig` to `executePlan`. The CLI wires these from the `--llm-provider`, `--llm-model`, `--llm-base-url`, and `--llm-engine` flags to build a shared `DeterministicNucleus` instance.
95
+ - If you embed AI Coder components elsewhere, supply your own factory that returns a `Nucleus` subclass and include at minimum an `llmCall` block with `provider`, `model`, and token limits.
96
+ - Tests and examples provide lightweight stub nuclei; use them as a reference when authoring new scripts or integrations.
97
+
98
+ ### Tools & Tasks
99
+
100
+ - All tools extend `Tool<I, O>` from `@ddse/acm-sdk`
101
+ - Tasks extend `Task<I, O>` and leverage context builder
102
+ - Tool call envelopes logged to ledger for determinism
103
+
104
+ ### Context Packets
105
+
106
+ - Context orchestration uses Phase 4 `ContextBuilder`
107
+ - Immutable packets with provenance and sources
108
+ - View current context with `/context` command
109
+
110
+ ### Ledger & Replay
111
+
112
+ - Event stream pane visualizes ledger entries
113
+ - Replay bundles saved automatically to `.aicoder/replays/`
114
+ - Includes session config, ledger, and budget summary
115
+
116
+ ### Budget Enforcement
117
+
118
+ - BudgetManager enforces spending limits before inference
119
+ - Provider metadata for OpenAI, Anthropic, Ollama, and more
120
+ - Real-time budget display in Tasks column
121
+
122
+ ## Architecture
123
+
124
+ The ACM AI Coder is built on the ACM framework and showcases all its capabilities:
125
+
126
+ ### ACM Framework Integration
127
+
128
+ 1. **SDK Layer**: All tools and tasks extend `Tool<I, O>` and `Task<I, O>` from `@ddse/acm-sdk`
129
+ 2. **Context Engine**: Intelligent repository understanding feeds into planning
130
+ 3. **Planning Phase**: LLM analyzes goal + context, generates Plan-A and Plan-B
131
+ 4. **Runtime Execution**: `@ddse/acm-runtime` executes plans with streaming, checkpoints, and verification
132
+ 5. **Policy Engine**: Safety guards with path restrictions and action gating
133
+ 6. **Replay Bundle**: Complete audit trail via `@ddse/acm-replay`
134
+
135
+ ### Workflow
136
+
137
+ 1. **Indexing**: Scan workspace, extract symbols, dependencies, and tests
138
+ 2. **Context Generation**: Create context pack with relevant files and symbols
139
+ 3. **Planning**: Feed context to LLM planner for multi-step plan generation
140
+ 4. **Approval**: User approves plan and operations that modify code
141
+ 5. **Execution**: ACM runtime executes with streaming progress
142
+ 6. **Checkpointing**: Automatic checkpoints after each task
143
+ 7. **Verification**: Tasks verify outputs match expectations
144
+
145
+ ### Safety Features
146
+
147
+ - **Dry Run Mode**: Preview all changes without modifying files
148
+ - **Approval Workflow**: User approval required for file modifications
149
+ - **Policy Engine**: Path allowlists and action restrictions
150
+ - **Automatic Backups**: `.backup` files created before edits
151
+ - **Checkpointing**: Resume from any point if execution is interrupted
152
+ - **Context Limits**: File size and result count limits prevent overload
153
+
154
+ ## How It Showcases ACM
155
+
156
+ This tool demonstrates every aspect of the ACM framework:
157
+
158
+ - **Capability Model**: Tasks are registered as capabilities with clear contracts
159
+ - **Tool Composition**: Tasks compose multiple tools to accomplish goals
160
+ - **Context Packets**: Immutable context with content-addressable refs
161
+ - **Plan Alternatives**: Planner generates Plan-A and Plan-B with rationale
162
+ - **Deterministic Execution**: Runtime executes plans with guards and verification
163
+ - **Policy Integration**: Pre/post hooks for safety enforcement
164
+ - **Memory Ledger**: Complete audit trail of all decisions
165
+ - **Streaming**: Real-time progress via StreamSink
166
+ - **Resumability**: FileCheckpointStore enables resume from crashes
167
+
168
+ ## Development
169
+
170
+ ### Running Tests
171
+
172
+ ```bash
173
+ # Run integration tests
174
+ pnpm --filter @ddse/acm-aicoder test
175
+ ```
176
+
177
+ <!-- markdownlint-enable MD024 MD032 -->
178
+
179
+ ### Building
180
+
181
+ ```bash
182
+ # Build TypeScript
183
+ pnpm --filter @ddse/acm-aicoder build
184
+
185
+ # Watch mode for development
186
+ pnpm --filter @ddse/acm-aicoder dev
187
+ ```
188
+
189
+ ## Examples
190
+
191
+ ### Example 1: Deep Workspace Analysis
192
+
193
+ ```bash
194
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal analyze --workspace .
195
+ ```
196
+
197
+ This will:
198
+
199
+ 1. Index all files in the workspace (respecting gitignore)
200
+ 2. Extract symbols (functions, classes, interfaces)
201
+ 3. Map dependencies from package.json
202
+ 4. Identify test files and their targets
203
+ 5. Generate a comprehensive report with statistics
204
+
205
+ Output includes:
206
+
207
+ - Total files scanned
208
+ - Code files by language
209
+ - Symbols extracted (functions, classes, etc.)
210
+ - Dependencies found
211
+ - Test file mappings
212
+
213
+ ### Example 2: Search for Code Patterns
214
+
215
+ ```bash
216
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal custom
217
+ # Enter: "Search for all error handling patterns in the codebase"
218
+ ```
219
+
220
+ This will:
221
+
222
+ 1. Build BM25 index of code files
223
+ 2. Search for "error handling try catch" patterns
224
+ 3. Return top-k results with context
225
+ 4. Show file paths, line numbers, and code snippets
226
+
227
+ ### Example 3: Implement a New Function
228
+
229
+ ```bash
230
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal custom
231
+ # Enter: "Implement a function to validate email addresses in src/utils.ts"
232
+ ```
233
+
234
+ This will:
235
+
236
+ 1. Read the target file
237
+ 2. Analyze existing code patterns
238
+ 3. Generate function implementation (with LLM)
239
+ 4. Show diff preview
240
+ 5. Request approval
241
+ 6. Apply changes with automatic backup
242
+
243
+ ### Example 4: Refactor Symbol Names
244
+
245
+ ```bash
246
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal custom
247
+ # Enter: "Rename function getUserData to fetchUserData everywhere"
248
+ ```
249
+
250
+ This will:
251
+
252
+ 1. Search for all occurrences of the symbol
253
+ 2. Generate list of affected files
254
+ 3. Show preview of changes
255
+ 4. Request approval
256
+ 5. Apply rename across all files (with backup)
257
+
258
+ ### Example 5: Fix TypeScript Errors
259
+
260
+ ```bash
261
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal custom
262
+ # Enter: "Fix all TypeScript compilation errors"
263
+ ```
264
+
265
+ This will:
266
+
267
+ 1. Run build to collect TypeScript errors
268
+ 2. Analyze each error with context
269
+ 3. Generate fixes (with LLM)
270
+ 4. Show diffs for each fix
271
+ 5. Request approval
272
+ 6. Apply fixes and verify build succeeds
273
+
274
+ ### Example 6: Generate Unit Tests
275
+
276
+ ```bash
277
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal custom
278
+ # Enter: "Generate unit tests for the validateEmail function in src/utils.ts"
279
+ ```
280
+
281
+ This will:
282
+
283
+ 1. Read and analyze the target function
284
+ 2. Generate test cases (with LLM)
285
+ 3. Create test file (e.g., `src/utils.test.ts`)
286
+ 4. Show preview
287
+ 5. Request approval
288
+ 6. Apply and run tests to verify
289
+
290
+ ### Example 7: Resume from Checkpoint
291
+
292
+ ```bash
293
+ # Start a long operation
294
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --goal implementFeature
295
+
296
+ # If interrupted (Ctrl+C), resume later:
297
+ pnpm --filter @ddse/acm-aicoder exec acm-aicoder --resume run-1696348800000
298
+ ```
299
+
300
+ The resume will:
301
+
302
+ 1. Load checkpoint from disk
303
+ 2. Restore plan and completed tasks
304
+ 3. Continue from the next task
305
+ 4. Maintain all context and state
306
+
307
+ ## Key Components
308
+
309
+ ### Context Engine
310
+
311
+ Located in `src/context/`:
312
+
313
+ - **WorkspaceIndexer**: Fast file scanning with caching
314
+ - **SymbolExtractor**: Parse TS/JS for symbols
315
+ - **DependencyMapper**: Extract package.json dependencies
316
+ - **TestMapper**: Identify test files
317
+ - **CodeSearch**: BM25-based semantic search
318
+ - **ContextPackGenerator**: Generate planning context
319
+
320
+ ### Tools V2
321
+
322
+ Located in `src/tools-v2/`:
323
+
324
+ - **read-tools.ts**: FileStatTool, FileReadToolV2, FileReadLinesTool, DiffTool
325
+ - **search-tools.ts**: CodeSearchTool, GrepTool
326
+ - **edit-tools.ts**: PatchApplyTool, CodeEditToolV2
327
+ - **test-tools.ts**: RunTestsToolV2, BuildTool
328
+
329
+ ### Tasks V2
330
+
331
+ Located in `src/tasks-v2/`:
332
+
333
+ - **analysis-tasks.ts**: AnalyzeWorkspaceTask, CollectContextPackTask, SearchCodeTask
334
+ - **developer-tasks.ts**: FindSymbolDefinitionTask, ImplementFunctionTask, RefactorRenameSymbolTask, FixTypeErrorTask, GenerateUnitTestsTask
335
+
336
+ ## Contributing
337
+
338
+ See [CONTRIBUTING.md](../../CONTRIBUTING.md) for development guidelines.
339
+
340
+ ## License
341
+
342
+ MIT
343
+
344
+ You can also use the AI Coder programmatically:
345
+
346
+ ```typescript
347
+ import {
348
+ // Context Engine
349
+ WorkspaceIndexer,
350
+ SymbolExtractor,
351
+ CodeSearch,
352
+ ContextPackGenerator,
353
+
354
+ // Tools V2
355
+ FileStatTool,
356
+ FileReadToolV2,
357
+ CodeSearchTool,
358
+ GrepTool,
359
+ DiffTool,
360
+ PatchApplyTool,
361
+ CodeEditToolV2,
362
+ RunTestsToolV2,
363
+ BuildTool,
364
+
365
+ // Tasks V2
366
+ AnalyzeWorkspaceTask,
367
+ FindSymbolDefinitionTask,
368
+ ImplementFunctionTask,
369
+ RefactorRenameSymbolTask,
370
+ GenerateUnitTestsTask,
371
+ CollectContextPackTask,
372
+
373
+ // Registries
374
+ SimpleCapabilityRegistry,
375
+ SimpleToolRegistry,
376
+ SimplePolicyEngine,
377
+ } from '@ddse/acm-aicoder';
378
+
379
+ import { executeResumablePlan } from '@ddse/acm-runtime';
380
+ import { StructuredLLMPlanner } from '@ddse/acm-planner';
381
+ import { createOllamaClient } from '@ddse/acm-llm';
382
+
383
+ // Setup
384
+ const rootPath = process.cwd();
385
+
386
+ // 1. Build workspace index
387
+ const indexer = new WorkspaceIndexer(rootPath);
388
+ const index = await indexer.buildIndex();
389
+
390
+ // 2. Setup search
391
+ const search = new CodeSearch(rootPath);
392
+ await search.indexFiles(index);
393
+
394
+ // 3. Register tools
395
+ const toolRegistry = new SimpleToolRegistry();
396
+ toolRegistry.register(new FileStatTool());
397
+ toolRegistry.register(new CodeSearchTool(rootPath));
398
+ toolRegistry.register(new GrepTool(rootPath));
399
+ toolRegistry.register(new CodeEditToolV2());
400
+ toolRegistry.register(new RunTestsToolV2());
401
+ toolRegistry.register(new BuildTool());
402
+
403
+ // 4. Register tasks
404
+ const capabilityRegistry = new SimpleCapabilityRegistry();
405
+ capabilityRegistry.register(
406
+ { name: 'analyze_workspace', sideEffects: false },
407
+ new AnalyzeWorkspaceTask()
408
+ );
409
+ capabilityRegistry.register(
410
+ { name: 'find_symbol', sideEffects: false },
411
+ new FindSymbolDefinitionTask()
412
+ );
413
+ capabilityRegistry.register(
414
+ { name: 'implement_function', sideEffects: true },
415
+ new ImplementFunctionTask()
416
+ );
417
+
418
+ // 5. Create context pack
419
+ const symbolExtractor = new SymbolExtractor(rootPath);
420
+ const symbols = await symbolExtractor.extractSymbols(index);
421
+
422
+ const packGenerator = new ContextPackGenerator(search);
423
+ const contextPack = await packGenerator.generate(
424
+ 'Find and fix all TypeScript errors',
425
+ index,
426
+ symbols,
427
+ [], // dependencies
428
+ [], // test mappings
429
+ { maxFiles: 10, maxSymbols: 30 }
430
+ );
431
+
432
+ // 6. Plan with context
433
+ const llm = createOllamaClient('llama3.1');
434
+ const planner = new StructuredLLMPlanner();
435
+
436
+ const goal = {
437
+ id: 'goal-1',
438
+ intent: 'Find and fix all TypeScript errors',
439
+ constraints: {},
440
+ };
441
+
442
+ const context = {
443
+ id: 'ctx-1',
444
+ facts: { contextPack },
445
+ version: '1.0',
446
+ };
447
+
448
+ const plannerResult = await planner.plan({
449
+ goal,
450
+ context,
451
+ capabilities: capabilityRegistry.list(),
452
+ llm,
453
+ });
454
+
455
+ // 7. Execute with runtime
456
+ const policy = new SimplePolicyEngine();
457
+ policy.setAllowedPaths(['src/**']);
458
+
459
+ const result = await executeResumablePlan({
460
+ goal,
461
+ context,
462
+ plan: plannerResult.plans[0],
463
+ capabilityRegistry,
464
+ toolRegistry,
465
+ policy,
466
+ verify: async (taskId, output, expressions) => true,
467
+ runId: `run-${Date.now()}`,
468
+ });
469
+
470
+ console.log('Execution complete:', result);
471
+ ```
472
+
473
+ ## Reference Pipeline Walkthrough
474
+
475
+ ### Build from Source
476
+
477
+ ```bash
478
+ # Build TypeScript
479
+ pnpm --filter @ddse/acm-aicoder build
480
+
481
+ # Watch mode for development
482
+ pnpm --filter @ddse/acm-aicoder dev
483
+ ```
484
+
485
+ ### Test Suite (Preview)
486
+
487
+ ```bash
488
+ # Run integration tests (coming soon)
489
+ pnpm --filter @ddse/acm-aicoder test
490
+ ```
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+
3
+ // ACM AI Coder - Phase 2 Interactive CLI
4
+ // Full-screen TUI with three-column layout
5
+ // Requires: --provider, --model, and --workspace (optional --base-url)
6
+
7
+ import React from 'react';
8
+ import { render } from 'ink';
9
+ import { ExternalContextProviderAdapter } from '@ddse/acm-sdk';
10
+ import { createOllamaClient, createVLLMClient } from '@ddse/acm-llm';
11
+ import { App } from '../src/ui/App.js';
12
+ import { AppStore } from '../src/ui/store.js';
13
+ import { InteractiveRuntime } from '../src/runtime/interactive-runtime.js';
14
+ import { parseCliArgs, validateAndNormalizeConfig } from '../src/config/session.js';
15
+ import {
16
+ SimpleCapabilityRegistry,
17
+ SimpleToolRegistry,
18
+ SimplePolicyEngine,
19
+ // V2 Tools
20
+ FileStatTool,
21
+ FileReadToolV2,
22
+ CodeSearchTool,
23
+ GrepTool,
24
+ DiffTool,
25
+ CodeEditToolV2,
26
+ RunTestsToolV2,
27
+ WorkspaceContextRetrievalTool,
28
+ type WorkspaceContextOperation,
29
+ BuildTool,
30
+ // V2 Tasks
31
+ AnalyzeWorkspaceTask,
32
+ CollectContextPackTask,
33
+ SearchCodeTask,
34
+ FindSymbolDefinitionTask,
35
+ ImplementFunctionTask,
36
+ RefactorRenameSymbolTask,
37
+ FixTypeErrorTask,
38
+ GenerateUnitTestsTask,
39
+ } from '../src/index.js';
40
+
41
+ function buildWorkspaceContextInput(
42
+ directive: string,
43
+ goalIntent?: string
44
+ ): {
45
+ directive: string;
46
+ goal?: string;
47
+ operations: WorkspaceContextOperation[];
48
+ } {
49
+ const separatorIndex = directive.indexOf(':');
50
+ const payload = separatorIndex >= 0 ? directive.slice(separatorIndex + 1).trim() : '';
51
+ const operations: WorkspaceContextOperation[] = [];
52
+
53
+ if (payload.length > 0) {
54
+ if (payload.startsWith('{')) {
55
+ try {
56
+ const parsed = JSON.parse(payload);
57
+ if (Array.isArray(parsed.operations)) {
58
+ return {
59
+ directive,
60
+ goal: goalIntent,
61
+ operations: parsed.operations as WorkspaceContextOperation[],
62
+ };
63
+ }
64
+ if (typeof parsed.query === 'string' && parsed.query.length > 0) {
65
+ operations.push({ type: 'search', query: parsed.query, includeContext: true });
66
+ }
67
+ if (typeof parsed.pattern === 'string' && parsed.pattern.length > 0) {
68
+ operations.push({ type: 'grep', pattern: parsed.pattern, maxResults: 20 });
69
+ }
70
+ } catch {
71
+ // Fall through to textual parsing
72
+ }
73
+ }
74
+
75
+ if (operations.length === 0) {
76
+ operations.push({ type: 'search', query: payload, includeContext: true });
77
+ operations.push({ type: 'grep', pattern: payload, maxResults: 20 });
78
+ }
79
+ }
80
+
81
+ return {
82
+ directive,
83
+ goal: goalIntent,
84
+ operations,
85
+ };
86
+ }
87
+
88
+ async function main() {
89
+ try {
90
+ // Parse and validate CLI arguments
91
+ const args = parseCliArgs(process.argv.slice(2));
92
+ const config = validateAndNormalizeConfig(args);
93
+
94
+ // Ensure the process operates within the validated workspace
95
+ process.chdir(config.workspace);
96
+
97
+ // Create LLM client based on provider selection
98
+ const llm = config.provider === 'vllm'
99
+ ? createVLLMClient(config.model, config.baseUrl)
100
+ : createOllamaClient(config.model, config.baseUrl);
101
+
102
+ // Setup registries
103
+ const toolRegistry = new SimpleToolRegistry();
104
+ const capabilityRegistry = new SimpleCapabilityRegistry();
105
+ const policyEngine = new SimplePolicyEngine();
106
+ const contextProvider = new ExternalContextProviderAdapter();
107
+
108
+ // Register tools
109
+ const fileStatTool = new FileStatTool(config.workspace);
110
+ const fileReadTool = new FileReadToolV2(config.workspace);
111
+ const codeSearchTool = new CodeSearchTool(config.workspace);
112
+ const grepTool = new GrepTool(config.workspace);
113
+ const diffTool = new DiffTool(config.workspace);
114
+ const codeEditTool = new CodeEditToolV2(config.workspace);
115
+ const runTestsTool = new RunTestsToolV2(config.workspace);
116
+ const buildTool = new BuildTool(config.workspace);
117
+ const workspaceContextTool = new WorkspaceContextRetrievalTool(config.workspace);
118
+
119
+ toolRegistry.register(fileStatTool);
120
+ toolRegistry.register(fileReadTool);
121
+ toolRegistry.register(codeSearchTool);
122
+ toolRegistry.register(grepTool);
123
+ toolRegistry.register(diffTool);
124
+ toolRegistry.register(codeEditTool);
125
+ toolRegistry.register(runTestsTool);
126
+ toolRegistry.register(buildTool);
127
+ toolRegistry.register(workspaceContextTool);
128
+
129
+ contextProvider.register(workspaceContextTool, {
130
+ match: directive =>
131
+ directive.startsWith('workspace.context') || directive.startsWith('workspace_context'),
132
+ buildInput: (directive, ctx) =>
133
+ buildWorkspaceContextInput(directive, ctx.runContext?.goal.intent),
134
+ describe:
135
+ 'Retrieve relevant workspace snippets, grep matches, and metadata to satisfy context requests.',
136
+ autoPromote: true,
137
+ maxArtifacts: 32,
138
+ });
139
+
140
+ // Register capabilities (tasks)
141
+ capabilityRegistry.register(
142
+ { name: 'analyze_workspace', sideEffects: false },
143
+ new AnalyzeWorkspaceTask()
144
+ );
145
+ capabilityRegistry.register(
146
+ { name: 'collect_context_pack', sideEffects: false },
147
+ new CollectContextPackTask()
148
+ );
149
+ capabilityRegistry.register(
150
+ { name: 'search_code', sideEffects: false },
151
+ new SearchCodeTask()
152
+ );
153
+ capabilityRegistry.register(
154
+ { name: 'find_symbol_definition', sideEffects: false },
155
+ new FindSymbolDefinitionTask()
156
+ );
157
+ capabilityRegistry.register(
158
+ { name: 'implement_function', sideEffects: true },
159
+ new ImplementFunctionTask()
160
+ );
161
+ capabilityRegistry.register(
162
+ { name: 'refactor_rename_symbol', sideEffects: true },
163
+ new RefactorRenameSymbolTask()
164
+ );
165
+ capabilityRegistry.register(
166
+ { name: 'fix_type_error', sideEffects: true },
167
+ new FixTypeErrorTask()
168
+ );
169
+ capabilityRegistry.register(
170
+ { name: 'generate_unit_tests', sideEffects: true },
171
+ new GenerateUnitTestsTask()
172
+ );
173
+
174
+ // Allow workspace operations
175
+ policyEngine.setAllowedPaths([config.workspace]);
176
+
177
+ // Create app store and runtime
178
+ const store = new AppStore();
179
+ const runtime = new InteractiveRuntime({
180
+ config,
181
+ llm,
182
+ capabilityRegistry,
183
+ toolRegistry,
184
+ policyEngine,
185
+ store,
186
+ contextProvider,
187
+ });
188
+
189
+ const initialBudget = runtime.getBudgetManager().getStatus();
190
+
191
+ // Welcome message
192
+ store.addMessage('system',
193
+ `Welcome to ACM AI Coder (Phase 2)\n\n` +
194
+ `Configuration:\n` +
195
+ ` Provider: ${config.provider}\n` +
196
+ ` Model: ${config.model}\n` +
197
+ (config.baseUrl ? ` Base URL: ${config.baseUrl}\n` : '') +
198
+ ` Workspace: ${config.workspace}\n` +
199
+ (initialBudget.maxTokens !== undefined ? ` Token allowance: ${initialBudget.maxTokens}\n` : '') +
200
+ `\n` +
201
+ `Type your goal to start planning, or /help for commands.`
202
+ );
203
+
204
+ // Update initial budget status
205
+ store.updateBudgetStatus(initialBudget);
206
+
207
+ // Handle commands from UI
208
+ const handleCommand = async (command: string) => {
209
+ if (command.startsWith('/')) {
210
+ // Already handled by UI component
211
+ return;
212
+ }
213
+
214
+ // Process as goal
215
+ await runtime.processGoal(command);
216
+ };
217
+
218
+ // Render TUI
219
+ render(<App store={store} onCommand={handleCommand} />);
220
+
221
+ } catch (error: any) {
222
+ console.error('Error starting ACM AI Coder:');
223
+ console.error(error.message);
224
+ console.error('\nFor help, run: acm-aicoder --help');
225
+ process.exit(1);
226
+ }
227
+ }
228
+
229
+ main().catch(err => {
230
+ console.error('Fatal error:', err);
231
+ process.exit(1);
232
+ });