@auto-engineer/server-implementer 0.4.7 → 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 (45) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/.turbo/turbo-format.log +20 -25
  3. package/.turbo/turbo-lint.log +5 -4
  4. package/.turbo/turbo-test.log +14 -12
  5. package/.turbo/turbo-type-check.log +5 -4
  6. package/CHANGELOG.md +12 -0
  7. package/README.md +264 -0
  8. package/dist/cli-manifest.d.ts +3 -0
  9. package/dist/cli-manifest.d.ts.map +1 -0
  10. package/dist/cli-manifest.js +23 -0
  11. package/dist/cli-manifest.js.map +1 -0
  12. package/dist/commands/implement-server.d.ts +6 -2
  13. package/dist/commands/implement-server.d.ts.map +1 -1
  14. package/dist/commands/implement-server.js +33 -3
  15. package/dist/commands/implement-server.js.map +1 -1
  16. package/dist/commands/implement-slice.d.ts +22 -0
  17. package/dist/commands/implement-slice.d.ts.map +1 -0
  18. package/dist/commands/implement-slice.js +262 -0
  19. package/dist/commands/implement-slice.js.map +1 -0
  20. package/dist/index.d.ts +3 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -1
  23. package/dist/index.js.map +1 -1
  24. package/package.json +10 -8
  25. package/src/cli-manifest.ts +24 -0
  26. package/src/commands/implement-server.ts +43 -3
  27. package/src/commands/implement-slice.ts +333 -0
  28. package/src/index.ts +10 -1
  29. package/dist/cli/implement-server.d.ts +0 -3
  30. package/dist/cli/implement-server.d.ts.map +0 -1
  31. package/dist/cli/implement-server.js +0 -39
  32. package/dist/cli/implement-server.js.map +0 -1
  33. package/dist/cli/index.d.ts +0 -2
  34. package/dist/cli/index.d.ts.map +0 -1
  35. package/dist/cli/index.js +0 -39
  36. package/dist/cli/index.js.map +0 -1
  37. package/src/agent/runAllSlices.js +0 -11
  38. package/src/agent/runFlows.js +0 -16
  39. package/src/agent/runSlice.js +0 -328
  40. package/src/agent/runTests.js +0 -100
  41. package/src/cli/implement-server.ts +0 -46
  42. package/src/cli/index.js +0 -21
  43. package/src/cli/index.ts +0 -48
  44. package/src/prompts/systemPrompt.js +0 -43
  45. package/src/utils/extractCodeBlock.js +0 -6
@@ -0,0 +1,262 @@
1
+ import { generateTextWithAI, getAvailableProviders } from '@auto-engineer/ai-gateway';
2
+ import path from 'path';
3
+ import { existsSync } from 'fs';
4
+ import { readFile, writeFile } from 'fs/promises';
5
+ import fg from 'fast-glob';
6
+ import createDebug from 'debug';
7
+ const debug = createDebug('server-impl:slice');
8
+ const debugHandler = createDebug('server-impl:slice:handler');
9
+ const debugProcess = createDebug('server-impl:slice:process');
10
+ const debugResult = createDebug('server-impl:slice:result');
11
+ // System prompt for AI implementation
12
+ const SYSTEM_PROMPT = `
13
+ You are a software engineer implementing missing logic in a sliced event-driven TypeScript backend. Each slice contains partially scaffolded code, and your task is to complete the logic following implementation instructions embedded in each file.
14
+
15
+ Project Characteristics:
16
+ - Architecture: sliced event-sourced CQRS (Command, Query, Reaction slices)
17
+ - Language: TypeScript with type-graphql and Emmett
18
+ - Each slice has scaffolded files with implementation instructions clearly marked with comments (e.g., '## IMPLEMENTATION INSTRUCTIONS ##') or TODOs.
19
+ - Tests (e.g., *.specs.ts) must pass.
20
+ - Type errors are not allowed.
21
+
22
+ Your Goal:
23
+ - Read the implementation instructions from the provided file.
24
+ - Generate only the code needed to fulfill the instructions, nothing extra and provide back the whole file without the instructions.
25
+ - Maintain immutability and adhere to functional best practices.
26
+ - Use only the types and domain constructs already present in the slice.
27
+ - Do not remove existing imports or types that are still referenced or required in the file.
28
+ - Return the entire updated file, not just the modified parts and remove any TODO comments or instructions after implementing the logic
29
+
30
+ Key rules:
31
+ - Never modify code outside the TODO or instruction areas.
32
+ - Ensure the code is production-ready and type-safe.
33
+ - Follow the slice type conventions:
34
+ - **Command slice**: validate command, inspect state, emit events, never mutate state. Uses graphql mutations.
35
+ - **Reaction slice**: respond to events with commands.
36
+ - **Query slice**: maintain projections based on events, do not emit or throw. Uses graphql queries.
37
+ - All code must be TypeScript compliant and follow functional patterns.
38
+ - If a test exists, make it pass.
39
+ - Keep implementations minimal and idiomatic.
40
+
41
+ Avoid:
42
+ - Adding new dependencies.
43
+ - Refactoring unrelated code.
44
+ - Changing the structure of already scaffolded files unless instructed.
45
+
46
+ You will receive:
47
+ - The path of the file to implement.
48
+ - The current contents of the file, with instruction comments.
49
+ - Other relevant files from the same slice (e.g., types, test, state, etc.).
50
+
51
+ You must:
52
+ - Return the entire updated file (no commentary and remove all implementation instructions).
53
+ - Ensure the output is valid TypeScript.
54
+ `;
55
+ // Helper function to extract code block from AI response
56
+ function extractCodeBlock(text) {
57
+ return text
58
+ .replace(/```(?:ts|typescript)?/g, '')
59
+ .replace(/```/g, '')
60
+ .trim();
61
+ }
62
+ // Load all TypeScript files from the slice directory
63
+ async function loadContextFiles(sliceDir) {
64
+ const files = await fg(['*.ts'], { cwd: sliceDir });
65
+ const context = {};
66
+ for (const file of files) {
67
+ const absPath = path.join(sliceDir, file);
68
+ context[file] = await readFile(absPath, 'utf-8');
69
+ }
70
+ return context;
71
+ }
72
+ // Find files that need implementation
73
+ function findFilesToImplement(contextFiles) {
74
+ return Object.entries(contextFiles).filter(([, content]) => content.includes('TODO:') || content.includes('IMPLEMENTATION INSTRUCTIONS'));
75
+ }
76
+ // Build prompt for initial implementation
77
+ function buildInitialPrompt(targetFile, context) {
78
+ return `
79
+ ${SYSTEM_PROMPT}
80
+
81
+ ---
82
+ 📄 Target file to implement: ${targetFile}
83
+
84
+ ${context[targetFile]}
85
+
86
+ ---
87
+ 🧠 Other files in the same slice:
88
+ ${Object.entries(context)
89
+ .filter(([name]) => name !== targetFile)
90
+ .map(([name, content]) => `// File: ${name}\n${content}`)
91
+ .join('\n\n')}
92
+
93
+ ---
94
+ Return only the whole updated file of ${targetFile}. Do not remove existing imports or types that are still referenced or required in the file. The file returned has to be production ready.
95
+ `.trim();
96
+ }
97
+ // Build prompt for retry with context
98
+ function buildRetryPrompt(targetFile, context, previousOutputs) {
99
+ return `
100
+ ${SYSTEM_PROMPT}
101
+
102
+ ---
103
+ The previous implementation needs adjustment based on this feedback:
104
+
105
+ ${previousOutputs}
106
+
107
+ 📄 File to update: ${targetFile}
108
+
109
+ ${context[targetFile]}
110
+
111
+ 🧠 Other files in the same slice:
112
+ ${Object.entries(context)
113
+ .filter(([name]) => name !== targetFile)
114
+ .map(([name, content]) => `// File: ${name}\n${content}`)
115
+ .join('\n\n')}
116
+
117
+ ---
118
+ Return only the corrected full contents of ${targetFile}, no commentary, no markdown.
119
+ `.trim();
120
+ }
121
+ // Main implementation function
122
+ async function implementSlice(sliceDir, flowName, context) {
123
+ const availableProviders = getAvailableProviders();
124
+ if (availableProviders.length === 0) {
125
+ throw new Error('No AI providers configured. Please set one of: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, or XAI_API_KEY');
126
+ }
127
+ const AI_PROVIDER = availableProviders[0];
128
+ const sliceName = path.basename(sliceDir);
129
+ debugProcess(`Implementing slice: ${sliceName} for flow: ${flowName}`);
130
+ try {
131
+ // Load all context files
132
+ const contextFiles = await loadContextFiles(sliceDir);
133
+ const filesToImplement = findFilesToImplement(contextFiles);
134
+ const implementedFiles = [];
135
+ if (filesToImplement.length === 0) {
136
+ debugProcess('No files with TODO or IMPLEMENTATION INSTRUCTIONS found');
137
+ return { success: true, filesImplemented: [] };
138
+ }
139
+ // Implement each file that needs it
140
+ for (const [targetFile] of filesToImplement) {
141
+ debugProcess(`Implementing ${targetFile}`);
142
+ let prompt;
143
+ if (context !== undefined && context.previousOutputs !== undefined && context.previousOutputs.length > 0) {
144
+ // Use retry prompt if we have previous context
145
+ prompt = buildRetryPrompt(targetFile, contextFiles, context.previousOutputs);
146
+ debugProcess(`Using retry prompt for attempt #${context.attemptNumber ?? 2}`);
147
+ }
148
+ else {
149
+ // Use initial prompt for first attempt
150
+ prompt = buildInitialPrompt(targetFile, contextFiles);
151
+ }
152
+ // Generate implementation with AI
153
+ const aiOutput = await generateTextWithAI(prompt, AI_PROVIDER);
154
+ const cleanedCode = extractCodeBlock(aiOutput);
155
+ // Write the implemented file
156
+ const filePath = path.join(sliceDir, targetFile);
157
+ await writeFile(filePath, cleanedCode, 'utf-8');
158
+ debugProcess(`Successfully implemented ${targetFile}`);
159
+ implementedFiles.push(targetFile);
160
+ // Update context for next file
161
+ contextFiles[targetFile] = cleanedCode;
162
+ }
163
+ return { success: true, filesImplemented: implementedFiles };
164
+ }
165
+ catch (error) {
166
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
167
+ debugProcess(`Implementation failed: ${errorMessage}`);
168
+ return { success: false, filesImplemented: [], error: errorMessage };
169
+ }
170
+ }
171
+ function logCommandDebugInfo(command) {
172
+ const { sliceDirectory, flowName, context } = command.data;
173
+ debug('Handling ImplementSliceCommand');
174
+ debug(' Slice directory: %s', sliceDirectory);
175
+ debug(' Flow name: %s', flowName);
176
+ debug(' Context provided: %s', context ? 'yes' : 'no');
177
+ if (context) {
178
+ debug(' Attempt number: %d', context.attemptNumber ?? 1);
179
+ }
180
+ debug(' Request ID: %s', command.requestId);
181
+ debug(' Correlation ID: %s', command.correlationId ?? 'none');
182
+ }
183
+ function createFailedEvent(command, error) {
184
+ return {
185
+ type: 'SliceImplementationFailed',
186
+ data: {
187
+ sliceDirectory: command.data.sliceDirectory,
188
+ flowName: command.data.flowName,
189
+ error,
190
+ },
191
+ timestamp: new Date(),
192
+ requestId: command.requestId,
193
+ correlationId: command.correlationId,
194
+ };
195
+ }
196
+ function createSuccessEvent(command, filesImplemented) {
197
+ return {
198
+ type: 'SliceImplemented',
199
+ data: {
200
+ sliceDirectory: command.data.sliceDirectory,
201
+ flowName: command.data.flowName,
202
+ filesImplemented,
203
+ },
204
+ timestamp: new Date(),
205
+ requestId: command.requestId,
206
+ correlationId: command.correlationId,
207
+ };
208
+ }
209
+ function logRetryContext(context) {
210
+ if (context !== undefined && context.previousOutputs !== undefined && context.previousOutputs.length > 0) {
211
+ debugProcess('Retrying with context from previous attempt #%d', context.attemptNumber ?? 1);
212
+ debugProcess('Previous outputs: %s', context.previousOutputs.substring(0, 500));
213
+ }
214
+ }
215
+ export async function handleImplementSliceCommand(command) {
216
+ const { sliceDirectory, flowName, context } = command.data;
217
+ logCommandDebugInfo(command);
218
+ try {
219
+ const sliceRoot = path.resolve(sliceDirectory);
220
+ debugHandler('Resolved paths:');
221
+ debugHandler(' Slice root: %s', sliceRoot);
222
+ if (!existsSync(sliceRoot)) {
223
+ debugHandler('ERROR: Slice directory not found at %s', sliceRoot);
224
+ return createFailedEvent(command, `Slice directory not found at: ${sliceRoot}`);
225
+ }
226
+ debugProcess('Starting slice implementation for: %s', sliceRoot);
227
+ logRetryContext(context);
228
+ const result = await implementSlice(sliceRoot, flowName, context);
229
+ if (!result.success) {
230
+ return createFailedEvent(command, result.error ?? 'Implementation failed');
231
+ }
232
+ debugResult('Process succeeded');
233
+ debugResult('Files implemented: %d', result.filesImplemented.length);
234
+ debugResult('Files: %s', result.filesImplemented.join(', '));
235
+ debugResult('Returning success event: SliceImplemented');
236
+ return createSuccessEvent(command, result.filesImplemented);
237
+ }
238
+ catch (error) {
239
+ debug('ERROR: Exception caught: %O', error);
240
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
241
+ return createFailedEvent(command, errorMessage);
242
+ }
243
+ }
244
+ export const implementSliceCommandHandler = {
245
+ name: 'ImplementSlice',
246
+ handle: async (command) => {
247
+ debug('CommandHandler executing for ImplementSlice');
248
+ const result = await handleImplementSliceCommand(command);
249
+ if (result.type === 'SliceImplemented') {
250
+ debug('Command handler completed: success');
251
+ console.log(`✅ Slice implementation completed successfully`);
252
+ console.log(` Flow: ${result.data.flowName}`);
253
+ console.log(` Files implemented: ${result.data.filesImplemented.length}`);
254
+ }
255
+ else {
256
+ debug('Command handler completed: failure - %s', result.data.error);
257
+ console.error(`❌ Slice implementation failed: ${result.data.error}`);
258
+ process.exit(1);
259
+ }
260
+ },
261
+ };
262
+ //# sourceMappingURL=implement-slice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implement-slice.js","sourceRoot":"","sources":["../../src/commands/implement-slice.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export { implementServerCommandHandler, handleImplementServerCommand, type ImplementServerCommand, type ServerImplementedEvent, type ServerImplementationFailedEvent, } from './commands/implement-server';
1
+ export { CLI_MANIFEST } from './cli-manifest';
2
+ export { implementServerCommandHandler, type ImplementServerCommand, type ServerImplementedEvent, type ServerImplementationFailedEvent, } from './commands/implement-server';
3
+ export { implementSliceCommandHandler, handleImplementSliceCommand, type ImplementSliceCommand, type SliceImplementedEvent, type SliceImplementationFailedEvent, } from './commands/implement-slice';
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,GACrC,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACL,6BAA6B,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,GACrC,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,8BAA8B,GACpC,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
- export { implementServerCommandHandler, handleImplementServerCommand, } from './commands/implement-server.js';
1
+ export { CLI_MANIFEST } from './cli-manifest.js';
2
+ export { implementServerCommandHandler, } from './commands/implement-server.js';
3
+ export { implementSliceCommandHandler, handleImplementSliceCommand, } from './commands/implement-slice.js';
2
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAI7B,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EACL,6BAA6B,GAI9B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,GAI5B,MAAM,4BAA4B,CAAC"}
package/package.json CHANGED
@@ -1,24 +1,28 @@
1
1
  {
2
2
  "name": "@auto-engineer/server-implementer",
3
- "version": "0.4.7",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
- "bin": {
8
- "implement-server": "./dist/cli/implement-server.js"
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
9
12
  },
10
13
  "publishConfig": {
11
14
  "access": "public"
12
15
  },
13
16
  "dependencies": {
14
- "@auto-engineer/ai-gateway": "^0.4.5",
15
- "@auto-engineer/message-bus": "^0.3.4",
17
+ "@auto-engineer/ai-gateway": "^0.5.0",
18
+ "@auto-engineer/message-bus": "^0.4.0",
16
19
  "@modelcontextprotocol/sdk": "^1.3.0",
17
20
  "debug": "^4.3.4",
18
21
  "fast-glob": "^3.3.3",
19
22
  "vite": "^5.4.1"
20
23
  },
21
24
  "devDependencies": {
25
+ "@auto-engineer/cli": "^0.6.0",
22
26
  "@types/fs-extra": "^11.0.4",
23
27
  "dotenv": "^16.6.1",
24
28
  "execa": "^9.6.0",
@@ -29,9 +33,7 @@
29
33
  "vitest": "^3.2.4"
30
34
  },
31
35
  "scripts": {
32
- "implement": "tsx src/cli/index.ts",
33
- "implement:server": "tsx src/cli/implement-server.ts",
34
- "build": "tsc && tsx ../../scripts/fix-esm-imports.ts && chmod +x dist/cli/implement-server.js",
36
+ "build": "tsc && tsx ../../scripts/fix-esm-imports.ts",
35
37
  "dev": "tsc --watch",
36
38
  "test": "vitest run",
37
39
  "lint": "eslint 'src/**/*.ts' --max-warnings 0 --config ../../eslint.config.ts",
@@ -0,0 +1,24 @@
1
+ import type { CliManifest } from '@auto-engineer/cli/manifest-types';
2
+
3
+ export const CLI_MANIFEST: CliManifest = {
4
+ category: '@auto-engineer/server-implementer',
5
+ commands: {
6
+ 'implement:server': {
7
+ handler: () => import('./commands/implement-server'),
8
+ description: 'AI implements server TODOs and tests',
9
+ usage: 'implement:server <server-dir>',
10
+ examples: ['$ auto implement:server ./server'],
11
+ args: [{ name: 'server-dir', description: 'Server directory path', required: true }],
12
+ },
13
+ 'implement:slice': {
14
+ handler: () => import('./commands/implement-slice'),
15
+ description: 'AI implements a specific server slice',
16
+ usage: 'implement:slice <server-dir> <slice-name>',
17
+ examples: ['$ auto implement:slice ./server enters-shopping-criteria'],
18
+ args: [
19
+ { name: 'server-dir', description: 'Server directory path', required: true },
20
+ { name: 'slice-name', description: 'Name of the slice to implement', required: true },
21
+ ],
22
+ },
23
+ },
24
+ };
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env node
2
1
  import { type CommandHandler, type Command, type Event } from '@auto-engineer/message-bus';
3
2
  import path from 'path';
4
3
  import { existsSync } from 'fs';
@@ -33,7 +32,7 @@ export type ServerImplementationFailedEvent = Event<
33
32
  }
34
33
  >;
35
34
 
36
- export async function handleImplementServerCommand(
35
+ async function handleImplementServerCommandInternal(
37
36
  command: ImplementServerCommand,
38
37
  ): Promise<ServerImplementedEvent | ServerImplementationFailedEvent> {
39
38
  const { serverDirectory } = command.data;
@@ -113,7 +112,7 @@ export const implementServerCommandHandler: CommandHandler<ImplementServerComman
113
112
  name: 'ImplementServer',
114
113
  handle: async (command: ImplementServerCommand): Promise<void> => {
115
114
  debug('CommandHandler executing for ImplementServer');
116
- const result = await handleImplementServerCommand(command);
115
+ const result = await handleImplementServerCommandInternal(command);
117
116
 
118
117
  if (result.type === 'ServerImplemented') {
119
118
  debug('Command handler completed: success');
@@ -128,3 +127,44 @@ export const implementServerCommandHandler: CommandHandler<ImplementServerComman
128
127
  }
129
128
  },
130
129
  };
130
+
131
+ // CLI arguments interface
132
+ interface CliArgs {
133
+ _: string[];
134
+ [key: string]: unknown;
135
+ }
136
+
137
+ // Type guard to check if it's an ImplementServerCommand
138
+ function isImplementServerCommand(obj: unknown): obj is ImplementServerCommand {
139
+ return (
140
+ typeof obj === 'object' &&
141
+ obj !== null &&
142
+ 'type' in obj &&
143
+ 'data' in obj &&
144
+ (obj as { type: unknown }).type === 'ImplementServer'
145
+ );
146
+ }
147
+
148
+ // Default export for CLI usage
149
+ export default async (commandOrArgs: ImplementServerCommand | CliArgs) => {
150
+ const command = isImplementServerCommand(commandOrArgs)
151
+ ? commandOrArgs
152
+ : {
153
+ type: 'ImplementServer' as const,
154
+ data: {
155
+ serverDirectory: commandOrArgs._?.[0] ?? 'server',
156
+ },
157
+ timestamp: new Date(),
158
+ };
159
+
160
+ const result = await handleImplementServerCommandInternal(command);
161
+ if (result.type === 'ServerImplemented') {
162
+ console.log(`✅ Server implementation completed successfully`);
163
+ if (result.data.flowsImplemented > 0) {
164
+ console.log(` ${result.data.flowsImplemented} flows implemented`);
165
+ }
166
+ } else {
167
+ console.error(`❌ Server implementation failed: ${result.data.error}`);
168
+ process.exit(1);
169
+ }
170
+ };