@barissozen/csns 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/.env.example +8 -0
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/agent/agent-runner.d.ts +48 -0
- package/dist/agent/agent-runner.d.ts.map +1 -0
- package/dist/agent/agent-runner.js +180 -0
- package/dist/agent/agent-runner.js.map +1 -0
- package/dist/agent/architect.d.ts +34 -0
- package/dist/agent/architect.d.ts.map +1 -0
- package/dist/agent/architect.js +156 -0
- package/dist/agent/architect.js.map +1 -0
- package/dist/agent/codebase-reader.d.ts +35 -0
- package/dist/agent/codebase-reader.d.ts.map +1 -0
- package/dist/agent/codebase-reader.js +305 -0
- package/dist/agent/codebase-reader.js.map +1 -0
- package/dist/agent/context-builder.d.ts +39 -0
- package/dist/agent/context-builder.d.ts.map +1 -0
- package/dist/agent/context-builder.js +163 -0
- package/dist/agent/context-builder.js.map +1 -0
- package/dist/agent/index.d.ts +14 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +12 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/output-parser.d.ts +27 -0
- package/dist/agent/output-parser.d.ts.map +1 -0
- package/dist/agent/output-parser.js +154 -0
- package/dist/agent/output-parser.js.map +1 -0
- package/dist/agent/process-spawner.d.ts +56 -0
- package/dist/agent/process-spawner.d.ts.map +1 -0
- package/dist/agent/process-spawner.js +153 -0
- package/dist/agent/process-spawner.js.map +1 -0
- package/dist/agent/tracer/index.d.ts +8 -0
- package/dist/agent/tracer/index.d.ts.map +1 -0
- package/dist/agent/tracer/index.js +6 -0
- package/dist/agent/tracer/index.js.map +1 -0
- package/dist/agent/tracer/reverse-engineer.d.ts +113 -0
- package/dist/agent/tracer/reverse-engineer.d.ts.map +1 -0
- package/dist/agent/tracer/reverse-engineer.js +695 -0
- package/dist/agent/tracer/reverse-engineer.js.map +1 -0
- package/dist/agent/tracer/runtime-tracer.d.ts +61 -0
- package/dist/agent/tracer/runtime-tracer.d.ts.map +1 -0
- package/dist/agent/tracer/runtime-tracer.js +484 -0
- package/dist/agent/tracer/runtime-tracer.js.map +1 -0
- package/dist/agent/tracer/semantic-analyzer.d.ts +24 -0
- package/dist/agent/tracer/semantic-analyzer.d.ts.map +1 -0
- package/dist/agent/tracer/semantic-analyzer.js +132 -0
- package/dist/agent/tracer/semantic-analyzer.js.map +1 -0
- package/dist/agent/tracer/static-analyzer.d.ts +44 -0
- package/dist/agent/tracer/static-analyzer.d.ts.map +1 -0
- package/dist/agent/tracer/static-analyzer.js +453 -0
- package/dist/agent/tracer/static-analyzer.js.map +1 -0
- package/dist/agent/tracer/tracer-agent.d.ts +61 -0
- package/dist/agent/tracer/tracer-agent.d.ts.map +1 -0
- package/dist/agent/tracer/tracer-agent.js +252 -0
- package/dist/agent/tracer/tracer-agent.js.map +1 -0
- package/dist/bin/csns.d.ts +24 -0
- package/dist/bin/csns.d.ts.map +1 -0
- package/dist/bin/csns.js +389 -0
- package/dist/bin/csns.js.map +1 -0
- package/dist/bin/pc.d.ts +13 -0
- package/dist/bin/pc.d.ts.map +1 -0
- package/dist/bin/pc.js +212 -0
- package/dist/bin/pc.js.map +1 -0
- package/dist/brief/brief-collector.d.ts +42 -0
- package/dist/brief/brief-collector.d.ts.map +1 -0
- package/dist/brief/brief-collector.js +228 -0
- package/dist/brief/brief-collector.js.map +1 -0
- package/dist/brief/index.d.ts +3 -0
- package/dist/brief/index.d.ts.map +1 -0
- package/dist/brief/index.js +3 -0
- package/dist/brief/index.js.map +1 -0
- package/dist/brief/smart-brief.d.ts +52 -0
- package/dist/brief/smart-brief.d.ts.map +1 -0
- package/dist/brief/smart-brief.js +440 -0
- package/dist/brief/smart-brief.js.map +1 -0
- package/dist/calculator/calculator.d.ts +7 -0
- package/dist/calculator/calculator.d.ts.map +1 -0
- package/dist/calculator/calculator.js +18 -0
- package/dist/calculator/calculator.js.map +1 -0
- package/dist/calculator/index.d.ts +2 -0
- package/dist/calculator/index.d.ts.map +1 -0
- package/dist/calculator/index.js +2 -0
- package/dist/calculator/index.js.map +1 -0
- package/dist/i18n/en.d.ts +6 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +136 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/index.d.ts +31 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +44 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/tr.d.ts +6 -0
- package/dist/i18n/tr.d.ts.map +1 -0
- package/dist/i18n/tr.js +136 -0
- package/dist/i18n/tr.js.map +1 -0
- package/dist/i18n/types.d.ts +86 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +9 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic-provider.d.ts +18 -0
- package/dist/llm/anthropic-provider.d.ts.map +1 -0
- package/dist/llm/anthropic-provider.js +55 -0
- package/dist/llm/anthropic-provider.js.map +1 -0
- package/dist/llm/factory.d.ts +21 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +59 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/index.d.ts +7 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +5 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/ollama-provider.d.ts +20 -0
- package/dist/llm/ollama-provider.d.ts.map +1 -0
- package/dist/llm/ollama-provider.js +62 -0
- package/dist/llm/ollama-provider.js.map +1 -0
- package/dist/llm/openai-provider.d.ts +20 -0
- package/dist/llm/openai-provider.d.ts.map +1 -0
- package/dist/llm/openai-provider.js +65 -0
- package/dist/llm/openai-provider.js.map +1 -0
- package/dist/llm/resolve.d.ts +10 -0
- package/dist/llm/resolve.d.ts.map +1 -0
- package/dist/llm/resolve.js +21 -0
- package/dist/llm/resolve.js.map +1 -0
- package/dist/llm/types.d.ts +45 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +11 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/memory-layer.d.ts +54 -0
- package/dist/memory/memory-layer.d.ts.map +1 -0
- package/dist/memory/memory-layer.js +297 -0
- package/dist/memory/memory-layer.js.map +1 -0
- package/dist/orchestrator/dependency-graph.d.ts +39 -0
- package/dist/orchestrator/dependency-graph.d.ts.map +1 -0
- package/dist/orchestrator/dependency-graph.js +134 -0
- package/dist/orchestrator/dependency-graph.js.map +1 -0
- package/dist/orchestrator/escalator.d.ts +42 -0
- package/dist/orchestrator/escalator.d.ts.map +1 -0
- package/dist/orchestrator/escalator.js +163 -0
- package/dist/orchestrator/escalator.js.map +1 -0
- package/dist/orchestrator/evaluator.d.ts +34 -0
- package/dist/orchestrator/evaluator.d.ts.map +1 -0
- package/dist/orchestrator/evaluator.js +335 -0
- package/dist/orchestrator/evaluator.js.map +1 -0
- package/dist/orchestrator/index.d.ts +9 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +9 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/integration-evaluator.d.ts +59 -0
- package/dist/orchestrator/integration-evaluator.d.ts.map +1 -0
- package/dist/orchestrator/integration-evaluator.js +405 -0
- package/dist/orchestrator/integration-evaluator.js.map +1 -0
- package/dist/orchestrator/milestone-manager.d.ts +28 -0
- package/dist/orchestrator/milestone-manager.d.ts.map +1 -0
- package/dist/orchestrator/milestone-manager.js +208 -0
- package/dist/orchestrator/milestone-manager.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +35 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/orchestrator.js +338 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/planner.d.ts +15 -0
- package/dist/orchestrator/planner.d.ts.map +1 -0
- package/dist/orchestrator/planner.js +87 -0
- package/dist/orchestrator/planner.js.map +1 -0
- package/dist/orchestrator/recovery.d.ts +45 -0
- package/dist/orchestrator/recovery.d.ts.map +1 -0
- package/dist/orchestrator/recovery.js +98 -0
- package/dist/orchestrator/recovery.js.map +1 -0
- package/dist/run-calculator-test.d.ts +11 -0
- package/dist/run-calculator-test.d.ts.map +1 -0
- package/dist/run-calculator-test.js +212 -0
- package/dist/run-calculator-test.js.map +1 -0
- package/dist/run-real-task.d.ts +14 -0
- package/dist/run-real-task.d.ts.map +1 -0
- package/dist/run-real-task.js +185 -0
- package/dist/run-real-task.js.map +1 -0
- package/dist/run-todo-test.d.ts +6 -0
- package/dist/run-todo-test.d.ts.map +1 -0
- package/dist/run-todo-test.js +149 -0
- package/dist/run-todo-test.js.map +1 -0
- package/dist/todo/index.d.ts +2 -0
- package/dist/todo/index.d.ts.map +1 -0
- package/dist/todo/index.js +2 -0
- package/dist/todo/index.js.map +1 -0
- package/dist/todo/server.d.ts +2 -0
- package/dist/todo/server.d.ts.map +1 -0
- package/dist/todo/server.js +32 -0
- package/dist/todo/server.js.map +1 -0
- package/dist/types/index.d.ts +412 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-evaluator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/integration-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAkF3B,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAA4B;gBAGrC,IAAI,SAAe,EACnB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAMjC;;;OAGG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0ExD;;OAEG;IACG,YAAY,CAChB,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,SAAuB,GAC7B,OAAO,CAAC,OAAO,CAAC;IAcnB;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAqCnE;;OAEG;IACH,UAAU,IAAI,IAAI;IAalB;;OAEG;IACH,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,YAAY,EAAE;IAyB3D;;;;;;;OAOG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EAAE,GACpB,OAAO,CAAC,qBAAqB,CAAC;IAmDjC,wCAAwC;YAC1B,mBAAmB;IAoCjC,8BAA8B;IAC9B,OAAO,CAAC,SAAS;IAkBjB,0BAA0B;IAC1B,OAAO,CAAC,WAAW;IAuDnB,4EAA4E;IAC5E,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration Evaluator — Kod Yazıldıktan Sonra Gerçekten Çalışıyor mu Testi
|
|
3
|
+
*
|
|
4
|
+
* HTTP endpoint'leri test eder:
|
|
5
|
+
* 1. Server başlat (npm run dev / node dist/index.js)
|
|
6
|
+
* 2. Hazır olana kadar bekle
|
|
7
|
+
* 3. HTTP istekleri at, response kontrol et
|
|
8
|
+
* 4. Server'ı durdur
|
|
9
|
+
*
|
|
10
|
+
* D013: Evaluator v2 — gerçek kontroller
|
|
11
|
+
* Yeni: Integration test katmanı
|
|
12
|
+
*/
|
|
13
|
+
import { spawn } from 'node:child_process';
|
|
14
|
+
import { readFile } from 'node:fs/promises';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import http from 'node:http';
|
|
17
|
+
/** Server başlatma timeout (ms) */
|
|
18
|
+
const SERVER_START_TIMEOUT = 30_000;
|
|
19
|
+
/** Her request timeout (ms) */
|
|
20
|
+
const REQUEST_TIMEOUT = 10_000;
|
|
21
|
+
/** Default port */
|
|
22
|
+
const DEFAULT_PORT = 3000;
|
|
23
|
+
/** Task açıklamasından test senaryosu çıkartma pattern'leri */
|
|
24
|
+
const TASK_TEST_PATTERNS = [
|
|
25
|
+
{
|
|
26
|
+
keywords: ['auth', 'authentication', 'login', 'register'],
|
|
27
|
+
tests: [
|
|
28
|
+
{
|
|
29
|
+
method: 'POST',
|
|
30
|
+
path: '/auth/register',
|
|
31
|
+
body: { email: 'test@test.com', password: 'Test123!', name: 'Test User' },
|
|
32
|
+
expectedStatus: 201,
|
|
33
|
+
description: 'Register new user',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
method: 'POST',
|
|
37
|
+
path: '/auth/login',
|
|
38
|
+
body: { email: 'test@test.com', password: 'Test123!' },
|
|
39
|
+
expectedStatus: 200,
|
|
40
|
+
description: 'Login existing user',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
keywords: ['todo', 'todos', 'task list', 'task management'],
|
|
46
|
+
tests: [
|
|
47
|
+
{
|
|
48
|
+
method: 'GET',
|
|
49
|
+
path: '/todos',
|
|
50
|
+
expectedStatus: 200,
|
|
51
|
+
description: 'List all todos',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
method: 'POST',
|
|
55
|
+
path: '/todos',
|
|
56
|
+
body: { title: 'Integration test todo', completed: false },
|
|
57
|
+
expectedStatus: 201,
|
|
58
|
+
description: 'Create new todo',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
method: 'GET',
|
|
62
|
+
path: '/todos',
|
|
63
|
+
expectedStatus: 200,
|
|
64
|
+
description: 'Verify todo was created',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
method: 'DELETE',
|
|
68
|
+
path: '/todos/1',
|
|
69
|
+
expectedStatus: 200,
|
|
70
|
+
description: 'Delete a todo',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
keywords: ['api', 'rest', 'endpoint', 'server', 'express'],
|
|
76
|
+
tests: [
|
|
77
|
+
{
|
|
78
|
+
method: 'GET',
|
|
79
|
+
path: '/',
|
|
80
|
+
expectedStatus: 200,
|
|
81
|
+
description: 'Root endpoint responds',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
method: 'GET',
|
|
85
|
+
path: '/health',
|
|
86
|
+
expectedStatus: 200,
|
|
87
|
+
description: 'Health check endpoint',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
export class IntegrationEvaluator {
|
|
93
|
+
serverProcess = null;
|
|
94
|
+
port;
|
|
95
|
+
log;
|
|
96
|
+
constructor(port = DEFAULT_PORT, log) {
|
|
97
|
+
this.port = port;
|
|
98
|
+
this.log = log ?? console.log;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Server'ı başlat. package.json'dan script çöz.
|
|
102
|
+
* Öncelik: npm start > node dist/index.js > npm run dev
|
|
103
|
+
*/
|
|
104
|
+
async startServer(projectRoot) {
|
|
105
|
+
const startCommand = await this.resolveStartCommand(projectRoot);
|
|
106
|
+
if (!startCommand) {
|
|
107
|
+
this.log(' ⚠️ Server başlatma komutu bulunamadı');
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
this.log(` 🚀 Server başlatılıyor: ${startCommand.cmd} ${startCommand.args.join(' ')}`);
|
|
111
|
+
return new Promise((resolve) => {
|
|
112
|
+
const proc = spawn(startCommand.cmd, startCommand.args, {
|
|
113
|
+
cwd: projectRoot,
|
|
114
|
+
env: { ...process.env, PORT: String(this.port), NODE_ENV: 'test' },
|
|
115
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
116
|
+
shell: true,
|
|
117
|
+
});
|
|
118
|
+
this.serverProcess = proc;
|
|
119
|
+
let resolved = false;
|
|
120
|
+
let output = '';
|
|
121
|
+
const onData = (data) => {
|
|
122
|
+
output += data.toString();
|
|
123
|
+
// Server hazır sinyali
|
|
124
|
+
if (output.includes('listening') ||
|
|
125
|
+
output.includes('started') ||
|
|
126
|
+
output.includes(`port ${this.port}`) ||
|
|
127
|
+
output.includes(`:${this.port}`)) {
|
|
128
|
+
if (!resolved) {
|
|
129
|
+
resolved = true;
|
|
130
|
+
resolve(true);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
proc.stdout?.on('data', onData);
|
|
135
|
+
proc.stderr?.on('data', onData);
|
|
136
|
+
proc.on('error', () => {
|
|
137
|
+
if (!resolved) {
|
|
138
|
+
resolved = true;
|
|
139
|
+
resolve(false);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
proc.on('exit', () => {
|
|
143
|
+
if (!resolved) {
|
|
144
|
+
resolved = true;
|
|
145
|
+
resolve(false);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// Timeout fallback — log sinyali gelmese de port kontrolü yap
|
|
149
|
+
setTimeout(() => {
|
|
150
|
+
if (!resolved) {
|
|
151
|
+
this.checkPort(this.port).then(available => {
|
|
152
|
+
if (!resolved) {
|
|
153
|
+
resolved = true;
|
|
154
|
+
resolve(available);
|
|
155
|
+
}
|
|
156
|
+
}).catch(() => {
|
|
157
|
+
if (!resolved) {
|
|
158
|
+
resolved = true;
|
|
159
|
+
resolve(false);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}, SERVER_START_TIMEOUT);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Server hazır olana kadar bekle (port polling).
|
|
168
|
+
*/
|
|
169
|
+
async waitForReady(port, timeout = SERVER_START_TIMEOUT) {
|
|
170
|
+
const targetPort = port ?? this.port;
|
|
171
|
+
const start = Date.now();
|
|
172
|
+
const interval = 500;
|
|
173
|
+
while (Date.now() - start < timeout) {
|
|
174
|
+
const ready = await this.checkPort(targetPort);
|
|
175
|
+
if (ready)
|
|
176
|
+
return true;
|
|
177
|
+
await this.delay(interval);
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Tek bir endpoint'i test et.
|
|
183
|
+
*/
|
|
184
|
+
async testEndpoint(test) {
|
|
185
|
+
const start = Date.now();
|
|
186
|
+
try {
|
|
187
|
+
const response = await this.httpRequest(test.method, test.path, test.body, test.headers);
|
|
188
|
+
const statusOk = test.expectedStatus
|
|
189
|
+
? response.status === test.expectedStatus
|
|
190
|
+
: response.status >= 200 && response.status < 400;
|
|
191
|
+
let bodyOk = true;
|
|
192
|
+
if (test.expectedBody && response.body) {
|
|
193
|
+
bodyOk = this.deepIncludes(response.body, test.expectedBody);
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
test,
|
|
197
|
+
passed: statusOk && bodyOk,
|
|
198
|
+
actualStatus: response.status,
|
|
199
|
+
actualBody: response.body,
|
|
200
|
+
duration: Date.now() - start,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return {
|
|
205
|
+
test,
|
|
206
|
+
passed: false,
|
|
207
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
208
|
+
duration: Date.now() - start,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Server'ı durdur.
|
|
214
|
+
*/
|
|
215
|
+
stopServer() {
|
|
216
|
+
if (this.serverProcess) {
|
|
217
|
+
this.serverProcess.kill('SIGTERM');
|
|
218
|
+
// Grace period sonrası zorla kapat
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
if (this.serverProcess && !this.serverProcess.killed) {
|
|
221
|
+
this.serverProcess.kill('SIGKILL');
|
|
222
|
+
}
|
|
223
|
+
}, 3000);
|
|
224
|
+
this.serverProcess = null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Task açıklamasından otomatik test senaryoları çıkar.
|
|
229
|
+
*/
|
|
230
|
+
inferTestsFromTask(taskDescription) {
|
|
231
|
+
const descLower = taskDescription.toLowerCase();
|
|
232
|
+
const allTests = [];
|
|
233
|
+
for (const pattern of TASK_TEST_PATTERNS) {
|
|
234
|
+
const match = pattern.keywords.some(kw => descLower.includes(kw));
|
|
235
|
+
if (match) {
|
|
236
|
+
allTests.push(...pattern.tests);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Eşleşme yoksa genel API testleri dön
|
|
240
|
+
if (allTests.length === 0) {
|
|
241
|
+
return [
|
|
242
|
+
{
|
|
243
|
+
method: 'GET',
|
|
244
|
+
path: '/',
|
|
245
|
+
description: 'Root endpoint check',
|
|
246
|
+
},
|
|
247
|
+
];
|
|
248
|
+
}
|
|
249
|
+
return allTests;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Tam integration test akışı:
|
|
253
|
+
* 1. Server başlat
|
|
254
|
+
* 2. Hazır olana kadar bekle
|
|
255
|
+
* 3. Testleri çalıştır
|
|
256
|
+
* 4. Server'ı durdur
|
|
257
|
+
* 5. Sonuçları döndür
|
|
258
|
+
*/
|
|
259
|
+
async runFullTest(projectRoot, tests) {
|
|
260
|
+
const serverStart = Date.now();
|
|
261
|
+
// 1. Server başlat
|
|
262
|
+
const started = await this.startServer(projectRoot);
|
|
263
|
+
const serverStartTime = Date.now() - serverStart;
|
|
264
|
+
if (!started) {
|
|
265
|
+
this.stopServer();
|
|
266
|
+
return {
|
|
267
|
+
serverStarted: false,
|
|
268
|
+
serverStartTime,
|
|
269
|
+
endpointResults: [],
|
|
270
|
+
passed: 0,
|
|
271
|
+
failed: tests.length,
|
|
272
|
+
total: tests.length,
|
|
273
|
+
summary: `Server başlatılamadı (${serverStartTime}ms). Integration testleri atlandı.`,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
this.log(` ✅ Server hazır (${serverStartTime}ms)`);
|
|
277
|
+
// 2. Testleri çalıştır
|
|
278
|
+
const results = [];
|
|
279
|
+
for (const test of tests) {
|
|
280
|
+
this.log(` 🧪 ${test.method} ${test.path} — ${test.description}`);
|
|
281
|
+
const result = await this.testEndpoint(test);
|
|
282
|
+
results.push(result);
|
|
283
|
+
this.log(` ${result.passed ? '✅' : '❌'} ${result.actualStatus ?? 'ERR'} (${result.duration}ms)`);
|
|
284
|
+
}
|
|
285
|
+
// 3. Server'ı durdur
|
|
286
|
+
this.stopServer();
|
|
287
|
+
// 4. Sonuçları hesapla
|
|
288
|
+
const passed = results.filter(r => r.passed).length;
|
|
289
|
+
const failed = results.filter(r => !r.passed).length;
|
|
290
|
+
return {
|
|
291
|
+
serverStarted: true,
|
|
292
|
+
serverStartTime,
|
|
293
|
+
endpointResults: results,
|
|
294
|
+
passed,
|
|
295
|
+
failed,
|
|
296
|
+
total: results.length,
|
|
297
|
+
summary: `Integration: ${passed}/${results.length} passed (server: ${serverStartTime}ms)`,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
// ── Private Helpers ─────────────────────────────────────
|
|
301
|
+
/** package.json'dan start komutu çöz */
|
|
302
|
+
async resolveStartCommand(projectRoot) {
|
|
303
|
+
try {
|
|
304
|
+
const pkgContent = await readFile(join(projectRoot, 'package.json'), 'utf-8');
|
|
305
|
+
const pkg = JSON.parse(pkgContent);
|
|
306
|
+
const scripts = pkg['scripts'];
|
|
307
|
+
if (scripts?.['start']) {
|
|
308
|
+
return { cmd: 'npm', args: ['run', 'start'] };
|
|
309
|
+
}
|
|
310
|
+
if (scripts?.['dev']) {
|
|
311
|
+
return { cmd: 'npm', args: ['run', 'dev'] };
|
|
312
|
+
}
|
|
313
|
+
// Fallback: main field
|
|
314
|
+
const main = pkg['main'];
|
|
315
|
+
if (main) {
|
|
316
|
+
return { cmd: 'node', args: [main] };
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
// package.json yok veya parse hatası
|
|
321
|
+
}
|
|
322
|
+
// Python?
|
|
323
|
+
try {
|
|
324
|
+
await readFile(join(projectRoot, 'main.py'), 'utf-8');
|
|
325
|
+
return { cmd: 'python', args: ['main.py'] };
|
|
326
|
+
}
|
|
327
|
+
catch { /* nope */ }
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
/** Port açık mı kontrol et */
|
|
331
|
+
checkPort(port) {
|
|
332
|
+
return new Promise((resolve) => {
|
|
333
|
+
const req = http.request({ host: '127.0.0.1', port, path: '/', method: 'GET', timeout: 2000 }, (res) => {
|
|
334
|
+
res.resume();
|
|
335
|
+
resolve(true);
|
|
336
|
+
});
|
|
337
|
+
req.on('error', () => resolve(false));
|
|
338
|
+
req.on('timeout', () => {
|
|
339
|
+
req.destroy();
|
|
340
|
+
resolve(false);
|
|
341
|
+
});
|
|
342
|
+
req.end();
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/** HTTP request helper */
|
|
346
|
+
httpRequest(method, path, body, headers) {
|
|
347
|
+
return new Promise((resolve, reject) => {
|
|
348
|
+
const bodyStr = body ? JSON.stringify(body) : undefined;
|
|
349
|
+
const reqHeaders = {
|
|
350
|
+
...(headers ?? {}),
|
|
351
|
+
};
|
|
352
|
+
if (bodyStr) {
|
|
353
|
+
reqHeaders['Content-Type'] = 'application/json';
|
|
354
|
+
reqHeaders['Content-Length'] = String(Buffer.byteLength(bodyStr));
|
|
355
|
+
}
|
|
356
|
+
const req = http.request({
|
|
357
|
+
host: '127.0.0.1',
|
|
358
|
+
port: this.port,
|
|
359
|
+
path,
|
|
360
|
+
method,
|
|
361
|
+
headers: reqHeaders,
|
|
362
|
+
timeout: REQUEST_TIMEOUT,
|
|
363
|
+
}, (res) => {
|
|
364
|
+
let data = '';
|
|
365
|
+
res.on('data', (chunk) => { data += chunk.toString(); });
|
|
366
|
+
res.on('end', () => {
|
|
367
|
+
let parsed = data;
|
|
368
|
+
try {
|
|
369
|
+
parsed = JSON.parse(data);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// text response
|
|
373
|
+
}
|
|
374
|
+
resolve({ status: res.statusCode ?? 0, body: parsed });
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
req.on('error', (err) => reject(err));
|
|
378
|
+
req.on('timeout', () => {
|
|
379
|
+
req.destroy();
|
|
380
|
+
reject(new Error(`Request timeout: ${method} ${path}`));
|
|
381
|
+
});
|
|
382
|
+
if (bodyStr) {
|
|
383
|
+
req.end(bodyStr);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
req.end();
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
/** Beklenen body'nin gerçek body'de olup olmadığını kontrol et (shallow) */
|
|
391
|
+
deepIncludes(actual, expected) {
|
|
392
|
+
if (typeof actual !== 'object' || actual === null)
|
|
393
|
+
return false;
|
|
394
|
+
const actualObj = actual;
|
|
395
|
+
for (const [key, value] of Object.entries(expected)) {
|
|
396
|
+
if (actualObj[key] !== value)
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
return true;
|
|
400
|
+
}
|
|
401
|
+
delay(ms) {
|
|
402
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=integration-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-evaluator.js","sourceRoot":"","sources":["../../src/orchestrator/integration-evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone Manager — Aşamalı Planlama
|
|
3
|
+
*
|
|
4
|
+
* Brief + mimari kararlardan milestone listesi üretir.
|
|
5
|
+
* Her milestone bağımlı olduğu önceki milestone'lar tamamlandıktan sonra başlar.
|
|
6
|
+
* STATE.md'ye milestone durumunu yazar.
|
|
7
|
+
*/
|
|
8
|
+
import type { ArchitectureDecisions, Milestone, MilestonePlan, MilestoneStatus } from '../types/index.js';
|
|
9
|
+
export declare class MilestoneManager {
|
|
10
|
+
/**
|
|
11
|
+
* Brief + mimari kararlardan milestone planı üret.
|
|
12
|
+
* Her proje en az 3 milestone içerir.
|
|
13
|
+
*/
|
|
14
|
+
createMilestones(_brief: string, architecture: ArchitectureDecisions): MilestonePlan;
|
|
15
|
+
/**
|
|
16
|
+
* STATE.md için milestone durumu render et
|
|
17
|
+
*/
|
|
18
|
+
renderMilestoneState(milestones: Milestone[]): string;
|
|
19
|
+
/**
|
|
20
|
+
* Sonraki çalıştırılabilir milestone'u bul
|
|
21
|
+
*/
|
|
22
|
+
getNextMilestone(milestones: Milestone[]): Milestone | null;
|
|
23
|
+
/**
|
|
24
|
+
* Milestone durumunu güncelle
|
|
25
|
+
*/
|
|
26
|
+
updateStatus(milestone: Milestone, status: MilestoneStatus): void;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=milestone-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"milestone-manager.d.ts","sourceRoot":"","sources":["../../src/orchestrator/milestone-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,gBAAgB;IAC3B;;;OAGG;IACH,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,qBAAqB,GAClC,aAAa;IAyKhB;;OAEG;IACH,oBAAoB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM;IAUrD;;OAEG;IACH,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI;IAY3D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;CASlE"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone Manager — Aşamalı Planlama
|
|
3
|
+
*
|
|
4
|
+
* Brief + mimari kararlardan milestone listesi üretir.
|
|
5
|
+
* Her milestone bağımlı olduğu önceki milestone'lar tamamlandıktan sonra başlar.
|
|
6
|
+
* STATE.md'ye milestone durumunu yazar.
|
|
7
|
+
*/
|
|
8
|
+
export class MilestoneManager {
|
|
9
|
+
/**
|
|
10
|
+
* Brief + mimari kararlardan milestone planı üret.
|
|
11
|
+
* Her proje en az 3 milestone içerir.
|
|
12
|
+
*/
|
|
13
|
+
createMilestones(_brief, architecture) {
|
|
14
|
+
const milestones = [];
|
|
15
|
+
let taskCounter = 1;
|
|
16
|
+
const nextTaskId = () => `T${String(taskCounter++).padStart(3, '0')}`;
|
|
17
|
+
// ── M01: Foundation ────────────────────────────────────
|
|
18
|
+
const foundationTasks = [
|
|
19
|
+
{
|
|
20
|
+
id: nextTaskId(),
|
|
21
|
+
title: 'Proje yapısı ve config',
|
|
22
|
+
description: 'package.json, tsconfig.json, .env, temel klasör yapısı',
|
|
23
|
+
type: 'code',
|
|
24
|
+
dependencies: [],
|
|
25
|
+
priority: 'critical',
|
|
26
|
+
estimatedComplexity: 'simple',
|
|
27
|
+
acceptanceCriteria: ['package.json mevcut', 'tsconfig.json mevcut', 'tsc --noEmit geçiyor'],
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
if (architecture.database !== 'in-memory') {
|
|
31
|
+
foundationTasks.push({
|
|
32
|
+
id: nextTaskId(),
|
|
33
|
+
title: `${architecture.database} schema ve bağlantı`,
|
|
34
|
+
description: `${architecture.database} veritabanı schema tanımı ve connection setup`,
|
|
35
|
+
type: 'code',
|
|
36
|
+
dependencies: [foundationTasks[0].id],
|
|
37
|
+
priority: 'critical',
|
|
38
|
+
estimatedComplexity: 'moderate',
|
|
39
|
+
acceptanceCriteria: ['DB bağlantısı çalışıyor', 'Schema migration mevcut'],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
milestones.push({
|
|
43
|
+
id: 'M01',
|
|
44
|
+
title: 'Foundation',
|
|
45
|
+
description: 'Proje altyapısı, config, DB schema',
|
|
46
|
+
dependsOn: [],
|
|
47
|
+
tasks: foundationTasks,
|
|
48
|
+
status: 'pending',
|
|
49
|
+
});
|
|
50
|
+
// ── M02: Auth (eğer seçildiyse) ───────────────────────
|
|
51
|
+
if (architecture.auth !== 'none') {
|
|
52
|
+
const authTasks = [
|
|
53
|
+
{
|
|
54
|
+
id: nextTaskId(),
|
|
55
|
+
title: `${architecture.auth} auth implementasyonu`,
|
|
56
|
+
description: `User model, ${architecture.auth} stratejisi, register/login`,
|
|
57
|
+
type: 'code',
|
|
58
|
+
dependencies: [],
|
|
59
|
+
priority: 'high',
|
|
60
|
+
estimatedComplexity: 'moderate',
|
|
61
|
+
acceptanceCriteria: ['Register çalışıyor', 'Login çalışıyor', 'Auth middleware mevcut'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: nextTaskId(),
|
|
65
|
+
title: 'Auth testleri',
|
|
66
|
+
description: 'Register, login, unauthorized access testleri',
|
|
67
|
+
type: 'test',
|
|
68
|
+
dependencies: [],
|
|
69
|
+
priority: 'high',
|
|
70
|
+
estimatedComplexity: 'simple',
|
|
71
|
+
acceptanceCriteria: ['Auth testleri geçiyor', 'Coverage > 80%'],
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
// Auth testleri auth implementasyonuna bağımlı
|
|
75
|
+
authTasks[1].dependencies = [authTasks[0].id];
|
|
76
|
+
milestones.push({
|
|
77
|
+
id: 'M02',
|
|
78
|
+
title: 'Auth',
|
|
79
|
+
description: `${architecture.auth} authentication sistemi`,
|
|
80
|
+
dependsOn: ['M01'],
|
|
81
|
+
tasks: authTasks,
|
|
82
|
+
status: 'pending',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// ── M03: API ──────────────────────────────────────────
|
|
86
|
+
const apiDeps = architecture.auth !== 'none' ? ['M02'] : ['M01'];
|
|
87
|
+
const apiTasks = [
|
|
88
|
+
{
|
|
89
|
+
id: nextTaskId(),
|
|
90
|
+
title: `${architecture.apiStyle} endpoints`,
|
|
91
|
+
description: `Ana business logic endpoints (${architecture.apiStyle} stili)`,
|
|
92
|
+
type: 'code',
|
|
93
|
+
dependencies: [],
|
|
94
|
+
priority: 'high',
|
|
95
|
+
estimatedComplexity: 'moderate',
|
|
96
|
+
acceptanceCriteria: ['CRUD endpoints çalışıyor', 'Validation mevcut', 'Error handling'],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: nextTaskId(),
|
|
100
|
+
title: 'API testleri',
|
|
101
|
+
description: 'Endpoint testleri, edge case\'ler',
|
|
102
|
+
type: 'test',
|
|
103
|
+
dependencies: [],
|
|
104
|
+
priority: 'high',
|
|
105
|
+
estimatedComplexity: 'simple',
|
|
106
|
+
acceptanceCriteria: ['API testleri geçiyor'],
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
apiTasks[1].dependencies = [apiTasks[0].id];
|
|
110
|
+
milestones.push({
|
|
111
|
+
id: architecture.auth !== 'none' ? 'M03' : 'M02',
|
|
112
|
+
title: 'API',
|
|
113
|
+
description: `${architecture.apiStyle} API endpoints ve business logic`,
|
|
114
|
+
dependsOn: apiDeps,
|
|
115
|
+
tasks: apiTasks,
|
|
116
|
+
status: 'pending',
|
|
117
|
+
});
|
|
118
|
+
// ── M04: Frontend (eğer seçildiyse) ───────────────────
|
|
119
|
+
if (architecture.frontend !== 'api-only') {
|
|
120
|
+
const prevMilestone = milestones[milestones.length - 1].id;
|
|
121
|
+
const feId = `M${String(milestones.length + 1).padStart(2, '0')}`;
|
|
122
|
+
milestones.push({
|
|
123
|
+
id: feId,
|
|
124
|
+
title: 'Frontend',
|
|
125
|
+
description: `${architecture.frontend} frontend`,
|
|
126
|
+
dependsOn: [prevMilestone],
|
|
127
|
+
tasks: [
|
|
128
|
+
{
|
|
129
|
+
id: nextTaskId(),
|
|
130
|
+
title: `${architecture.frontend} setup + routing`,
|
|
131
|
+
description: `${architecture.frontend} projesi oluştur, routing, API entegrasyonu`,
|
|
132
|
+
type: 'code',
|
|
133
|
+
dependencies: [],
|
|
134
|
+
priority: 'medium',
|
|
135
|
+
estimatedComplexity: 'moderate',
|
|
136
|
+
acceptanceCriteria: ['Frontend render oluyor', 'API ile konuşuyor'],
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
status: 'pending',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// ── Final: Integration ────────────────────────────────
|
|
143
|
+
const lastMilestone = milestones[milestones.length - 1].id;
|
|
144
|
+
const integrationId = `M${String(milestones.length + 1).padStart(2, '0')}`;
|
|
145
|
+
milestones.push({
|
|
146
|
+
id: integrationId,
|
|
147
|
+
title: 'Integration',
|
|
148
|
+
description: 'E2E testler, docker-compose, final review',
|
|
149
|
+
dependsOn: [lastMilestone],
|
|
150
|
+
tasks: [
|
|
151
|
+
{
|
|
152
|
+
id: nextTaskId(),
|
|
153
|
+
title: 'E2E entegrasyon testleri',
|
|
154
|
+
description: 'Tüm sistem birlikte çalışıyor mu? E2E testleri yaz.',
|
|
155
|
+
type: 'test',
|
|
156
|
+
dependencies: [],
|
|
157
|
+
priority: 'medium',
|
|
158
|
+
estimatedComplexity: 'moderate',
|
|
159
|
+
acceptanceCriteria: ['E2E testler geçiyor', 'Tüm milestone\'lar entegre'],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
status: 'pending',
|
|
163
|
+
});
|
|
164
|
+
const totalTasks = milestones.reduce((sum, m) => sum + m.tasks.length, 0);
|
|
165
|
+
return { milestones, totalTasks };
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* STATE.md için milestone durumu render et
|
|
169
|
+
*/
|
|
170
|
+
renderMilestoneState(milestones) {
|
|
171
|
+
return milestones
|
|
172
|
+
.map(m => {
|
|
173
|
+
const icon = m.status === 'done' ? '[x]' : '[ ]';
|
|
174
|
+
const status = m.status !== 'pending' ? ` — ${m.status}` : '';
|
|
175
|
+
return `${icon} ${m.id}: ${m.title}${status}`;
|
|
176
|
+
})
|
|
177
|
+
.join('\n');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Sonraki çalıştırılabilir milestone'u bul
|
|
181
|
+
*/
|
|
182
|
+
getNextMilestone(milestones) {
|
|
183
|
+
for (const m of milestones) {
|
|
184
|
+
if (m.status !== 'pending')
|
|
185
|
+
continue;
|
|
186
|
+
const depsComplete = m.dependsOn.every(depId => {
|
|
187
|
+
const dep = milestones.find(x => x.id === depId);
|
|
188
|
+
return dep?.status === 'done';
|
|
189
|
+
});
|
|
190
|
+
if (depsComplete)
|
|
191
|
+
return m;
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Milestone durumunu güncelle
|
|
197
|
+
*/
|
|
198
|
+
updateStatus(milestone, status) {
|
|
199
|
+
milestone.status = status;
|
|
200
|
+
if (status === 'running' && !milestone.startedAt) {
|
|
201
|
+
milestone.startedAt = new Date().toISOString();
|
|
202
|
+
}
|
|
203
|
+
if (status === 'done' || status === 'failed' || status === 'skipped') {
|
|
204
|
+
milestone.completedAt = new Date().toISOString();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=milestone-manager.js.map
|