@auto-engineer/server-implementer 1.123.0 → 1.125.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +6 -6
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +99 -0
- package/dist/src/agent/runSlice.d.ts.map +1 -1
- package/dist/src/agent/runSlice.js +4 -3
- package/dist/src/agent/runSlice.js.map +1 -1
- package/dist/src/commands/implement-slice.d.ts.map +1 -1
- package/dist/src/commands/implement-slice.js +3 -11
- package/dist/src/commands/implement-slice.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/prompts/systemPrompt.d.ts +1 -1
- package/dist/src/prompts/systemPrompt.d.ts.map +1 -1
- package/dist/src/prompts/systemPrompt.js +8 -1
- package/dist/src/prompts/systemPrompt.js.map +1 -1
- package/dist/src/utils/findFilesToImplement.d.ts +2 -0
- package/dist/src/utils/findFilesToImplement.d.ts.map +1 -0
- package/dist/src/utils/findFilesToImplement.js +14 -0
- package/dist/src/utils/findFilesToImplement.js.map +1 -0
- package/dist/src/utils/findFilesToImplement.specs.d.ts +2 -0
- package/dist/src/utils/findFilesToImplement.specs.d.ts.map +1 -0
- package/dist/src/utils/findFilesToImplement.specs.js +73 -0
- package/dist/src/utils/findFilesToImplement.specs.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/agent/runSlice.ts +4 -5
- package/src/commands/implement-slice.ts +3 -13
- package/src/prompts/systemPrompt.ts +8 -1
- package/src/utils/findFilesToImplement.specs.ts +90 -0
- package/src/utils/findFilesToImplement.ts +16 -0
package/package.json
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"debug": "^4.3.4",
|
|
19
19
|
"fast-glob": "^3.3.3",
|
|
20
20
|
"vite": "^5.4.1",
|
|
21
|
-
"@auto-engineer/model-factory": "1.
|
|
22
|
-
"@auto-engineer/message-bus": "1.
|
|
21
|
+
"@auto-engineer/model-factory": "1.125.0",
|
|
22
|
+
"@auto-engineer/message-bus": "1.125.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"glob": "^11.0.3",
|
|
30
30
|
"tsx": "^4.20.3",
|
|
31
31
|
"typescript": "^5.8.3",
|
|
32
|
-
"@auto-engineer/cli": "1.
|
|
32
|
+
"@auto-engineer/cli": "1.125.0"
|
|
33
33
|
},
|
|
34
|
-
"version": "1.
|
|
34
|
+
"version": "1.125.0",
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsc && tsx ../../scripts/fix-esm-imports.ts",
|
|
37
37
|
"test": "vitest run --reporter=dot",
|
package/src/agent/runSlice.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { SYSTEM_PROMPT } from '../prompts/systemPrompt';
|
|
|
8
8
|
import { buildContextSections } from '../utils/buildContextSections';
|
|
9
9
|
import { buildShadowWarning } from '../utils/detectImportedTypeShadowing';
|
|
10
10
|
import { extractCodeBlock } from '../utils/extractCodeBlock';
|
|
11
|
+
import { findFilesToImplement } from '../utils/findFilesToImplement';
|
|
11
12
|
import { loadContextFiles } from '../utils/loadContextFiles';
|
|
12
13
|
import { runTests } from './runTests';
|
|
13
14
|
|
|
@@ -36,7 +37,7 @@ export async function runSlice(sliceDir: string, flow: string): Promise<void> {
|
|
|
36
37
|
const sliceName = path.basename(sliceDir);
|
|
37
38
|
console.log(`✏️ Implementing slice: ${sliceName} for flow: ${flow}`);
|
|
38
39
|
const contextFiles = await loadContextFiles(sliceDir);
|
|
39
|
-
const filesToImplement = findFilesToImplement(contextFiles);
|
|
40
|
+
const filesToImplement = findFilesToImplement(contextFiles, needsImplementation);
|
|
40
41
|
for (const [targetFile] of filesToImplement) {
|
|
41
42
|
await implementFileFromAI(sliceDir, targetFile, contextFiles);
|
|
42
43
|
}
|
|
@@ -103,10 +104,8 @@ async function retryFailedFiles(
|
|
|
103
104
|
return result;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
function
|
|
107
|
-
return
|
|
108
|
-
([, content]) => content.includes('TODO:') || content.includes('IMPLEMENTATION INSTRUCTIONS'),
|
|
109
|
-
);
|
|
107
|
+
function needsImplementation(content: string): boolean {
|
|
108
|
+
return content.includes('TODO:') || content.includes('IMPLEMENTATION INSTRUCTIONS');
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
function buildInitialPrompt(targetFile: string, context: Record<string, string>): string {
|
|
@@ -8,6 +8,8 @@ import createDebug from 'debug';
|
|
|
8
8
|
import { SYSTEM_PROMPT } from '../prompts/systemPrompt';
|
|
9
9
|
import { buildContextSections } from '../utils/buildContextSections';
|
|
10
10
|
import { buildShadowWarning } from '../utils/detectImportedTypeShadowing';
|
|
11
|
+
import { extractCodeBlock } from '../utils/extractCodeBlock';
|
|
12
|
+
import { findFilesToImplement } from '../utils/findFilesToImplement';
|
|
11
13
|
import { loadContextFiles } from '../utils/loadContextFiles';
|
|
12
14
|
|
|
13
15
|
const debug = createDebug('auto:server-implementer:slice');
|
|
@@ -95,14 +97,6 @@ export const commandHandler = defineCommandHandler<
|
|
|
95
97
|
},
|
|
96
98
|
});
|
|
97
99
|
|
|
98
|
-
// Helper function to extract code block from AI response
|
|
99
|
-
function extractCodeBlock(text: string): string {
|
|
100
|
-
return text
|
|
101
|
-
.replace(/```(?:ts|typescript)?/g, '')
|
|
102
|
-
.replace(/```/g, '')
|
|
103
|
-
.trim();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
100
|
const IMPLEMENTATION_MARKER = '// @auto-implement';
|
|
107
101
|
|
|
108
102
|
function hasImplementationMarker(content: string): boolean {
|
|
@@ -122,10 +116,6 @@ function needsImplementation(content: string): boolean {
|
|
|
122
116
|
);
|
|
123
117
|
}
|
|
124
118
|
|
|
125
|
-
function findFilesToImplement(contextFiles: Record<string, string>): Array<[string, string]> {
|
|
126
|
-
return Object.entries(contextFiles).filter(([, content]) => hasImplementationMarker(content));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
119
|
function buildInitialPrompt(targetFile: string, context: Record<string, string>): string {
|
|
130
120
|
return `
|
|
131
121
|
${SYSTEM_PROMPT}
|
|
@@ -228,7 +218,7 @@ async function implementSlice(
|
|
|
228
218
|
|
|
229
219
|
await addMarkersToFiles(slicePath, contextFiles);
|
|
230
220
|
|
|
231
|
-
const filesToImplement = findFilesToImplement(contextFiles);
|
|
221
|
+
const filesToImplement = findFilesToImplement(contextFiles, hasImplementationMarker);
|
|
232
222
|
debugProcess(`Found ${filesToImplement.length} files with markers to implement`);
|
|
233
223
|
|
|
234
224
|
if (filesToImplement.length === 0) {
|
|
@@ -13,6 +13,8 @@ You are a software engineer implementing @auto-implement files in a sliced event
|
|
|
13
13
|
- Complete the logic in the target file following embedded instructions
|
|
14
14
|
- Return the entire updated file, production-ready
|
|
15
15
|
- Remove all TODO/instruction comments after implementing
|
|
16
|
+
- Scaffolded files contain fixed generated structure.
|
|
17
|
+
Only change code inside the implementation area indicated by TODOs or instruction comments.
|
|
16
18
|
|
|
17
19
|
## 3. EMMETT FRAMEWORK PATTERNS
|
|
18
20
|
|
|
@@ -42,6 +44,9 @@ Projection evolve(document, event) returns updated document.
|
|
|
42
44
|
- Never create imports to modules not shown in the provided context.
|
|
43
45
|
- If you need a type that doesn't exist in any provided file,
|
|
44
46
|
use inline types or primitive values instead.
|
|
47
|
+
- Preserve existing import statements exactly — do not remove, rename, replace,
|
|
48
|
+
or reorganize them unless a scaffold instruction explicitly requires a change.
|
|
49
|
+
- Use the node: protocol for Node.js built-in modules (e.g., node:crypto, node:path).
|
|
45
50
|
|
|
46
51
|
## 5. TEST SPECIFICATIONS GUIDANCE
|
|
47
52
|
|
|
@@ -59,7 +64,6 @@ Projection evolve(document, event) returns updated document.
|
|
|
59
64
|
- Immutability: functional patterns, never mutate state
|
|
60
65
|
- Include ALL required fields in object literals
|
|
61
66
|
- Preserve index signatures ([key: string]: unknown)
|
|
62
|
-
- Do not remove existing imports still referenced
|
|
63
67
|
- When mapping objects to a typed array, include ALL required fields in each object literal
|
|
64
68
|
|
|
65
69
|
## 7. SLICE CONVENTIONS
|
|
@@ -76,6 +80,9 @@ Projection evolve(document, event) returns updated document.
|
|
|
76
80
|
- String literals for enum-typed fields
|
|
77
81
|
- Hardcoding values that should be computed from inputs
|
|
78
82
|
- Reproducing literal values from test examples
|
|
83
|
+
- Type assertions and escape hatches such as \`as any\`, \`as unknown as\`, or broad casts to silence errors
|
|
84
|
+
- Changing scaffolded framework calls or helper names unless explicitly instructed by the scaffold
|
|
85
|
+
- Importing types or modules not directly referenced in the implementation code
|
|
79
86
|
|
|
80
87
|
## 9. OUTPUT
|
|
81
88
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { findFilesToImplement } from './findFilesToImplement';
|
|
3
|
+
|
|
4
|
+
describe('findFilesToImplement', () => {
|
|
5
|
+
const hasMarker = (content: string) => content.includes('TODO');
|
|
6
|
+
|
|
7
|
+
it('filters files by predicate', () => {
|
|
8
|
+
const files = {
|
|
9
|
+
'state.ts': 'TODO: implement',
|
|
10
|
+
'evolve.ts': 'export const evolve = () => {}',
|
|
11
|
+
'decide.ts': 'TODO: implement',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const result = findFilesToImplement(files, hasMarker);
|
|
15
|
+
|
|
16
|
+
expect(result).toEqual([
|
|
17
|
+
['state.ts', 'TODO: implement'],
|
|
18
|
+
['decide.ts', 'TODO: implement'],
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('sorts priority files in correct order', () => {
|
|
23
|
+
const files = {
|
|
24
|
+
'decide.ts': 'TODO',
|
|
25
|
+
'state.ts': 'TODO',
|
|
26
|
+
'evolve.ts': 'TODO',
|
|
27
|
+
'events.ts': 'TODO',
|
|
28
|
+
'commands.ts': 'TODO',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const result = findFilesToImplement(files, hasMarker);
|
|
32
|
+
|
|
33
|
+
expect(result).toEqual([
|
|
34
|
+
['state.ts', 'TODO'],
|
|
35
|
+
['events.ts', 'TODO'],
|
|
36
|
+
['commands.ts', 'TODO'],
|
|
37
|
+
['evolve.ts', 'TODO'],
|
|
38
|
+
['decide.ts', 'TODO'],
|
|
39
|
+
]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('sorts non-priority files after priority files in alphabetical order', () => {
|
|
43
|
+
const files = {
|
|
44
|
+
'zebra.ts': 'TODO',
|
|
45
|
+
'decide.ts': 'TODO',
|
|
46
|
+
'alpha.ts': 'TODO',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const result = findFilesToImplement(files, hasMarker);
|
|
50
|
+
|
|
51
|
+
expect(result).toEqual([
|
|
52
|
+
['decide.ts', 'TODO'],
|
|
53
|
+
['alpha.ts', 'TODO'],
|
|
54
|
+
['zebra.ts', 'TODO'],
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('sorts non-priority files alphabetically among themselves', () => {
|
|
59
|
+
const files = {
|
|
60
|
+
'zebra.ts': 'TODO',
|
|
61
|
+
'middleware.ts': 'TODO',
|
|
62
|
+
'alpha.ts': 'TODO',
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const result = findFilesToImplement(files, hasMarker);
|
|
66
|
+
|
|
67
|
+
expect(result).toEqual([
|
|
68
|
+
['alpha.ts', 'TODO'],
|
|
69
|
+
['middleware.ts', 'TODO'],
|
|
70
|
+
['zebra.ts', 'TODO'],
|
|
71
|
+
]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('returns empty array for empty input', () => {
|
|
75
|
+
const result = findFilesToImplement({}, hasMarker);
|
|
76
|
+
|
|
77
|
+
expect(result).toEqual([]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('returns empty array when no files match predicate', () => {
|
|
81
|
+
const files = {
|
|
82
|
+
'state.ts': 'export type State = {}',
|
|
83
|
+
'evolve.ts': 'export const evolve = () => {}',
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const result = findFilesToImplement(files, hasMarker);
|
|
87
|
+
|
|
88
|
+
expect(result).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const IMPLEMENTATION_PRIORITY = ['state.ts', 'events.ts', 'commands.ts', 'evolve.ts', 'decide.ts'];
|
|
2
|
+
|
|
3
|
+
export function findFilesToImplement(
|
|
4
|
+
contextFiles: Record<string, string>,
|
|
5
|
+
markerPredicate: (content: string) => boolean,
|
|
6
|
+
): Array<[string, string]> {
|
|
7
|
+
const files = Object.entries(contextFiles).filter(([, content]) => markerPredicate(content));
|
|
8
|
+
return files.sort(([a], [b]) => {
|
|
9
|
+
const ai = IMPLEMENTATION_PRIORITY.indexOf(a);
|
|
10
|
+
const bi = IMPLEMENTATION_PRIORITY.indexOf(b);
|
|
11
|
+
const ap = ai === -1 ? 999 : ai;
|
|
12
|
+
const bp = bi === -1 ? 999 : bi;
|
|
13
|
+
if (ap !== bp) return ap - bp;
|
|
14
|
+
return a.localeCompare(b);
|
|
15
|
+
});
|
|
16
|
+
}
|