ai-sdlc 0.3.1-alpha.2 → 0.3.1-alpha.2-alpha.2
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/dist/agents/verification.d.ts +23 -3
- package/dist/agents/verification.d.ts.map +1 -1
- package/dist/agents/verification.js +93 -11
- package/dist/agents/verification.js.map +1 -1
- package/dist/cli/commands.d.ts +8 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +67 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/formatting.d.ts +15 -0
- package/dist/cli/formatting.d.ts.map +1 -1
- package/dist/cli/formatting.js +34 -0
- package/dist/cli/formatting.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +6 -4
- package/dist/cli/runner.js.map +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +92 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/stack-detector.d.ts +28 -0
- package/dist/core/stack-detector.d.ts.map +1 -0
- package/dist/core/stack-detector.js +395 -0
- package/dist/core/stack-detector.js.map +1 -0
- package/dist/core/story-logger.d.ts +51 -1
- package/dist/core/story-logger.d.ts.map +1 -1
- package/dist/core/story-logger.js +69 -3
- package/dist/core/story-logger.js.map +1 -1
- package/dist/core/story.d.ts.map +1 -1
- package/dist/core/story.js +8 -4
- package/dist/core/story.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/services/gh-cli.d.ts +81 -0
- package/dist/services/gh-cli.d.ts.map +1 -1
- package/dist/services/gh-cli.js +257 -0
- package/dist/services/gh-cli.js.map +1 -1
- package/dist/services/ticket-provider/github-provider.d.ts +27 -12
- package/dist/services/ticket-provider/github-provider.d.ts.map +1 -1
- package/dist/services/ticket-provider/github-provider.js +51 -17
- package/dist/services/ticket-provider/github-provider.js.map +1 -1
- package/dist/types/index.d.ts +36 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/services/github-projects/client.d.ts +0 -25
- package/dist/services/github-projects/client.d.ts.map +0 -1
- package/dist/services/github-projects/client.js +0 -99
- package/dist/services/github-projects/client.js.map +0 -1
- package/dist/services/github-projects/index.d.ts +0 -8
- package/dist/services/github-projects/index.d.ts.map +0 -1
- package/dist/services/github-projects/index.js +0 -8
- package/dist/services/github-projects/index.js.map +0 -1
- package/dist/services/github-projects/priority-normalizer.d.ts +0 -21
- package/dist/services/github-projects/priority-normalizer.d.ts.map +0 -1
- package/dist/services/github-projects/priority-normalizer.js +0 -36
- package/dist/services/github-projects/priority-normalizer.js.map +0 -1
- package/dist/services/github-projects/queries.d.ts +0 -17
- package/dist/services/github-projects/queries.d.ts.map +0 -1
- package/dist/services/github-projects/queries.js +0 -79
- package/dist/services/github-projects/queries.js.map +0 -1
- package/dist/services/github-projects/types.d.ts +0 -46
- package/dist/services/github-projects/types.d.ts.map +0 -1
- package/dist/services/github-projects/types.js +0 -5
- package/dist/services/github-projects/types.js.map +0 -1
- package/dist/services/priority-sync.d.ts +0 -25
- package/dist/services/priority-sync.d.ts.map +0 -1
- package/dist/services/priority-sync.js +0 -67
- package/dist/services/priority-sync.js.map +0 -1
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Stack definitions ordered by detection priority.
|
|
5
|
+
* More specific stacks (with secondary markers) come before generic ones.
|
|
6
|
+
*/
|
|
7
|
+
const STACK_DEFINITIONS = [
|
|
8
|
+
// Node.js variants (order matters: check lock files first)
|
|
9
|
+
{
|
|
10
|
+
stack: 'node-bun',
|
|
11
|
+
primaryMarker: 'package.json',
|
|
12
|
+
secondaryMarker: 'bun.lockb',
|
|
13
|
+
commands: {
|
|
14
|
+
install: 'bun install',
|
|
15
|
+
build: 'bun run build',
|
|
16
|
+
test: 'bun test',
|
|
17
|
+
start: 'bun start',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
stack: 'node-pnpm',
|
|
22
|
+
primaryMarker: 'package.json',
|
|
23
|
+
secondaryMarker: 'pnpm-lock.yaml',
|
|
24
|
+
commands: {
|
|
25
|
+
install: 'pnpm install',
|
|
26
|
+
build: 'pnpm run build',
|
|
27
|
+
test: 'pnpm test',
|
|
28
|
+
start: 'pnpm start',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
stack: 'node-yarn',
|
|
33
|
+
primaryMarker: 'package.json',
|
|
34
|
+
secondaryMarker: 'yarn.lock',
|
|
35
|
+
commands: {
|
|
36
|
+
install: 'yarn install',
|
|
37
|
+
build: 'yarn build',
|
|
38
|
+
test: 'yarn test',
|
|
39
|
+
start: 'yarn start',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
stack: 'node-npm',
|
|
44
|
+
primaryMarker: 'package.json',
|
|
45
|
+
secondaryMarker: 'package-lock.json',
|
|
46
|
+
commands: {
|
|
47
|
+
install: 'npm install',
|
|
48
|
+
build: 'npm run build',
|
|
49
|
+
test: 'npm test',
|
|
50
|
+
start: 'npm start',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
// Python variants
|
|
54
|
+
{
|
|
55
|
+
stack: 'python-poetry',
|
|
56
|
+
primaryMarker: 'pyproject.toml',
|
|
57
|
+
secondaryMarker: 'poetry.lock',
|
|
58
|
+
commands: {
|
|
59
|
+
install: 'poetry install',
|
|
60
|
+
build: 'poetry build',
|
|
61
|
+
test: 'poetry run pytest',
|
|
62
|
+
start: 'poetry run python -m main',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
stack: 'python-uv',
|
|
67
|
+
primaryMarker: 'pyproject.toml',
|
|
68
|
+
secondaryMarker: 'uv.lock',
|
|
69
|
+
commands: {
|
|
70
|
+
install: 'uv sync',
|
|
71
|
+
build: 'uv build',
|
|
72
|
+
test: 'uv run pytest',
|
|
73
|
+
start: 'uv run python -m main',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
stack: 'python-pip',
|
|
78
|
+
primaryMarker: 'requirements.txt',
|
|
79
|
+
commands: {
|
|
80
|
+
install: 'pip install -r requirements.txt',
|
|
81
|
+
test: 'pytest',
|
|
82
|
+
start: 'python main.py',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
// Rust
|
|
86
|
+
{
|
|
87
|
+
stack: 'rust-cargo',
|
|
88
|
+
primaryMarker: 'Cargo.toml',
|
|
89
|
+
commands: {
|
|
90
|
+
install: 'cargo fetch',
|
|
91
|
+
build: 'cargo build',
|
|
92
|
+
test: 'cargo test',
|
|
93
|
+
start: 'cargo run',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
// Go
|
|
97
|
+
{
|
|
98
|
+
stack: 'go-mod',
|
|
99
|
+
primaryMarker: 'go.mod',
|
|
100
|
+
commands: {
|
|
101
|
+
install: 'go mod download',
|
|
102
|
+
build: 'go build ./...',
|
|
103
|
+
test: 'go test ./...',
|
|
104
|
+
start: 'go run .',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
// Ruby
|
|
108
|
+
{
|
|
109
|
+
stack: 'ruby-bundler',
|
|
110
|
+
primaryMarker: 'Gemfile',
|
|
111
|
+
commands: {
|
|
112
|
+
install: 'bundle install',
|
|
113
|
+
test: 'bundle exec rspec',
|
|
114
|
+
start: 'bundle exec ruby main.rb',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
// Java variants
|
|
118
|
+
{
|
|
119
|
+
stack: 'java-gradle',
|
|
120
|
+
primaryMarker: 'build.gradle',
|
|
121
|
+
commands: {
|
|
122
|
+
install: './gradlew dependencies',
|
|
123
|
+
build: './gradlew build',
|
|
124
|
+
test: './gradlew test',
|
|
125
|
+
start: './gradlew run',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
stack: 'java-maven',
|
|
130
|
+
primaryMarker: 'pom.xml',
|
|
131
|
+
commands: {
|
|
132
|
+
install: 'mvn install -DskipTests',
|
|
133
|
+
build: 'mvn compile',
|
|
134
|
+
test: 'mvn test',
|
|
135
|
+
start: 'mvn exec:java',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
// .NET
|
|
139
|
+
{
|
|
140
|
+
stack: 'dotnet',
|
|
141
|
+
primaryMarker: '*.csproj',
|
|
142
|
+
commands: {
|
|
143
|
+
install: 'dotnet restore',
|
|
144
|
+
build: 'dotnet build',
|
|
145
|
+
test: 'dotnet test',
|
|
146
|
+
start: 'dotnet run',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
/**
|
|
151
|
+
* Common subdirectory patterns to check for projects.
|
|
152
|
+
* Includes monorepo patterns and common app directory names.
|
|
153
|
+
*/
|
|
154
|
+
const SUBDIRECTORY_PATTERNS = [
|
|
155
|
+
// Common app directories
|
|
156
|
+
'app',
|
|
157
|
+
'src',
|
|
158
|
+
'backend',
|
|
159
|
+
'frontend',
|
|
160
|
+
'api',
|
|
161
|
+
'server',
|
|
162
|
+
'client',
|
|
163
|
+
'web',
|
|
164
|
+
'mobile',
|
|
165
|
+
'service',
|
|
166
|
+
'services',
|
|
167
|
+
// Monorepo patterns (glob-like, will be expanded)
|
|
168
|
+
'packages/*',
|
|
169
|
+
'apps/*',
|
|
170
|
+
'projects/*',
|
|
171
|
+
'libs/*',
|
|
172
|
+
'modules/*',
|
|
173
|
+
];
|
|
174
|
+
/**
|
|
175
|
+
* Check if a file or glob pattern exists in a directory.
|
|
176
|
+
* Handles glob patterns like "*.csproj".
|
|
177
|
+
*/
|
|
178
|
+
function markerExists(dir, marker) {
|
|
179
|
+
if (marker.includes('*')) {
|
|
180
|
+
// Handle glob pattern
|
|
181
|
+
const pattern = marker.replace('*', '');
|
|
182
|
+
try {
|
|
183
|
+
const files = readdirSync(dir);
|
|
184
|
+
return files.some(f => f.endsWith(pattern) || f.startsWith(pattern.replace('*', '')));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return existsSync(path.join(dir, marker));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Detect the tech stack for a given directory.
|
|
194
|
+
* Returns 'unknown' if no recognized stack is found.
|
|
195
|
+
*/
|
|
196
|
+
export function detectStack(dir) {
|
|
197
|
+
for (const def of STACK_DEFINITIONS) {
|
|
198
|
+
// Check primary marker
|
|
199
|
+
if (!markerExists(dir, def.primaryMarker)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
// Check exclusion markers
|
|
203
|
+
if (def.excludeMarkers?.some(m => markerExists(dir, m))) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
// If we have a secondary marker requirement, check it
|
|
207
|
+
if (def.secondaryMarker) {
|
|
208
|
+
if (markerExists(dir, def.secondaryMarker)) {
|
|
209
|
+
return def.stack;
|
|
210
|
+
}
|
|
211
|
+
// Continue to check next definition (might be a fallback)
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
// No secondary marker required, this matches
|
|
215
|
+
return def.stack;
|
|
216
|
+
}
|
|
217
|
+
// Check for package.json without any lock file (default to npm)
|
|
218
|
+
if (markerExists(dir, 'package.json')) {
|
|
219
|
+
return 'node-npm';
|
|
220
|
+
}
|
|
221
|
+
// Check for pyproject.toml without poetry.lock (default to pip)
|
|
222
|
+
if (markerExists(dir, 'pyproject.toml')) {
|
|
223
|
+
return 'python-pip';
|
|
224
|
+
}
|
|
225
|
+
return 'unknown';
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Get default commands for a given tech stack.
|
|
229
|
+
*/
|
|
230
|
+
export function getDefaultCommands(stack) {
|
|
231
|
+
const def = STACK_DEFINITIONS.find(d => d.stack === stack);
|
|
232
|
+
return def?.commands ?? {};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Generate a human-readable name for a project based on its path and stack.
|
|
236
|
+
*/
|
|
237
|
+
function generateProjectName(projectPath, stack) {
|
|
238
|
+
if (projectPath === '.') {
|
|
239
|
+
return 'Root Project';
|
|
240
|
+
}
|
|
241
|
+
// Use the directory name as the base
|
|
242
|
+
const dirName = path.basename(projectPath);
|
|
243
|
+
// Capitalize first letter
|
|
244
|
+
const capitalizedName = dirName.charAt(0).toUpperCase() + dirName.slice(1);
|
|
245
|
+
// Add stack context for clarity
|
|
246
|
+
const stackLabels = {
|
|
247
|
+
'node-npm': 'Node.js',
|
|
248
|
+
'node-yarn': 'Node.js',
|
|
249
|
+
'node-pnpm': 'Node.js',
|
|
250
|
+
'node-bun': 'Bun',
|
|
251
|
+
'python-pip': 'Python',
|
|
252
|
+
'python-poetry': 'Python',
|
|
253
|
+
'python-uv': 'Python',
|
|
254
|
+
'rust-cargo': 'Rust',
|
|
255
|
+
'go-mod': 'Go',
|
|
256
|
+
'ruby-bundler': 'Ruby',
|
|
257
|
+
'java-maven': 'Java',
|
|
258
|
+
'java-gradle': 'Java',
|
|
259
|
+
'dotnet': '.NET',
|
|
260
|
+
};
|
|
261
|
+
const stackLabel = stackLabels[stack];
|
|
262
|
+
if (stackLabel) {
|
|
263
|
+
return `${capitalizedName} (${stackLabel})`;
|
|
264
|
+
}
|
|
265
|
+
return capitalizedName;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Expand glob-like patterns in subdirectory list.
|
|
269
|
+
* For example, "packages/*" becomes ["packages/foo", "packages/bar", ...].
|
|
270
|
+
*/
|
|
271
|
+
function expandSubdirectories(baseDir, patterns) {
|
|
272
|
+
const result = [];
|
|
273
|
+
for (const pattern of patterns) {
|
|
274
|
+
if (pattern.includes('*')) {
|
|
275
|
+
// Glob pattern - expand it
|
|
276
|
+
const [parentDir] = pattern.split('/*');
|
|
277
|
+
const fullParentPath = path.join(baseDir, parentDir);
|
|
278
|
+
if (existsSync(fullParentPath)) {
|
|
279
|
+
try {
|
|
280
|
+
const entries = readdirSync(fullParentPath);
|
|
281
|
+
for (const entry of entries) {
|
|
282
|
+
const entryPath = path.join(fullParentPath, entry);
|
|
283
|
+
if (statSync(entryPath).isDirectory()) {
|
|
284
|
+
result.push(path.join(parentDir, entry));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// Ignore permission errors
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
// Direct directory name
|
|
295
|
+
result.push(pattern);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Scan a repository and detect all projects.
|
|
302
|
+
* Checks both root and common subdirectories.
|
|
303
|
+
*
|
|
304
|
+
* @param repoRoot - Root directory of the repository
|
|
305
|
+
* @returns Array of detected project configurations
|
|
306
|
+
*/
|
|
307
|
+
export function detectProjects(repoRoot) {
|
|
308
|
+
const projects = [];
|
|
309
|
+
const processedPaths = new Set();
|
|
310
|
+
// Helper to add a project if it has a detectable stack
|
|
311
|
+
const addProject = (projectPath) => {
|
|
312
|
+
const absolutePath = path.isAbsolute(projectPath)
|
|
313
|
+
? projectPath
|
|
314
|
+
: path.join(repoRoot, projectPath);
|
|
315
|
+
const relativePath = path.relative(repoRoot, absolutePath) || '.';
|
|
316
|
+
// Skip if already processed
|
|
317
|
+
if (processedPaths.has(relativePath)) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
// Check if directory exists
|
|
321
|
+
if (!existsSync(absolutePath)) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
const stack = detectStack(absolutePath);
|
|
325
|
+
if (stack === 'unknown') {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
processedPaths.add(relativePath);
|
|
329
|
+
projects.push({
|
|
330
|
+
name: generateProjectName(relativePath, stack),
|
|
331
|
+
path: relativePath,
|
|
332
|
+
stack,
|
|
333
|
+
commands: getDefaultCommands(stack),
|
|
334
|
+
});
|
|
335
|
+
return true;
|
|
336
|
+
};
|
|
337
|
+
// First, check the root directory
|
|
338
|
+
addProject(repoRoot);
|
|
339
|
+
// Then check common subdirectories
|
|
340
|
+
const subdirs = expandSubdirectories(repoRoot, SUBDIRECTORY_PATTERNS);
|
|
341
|
+
for (const subdir of subdirs) {
|
|
342
|
+
addProject(path.join(repoRoot, subdir));
|
|
343
|
+
}
|
|
344
|
+
return projects;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get the primary project from a list of detected projects.
|
|
348
|
+
* Returns the root project if it exists, otherwise the first project.
|
|
349
|
+
*/
|
|
350
|
+
export function getPrimaryProject(projects) {
|
|
351
|
+
// Prefer root project
|
|
352
|
+
const rootProject = projects.find(p => p.path === '.');
|
|
353
|
+
if (rootProject) {
|
|
354
|
+
return rootProject;
|
|
355
|
+
}
|
|
356
|
+
// Otherwise return first detected project
|
|
357
|
+
return projects[0];
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Format detected projects for CLI display.
|
|
361
|
+
*/
|
|
362
|
+
export function formatDetectedProjects(projects) {
|
|
363
|
+
if (projects.length === 0) {
|
|
364
|
+
return 'No projects detected.';
|
|
365
|
+
}
|
|
366
|
+
const lines = ['Detected project structure:'];
|
|
367
|
+
for (const project of projects) {
|
|
368
|
+
const stackDisplay = formatStackDisplay(project.stack);
|
|
369
|
+
lines.push(` - ${project.path}: ${stackDisplay}`);
|
|
370
|
+
}
|
|
371
|
+
return lines.join('\n');
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Format a tech stack for human-readable display.
|
|
375
|
+
*/
|
|
376
|
+
function formatStackDisplay(stack) {
|
|
377
|
+
const labels = {
|
|
378
|
+
'node-npm': 'Node.js (npm)',
|
|
379
|
+
'node-yarn': 'Node.js (Yarn)',
|
|
380
|
+
'node-pnpm': 'Node.js (pnpm)',
|
|
381
|
+
'node-bun': 'Bun',
|
|
382
|
+
'python-pip': 'Python (pip)',
|
|
383
|
+
'python-poetry': 'Python (Poetry)',
|
|
384
|
+
'python-uv': 'Python (uv)',
|
|
385
|
+
'rust-cargo': 'Rust (Cargo)',
|
|
386
|
+
'go-mod': 'Go',
|
|
387
|
+
'ruby-bundler': 'Ruby (Bundler)',
|
|
388
|
+
'java-maven': 'Java (Maven)',
|
|
389
|
+
'java-gradle': 'Java (Gradle)',
|
|
390
|
+
'dotnet': '.NET',
|
|
391
|
+
'unknown': 'Unknown',
|
|
392
|
+
};
|
|
393
|
+
return labels[stack] || stack;
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=stack-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-detector.js","sourceRoot":"","sources":["../../src/core/stack-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,42 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each story execution creates a new timestamped log file with dual output
|
|
5
5
|
* (console + file) for debugging and audit trail.
|
|
6
|
+
*
|
|
7
|
+
* Features correlation IDs for cross-process tracing:
|
|
8
|
+
* - Generate unique trace IDs for each execution
|
|
9
|
+
* - Propagate IDs via environment variables between processes
|
|
10
|
+
* - Include IDs in all log entries for easy filtering
|
|
6
11
|
*/
|
|
7
12
|
import { LogLevel } from '../types/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* Generate a short, unique correlation ID for tracing
|
|
15
|
+
*
|
|
16
|
+
* Format: <timestamp-base36>-<random-hex>
|
|
17
|
+
* Example: "lxyz12-a3f9"
|
|
18
|
+
*
|
|
19
|
+
* This ID can be passed between processes via environment variables
|
|
20
|
+
* and included in log entries for cross-process debugging.
|
|
21
|
+
*
|
|
22
|
+
* @returns A unique correlation ID string
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateCorrelationId(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Get the correlation ID from environment or generate a new one
|
|
27
|
+
*
|
|
28
|
+
* Checks AI_SDLC_CORRELATION_ID environment variable first.
|
|
29
|
+
* If not set, generates a new ID.
|
|
30
|
+
*
|
|
31
|
+
* @returns Correlation ID string
|
|
32
|
+
*/
|
|
33
|
+
export declare function getOrCreateCorrelationId(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Set correlation ID in environment for child processes
|
|
36
|
+
*
|
|
37
|
+
* Call this before spawning child processes to propagate the trace ID.
|
|
38
|
+
*
|
|
39
|
+
* @param correlationId - The correlation ID to set
|
|
40
|
+
*/
|
|
41
|
+
export declare function setCorrelationIdEnv(correlationId: string): void;
|
|
8
42
|
/**
|
|
9
43
|
* Per-story logger that writes to timestamped files
|
|
10
44
|
*
|
|
@@ -12,6 +46,7 @@ import { LogLevel } from '../types/index.js';
|
|
|
12
46
|
* - Dual output: console + timestamped file per execution
|
|
13
47
|
* - Automatic log rotation (keeps last N logs per story)
|
|
14
48
|
* - Crash-safe synchronous writes
|
|
49
|
+
* - Correlation IDs for cross-process tracing
|
|
15
50
|
* - Location: stories/{id}/logs/{timestamp}.log
|
|
16
51
|
*/
|
|
17
52
|
export declare class StoryLogger {
|
|
@@ -19,20 +54,25 @@ export declare class StoryLogger {
|
|
|
19
54
|
private storyId;
|
|
20
55
|
private logPath;
|
|
21
56
|
private closed;
|
|
57
|
+
private correlationId;
|
|
22
58
|
/**
|
|
23
59
|
* Initialize a per-story logger
|
|
24
60
|
*
|
|
25
61
|
* @param storyId - Story ID (sanitized automatically)
|
|
26
62
|
* @param sdlcRoot - Path to .ai-sdlc directory
|
|
27
63
|
* @param maxLogs - Maximum number of log files to retain per story (default: 5)
|
|
64
|
+
* @param correlationId - Optional correlation ID for tracing (auto-generated if not provided)
|
|
28
65
|
*/
|
|
29
|
-
constructor(storyId: string, sdlcRoot: string, maxLogs?: number);
|
|
66
|
+
constructor(storyId: string, sdlcRoot: string, maxLogs?: number, correlationId?: string);
|
|
30
67
|
/**
|
|
31
68
|
* Log a message with specified level
|
|
32
69
|
*
|
|
33
70
|
* Writes to both console and file. Sanitizes message to prevent issues
|
|
34
71
|
* with very long lines or non-printable characters.
|
|
35
72
|
*
|
|
73
|
+
* Log entry format includes correlation ID for cross-process tracing:
|
|
74
|
+
* [timestamp] [correlationId] [level] message
|
|
75
|
+
*
|
|
36
76
|
* @param level - Log level (INFO, AGENT, ERROR, WARN, DEBUG)
|
|
37
77
|
* @param message - Message to log
|
|
38
78
|
*/
|
|
@@ -52,6 +92,16 @@ export declare class StoryLogger {
|
|
|
52
92
|
* @returns Absolute path to the current log file
|
|
53
93
|
*/
|
|
54
94
|
getLogPath(): string;
|
|
95
|
+
/**
|
|
96
|
+
* Get the correlation ID for this logger session
|
|
97
|
+
*
|
|
98
|
+
* Use this ID to correlate logs across multiple processes.
|
|
99
|
+
* Pass it to child processes via environment or log it for
|
|
100
|
+
* later cross-referencing.
|
|
101
|
+
*
|
|
102
|
+
* @returns The correlation ID string
|
|
103
|
+
*/
|
|
104
|
+
getCorrelationId(): string;
|
|
55
105
|
/**
|
|
56
106
|
* Sanitize log message to prevent issues
|
|
57
107
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"story-logger.d.ts","sourceRoot":"","sources":["../../src/core/story-logger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"story-logger.d.ts","sourceRoot":"","sources":["../../src/core/story-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAkB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAK7D;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAI9C;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED;;;;;;;;;GASG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;;;OAOG;gBACS,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,MAAU,EAAE,aAAa,CAAC,EAAE,MAAM;IA4C1F;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAwC3C;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;;;;;OAQG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;CAsBtB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBjF;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAKzF;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAiC9C"}
|
|
@@ -3,12 +3,56 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Each story execution creates a new timestamped log file with dual output
|
|
5
5
|
* (console + file) for debugging and audit trail.
|
|
6
|
+
*
|
|
7
|
+
* Features correlation IDs for cross-process tracing:
|
|
8
|
+
* - Generate unique trace IDs for each execution
|
|
9
|
+
* - Propagate IDs via environment variables between processes
|
|
10
|
+
* - Include IDs in all log entries for easy filtering
|
|
6
11
|
*/
|
|
7
12
|
import fs from 'fs';
|
|
8
13
|
import path from 'path';
|
|
14
|
+
import crypto from 'crypto';
|
|
9
15
|
import { sanitizeStoryId } from './story.js';
|
|
10
16
|
import { STORIES_FOLDER } from '../types/index.js';
|
|
11
17
|
const MAX_MESSAGE_LENGTH = 10 * 1024; // 10KB per log entry
|
|
18
|
+
const CORRELATION_ID_ENV_VAR = 'AI_SDLC_CORRELATION_ID';
|
|
19
|
+
/**
|
|
20
|
+
* Generate a short, unique correlation ID for tracing
|
|
21
|
+
*
|
|
22
|
+
* Format: <timestamp-base36>-<random-hex>
|
|
23
|
+
* Example: "lxyz12-a3f9"
|
|
24
|
+
*
|
|
25
|
+
* This ID can be passed between processes via environment variables
|
|
26
|
+
* and included in log entries for cross-process debugging.
|
|
27
|
+
*
|
|
28
|
+
* @returns A unique correlation ID string
|
|
29
|
+
*/
|
|
30
|
+
export function generateCorrelationId() {
|
|
31
|
+
const timestamp = Date.now().toString(36);
|
|
32
|
+
const random = crypto.randomBytes(2).toString('hex');
|
|
33
|
+
return `${timestamp}-${random}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the correlation ID from environment or generate a new one
|
|
37
|
+
*
|
|
38
|
+
* Checks AI_SDLC_CORRELATION_ID environment variable first.
|
|
39
|
+
* If not set, generates a new ID.
|
|
40
|
+
*
|
|
41
|
+
* @returns Correlation ID string
|
|
42
|
+
*/
|
|
43
|
+
export function getOrCreateCorrelationId() {
|
|
44
|
+
return process.env[CORRELATION_ID_ENV_VAR] || generateCorrelationId();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set correlation ID in environment for child processes
|
|
48
|
+
*
|
|
49
|
+
* Call this before spawning child processes to propagate the trace ID.
|
|
50
|
+
*
|
|
51
|
+
* @param correlationId - The correlation ID to set
|
|
52
|
+
*/
|
|
53
|
+
export function setCorrelationIdEnv(correlationId) {
|
|
54
|
+
process.env[CORRELATION_ID_ENV_VAR] = correlationId;
|
|
55
|
+
}
|
|
12
56
|
/**
|
|
13
57
|
* Per-story logger that writes to timestamped files
|
|
14
58
|
*
|
|
@@ -16,6 +60,7 @@ const MAX_MESSAGE_LENGTH = 10 * 1024; // 10KB per log entry
|
|
|
16
60
|
* - Dual output: console + timestamped file per execution
|
|
17
61
|
* - Automatic log rotation (keeps last N logs per story)
|
|
18
62
|
* - Crash-safe synchronous writes
|
|
63
|
+
* - Correlation IDs for cross-process tracing
|
|
19
64
|
* - Location: stories/{id}/logs/{timestamp}.log
|
|
20
65
|
*/
|
|
21
66
|
export class StoryLogger {
|
|
@@ -23,14 +68,20 @@ export class StoryLogger {
|
|
|
23
68
|
storyId;
|
|
24
69
|
logPath;
|
|
25
70
|
closed = false;
|
|
71
|
+
correlationId;
|
|
26
72
|
/**
|
|
27
73
|
* Initialize a per-story logger
|
|
28
74
|
*
|
|
29
75
|
* @param storyId - Story ID (sanitized automatically)
|
|
30
76
|
* @param sdlcRoot - Path to .ai-sdlc directory
|
|
31
77
|
* @param maxLogs - Maximum number of log files to retain per story (default: 5)
|
|
78
|
+
* @param correlationId - Optional correlation ID for tracing (auto-generated if not provided)
|
|
32
79
|
*/
|
|
33
|
-
constructor(storyId, sdlcRoot, maxLogs = 5) {
|
|
80
|
+
constructor(storyId, sdlcRoot, maxLogs = 5, correlationId) {
|
|
81
|
+
// Initialize correlation ID (from param, env, or generate new)
|
|
82
|
+
this.correlationId = correlationId || getOrCreateCorrelationId();
|
|
83
|
+
// Set in env for child processes
|
|
84
|
+
setCorrelationIdEnv(this.correlationId);
|
|
34
85
|
// SECURITY: Sanitize story ID to prevent path traversal
|
|
35
86
|
this.storyId = sanitizeStoryId(storyId);
|
|
36
87
|
const logDir = path.join(sdlcRoot, STORIES_FOLDER, this.storyId, 'logs');
|
|
@@ -67,6 +118,9 @@ export class StoryLogger {
|
|
|
67
118
|
* Writes to both console and file. Sanitizes message to prevent issues
|
|
68
119
|
* with very long lines or non-printable characters.
|
|
69
120
|
*
|
|
121
|
+
* Log entry format includes correlation ID for cross-process tracing:
|
|
122
|
+
* [timestamp] [correlationId] [level] message
|
|
123
|
+
*
|
|
70
124
|
* @param level - Log level (INFO, AGENT, ERROR, WARN, DEBUG)
|
|
71
125
|
* @param message - Message to log
|
|
72
126
|
*/
|
|
@@ -77,9 +131,9 @@ export class StoryLogger {
|
|
|
77
131
|
}
|
|
78
132
|
// Sanitize and truncate message
|
|
79
133
|
const sanitized = this.sanitizeMessage(message);
|
|
80
|
-
// Format log entry with ISO 8601 timestamp
|
|
134
|
+
// Format log entry with ISO 8601 timestamp and correlation ID
|
|
81
135
|
const timestamp = new Date().toISOString();
|
|
82
|
-
const entry = `[${timestamp}] [${level}] ${sanitized}\n`;
|
|
136
|
+
const entry = `[${timestamp}] [${this.correlationId}] [${level}] ${sanitized}\n`;
|
|
83
137
|
// Write to file synchronously (crash-safe)
|
|
84
138
|
try {
|
|
85
139
|
this.logStream.write(entry);
|
|
@@ -135,6 +189,18 @@ export class StoryLogger {
|
|
|
135
189
|
getLogPath() {
|
|
136
190
|
return this.logPath;
|
|
137
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Get the correlation ID for this logger session
|
|
194
|
+
*
|
|
195
|
+
* Use this ID to correlate logs across multiple processes.
|
|
196
|
+
* Pass it to child processes via environment or log it for
|
|
197
|
+
* later cross-referencing.
|
|
198
|
+
*
|
|
199
|
+
* @returns The correlation ID string
|
|
200
|
+
*/
|
|
201
|
+
getCorrelationId() {
|
|
202
|
+
return this.correlationId;
|
|
203
|
+
}
|
|
138
204
|
/**
|
|
139
205
|
* Sanitize log message to prevent issues
|
|
140
206
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"story-logger.js","sourceRoot":"","sources":["../../src/core/story-logger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"story-logger.js","sourceRoot":"","sources":["../../src/core/story-logger.ts"],"names":[],"mappings":"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"}
|