ai-sdlc 0.2.0-alpha.9 → 0.2.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/README.md +53 -1058
- package/dist/agents/implementation.d.ts +6 -0
- package/dist/agents/implementation.d.ts.map +1 -1
- package/dist/agents/implementation.js +87 -13
- package/dist/agents/implementation.js.map +1 -1
- package/dist/agents/planning.d.ts.map +1 -1
- package/dist/agents/planning.js +22 -3
- package/dist/agents/planning.js.map +1 -1
- package/dist/agents/refinement.d.ts.map +1 -1
- package/dist/agents/refinement.js +22 -3
- package/dist/agents/refinement.js.map +1 -1
- package/dist/agents/research.d.ts +85 -1
- package/dist/agents/research.d.ts.map +1 -1
- package/dist/agents/research.js +506 -16
- package/dist/agents/research.js.map +1 -1
- package/dist/agents/review.d.ts +67 -2
- package/dist/agents/review.d.ts.map +1 -1
- package/dist/agents/review.js +477 -68
- package/dist/agents/review.js.map +1 -1
- package/dist/agents/rework.d.ts.map +1 -1
- package/dist/agents/rework.js +22 -3
- package/dist/agents/rework.js.map +1 -1
- package/dist/agents/state-assessor.d.ts +3 -3
- package/dist/agents/state-assessor.d.ts.map +1 -1
- package/dist/agents/state-assessor.js +6 -6
- package/dist/agents/state-assessor.js.map +1 -1
- package/dist/agents/test-pattern-detector.d.ts +49 -0
- package/dist/agents/test-pattern-detector.d.ts.map +1 -0
- package/dist/agents/test-pattern-detector.js +273 -0
- package/dist/agents/test-pattern-detector.js.map +1 -0
- package/dist/agents/verification.d.ts +11 -0
- package/dist/agents/verification.d.ts.map +1 -1
- package/dist/agents/verification.js +74 -1
- package/dist/agents/verification.js.map +1 -1
- package/dist/cli/commands/migrate.js +1 -1
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands.d.ts +43 -3
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +588 -150
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +20 -3
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +18 -6
- package/dist/cli/runner.js.map +1 -1
- package/dist/core/auth.d.ts +43 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +105 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/client.d.ts +6 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +57 -3
- package/dist/core/client.js.map +1 -1
- package/dist/core/config.d.ts +5 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +27 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/conflict-detector.d.ts +108 -0
- package/dist/core/conflict-detector.d.ts.map +1 -0
- package/dist/core/conflict-detector.js +413 -0
- package/dist/core/conflict-detector.js.map +1 -0
- package/dist/core/git-utils.d.ts +10 -1
- package/dist/core/git-utils.d.ts.map +1 -1
- package/dist/core/git-utils.js +55 -4
- package/dist/core/git-utils.js.map +1 -1
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +17 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/kanban.d.ts +1 -1
- package/dist/core/kanban.d.ts.map +1 -1
- package/dist/core/kanban.js +3 -3
- package/dist/core/kanban.js.map +1 -1
- package/dist/core/logger.d.ts +92 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +221 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/story-logger.d.ts +102 -0
- package/dist/core/story-logger.d.ts.map +1 -0
- package/dist/core/story-logger.js +265 -0
- package/dist/core/story-logger.js.map +1 -0
- package/dist/core/story.d.ts +79 -20
- package/dist/core/story.d.ts.map +1 -1
- package/dist/core/story.js +221 -39
- package/dist/core/story.js.map +1 -1
- package/dist/core/workflow-state.d.ts +45 -6
- package/dist/core/workflow-state.d.ts.map +1 -1
- package/dist/core/workflow-state.js +201 -12
- package/dist/core/workflow-state.js.map +1 -1
- package/dist/core/worktree.d.ts +9 -0
- package/dist/core/worktree.d.ts.map +1 -1
- package/dist/core/worktree.js +52 -1
- package/dist/core/worktree.js.map +1 -1
- package/dist/index.js +112 -6
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +123 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-state.d.ts","sourceRoot":"","sources":["../../src/core/workflow-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAE9B,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-state.d.ts","sourceRoot":"","sources":["../../src/core/workflow-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAE9B,MAAM,4BAA4B,CAAC;AAQpC;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,sBAAsB,EAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAuCxC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,GAAG,6BAA6B,CAyC/E;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1F;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAG5E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA0IjD"}
|
|
@@ -8,12 +8,26 @@ import fs from 'fs';
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import crypto from 'crypto';
|
|
10
10
|
import writeFileAtomic from 'write-file-atomic';
|
|
11
|
+
import { STORIES_FOLDER } from '../types/index.js';
|
|
12
|
+
import { sanitizeStoryId } from './story.js';
|
|
13
|
+
import { getLogger } from './logger.js';
|
|
11
14
|
const STATE_FILE_NAME = '.workflow-state.json';
|
|
12
15
|
const CURRENT_VERSION = '1.0';
|
|
13
16
|
/**
|
|
14
|
-
* Get the path to the workflow state file
|
|
17
|
+
* Get the path to the workflow state file.
|
|
18
|
+
*
|
|
19
|
+
* SECURITY: storyId is sanitized using sanitizeStoryId() to prevent path traversal attacks.
|
|
20
|
+
* Never construct paths manually - always use this function to ensure proper sanitization.
|
|
21
|
+
*
|
|
22
|
+
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
23
|
+
* @param storyId - Optional story ID for per-story state isolation
|
|
24
|
+
* @returns Path to the workflow state file (story-specific or global)
|
|
15
25
|
*/
|
|
16
|
-
export function getStateFilePath(sdlcRoot) {
|
|
26
|
+
export function getStateFilePath(sdlcRoot, storyId) {
|
|
27
|
+
if (storyId) {
|
|
28
|
+
const sanitized = sanitizeStoryId(storyId);
|
|
29
|
+
return path.join(sdlcRoot, STORIES_FOLDER, sanitized, STATE_FILE_NAME);
|
|
30
|
+
}
|
|
17
31
|
return path.join(sdlcRoot, STATE_FILE_NAME);
|
|
18
32
|
}
|
|
19
33
|
/**
|
|
@@ -44,17 +58,33 @@ export function calculateStoryHash(storyPath) {
|
|
|
44
58
|
*
|
|
45
59
|
* @param state - The workflow execution state to save
|
|
46
60
|
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
61
|
+
* @param storyId - Optional story ID for per-story state isolation
|
|
47
62
|
*/
|
|
48
|
-
export async function saveWorkflowState(state, sdlcRoot) {
|
|
49
|
-
const
|
|
63
|
+
export async function saveWorkflowState(state, sdlcRoot, storyId) {
|
|
64
|
+
const logger = getLogger();
|
|
65
|
+
const statePath = getStateFilePath(sdlcRoot, storyId);
|
|
50
66
|
const stateJson = JSON.stringify(state, null, 2);
|
|
67
|
+
logger.debug('workflow-state', 'Saving workflow state', {
|
|
68
|
+
workflowId: state.workflowId,
|
|
69
|
+
storyId,
|
|
70
|
+
actionCount: state.completedActions.length,
|
|
71
|
+
});
|
|
51
72
|
try {
|
|
52
|
-
// Ensure the directory exists
|
|
53
|
-
|
|
73
|
+
// Ensure the directory exists (including story subdirectories)
|
|
74
|
+
const stateDir = path.dirname(statePath);
|
|
75
|
+
await fs.promises.mkdir(stateDir, { recursive: true });
|
|
54
76
|
// Write atomically to prevent corruption
|
|
55
77
|
await writeFileAtomic(statePath, stateJson, { encoding: 'utf-8' });
|
|
56
78
|
}
|
|
57
79
|
catch (error) {
|
|
80
|
+
// Specific permission error handling
|
|
81
|
+
if (error && typeof error === 'object' && 'code' in error) {
|
|
82
|
+
const code = error.code;
|
|
83
|
+
if (code === 'EACCES' || code === 'EPERM') {
|
|
84
|
+
throw new Error(`Permission denied: Cannot write workflow state to ${statePath}. ` +
|
|
85
|
+
`Check file permissions for the directory and ensure it is writable.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
58
88
|
throw new Error(`Failed to save workflow state: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
89
|
}
|
|
60
90
|
}
|
|
@@ -62,13 +92,16 @@ export async function saveWorkflowState(state, sdlcRoot) {
|
|
|
62
92
|
* Load workflow state from disk
|
|
63
93
|
*
|
|
64
94
|
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
95
|
+
* @param storyId - Optional story ID for per-story state isolation
|
|
65
96
|
* @returns The workflow state, or null if no state file exists
|
|
66
97
|
*/
|
|
67
|
-
export async function loadWorkflowState(sdlcRoot) {
|
|
68
|
-
const
|
|
98
|
+
export async function loadWorkflowState(sdlcRoot, storyId) {
|
|
99
|
+
const logger = getLogger();
|
|
100
|
+
const statePath = getStateFilePath(sdlcRoot, storyId);
|
|
69
101
|
try {
|
|
70
102
|
// Check if file exists
|
|
71
103
|
if (!fs.existsSync(statePath)) {
|
|
104
|
+
logger.debug('workflow-state', 'No workflow state found', { storyId });
|
|
72
105
|
return null;
|
|
73
106
|
}
|
|
74
107
|
// Read and parse the state file
|
|
@@ -79,10 +112,17 @@ export async function loadWorkflowState(sdlcRoot) {
|
|
|
79
112
|
if (!validation.valid) {
|
|
80
113
|
throw new Error(`Invalid state file: ${validation.errors.join(', ')}`);
|
|
81
114
|
}
|
|
115
|
+
logger.debug('workflow-state', 'Loaded workflow state', {
|
|
116
|
+
workflowId: state.workflowId,
|
|
117
|
+
storyId,
|
|
118
|
+
actionCount: state.completedActions.length,
|
|
119
|
+
ageMs: Date.now() - new Date(state.timestamp).getTime(),
|
|
120
|
+
});
|
|
82
121
|
return state;
|
|
83
122
|
}
|
|
84
123
|
catch (error) {
|
|
85
124
|
if (error instanceof SyntaxError) {
|
|
125
|
+
logger.error('workflow-state', 'Corrupted state file', { statePath });
|
|
86
126
|
throw new Error(`Corrupted workflow state file at ${statePath}. ` +
|
|
87
127
|
`Delete the file to start fresh: rm "${statePath}"`);
|
|
88
128
|
}
|
|
@@ -136,9 +176,10 @@ export function validateWorkflowState(state) {
|
|
|
136
176
|
* Clear workflow state (delete the state file)
|
|
137
177
|
*
|
|
138
178
|
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
179
|
+
* @param storyId - Optional story ID for per-story state isolation
|
|
139
180
|
*/
|
|
140
|
-
export async function clearWorkflowState(sdlcRoot) {
|
|
141
|
-
const statePath = getStateFilePath(sdlcRoot);
|
|
181
|
+
export async function clearWorkflowState(sdlcRoot, storyId) {
|
|
182
|
+
const statePath = getStateFilePath(sdlcRoot, storyId);
|
|
142
183
|
try {
|
|
143
184
|
if (fs.existsSync(statePath)) {
|
|
144
185
|
await fs.promises.unlink(statePath);
|
|
@@ -153,10 +194,158 @@ export async function clearWorkflowState(sdlcRoot) {
|
|
|
153
194
|
* Check if workflow state exists
|
|
154
195
|
*
|
|
155
196
|
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
197
|
+
* @param storyId - Optional story ID for per-story state isolation
|
|
156
198
|
* @returns True if state file exists
|
|
157
199
|
*/
|
|
158
|
-
export function hasWorkflowState(sdlcRoot) {
|
|
159
|
-
const statePath = getStateFilePath(sdlcRoot);
|
|
200
|
+
export function hasWorkflowState(sdlcRoot, storyId) {
|
|
201
|
+
const statePath = getStateFilePath(sdlcRoot, storyId);
|
|
160
202
|
return fs.existsSync(statePath);
|
|
161
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Migrate global workflow state to story-specific location.
|
|
206
|
+
*
|
|
207
|
+
* Call this function at CLI startup (before loading workflow state) to automatically
|
|
208
|
+
* move legacy global state files to the new per-story location.
|
|
209
|
+
*
|
|
210
|
+
* Migration behavior:
|
|
211
|
+
* - Extracts story ID from context.options.story, completedActions, or currentAction
|
|
212
|
+
* - Skips migration if workflow is currently in progress (currentAction set)
|
|
213
|
+
* - Skips migration if no story ID can be determined
|
|
214
|
+
* - Validates target file if it already exists before deleting global file
|
|
215
|
+
* - Deletes global file only after successful write to target location
|
|
216
|
+
*
|
|
217
|
+
* @param sdlcRoot - Path to the .ai-sdlc directory
|
|
218
|
+
* @returns Promise resolving to migration result object:
|
|
219
|
+
* - migrated: boolean - true if migration was performed, false if skipped
|
|
220
|
+
* - message: string - Human-readable description of what happened
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* const result = await migrateGlobalWorkflowState(sdlcRoot);
|
|
224
|
+
* if (result.migrated) {
|
|
225
|
+
* console.log(result.message); // "Successfully migrated workflow state to story S-0033"
|
|
226
|
+
* }
|
|
227
|
+
*/
|
|
228
|
+
export async function migrateGlobalWorkflowState(sdlcRoot) {
|
|
229
|
+
const globalStatePath = getStateFilePath(sdlcRoot);
|
|
230
|
+
// Check if global state file exists
|
|
231
|
+
if (!fs.existsSync(globalStatePath)) {
|
|
232
|
+
return { migrated: false, message: 'No global workflow state file found' };
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
// Read and parse the global state
|
|
236
|
+
const content = await fs.promises.readFile(globalStatePath, 'utf-8');
|
|
237
|
+
const state = JSON.parse(content);
|
|
238
|
+
// Check if workflow in progress IMMEDIATELY after reading state
|
|
239
|
+
if (state.currentAction) {
|
|
240
|
+
return {
|
|
241
|
+
migrated: false,
|
|
242
|
+
message: 'Skipping migration: workflow currently in progress. Complete or reset workflow before migrating.',
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// Determine the story ID from the state
|
|
246
|
+
let storyId;
|
|
247
|
+
// Try to get story ID from context.options.story first
|
|
248
|
+
if (state.context?.options?.story) {
|
|
249
|
+
storyId = state.context.options.story;
|
|
250
|
+
}
|
|
251
|
+
// Fallback to first completed action's storyId
|
|
252
|
+
if (!storyId && state.completedActions && state.completedActions.length > 0) {
|
|
253
|
+
const firstAction = state.completedActions[0];
|
|
254
|
+
if (firstAction && 'storyId' in firstAction) {
|
|
255
|
+
storyId = firstAction.storyId;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// If no story ID found, leave state in place
|
|
259
|
+
if (!storyId) {
|
|
260
|
+
return {
|
|
261
|
+
migrated: false,
|
|
262
|
+
message: 'Cannot migrate: no story ID found in workflow state. Manual migration required.',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// SECURITY: Sanitize story ID to prevent path traversal
|
|
266
|
+
let sanitizedStoryId;
|
|
267
|
+
try {
|
|
268
|
+
sanitizedStoryId = sanitizeStoryId(storyId);
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
return {
|
|
272
|
+
migrated: false,
|
|
273
|
+
message: `Cannot migrate: invalid story ID "${storyId}". ${error instanceof Error ? error.message : String(error)}`,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Check if target location already exists (idempotent)
|
|
277
|
+
const targetPath = getStateFilePath(sdlcRoot, sanitizedStoryId);
|
|
278
|
+
if (fs.existsSync(targetPath)) {
|
|
279
|
+
// Validate existing target is not corrupt before deleting global backup
|
|
280
|
+
try {
|
|
281
|
+
const targetContent = await fs.promises.readFile(targetPath, 'utf-8');
|
|
282
|
+
const targetState = JSON.parse(targetContent);
|
|
283
|
+
const validation = validateWorkflowState(targetState);
|
|
284
|
+
if (!validation.valid) {
|
|
285
|
+
return {
|
|
286
|
+
migrated: false,
|
|
287
|
+
message: `Target state file exists but is invalid. Keeping global file as backup. Manual intervention required. Errors: ${validation.errors.join(', ')}`,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// Target is valid, safe to delete global
|
|
291
|
+
await fs.promises.unlink(globalStatePath);
|
|
292
|
+
return {
|
|
293
|
+
migrated: true,
|
|
294
|
+
message: `Global workflow state already migrated to story ${sanitizedStoryId}. Removed duplicate global file.`,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
return {
|
|
299
|
+
migrated: false,
|
|
300
|
+
message: `Target state file exists but is corrupted. Keeping global file as backup. Manual intervention required. Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// Create target directory
|
|
305
|
+
const targetDir = path.dirname(targetPath);
|
|
306
|
+
await fs.promises.mkdir(targetDir, { recursive: true });
|
|
307
|
+
// Write to target location atomically
|
|
308
|
+
const stateJson = JSON.stringify(state, null, 2);
|
|
309
|
+
await writeFileAtomic(targetPath, stateJson, { encoding: 'utf-8' });
|
|
310
|
+
// Verify target file was created successfully
|
|
311
|
+
if (!fs.existsSync(targetPath)) {
|
|
312
|
+
throw new Error('Target state file was not created successfully');
|
|
313
|
+
}
|
|
314
|
+
// Delete global file only after successful write
|
|
315
|
+
await fs.promises.unlink(globalStatePath);
|
|
316
|
+
return {
|
|
317
|
+
migrated: true,
|
|
318
|
+
message: `Successfully migrated workflow state from global to story-specific location: ${sanitizedStoryId}`,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
// Specific error handling for common cases
|
|
323
|
+
if (error && typeof error === 'object' && 'code' in error) {
|
|
324
|
+
const code = error.code;
|
|
325
|
+
if (code === 'ENOENT') {
|
|
326
|
+
return {
|
|
327
|
+
migrated: false,
|
|
328
|
+
message: 'Global state file disappeared during migration. No action taken.',
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
if (code === 'EACCES' || code === 'EPERM') {
|
|
332
|
+
return {
|
|
333
|
+
migrated: false,
|
|
334
|
+
message: `Permission denied during migration. Check file permissions for: ${globalStatePath}`,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (error instanceof SyntaxError) {
|
|
339
|
+
return {
|
|
340
|
+
migrated: false,
|
|
341
|
+
message: 'Global state file contains invalid JSON. Manual migration required.',
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
345
|
+
return {
|
|
346
|
+
migrated: false,
|
|
347
|
+
message: `Migration failed: ${errorMsg}`,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
162
351
|
//# sourceMappingURL=workflow-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-state.js","sourceRoot":"","sources":["../../src/core/workflow-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,eAAe,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-state.js","sourceRoot":"","sources":["../../src/core/workflow-state.ts"],"names":[],"mappings":"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"}
|
package/dist/core/worktree.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export declare class GitWorktreeService {
|
|
|
40
40
|
/**
|
|
41
41
|
* Validate that a worktree can be created
|
|
42
42
|
* Checks for uncommitted changes in the working directory
|
|
43
|
+
* Note: Changes in .ai-sdlc/ directory are excluded since they're expected
|
|
44
|
+
* during normal workflow (story file updates, etc.)
|
|
43
45
|
*/
|
|
44
46
|
validateCanCreateWorktree(): WorktreeValidationResult;
|
|
45
47
|
/**
|
|
@@ -53,6 +55,13 @@ export declare class GitWorktreeService {
|
|
|
53
55
|
* @throws Error if worktree creation fails
|
|
54
56
|
*/
|
|
55
57
|
create(options: WorktreeOptions): string;
|
|
58
|
+
/**
|
|
59
|
+
* Install npm dependencies in a worktree
|
|
60
|
+
* Detects the package manager (npm/yarn/pnpm) and runs the appropriate install command
|
|
61
|
+
* @param worktreePath - Path to the worktree
|
|
62
|
+
* @throws Error if installation fails
|
|
63
|
+
*/
|
|
64
|
+
installDependencies(worktreePath: string): void;
|
|
56
65
|
/**
|
|
57
66
|
* List all ai-sdlc managed worktrees
|
|
58
67
|
* @returns Array of WorktreeInfo objects for worktrees in the basePath
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/core/worktree.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/core/worktree.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKjD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4BD;;GAEG;AACH,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,gBAAgB;gBADhB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM;IAGlC;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAItD;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpD;;;;OAIG;IACH,gBAAgB,IAAI,MAAM;IA4B1B;;;;;OAKG;IACH,yBAAyB,IAAI,wBAAwB;IAerD;;OAEG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM;IA4CxC;;;;;OAKG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAgC/C;;;OAGG;IACH,IAAI,IAAI,YAAY,EAAE;IA8CtB;;;;OAIG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;CAmBnC"}
|
package/dist/core/worktree.js
CHANGED
|
@@ -2,6 +2,8 @@ import { spawnSync } from 'child_process';
|
|
|
2
2
|
import { existsSync } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { isCleanWorkingDirectory } from './git-utils.js';
|
|
5
|
+
/** Default patterns to exclude from working directory cleanliness checks */
|
|
6
|
+
const DEFAULT_EXCLUDE_PATTERNS = ['.ai-sdlc/**'];
|
|
5
7
|
/**
|
|
6
8
|
* Error messages used by the worktree service
|
|
7
9
|
*/
|
|
@@ -16,6 +18,15 @@ const ERROR_MESSAGES = {
|
|
|
16
18
|
WORKTREE_HAS_CHANGES: 'Worktree has uncommitted changes. Use --force to remove.',
|
|
17
19
|
LIST_FAILED: 'Failed to list worktrees',
|
|
18
20
|
REMOVE_FAILED: 'Failed to remove worktree',
|
|
21
|
+
INSTALL_FAILED: 'Failed to install dependencies',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Lock file to package manager mapping
|
|
25
|
+
*/
|
|
26
|
+
const LOCK_FILE_TO_PM = {
|
|
27
|
+
'package-lock.json': 'npm',
|
|
28
|
+
'yarn.lock': 'yarn',
|
|
29
|
+
'pnpm-lock.yaml': 'pnpm',
|
|
19
30
|
};
|
|
20
31
|
/**
|
|
21
32
|
* Service for managing git worktrees for isolated story execution
|
|
@@ -72,9 +83,14 @@ export class GitWorktreeService {
|
|
|
72
83
|
/**
|
|
73
84
|
* Validate that a worktree can be created
|
|
74
85
|
* Checks for uncommitted changes in the working directory
|
|
86
|
+
* Note: Changes in .ai-sdlc/ directory are excluded since they're expected
|
|
87
|
+
* during normal workflow (story file updates, etc.)
|
|
75
88
|
*/
|
|
76
89
|
validateCanCreateWorktree() {
|
|
77
|
-
|
|
90
|
+
const cleanCheckOptions = {
|
|
91
|
+
excludePatterns: DEFAULT_EXCLUDE_PATTERNS,
|
|
92
|
+
};
|
|
93
|
+
if (!isCleanWorkingDirectory(this.projectRoot, cleanCheckOptions)) {
|
|
78
94
|
return {
|
|
79
95
|
valid: false,
|
|
80
96
|
error: ERROR_MESSAGES.UNCOMMITTED_CHANGES,
|
|
@@ -122,8 +138,43 @@ export class GitWorktreeService {
|
|
|
122
138
|
// Generic error with stderr details
|
|
123
139
|
throw new Error(`${ERROR_MESSAGES.CREATE_FAILED}: ${stderr}`);
|
|
124
140
|
}
|
|
141
|
+
// Install dependencies in the new worktree
|
|
142
|
+
this.installDependencies(worktreePath);
|
|
125
143
|
return worktreePath;
|
|
126
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Install npm dependencies in a worktree
|
|
147
|
+
* Detects the package manager (npm/yarn/pnpm) and runs the appropriate install command
|
|
148
|
+
* @param worktreePath - Path to the worktree
|
|
149
|
+
* @throws Error if installation fails
|
|
150
|
+
*/
|
|
151
|
+
installDependencies(worktreePath) {
|
|
152
|
+
const packageJsonPath = path.join(worktreePath, 'package.json');
|
|
153
|
+
// Skip if not a Node.js project
|
|
154
|
+
if (!existsSync(packageJsonPath)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Detect package manager from lock file
|
|
158
|
+
let packageManager = 'npm'; // default
|
|
159
|
+
for (const [lockFile, pm] of Object.entries(LOCK_FILE_TO_PM)) {
|
|
160
|
+
if (existsSync(path.join(worktreePath, lockFile))) {
|
|
161
|
+
packageManager = pm;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Run install command
|
|
166
|
+
const result = spawnSync(packageManager, ['install'], {
|
|
167
|
+
cwd: worktreePath,
|
|
168
|
+
encoding: 'utf-8',
|
|
169
|
+
shell: false,
|
|
170
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
171
|
+
timeout: 120000, // 2 minute timeout
|
|
172
|
+
});
|
|
173
|
+
if (result.status !== 0) {
|
|
174
|
+
const stderr = result.stderr?.toString() || '';
|
|
175
|
+
throw new Error(`${ERROR_MESSAGES.INSTALL_FAILED}: ${stderr}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
127
178
|
/**
|
|
128
179
|
* List all ai-sdlc managed worktrees
|
|
129
180
|
* @returns Array of WorktreeInfo objects for worktrees in the basePath
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/core/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/core/worktree.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
+
import { createRequire } from 'module';
|
|
3
4
|
import { init, status, add, run, details, unblock, migrate, listWorktrees, addWorktree, removeWorktree } from './cli/commands.js';
|
|
4
5
|
import { hasApiKey } from './core/auth.js';
|
|
5
|
-
import { loadConfig, saveConfig } from './core/config.js';
|
|
6
|
+
import { loadConfig, saveConfig, DEFAULT_LOGGING_CONFIG, getSdlcRoot } from './core/config.js';
|
|
6
7
|
import { getThemedChalk } from './core/theme.js';
|
|
8
|
+
import { initLogger, getLogger } from './core/logger.js';
|
|
9
|
+
import { getLatestLogPath, readLastLines, tailLog } from './core/story-logger.js';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
const packageJson = require('../package.json');
|
|
7
14
|
// Check for API key when running commands that need it
|
|
8
15
|
function checkApiKey() {
|
|
9
16
|
if (!hasApiKey()) {
|
|
@@ -24,7 +31,7 @@ const program = new Command();
|
|
|
24
31
|
program
|
|
25
32
|
.name('ai-sdlc')
|
|
26
33
|
.description('Agent-first SDLC workflow manager')
|
|
27
|
-
.version(
|
|
34
|
+
.version(packageJson.version);
|
|
28
35
|
program
|
|
29
36
|
.command('init')
|
|
30
37
|
.description('Initialize .ai-sdlc folder structure')
|
|
@@ -35,9 +42,10 @@ program
|
|
|
35
42
|
.option('--active', 'Hide done stories from output')
|
|
36
43
|
.action((options) => status(options));
|
|
37
44
|
program
|
|
38
|
-
.command('add
|
|
45
|
+
.command('add [title]')
|
|
39
46
|
.description('Add a new story to the backlog')
|
|
40
|
-
.
|
|
47
|
+
.option('-f, --file <path>', 'Create story from file (supports .md, .txt, .markdown)')
|
|
48
|
+
.action((title, options) => add(title, options));
|
|
41
49
|
program
|
|
42
50
|
.command('details <id>')
|
|
43
51
|
.alias('d')
|
|
@@ -66,16 +74,50 @@ program
|
|
|
66
74
|
.option('--max-iterations <number>', 'Maximum retry iterations (default: infinite)')
|
|
67
75
|
.option('--watch', 'Run in daemon mode, continuously processing backlog')
|
|
68
76
|
.option('-v, --verbose', 'Show detailed daemon output (use with --watch)')
|
|
69
|
-
.option('--force', 'Skip git validation checks (use with caution)')
|
|
77
|
+
.option('--force', 'Skip git validation and conflict checks (use with caution)')
|
|
70
78
|
.option('--worktree', 'Create isolated git worktree for story execution (requires --story)')
|
|
71
79
|
.option('--no-worktree', 'Disable worktree even when enabled in config')
|
|
80
|
+
.option('--log-level <level>', 'Set log verbosity (debug, info, warn, error)', 'info')
|
|
72
81
|
.action((options) => {
|
|
73
82
|
if (!options.dryRun && !options.watch) {
|
|
74
83
|
checkApiKey();
|
|
75
84
|
}
|
|
85
|
+
// Initialize logger with config and CLI override
|
|
86
|
+
const config = loadConfig();
|
|
87
|
+
const logConfig = {
|
|
88
|
+
...DEFAULT_LOGGING_CONFIG,
|
|
89
|
+
...config.logging,
|
|
90
|
+
};
|
|
91
|
+
// CLI --log-level overrides config
|
|
92
|
+
if (options.logLevel) {
|
|
93
|
+
const validLevels = ['debug', 'info', 'warn', 'error'];
|
|
94
|
+
if (validLevels.includes(options.logLevel)) {
|
|
95
|
+
logConfig.level = options.logLevel;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const c = getThemedChalk(config);
|
|
99
|
+
console.log(c.warning(`Invalid log level "${options.logLevel}", using "${logConfig.level}"`));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
initLogger(process.cwd(), logConfig);
|
|
103
|
+
// Log startup information
|
|
104
|
+
const logger = getLogger();
|
|
105
|
+
logger.info('cli', 'ai-sdlc started', {
|
|
106
|
+
version: packageJson.version,
|
|
107
|
+
command: 'run',
|
|
108
|
+
options: {
|
|
109
|
+
auto: options.auto,
|
|
110
|
+
dryRun: options.dryRun,
|
|
111
|
+
continue: options.continue,
|
|
112
|
+
story: options.story,
|
|
113
|
+
step: options.step,
|
|
114
|
+
worktree: options.worktree,
|
|
115
|
+
watch: options.watch,
|
|
116
|
+
logLevel: logConfig.level,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
76
119
|
// Validate --worktree requires --story
|
|
77
120
|
if (options.worktree && !options.story) {
|
|
78
|
-
const config = loadConfig();
|
|
79
121
|
const c = getThemedChalk(config);
|
|
80
122
|
console.log(c.error('Error: --worktree requires --story flag'));
|
|
81
123
|
process.exit(1);
|
|
@@ -123,6 +165,70 @@ program
|
|
|
123
165
|
console.log(c.dim('Available keys: theme'));
|
|
124
166
|
}
|
|
125
167
|
});
|
|
168
|
+
// Logs command
|
|
169
|
+
program
|
|
170
|
+
.command('logs <storyId>')
|
|
171
|
+
.description('View logs for a story')
|
|
172
|
+
.option('-t, --tail', 'Follow log output (like tail -f)')
|
|
173
|
+
.option('-n, --lines <n>', 'Number of lines to show', '50')
|
|
174
|
+
.option('-f, --file <timestamp>', 'View specific log file by timestamp (e.g., 2026-01-15T10-30-00)')
|
|
175
|
+
.action(async (storyId, options) => {
|
|
176
|
+
try {
|
|
177
|
+
const config = loadConfig();
|
|
178
|
+
const c = getThemedChalk(config);
|
|
179
|
+
const sdlcRoot = getSdlcRoot();
|
|
180
|
+
// Determine which log file to view
|
|
181
|
+
let logPath;
|
|
182
|
+
if (options.file) {
|
|
183
|
+
// View specific log file by timestamp
|
|
184
|
+
const sanitizedStoryId = storyId; // Will be sanitized by getLatestLogPath
|
|
185
|
+
const logDir = path.join(sdlcRoot, 'stories', sanitizedStoryId, 'logs');
|
|
186
|
+
logPath = path.join(logDir, `${options.file}.log`);
|
|
187
|
+
if (!fs.existsSync(logPath)) {
|
|
188
|
+
console.log(c.error(`Log file not found: ${options.file}.log`));
|
|
189
|
+
console.log(c.dim(` Story: ${storyId}`));
|
|
190
|
+
console.log(c.dim(` Expected path: ${logPath}`));
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Get latest log file
|
|
196
|
+
logPath = getLatestLogPath(sdlcRoot, storyId);
|
|
197
|
+
if (!logPath) {
|
|
198
|
+
console.log(c.error(`No logs found for story: ${storyId}`));
|
|
199
|
+
console.log(c.dim(' Logs are created when running actions with `ai-sdlc run`'));
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Display logs
|
|
204
|
+
if (options.tail) {
|
|
205
|
+
// Follow mode (tail -f)
|
|
206
|
+
console.log(c.dim(`Following log: ${path.basename(logPath)}`));
|
|
207
|
+
console.log(c.dim(`Press Ctrl+C to exit\n`));
|
|
208
|
+
tailLog(logPath);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
// Show last N lines
|
|
212
|
+
const numLines = parseInt(options.lines || '50', 10);
|
|
213
|
+
const content = await readLastLines(logPath, numLines);
|
|
214
|
+
console.log(c.dim(`Log file: ${path.basename(logPath)}`));
|
|
215
|
+
console.log(c.dim(`Showing last ${numLines} lines\n`));
|
|
216
|
+
console.log(content);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
const config = loadConfig();
|
|
221
|
+
const c = getThemedChalk(config);
|
|
222
|
+
if (error instanceof Error && error.message.includes('Invalid story ID')) {
|
|
223
|
+
console.log(c.error(`Invalid story ID: ${storyId}`));
|
|
224
|
+
console.log(c.dim(' Story IDs cannot contain path traversal sequences or separators'));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.log(c.error(`Error viewing logs: ${error instanceof Error ? error.message : String(error)}`));
|
|
228
|
+
}
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
126
232
|
// Worktree management commands
|
|
127
233
|
program
|
|
128
234
|
.command('worktrees')
|