@auto-engineer/server-implementer 0.5.1 → 0.6.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-format.log +19 -20
- package/.turbo/turbo-lint.log +4 -5
- package/CHANGELOG.md +12 -0
- package/dist/cli-manifest.d.ts.map +1 -1
- package/dist/cli-manifest.js +4 -17
- package/dist/cli-manifest.js.map +1 -1
- package/dist/commands/implement-server.d.ts +41 -7
- package/dist/commands/implement-server.d.ts.map +1 -1
- package/dist/commands/implement-server.js +13 -35
- package/dist/commands/implement-server.js.map +1 -1
- package/dist/commands/implement-slice.d.ts +48 -7
- package/dist/commands/implement-slice.d.ts.map +1 -1
- package/dist/commands/implement-slice.js +49 -41
- package/dist/commands/implement-slice.js.map +1 -1
- package/package.json +4 -4
- package/src/cli-manifest.ts +4 -17
- package/src/commands/implement-server.ts +21 -46
- package/src/commands/implement-slice.ts +82 -73
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @auto-engineer/server-implementer@0.
|
|
2
|
+
> @auto-engineer/server-implementer@0.6.0 build /Users/sam/WebstormProjects/top/auto-engineer/packages/server-implementer
|
|
3
3
|
> tsc && tsx ../../scripts/fix-esm-imports.ts
|
|
4
4
|
|
|
5
5
|
Fixed ESM imports in dist/
|
package/.turbo/turbo-format.log
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
src/agent/
|
|
11
|
-
src/agent/
|
|
12
|
-
src/agent/
|
|
13
|
-
src/
|
|
14
|
-
src/
|
|
15
|
-
src/commands/implement-
|
|
16
|
-
src/
|
|
17
|
-
src/
|
|
18
|
-
src/
|
|
19
|
-
|
|
20
|
-
tsconfig.json[2K[1G[90mtsconfig.json[39m 1ms (unchanged)
|
|
1
|
+
|
|
2
|
+
> @auto-engineer/server-implementer@0.5.1 format /Users/sam/WebstormProjects/top/auto-engineer/packages/server-implementer
|
|
3
|
+
> prettier --write "**/*.{js,ts,json,md,yml,yaml}" --ignore-path ../../.prettierignore
|
|
4
|
+
|
|
5
|
+
CHANGELOG.md 26ms (unchanged)
|
|
6
|
+
DEBUG.md 4ms (unchanged)
|
|
7
|
+
package.json 19ms (unchanged)
|
|
8
|
+
README.md 68ms (unchanged)
|
|
9
|
+
src/agent/runAllSlices.ts 4ms (unchanged)
|
|
10
|
+
src/agent/runFlows.ts 5ms (unchanged)
|
|
11
|
+
src/agent/runSlice.ts 37ms (unchanged)
|
|
12
|
+
src/agent/runTests.ts 9ms (unchanged)
|
|
13
|
+
src/cli-manifest.ts 2ms (unchanged)
|
|
14
|
+
src/commands/implement-server.ts 5ms (unchanged)
|
|
15
|
+
src/commands/implement-slice.ts 12ms (unchanged)
|
|
16
|
+
src/index.ts 2ms (unchanged)
|
|
17
|
+
src/prompts/systemPrompt.ts 1ms (unchanged)
|
|
18
|
+
src/utils/extractCodeBlock.ts 1ms (unchanged)
|
|
19
|
+
tsconfig.json 2ms (unchanged)
|
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
|
|
2
|
+
> @auto-engineer/server-implementer@0.5.1 lint /Users/sam/WebstormProjects/top/auto-engineer/packages/server-implementer
|
|
3
|
+
> eslint 'src/**/*.ts' --max-warnings 0 --config ../../eslint.config.ts
|
|
4
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @auto-engineer/server-implementer
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Major overhaul of the plugin system
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @auto-engineer/ai-gateway@0.6.0
|
|
13
|
+
- @auto-engineer/message-bus@0.5.0
|
|
14
|
+
|
|
3
15
|
## 0.5.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-manifest.d.ts","sourceRoot":"","sources":["../src/cli-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-manifest.d.ts","sourceRoot":"","sources":["../src/cli-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAIrE,eAAO,MAAM,YAAY,EAAE,WAM1B,CAAC"}
|
package/dist/cli-manifest.js
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
|
+
import { implementServerManifest } from './commands/implement-server.js';
|
|
2
|
+
import { implementSliceManifest } from './commands/implement-slice.js';
|
|
1
3
|
export const CLI_MANIFEST = {
|
|
2
4
|
category: '@auto-engineer/server-implementer',
|
|
3
5
|
commands: {
|
|
4
|
-
'implement:server':
|
|
5
|
-
|
|
6
|
-
description: 'AI implements server TODOs and tests',
|
|
7
|
-
usage: 'implement:server <server-dir>',
|
|
8
|
-
examples: ['$ auto implement:server ./server'],
|
|
9
|
-
args: [{ name: 'server-dir', description: 'Server directory path', required: true }],
|
|
10
|
-
},
|
|
11
|
-
'implement:slice': {
|
|
12
|
-
handler: () => import('./commands/implement-slice.js'),
|
|
13
|
-
description: 'AI implements a specific server slice',
|
|
14
|
-
usage: 'implement:slice <server-dir> <slice-name>',
|
|
15
|
-
examples: ['$ auto implement:slice ./server enters-shopping-criteria'],
|
|
16
|
-
args: [
|
|
17
|
-
{ name: 'server-dir', description: 'Server directory path', required: true },
|
|
18
|
-
{ name: 'slice-name', description: 'Name of the slice to implement', required: true },
|
|
19
|
-
],
|
|
20
|
-
},
|
|
6
|
+
'implement:server': implementServerManifest,
|
|
7
|
+
'implement:slice': implementSliceManifest,
|
|
21
8
|
},
|
|
22
9
|
};
|
|
23
10
|
//# sourceMappingURL=cli-manifest.js.map
|
package/dist/cli-manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-manifest.js","sourceRoot":"","sources":["../src/cli-manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-manifest.js","sourceRoot":"","sources":["../src/cli-manifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,CAAC,MAAM,YAAY,GAAgB;IACvC,QAAQ,EAAE,mCAAmC;IAC7C,QAAQ,EAAE;QACR,kBAAkB,EAAE,uBAAuB;QAC3C,iBAAiB,EAAE,sBAAsB;KAC1C;CACF,CAAC"}
|
|
@@ -1,4 +1,43 @@
|
|
|
1
1
|
import { type CommandHandler, type Command, type Event } from '@auto-engineer/message-bus';
|
|
2
|
+
export declare const implementServerManifest: {
|
|
3
|
+
handler: () => Promise<{
|
|
4
|
+
default: CommandHandler<Readonly<{
|
|
5
|
+
type: "ImplementServer";
|
|
6
|
+
data: Readonly<{
|
|
7
|
+
serverDirectory: string;
|
|
8
|
+
}>;
|
|
9
|
+
timestamp?: Date;
|
|
10
|
+
requestId?: string;
|
|
11
|
+
correlationId?: string;
|
|
12
|
+
}>, Readonly<{
|
|
13
|
+
type: "ServerImplemented";
|
|
14
|
+
data: {
|
|
15
|
+
serverDirectory: string;
|
|
16
|
+
flowsImplemented: number;
|
|
17
|
+
};
|
|
18
|
+
timestamp?: Date;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
correlationId?: string;
|
|
21
|
+
}> | Readonly<{
|
|
22
|
+
type: "ServerImplementationFailed";
|
|
23
|
+
data: {
|
|
24
|
+
serverDirectory: string;
|
|
25
|
+
error: string;
|
|
26
|
+
};
|
|
27
|
+
timestamp?: Date;
|
|
28
|
+
requestId?: string;
|
|
29
|
+
correlationId?: string;
|
|
30
|
+
}>>;
|
|
31
|
+
}>;
|
|
32
|
+
description: string;
|
|
33
|
+
usage: string;
|
|
34
|
+
examples: string[];
|
|
35
|
+
args: {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
required: boolean;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
2
41
|
export type ImplementServerCommand = Command<'ImplementServer', {
|
|
3
42
|
serverDirectory: string;
|
|
4
43
|
}>;
|
|
@@ -10,11 +49,6 @@ export type ServerImplementationFailedEvent = Event<'ServerImplementationFailed'
|
|
|
10
49
|
serverDirectory: string;
|
|
11
50
|
error: string;
|
|
12
51
|
}>;
|
|
13
|
-
export declare const implementServerCommandHandler: CommandHandler<ImplementServerCommand>;
|
|
14
|
-
|
|
15
|
-
_: string[];
|
|
16
|
-
[key: string]: unknown;
|
|
17
|
-
}
|
|
18
|
-
declare const _default: (commandOrArgs: ImplementServerCommand | CliArgs) => Promise<void>;
|
|
19
|
-
export default _default;
|
|
52
|
+
export declare const implementServerCommandHandler: CommandHandler<ImplementServerCommand, ServerImplementedEvent | ServerImplementationFailedEvent>;
|
|
53
|
+
export default implementServerCommandHandler;
|
|
20
54
|
//# sourceMappingURL=implement-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement-server.d.ts","sourceRoot":"","sources":["../../src/commands/implement-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAW3F,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC1C,iBAAiB,EACjB;IACE,eAAe,EAAE,MAAM,CAAC;CACzB,CACF,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,KAAK,CACxC,mBAAmB,EACnB;IACE,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CACF,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,KAAK,CACjD,4BAA4B,EAC5B;IACE,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf,CACF,CAAC;AA8EF,eAAO,MAAM,6BAA6B,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"implement-server.d.ts","sourceRoot":"","sources":["../../src/commands/implement-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAW3F,eAAO,MAAM,uBAAuB;;;;;iCAWf,MAAM;;;;;;;;iCAON,MAAM;kCACL,MAAM;;;;;;;;iCAOP,MAAM;uBAChB,MAAM;;;;;;;;;;;;;;;CArBhB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC1C,iBAAiB,EACjB;IACE,eAAe,EAAE,MAAM,CAAC;CACzB,CACF,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,KAAK,CACxC,mBAAmB,EACnB;IACE,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CACF,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,KAAK,CACjD,4BAA4B,EAC5B;IACE,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf,CACF,CAAC;AA8EF,eAAO,MAAM,6BAA6B,EAAE,cAAc,CACxD,sBAAsB,EACtB,sBAAsB,GAAG,+BAA+B,CAqBzD,CAAC;AAGF,eAAe,6BAA6B,CAAC"}
|
|
@@ -6,6 +6,13 @@ const debug = createDebug('server-impl:command');
|
|
|
6
6
|
const debugHandler = createDebug('server-impl:command:handler');
|
|
7
7
|
const debugProcess = createDebug('server-impl:command:process');
|
|
8
8
|
const debugResult = createDebug('server-impl:command:result');
|
|
9
|
+
export const implementServerManifest = {
|
|
10
|
+
handler: () => Promise.resolve({ default: implementServerCommandHandler }),
|
|
11
|
+
description: 'AI implements server TODOs and tests',
|
|
12
|
+
usage: 'implement:server <server-dir>',
|
|
13
|
+
examples: ['$ auto implement:server ./server'],
|
|
14
|
+
args: [{ name: 'server-dir', description: 'Server directory path', required: true }],
|
|
15
|
+
};
|
|
9
16
|
async function handleImplementServerCommandInternal(command) {
|
|
10
17
|
const { serverDirectory } = command.data;
|
|
11
18
|
debug('Handling ImplementServerCommand');
|
|
@@ -75,47 +82,18 @@ export const implementServerCommandHandler = {
|
|
|
75
82
|
const result = await handleImplementServerCommandInternal(command);
|
|
76
83
|
if (result.type === 'ServerImplemented') {
|
|
77
84
|
debug('Command handler completed: success');
|
|
78
|
-
|
|
85
|
+
debug('✅ Server implementation completed successfully');
|
|
79
86
|
if (result.data.flowsImplemented > 0) {
|
|
80
|
-
|
|
87
|
+
debug(' %d flows implemented', result.data.flowsImplemented);
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
else {
|
|
84
91
|
debug('Command handler completed: failure - %s', result.data.error);
|
|
85
|
-
|
|
86
|
-
process.exit(1);
|
|
92
|
+
debug('❌ Server implementation failed: %s', result.data.error);
|
|
87
93
|
}
|
|
94
|
+
return result;
|
|
88
95
|
},
|
|
89
96
|
};
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
return (typeof obj === 'object' &&
|
|
93
|
-
obj !== null &&
|
|
94
|
-
'type' in obj &&
|
|
95
|
-
'data' in obj &&
|
|
96
|
-
obj.type === 'ImplementServer');
|
|
97
|
-
}
|
|
98
|
-
// Default export for CLI usage
|
|
99
|
-
export default async (commandOrArgs) => {
|
|
100
|
-
const command = isImplementServerCommand(commandOrArgs)
|
|
101
|
-
? commandOrArgs
|
|
102
|
-
: {
|
|
103
|
-
type: 'ImplementServer',
|
|
104
|
-
data: {
|
|
105
|
-
serverDirectory: commandOrArgs._?.[0] ?? 'server',
|
|
106
|
-
},
|
|
107
|
-
timestamp: new Date(),
|
|
108
|
-
};
|
|
109
|
-
const result = await handleImplementServerCommandInternal(command);
|
|
110
|
-
if (result.type === 'ServerImplemented') {
|
|
111
|
-
console.log(`✅ Server implementation completed successfully`);
|
|
112
|
-
if (result.data.flowsImplemented > 0) {
|
|
113
|
-
console.log(` ${result.data.flowsImplemented} flows implemented`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
console.error(`❌ Server implementation failed: ${result.data.error}`);
|
|
118
|
-
process.exit(1);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
97
|
+
// Default export is the command handler
|
|
98
|
+
export default implementServerCommandHandler;
|
|
121
99
|
//# sourceMappingURL=implement-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement-server.js","sourceRoot":"","sources":["../../src/commands/implement-server.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,WAAW,MAAM,OAAO,CAAC;AAEhC,MAAM,KAAK,GAAG,WAAW,CAAC,qBAAqB,CAAC,CAAC;AACjD,MAAM,YAAY,GAAG,WAAW,CAAC,6BAA6B,CAAC,CAAC;AAChE,MAAM,YAAY,GAAG,WAAW,CAAC,6BAA6B,CAAC,CAAC;AAChE,MAAM,WAAW,GAAG,WAAW,CAAC,4BAA4B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"implement-server.js","sourceRoot":"","sources":["../../src/commands/implement-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,63 @@
|
|
|
1
1
|
import { type CommandHandler, type Command, type Event } from '@auto-engineer/message-bus';
|
|
2
|
+
export declare const implementSliceManifest: {
|
|
3
|
+
handler: () => Promise<{
|
|
4
|
+
default: CommandHandler<Readonly<{
|
|
5
|
+
type: "ImplementSlice";
|
|
6
|
+
data: Readonly<{
|
|
7
|
+
slicePath: string;
|
|
8
|
+
context?: {
|
|
9
|
+
previousOutputs?: string;
|
|
10
|
+
attemptNumber?: number;
|
|
11
|
+
};
|
|
12
|
+
}>;
|
|
13
|
+
timestamp?: Date;
|
|
14
|
+
requestId?: string;
|
|
15
|
+
correlationId?: string;
|
|
16
|
+
}>, Readonly<{
|
|
17
|
+
type: "SliceImplemented";
|
|
18
|
+
data: {
|
|
19
|
+
slicePath: string;
|
|
20
|
+
filesImplemented: string[];
|
|
21
|
+
};
|
|
22
|
+
timestamp?: Date;
|
|
23
|
+
requestId?: string;
|
|
24
|
+
correlationId?: string;
|
|
25
|
+
}> | Readonly<{
|
|
26
|
+
type: "SliceImplementationFailed";
|
|
27
|
+
data: {
|
|
28
|
+
slicePath: string;
|
|
29
|
+
error: string;
|
|
30
|
+
};
|
|
31
|
+
timestamp?: Date;
|
|
32
|
+
requestId?: string;
|
|
33
|
+
correlationId?: string;
|
|
34
|
+
}>>;
|
|
35
|
+
}>;
|
|
36
|
+
description: string;
|
|
37
|
+
usage: string;
|
|
38
|
+
examples: string[];
|
|
39
|
+
args: {
|
|
40
|
+
name: string;
|
|
41
|
+
description: string;
|
|
42
|
+
required: boolean;
|
|
43
|
+
}[];
|
|
44
|
+
};
|
|
2
45
|
export type ImplementSliceCommand = Command<'ImplementSlice', {
|
|
3
|
-
|
|
4
|
-
flowName: string;
|
|
46
|
+
slicePath: string;
|
|
5
47
|
context?: {
|
|
6
48
|
previousOutputs?: string;
|
|
7
49
|
attemptNumber?: number;
|
|
8
50
|
};
|
|
9
51
|
}>;
|
|
10
52
|
export type SliceImplementedEvent = Event<'SliceImplemented', {
|
|
11
|
-
|
|
12
|
-
flowName: string;
|
|
53
|
+
slicePath: string;
|
|
13
54
|
filesImplemented: string[];
|
|
14
55
|
}>;
|
|
15
56
|
export type SliceImplementationFailedEvent = Event<'SliceImplementationFailed', {
|
|
16
|
-
|
|
17
|
-
flowName: string;
|
|
57
|
+
slicePath: string;
|
|
18
58
|
error: string;
|
|
19
59
|
}>;
|
|
20
60
|
export declare function handleImplementSliceCommand(command: ImplementSliceCommand): Promise<SliceImplementedEvent | SliceImplementationFailedEvent>;
|
|
21
|
-
export declare const implementSliceCommandHandler: CommandHandler<ImplementSliceCommand>;
|
|
61
|
+
export declare const implementSliceCommandHandler: CommandHandler<ImplementSliceCommand, SliceImplementedEvent | SliceImplementationFailedEvent>;
|
|
62
|
+
export default implementSliceCommandHandler;
|
|
22
63
|
//# sourceMappingURL=implement-slice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement-slice.d.ts","sourceRoot":"","sources":["../../src/commands/implement-slice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"implement-slice.d.ts","sourceRoot":"","sources":["../../src/commands/implement-slice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAa3F,eAAO,MAAM,sBAAsB;;;;;2BAapB,MAAM;0BACP;oBACR,eAAe,CAAC,EAAE,MAAM,CAAC;oBACzB,aAAa,CAAC,EAAE,MAAM,CAAC;iBACxB;;;;;;;;2BAOU,MAAM;kCACC,MAAM,EAAE;;;;;;;;2BAOf,MAAM;uBACV,MAAM;;;;;;;;;;;;;;;CAzBhB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,gBAAgB,EAChB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CACF,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,KAAK,CACvC,kBAAkB,EAClB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,CACF,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,KAAK,CAChD,2BAA2B,EAC3B;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CACF,CAAC;AAuOF,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,qBAAqB,GAAG,8BAA8B,CAAC,CAmCjE;AAED,eAAO,MAAM,4BAA4B,EAAE,cAAc,CACvD,qBAAqB,EACrB,qBAAqB,GAAG,8BAA8B,CAkBvD,CAAC;AAGF,eAAe,4BAA4B,CAAC"}
|
|
@@ -8,6 +8,36 @@ const debug = createDebug('server-impl:slice');
|
|
|
8
8
|
const debugHandler = createDebug('server-impl:slice:handler');
|
|
9
9
|
const debugProcess = createDebug('server-impl:slice:process');
|
|
10
10
|
const debugResult = createDebug('server-impl:slice:result');
|
|
11
|
+
export const implementSliceManifest = {
|
|
12
|
+
handler: () => Promise.resolve({ default: implementSliceCommandHandler }),
|
|
13
|
+
description: 'AI implements a specific server slice',
|
|
14
|
+
usage: 'implement:slice <slice-path>',
|
|
15
|
+
examples: [
|
|
16
|
+
'$ auto implement:slice ./server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant',
|
|
17
|
+
],
|
|
18
|
+
args: [{ name: 'slice-path', description: 'Path to the slice directory to implement', required: true }],
|
|
19
|
+
};
|
|
20
|
+
// Helper function to extract code block from AI response
|
|
21
|
+
function extractCodeBlock(text) {
|
|
22
|
+
return text
|
|
23
|
+
.replace(/```(?:ts|typescript)?/g, '')
|
|
24
|
+
.replace(/```/g, '')
|
|
25
|
+
.trim();
|
|
26
|
+
}
|
|
27
|
+
// Load all TypeScript files from the slice directory
|
|
28
|
+
async function loadContextFiles(sliceDir) {
|
|
29
|
+
const files = await fg(['*.ts'], { cwd: sliceDir });
|
|
30
|
+
const context = {};
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const absPath = path.join(sliceDir, file);
|
|
33
|
+
context[file] = await readFile(absPath, 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
return context;
|
|
36
|
+
}
|
|
37
|
+
// Find files that need implementation
|
|
38
|
+
function findFilesToImplement(contextFiles) {
|
|
39
|
+
return Object.entries(contextFiles).filter(([, content]) => content.includes('TODO:') || content.includes('IMPLEMENTATION INSTRUCTIONS'));
|
|
40
|
+
}
|
|
11
41
|
// System prompt for AI implementation
|
|
12
42
|
const SYSTEM_PROMPT = `
|
|
13
43
|
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.
|
|
@@ -52,27 +82,6 @@ You must:
|
|
|
52
82
|
- Return the entire updated file (no commentary and remove all implementation instructions).
|
|
53
83
|
- Ensure the output is valid TypeScript.
|
|
54
84
|
`;
|
|
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
85
|
// Build prompt for initial implementation
|
|
77
86
|
function buildInitialPrompt(targetFile, context) {
|
|
78
87
|
return `
|
|
@@ -119,17 +128,17 @@ Return only the corrected full contents of ${targetFile}, no commentary, no mark
|
|
|
119
128
|
`.trim();
|
|
120
129
|
}
|
|
121
130
|
// Main implementation function
|
|
122
|
-
async function implementSlice(
|
|
131
|
+
async function implementSlice(slicePath, context) {
|
|
123
132
|
const availableProviders = getAvailableProviders();
|
|
124
133
|
if (availableProviders.length === 0) {
|
|
125
134
|
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
135
|
}
|
|
127
136
|
const AI_PROVIDER = availableProviders[0];
|
|
128
|
-
const sliceName = path.basename(
|
|
129
|
-
debugProcess(`Implementing slice: ${sliceName}
|
|
137
|
+
const sliceName = path.basename(slicePath);
|
|
138
|
+
debugProcess(`Implementing slice: ${sliceName}`);
|
|
130
139
|
try {
|
|
131
140
|
// Load all context files
|
|
132
|
-
const contextFiles = await loadContextFiles(
|
|
141
|
+
const contextFiles = await loadContextFiles(slicePath);
|
|
133
142
|
const filesToImplement = findFilesToImplement(contextFiles);
|
|
134
143
|
const implementedFiles = [];
|
|
135
144
|
if (filesToImplement.length === 0) {
|
|
@@ -153,7 +162,7 @@ async function implementSlice(sliceDir, flowName, context) {
|
|
|
153
162
|
const aiOutput = await generateTextWithAI(prompt, AI_PROVIDER);
|
|
154
163
|
const cleanedCode = extractCodeBlock(aiOutput);
|
|
155
164
|
// Write the implemented file
|
|
156
|
-
const filePath = path.join(
|
|
165
|
+
const filePath = path.join(slicePath, targetFile);
|
|
157
166
|
await writeFile(filePath, cleanedCode, 'utf-8');
|
|
158
167
|
debugProcess(`Successfully implemented ${targetFile}`);
|
|
159
168
|
implementedFiles.push(targetFile);
|
|
@@ -169,10 +178,9 @@ async function implementSlice(sliceDir, flowName, context) {
|
|
|
169
178
|
}
|
|
170
179
|
}
|
|
171
180
|
function logCommandDebugInfo(command) {
|
|
172
|
-
const {
|
|
181
|
+
const { slicePath, context } = command.data;
|
|
173
182
|
debug('Handling ImplementSliceCommand');
|
|
174
|
-
debug(' Slice
|
|
175
|
-
debug(' Flow name: %s', flowName);
|
|
183
|
+
debug(' Slice path: %s', slicePath);
|
|
176
184
|
debug(' Context provided: %s', context ? 'yes' : 'no');
|
|
177
185
|
if (context) {
|
|
178
186
|
debug(' Attempt number: %d', context.attemptNumber ?? 1);
|
|
@@ -184,8 +192,7 @@ function createFailedEvent(command, error) {
|
|
|
184
192
|
return {
|
|
185
193
|
type: 'SliceImplementationFailed',
|
|
186
194
|
data: {
|
|
187
|
-
|
|
188
|
-
flowName: command.data.flowName,
|
|
195
|
+
slicePath: command.data.slicePath,
|
|
189
196
|
error,
|
|
190
197
|
},
|
|
191
198
|
timestamp: new Date(),
|
|
@@ -197,8 +204,7 @@ function createSuccessEvent(command, filesImplemented) {
|
|
|
197
204
|
return {
|
|
198
205
|
type: 'SliceImplemented',
|
|
199
206
|
data: {
|
|
200
|
-
|
|
201
|
-
flowName: command.data.flowName,
|
|
207
|
+
slicePath: command.data.slicePath,
|
|
202
208
|
filesImplemented,
|
|
203
209
|
},
|
|
204
210
|
timestamp: new Date(),
|
|
@@ -213,10 +219,10 @@ function logRetryContext(context) {
|
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
221
|
export async function handleImplementSliceCommand(command) {
|
|
216
|
-
const {
|
|
222
|
+
const { slicePath, context } = command.data;
|
|
217
223
|
logCommandDebugInfo(command);
|
|
218
224
|
try {
|
|
219
|
-
const sliceRoot = path.resolve(
|
|
225
|
+
const sliceRoot = path.resolve(slicePath);
|
|
220
226
|
debugHandler('Resolved paths:');
|
|
221
227
|
debugHandler(' Slice root: %s', sliceRoot);
|
|
222
228
|
if (!existsSync(sliceRoot)) {
|
|
@@ -225,7 +231,7 @@ export async function handleImplementSliceCommand(command) {
|
|
|
225
231
|
}
|
|
226
232
|
debugProcess('Starting slice implementation for: %s', sliceRoot);
|
|
227
233
|
logRetryContext(context);
|
|
228
|
-
const result = await implementSlice(sliceRoot,
|
|
234
|
+
const result = await implementSlice(sliceRoot, context);
|
|
229
235
|
if (!result.success) {
|
|
230
236
|
return createFailedEvent(command, result.error ?? 'Implementation failed');
|
|
231
237
|
}
|
|
@@ -248,15 +254,17 @@ export const implementSliceCommandHandler = {
|
|
|
248
254
|
const result = await handleImplementSliceCommand(command);
|
|
249
255
|
if (result.type === 'SliceImplemented') {
|
|
250
256
|
debug('Command handler completed: success');
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
257
|
+
debug('✅ Slice implementation completed successfully');
|
|
258
|
+
debug(' Slice: %s', path.basename(result.data.slicePath));
|
|
259
|
+
debug(' Files implemented: %d', result.data.filesImplemented.length);
|
|
254
260
|
}
|
|
255
261
|
else {
|
|
256
262
|
debug('Command handler completed: failure - %s', result.data.error);
|
|
257
|
-
|
|
258
|
-
process.exit(1);
|
|
263
|
+
debug('❌ Slice implementation failed: %s', result.data.error);
|
|
259
264
|
}
|
|
265
|
+
return result;
|
|
260
266
|
},
|
|
261
267
|
};
|
|
268
|
+
// Default export is the command handler
|
|
269
|
+
export default implementSliceCommandHandler;
|
|
262
270
|
//# sourceMappingURL=implement-slice.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement-slice.js","sourceRoot":"","sources":["../../src/commands/implement-slice.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,WAAW,MAAM,OAAO,CAAC;AAEhC,MAAM,KAAK,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC;AAC/C,MAAM,YAAY,GAAG,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAC9D,MAAM,YAAY,GAAG,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAC9D,MAAM,WAAW,GAAG,WAAW,CAAC,0BAA0B,CAAC,CAAC;AAE5D,
|
|
1
|
+
{"version":3,"file":"implement-slice.js","sourceRoot":"","sources":["../../src/commands/implement-slice.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auto-engineer/server-implementer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@auto-engineer/ai-gateway": "^0.
|
|
18
|
-
"@auto-engineer/message-bus": "^0.
|
|
17
|
+
"@auto-engineer/ai-gateway": "^0.6.0",
|
|
18
|
+
"@auto-engineer/message-bus": "^0.5.0",
|
|
19
19
|
"@modelcontextprotocol/sdk": "^1.3.0",
|
|
20
20
|
"debug": "^4.3.4",
|
|
21
21
|
"fast-glob": "^3.3.3",
|
|
22
22
|
"vite": "^5.4.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@auto-engineer/cli": "^0.
|
|
25
|
+
"@auto-engineer/cli": "^0.7.0",
|
|
26
26
|
"@types/fs-extra": "^11.0.4",
|
|
27
27
|
"dotenv": "^16.6.1",
|
|
28
28
|
"execa": "^9.6.0",
|
package/src/cli-manifest.ts
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import type { CliManifest } from '@auto-engineer/cli/manifest-types';
|
|
2
|
+
import { implementServerManifest } from './commands/implement-server';
|
|
3
|
+
import { implementSliceManifest } from './commands/implement-slice';
|
|
2
4
|
|
|
3
5
|
export const CLI_MANIFEST: CliManifest = {
|
|
4
6
|
category: '@auto-engineer/server-implementer',
|
|
5
7
|
commands: {
|
|
6
|
-
'implement:server':
|
|
7
|
-
|
|
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
|
-
},
|
|
8
|
+
'implement:server': implementServerManifest,
|
|
9
|
+
'implement:slice': implementSliceManifest,
|
|
23
10
|
},
|
|
24
11
|
};
|
|
@@ -9,6 +9,14 @@ const debugHandler = createDebug('server-impl:command:handler');
|
|
|
9
9
|
const debugProcess = createDebug('server-impl:command:process');
|
|
10
10
|
const debugResult = createDebug('server-impl:command:result');
|
|
11
11
|
|
|
12
|
+
export const implementServerManifest = {
|
|
13
|
+
handler: () => Promise.resolve({ default: implementServerCommandHandler }),
|
|
14
|
+
description: 'AI implements server TODOs and tests',
|
|
15
|
+
usage: 'implement:server <server-dir>',
|
|
16
|
+
examples: ['$ auto implement:server ./server'],
|
|
17
|
+
args: [{ name: 'server-dir', description: 'Server directory path', required: true }],
|
|
18
|
+
};
|
|
19
|
+
|
|
12
20
|
export type ImplementServerCommand = Command<
|
|
13
21
|
'ImplementServer',
|
|
14
22
|
{
|
|
@@ -108,63 +116,30 @@ async function handleImplementServerCommandInternal(
|
|
|
108
116
|
}
|
|
109
117
|
}
|
|
110
118
|
|
|
111
|
-
export const implementServerCommandHandler: CommandHandler<
|
|
119
|
+
export const implementServerCommandHandler: CommandHandler<
|
|
120
|
+
ImplementServerCommand,
|
|
121
|
+
ServerImplementedEvent | ServerImplementationFailedEvent
|
|
122
|
+
> = {
|
|
112
123
|
name: 'ImplementServer',
|
|
113
|
-
handle: async (
|
|
124
|
+
handle: async (
|
|
125
|
+
command: ImplementServerCommand,
|
|
126
|
+
): Promise<ServerImplementedEvent | ServerImplementationFailedEvent> => {
|
|
114
127
|
debug('CommandHandler executing for ImplementServer');
|
|
115
128
|
const result = await handleImplementServerCommandInternal(command);
|
|
116
129
|
|
|
117
130
|
if (result.type === 'ServerImplemented') {
|
|
118
131
|
debug('Command handler completed: success');
|
|
119
|
-
|
|
132
|
+
debug('✅ Server implementation completed successfully');
|
|
120
133
|
if (result.data.flowsImplemented > 0) {
|
|
121
|
-
|
|
134
|
+
debug(' %d flows implemented', result.data.flowsImplemented);
|
|
122
135
|
}
|
|
123
136
|
} else {
|
|
124
137
|
debug('Command handler completed: failure - %s', result.data.error);
|
|
125
|
-
|
|
126
|
-
process.exit(1);
|
|
138
|
+
debug('❌ Server implementation failed: %s', result.data.error);
|
|
127
139
|
}
|
|
140
|
+
return result;
|
|
128
141
|
},
|
|
129
142
|
};
|
|
130
143
|
|
|
131
|
-
//
|
|
132
|
-
|
|
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
|
-
};
|
|
144
|
+
// Default export is the command handler
|
|
145
|
+
export default implementServerCommandHandler;
|
|
@@ -11,56 +11,20 @@ const debugHandler = createDebug('server-impl:slice:handler');
|
|
|
11
11
|
const debugProcess = createDebug('server-impl:slice:process');
|
|
12
12
|
const debugResult = createDebug('server-impl:slice:result');
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Type errors are not allowed.
|
|
24
|
-
|
|
25
|
-
Your Goal:
|
|
26
|
-
- Read the implementation instructions from the provided file.
|
|
27
|
-
- Generate only the code needed to fulfill the instructions, nothing extra and provide back the whole file without the instructions.
|
|
28
|
-
- Maintain immutability and adhere to functional best practices.
|
|
29
|
-
- Use only the types and domain constructs already present in the slice.
|
|
30
|
-
- Do not remove existing imports or types that are still referenced or required in the file.
|
|
31
|
-
- Return the entire updated file, not just the modified parts and remove any TODO comments or instructions after implementing the logic
|
|
32
|
-
|
|
33
|
-
Key rules:
|
|
34
|
-
- Never modify code outside the TODO or instruction areas.
|
|
35
|
-
- Ensure the code is production-ready and type-safe.
|
|
36
|
-
- Follow the slice type conventions:
|
|
37
|
-
- **Command slice**: validate command, inspect state, emit events, never mutate state. Uses graphql mutations.
|
|
38
|
-
- **Reaction slice**: respond to events with commands.
|
|
39
|
-
- **Query slice**: maintain projections based on events, do not emit or throw. Uses graphql queries.
|
|
40
|
-
- All code must be TypeScript compliant and follow functional patterns.
|
|
41
|
-
- If a test exists, make it pass.
|
|
42
|
-
- Keep implementations minimal and idiomatic.
|
|
43
|
-
|
|
44
|
-
Avoid:
|
|
45
|
-
- Adding new dependencies.
|
|
46
|
-
- Refactoring unrelated code.
|
|
47
|
-
- Changing the structure of already scaffolded files unless instructed.
|
|
48
|
-
|
|
49
|
-
You will receive:
|
|
50
|
-
- The path of the file to implement.
|
|
51
|
-
- The current contents of the file, with instruction comments.
|
|
52
|
-
- Other relevant files from the same slice (e.g., types, test, state, etc.).
|
|
53
|
-
|
|
54
|
-
You must:
|
|
55
|
-
- Return the entire updated file (no commentary and remove all implementation instructions).
|
|
56
|
-
- Ensure the output is valid TypeScript.
|
|
57
|
-
`;
|
|
14
|
+
export const implementSliceManifest = {
|
|
15
|
+
handler: () => Promise.resolve({ default: implementSliceCommandHandler }),
|
|
16
|
+
description: 'AI implements a specific server slice',
|
|
17
|
+
usage: 'implement:slice <slice-path>',
|
|
18
|
+
examples: [
|
|
19
|
+
'$ auto implement:slice ./server/src/domain/flows/seasonal-assistant/enters-shopping-criteria-into-assistant',
|
|
20
|
+
],
|
|
21
|
+
args: [{ name: 'slice-path', description: 'Path to the slice directory to implement', required: true }],
|
|
22
|
+
};
|
|
58
23
|
|
|
59
24
|
export type ImplementSliceCommand = Command<
|
|
60
25
|
'ImplementSlice',
|
|
61
26
|
{
|
|
62
|
-
|
|
63
|
-
flowName: string;
|
|
27
|
+
slicePath: string;
|
|
64
28
|
context?: {
|
|
65
29
|
previousOutputs?: string;
|
|
66
30
|
attemptNumber?: number;
|
|
@@ -71,8 +35,7 @@ export type ImplementSliceCommand = Command<
|
|
|
71
35
|
export type SliceImplementedEvent = Event<
|
|
72
36
|
'SliceImplemented',
|
|
73
37
|
{
|
|
74
|
-
|
|
75
|
-
flowName: string;
|
|
38
|
+
slicePath: string;
|
|
76
39
|
filesImplemented: string[];
|
|
77
40
|
}
|
|
78
41
|
>;
|
|
@@ -80,8 +43,7 @@ export type SliceImplementedEvent = Event<
|
|
|
80
43
|
export type SliceImplementationFailedEvent = Event<
|
|
81
44
|
'SliceImplementationFailed',
|
|
82
45
|
{
|
|
83
|
-
|
|
84
|
-
flowName: string;
|
|
46
|
+
slicePath: string;
|
|
85
47
|
error: string;
|
|
86
48
|
}
|
|
87
49
|
>;
|
|
@@ -112,6 +74,51 @@ function findFilesToImplement(contextFiles: Record<string, string>): Array<[stri
|
|
|
112
74
|
);
|
|
113
75
|
}
|
|
114
76
|
|
|
77
|
+
// System prompt for AI implementation
|
|
78
|
+
const SYSTEM_PROMPT = `
|
|
79
|
+
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.
|
|
80
|
+
|
|
81
|
+
Project Characteristics:
|
|
82
|
+
- Architecture: sliced event-sourced CQRS (Command, Query, Reaction slices)
|
|
83
|
+
- Language: TypeScript with type-graphql and Emmett
|
|
84
|
+
- Each slice has scaffolded files with implementation instructions clearly marked with comments (e.g., '## IMPLEMENTATION INSTRUCTIONS ##') or TODOs.
|
|
85
|
+
- Tests (e.g., *.specs.ts) must pass.
|
|
86
|
+
- Type errors are not allowed.
|
|
87
|
+
|
|
88
|
+
Your Goal:
|
|
89
|
+
- Read the implementation instructions from the provided file.
|
|
90
|
+
- Generate only the code needed to fulfill the instructions, nothing extra and provide back the whole file without the instructions.
|
|
91
|
+
- Maintain immutability and adhere to functional best practices.
|
|
92
|
+
- Use only the types and domain constructs already present in the slice.
|
|
93
|
+
- Do not remove existing imports or types that are still referenced or required in the file.
|
|
94
|
+
- Return the entire updated file, not just the modified parts and remove any TODO comments or instructions after implementing the logic
|
|
95
|
+
|
|
96
|
+
Key rules:
|
|
97
|
+
- Never modify code outside the TODO or instruction areas.
|
|
98
|
+
- Ensure the code is production-ready and type-safe.
|
|
99
|
+
- Follow the slice type conventions:
|
|
100
|
+
- **Command slice**: validate command, inspect state, emit events, never mutate state. Uses graphql mutations.
|
|
101
|
+
- **Reaction slice**: respond to events with commands.
|
|
102
|
+
- **Query slice**: maintain projections based on events, do not emit or throw. Uses graphql queries.
|
|
103
|
+
- All code must be TypeScript compliant and follow functional patterns.
|
|
104
|
+
- If a test exists, make it pass.
|
|
105
|
+
- Keep implementations minimal and idiomatic.
|
|
106
|
+
|
|
107
|
+
Avoid:
|
|
108
|
+
- Adding new dependencies.
|
|
109
|
+
- Refactoring unrelated code.
|
|
110
|
+
- Changing the structure of already scaffolded files unless instructed.
|
|
111
|
+
|
|
112
|
+
You will receive:
|
|
113
|
+
- The path of the file to implement.
|
|
114
|
+
- The current contents of the file, with instruction comments.
|
|
115
|
+
- Other relevant files from the same slice (e.g., types, test, state, etc.).
|
|
116
|
+
|
|
117
|
+
You must:
|
|
118
|
+
- Return the entire updated file (no commentary and remove all implementation instructions).
|
|
119
|
+
- Ensure the output is valid TypeScript.
|
|
120
|
+
`;
|
|
121
|
+
|
|
115
122
|
// Build prompt for initial implementation
|
|
116
123
|
function buildInitialPrompt(targetFile: string, context: Record<string, string>): string {
|
|
117
124
|
return `
|
|
@@ -161,8 +168,7 @@ Return only the corrected full contents of ${targetFile}, no commentary, no mark
|
|
|
161
168
|
|
|
162
169
|
// Main implementation function
|
|
163
170
|
async function implementSlice(
|
|
164
|
-
|
|
165
|
-
flowName: string,
|
|
171
|
+
slicePath: string,
|
|
166
172
|
context?: { previousOutputs?: string; attemptNumber?: number },
|
|
167
173
|
): Promise<{ success: boolean; filesImplemented: string[]; error?: string }> {
|
|
168
174
|
const availableProviders = getAvailableProviders();
|
|
@@ -174,13 +180,13 @@ async function implementSlice(
|
|
|
174
180
|
}
|
|
175
181
|
|
|
176
182
|
const AI_PROVIDER = availableProviders[0];
|
|
177
|
-
const sliceName = path.basename(
|
|
183
|
+
const sliceName = path.basename(slicePath);
|
|
178
184
|
|
|
179
|
-
debugProcess(`Implementing slice: ${sliceName}
|
|
185
|
+
debugProcess(`Implementing slice: ${sliceName}`);
|
|
180
186
|
|
|
181
187
|
try {
|
|
182
188
|
// Load all context files
|
|
183
|
-
const contextFiles = await loadContextFiles(
|
|
189
|
+
const contextFiles = await loadContextFiles(slicePath);
|
|
184
190
|
const filesToImplement = findFilesToImplement(contextFiles);
|
|
185
191
|
const implementedFiles: string[] = [];
|
|
186
192
|
|
|
@@ -208,7 +214,7 @@ async function implementSlice(
|
|
|
208
214
|
const cleanedCode = extractCodeBlock(aiOutput);
|
|
209
215
|
|
|
210
216
|
// Write the implemented file
|
|
211
|
-
const filePath = path.join(
|
|
217
|
+
const filePath = path.join(slicePath, targetFile);
|
|
212
218
|
await writeFile(filePath, cleanedCode, 'utf-8');
|
|
213
219
|
|
|
214
220
|
debugProcess(`Successfully implemented ${targetFile}`);
|
|
@@ -227,10 +233,9 @@ async function implementSlice(
|
|
|
227
233
|
}
|
|
228
234
|
|
|
229
235
|
function logCommandDebugInfo(command: ImplementSliceCommand): void {
|
|
230
|
-
const {
|
|
236
|
+
const { slicePath, context } = command.data;
|
|
231
237
|
debug('Handling ImplementSliceCommand');
|
|
232
|
-
debug(' Slice
|
|
233
|
-
debug(' Flow name: %s', flowName);
|
|
238
|
+
debug(' Slice path: %s', slicePath);
|
|
234
239
|
debug(' Context provided: %s', context ? 'yes' : 'no');
|
|
235
240
|
if (context) {
|
|
236
241
|
debug(' Attempt number: %d', context.attemptNumber ?? 1);
|
|
@@ -243,8 +248,7 @@ function createFailedEvent(command: ImplementSliceCommand, error: string): Slice
|
|
|
243
248
|
return {
|
|
244
249
|
type: 'SliceImplementationFailed',
|
|
245
250
|
data: {
|
|
246
|
-
|
|
247
|
-
flowName: command.data.flowName,
|
|
251
|
+
slicePath: command.data.slicePath,
|
|
248
252
|
error,
|
|
249
253
|
},
|
|
250
254
|
timestamp: new Date(),
|
|
@@ -257,8 +261,7 @@ function createSuccessEvent(command: ImplementSliceCommand, filesImplemented: st
|
|
|
257
261
|
return {
|
|
258
262
|
type: 'SliceImplemented',
|
|
259
263
|
data: {
|
|
260
|
-
|
|
261
|
-
flowName: command.data.flowName,
|
|
264
|
+
slicePath: command.data.slicePath,
|
|
262
265
|
filesImplemented,
|
|
263
266
|
},
|
|
264
267
|
timestamp: new Date(),
|
|
@@ -277,12 +280,12 @@ function logRetryContext(context: { previousOutputs?: string; attemptNumber?: nu
|
|
|
277
280
|
export async function handleImplementSliceCommand(
|
|
278
281
|
command: ImplementSliceCommand,
|
|
279
282
|
): Promise<SliceImplementedEvent | SliceImplementationFailedEvent> {
|
|
280
|
-
const {
|
|
283
|
+
const { slicePath, context } = command.data;
|
|
281
284
|
|
|
282
285
|
logCommandDebugInfo(command);
|
|
283
286
|
|
|
284
287
|
try {
|
|
285
|
-
const sliceRoot = path.resolve(
|
|
288
|
+
const sliceRoot = path.resolve(slicePath);
|
|
286
289
|
debugHandler('Resolved paths:');
|
|
287
290
|
debugHandler(' Slice root: %s', sliceRoot);
|
|
288
291
|
|
|
@@ -294,7 +297,7 @@ export async function handleImplementSliceCommand(
|
|
|
294
297
|
debugProcess('Starting slice implementation for: %s', sliceRoot);
|
|
295
298
|
logRetryContext(context);
|
|
296
299
|
|
|
297
|
-
const result = await implementSlice(sliceRoot,
|
|
300
|
+
const result = await implementSlice(sliceRoot, context);
|
|
298
301
|
|
|
299
302
|
if (!result.success) {
|
|
300
303
|
return createFailedEvent(command, result.error ?? 'Implementation failed');
|
|
@@ -313,21 +316,27 @@ export async function handleImplementSliceCommand(
|
|
|
313
316
|
}
|
|
314
317
|
}
|
|
315
318
|
|
|
316
|
-
export const implementSliceCommandHandler: CommandHandler<
|
|
319
|
+
export const implementSliceCommandHandler: CommandHandler<
|
|
320
|
+
ImplementSliceCommand,
|
|
321
|
+
SliceImplementedEvent | SliceImplementationFailedEvent
|
|
322
|
+
> = {
|
|
317
323
|
name: 'ImplementSlice',
|
|
318
|
-
handle: async (command: ImplementSliceCommand): Promise<
|
|
324
|
+
handle: async (command: ImplementSliceCommand): Promise<SliceImplementedEvent | SliceImplementationFailedEvent> => {
|
|
319
325
|
debug('CommandHandler executing for ImplementSlice');
|
|
320
326
|
const result = await handleImplementSliceCommand(command);
|
|
321
327
|
|
|
322
328
|
if (result.type === 'SliceImplemented') {
|
|
323
329
|
debug('Command handler completed: success');
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
330
|
+
debug('✅ Slice implementation completed successfully');
|
|
331
|
+
debug(' Slice: %s', path.basename(result.data.slicePath));
|
|
332
|
+
debug(' Files implemented: %d', result.data.filesImplemented.length);
|
|
327
333
|
} else {
|
|
328
334
|
debug('Command handler completed: failure - %s', result.data.error);
|
|
329
|
-
|
|
330
|
-
process.exit(1);
|
|
335
|
+
debug('❌ Slice implementation failed: %s', result.data.error);
|
|
331
336
|
}
|
|
337
|
+
return result;
|
|
332
338
|
},
|
|
333
339
|
};
|
|
340
|
+
|
|
341
|
+
// Default export is the command handler
|
|
342
|
+
export default implementSliceCommandHandler;
|