aiag-cli 1.6.3 → 1.7.1
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 +50 -2
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/auto.d.ts +1 -2
- package/dist/commands/auto.d.ts.map +1 -1
- package/dist/commands/auto.js +28 -173
- package/dist/commands/auto.js.map +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +246 -170
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/next.d.ts.map +1 -1
- package/dist/commands/next.js +36 -3
- package/dist/commands/next.js.map +1 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +11 -1
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +46 -40
- package/dist/commands/work.js.map +1 -1
- package/dist/utils/claudeMd.d.ts +49 -0
- package/dist/utils/claudeMd.d.ts.map +1 -0
- package/dist/utils/claudeMd.js +413 -0
- package/dist/utils/claudeMd.js.map +1 -0
- package/dist/utils/initializerAgent.d.ts +24 -0
- package/dist/utils/initializerAgent.d.ts.map +1 -0
- package/dist/utils/initializerAgent.js +182 -0
- package/dist/utils/initializerAgent.js.map +1 -0
- package/dist/utils/messages.d.ts +184 -0
- package/dist/utils/messages.d.ts.map +1 -0
- package/dist/utils/messages.js +232 -0
- package/dist/utils/messages.js.map +1 -0
- package/dist/utils/output.d.ts +22 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +38 -0
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/prd.d.ts +39 -0
- package/dist/utils/prd.d.ts.map +1 -0
- package/dist/utils/prd.js +77 -0
- package/dist/utils/prd.js.map +1 -0
- package/dist/utils/sessionContext.d.ts +33 -0
- package/dist/utils/sessionContext.d.ts.map +1 -0
- package/dist/utils/sessionContext.js +132 -0
- package/dist/utils/sessionContext.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEpE;;GAEG;AAGH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AAE/C,eAAO,MAAM,MAAM;;;;;;;;CAQlB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;;;;;;;CAWjB,CAAC;AAEF;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAW,EAClB,MAAM,GAAE,MAAY,EACpB,KAAK,GAAE,MAAY,GAClB,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC;CACjB,GAAG,MAAM,CAiBT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAa3E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEvE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAMjG;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAOnG;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,MAAY,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAE1E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAE,MAAU,GAAG,IAAI,CAItD"}
|
package/dist/utils/output.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { messages, formatMessage, getMessage } from './messages.js';
|
|
2
3
|
/**
|
|
3
4
|
* Output utilities for CLI
|
|
4
5
|
*/
|
|
6
|
+
// 메시지 시스템 re-export
|
|
7
|
+
export { messages, formatMessage, getMessage };
|
|
5
8
|
export const colors = {
|
|
6
9
|
success: chalk.green,
|
|
7
10
|
error: chalk.red,
|
|
@@ -113,4 +116,39 @@ export function printInfo(message) {
|
|
|
113
116
|
export function printKeyValue(key, value) {
|
|
114
117
|
console.log(` ${colors.dim(key + ':')} ${value}`);
|
|
115
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Print a message using key path
|
|
121
|
+
* @example printMessageByKey('init.header') → "AIAG 프로젝트 초기화"
|
|
122
|
+
*/
|
|
123
|
+
export function printMessageByKey(keyPath, params) {
|
|
124
|
+
let message = getMessage(keyPath);
|
|
125
|
+
if (params) {
|
|
126
|
+
message = formatMessage(message, params);
|
|
127
|
+
}
|
|
128
|
+
console.log(message);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Print a list of items with bullets
|
|
132
|
+
*/
|
|
133
|
+
export function printList(items, options = {}) {
|
|
134
|
+
const indent = ' '.repeat(options.indent || 2);
|
|
135
|
+
const bullet = options.bullet || icons.bullet;
|
|
136
|
+
for (const item of items) {
|
|
137
|
+
console.log(`${indent}${bullet} ${item}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Print a divider line
|
|
142
|
+
*/
|
|
143
|
+
export function printDivider(char = '─', length = 50) {
|
|
144
|
+
console.log(colors.dim(char.repeat(length)));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Print empty lines
|
|
148
|
+
*/
|
|
149
|
+
export function printEmptyLine(count = 1) {
|
|
150
|
+
for (let i = 0; i < count; i++) {
|
|
151
|
+
console.log('');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
116
154
|
//# sourceMappingURL=output.js.map
|
package/dist/utils/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD (Product Requirements Document) 관리 유틸리티
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* PRD 파일 검색 우선순위 목록
|
|
6
|
+
*/
|
|
7
|
+
export declare const PRD_CANDIDATES: string[];
|
|
8
|
+
/**
|
|
9
|
+
* PRD 파일을 찾습니다
|
|
10
|
+
* @param userSpecified 사용자가 지정한 PRD 경로
|
|
11
|
+
* @param baseDir 검색 시작 디렉토리 (기본: 현재 디렉토리)
|
|
12
|
+
* @returns PRD 파일의 절대 경로 또는 null
|
|
13
|
+
*/
|
|
14
|
+
export declare function findPrd(userSpecified?: string, baseDir?: string): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* PRD 파일을 읽습니다
|
|
17
|
+
* @param prdPath PRD 파일 경로
|
|
18
|
+
* @returns PRD 내용
|
|
19
|
+
*/
|
|
20
|
+
export declare function readPrd(prdPath: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* PRD 파일이 존재하는지 확인
|
|
23
|
+
* @param baseDir 검색 디렉토리
|
|
24
|
+
* @returns PRD 존재 여부
|
|
25
|
+
*/
|
|
26
|
+
export declare function hasPrd(baseDir?: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* PRD 파일 정보를 가져옵니다
|
|
29
|
+
* @param prdPath PRD 파일 경로
|
|
30
|
+
* @returns 파일 정보
|
|
31
|
+
*/
|
|
32
|
+
export declare function getPrdInfo(prdPath: string): {
|
|
33
|
+
path: string;
|
|
34
|
+
relativePath: string;
|
|
35
|
+
size: number;
|
|
36
|
+
sizeKB: string;
|
|
37
|
+
lastModified: Date;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=prd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/utils/prd.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,eAAO,MAAM,cAAc,UAU1B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAoB9F;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,IAAI,CAAC;CACpB,CAWA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD (Product Requirements Document) 관리 유틸리티
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* PRD 파일 검색 우선순위 목록
|
|
8
|
+
*/
|
|
9
|
+
export const PRD_CANDIDATES = [
|
|
10
|
+
'PRD.md',
|
|
11
|
+
'REQUIREMENTS.md',
|
|
12
|
+
'docs/prd.md',
|
|
13
|
+
'docs/PRD.md',
|
|
14
|
+
'docs/requirements.md',
|
|
15
|
+
'docs/REQUIREMENTS.md',
|
|
16
|
+
'.aiag/PRD.md',
|
|
17
|
+
'spec/PRD.md',
|
|
18
|
+
'spec/requirements.md',
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* PRD 파일을 찾습니다
|
|
22
|
+
* @param userSpecified 사용자가 지정한 PRD 경로
|
|
23
|
+
* @param baseDir 검색 시작 디렉토리 (기본: 현재 디렉토리)
|
|
24
|
+
* @returns PRD 파일의 절대 경로 또는 null
|
|
25
|
+
*/
|
|
26
|
+
export function findPrd(userSpecified, baseDir = process.cwd()) {
|
|
27
|
+
// 사용자가 지정한 경로 우선
|
|
28
|
+
if (userSpecified) {
|
|
29
|
+
const fullPath = path.resolve(baseDir, userSpecified);
|
|
30
|
+
if (fs.existsSync(fullPath)) {
|
|
31
|
+
return fullPath;
|
|
32
|
+
}
|
|
33
|
+
// 사용자가 지정했는데 없으면 null (에러 처리 위해)
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
// 자동 탐색
|
|
37
|
+
for (const candidate of PRD_CANDIDATES) {
|
|
38
|
+
const fullPath = path.join(baseDir, candidate);
|
|
39
|
+
if (fs.existsSync(fullPath)) {
|
|
40
|
+
return fullPath;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* PRD 파일을 읽습니다
|
|
47
|
+
* @param prdPath PRD 파일 경로
|
|
48
|
+
* @returns PRD 내용
|
|
49
|
+
*/
|
|
50
|
+
export function readPrd(prdPath) {
|
|
51
|
+
return fs.readFileSync(prdPath, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* PRD 파일이 존재하는지 확인
|
|
55
|
+
* @param baseDir 검색 디렉토리
|
|
56
|
+
* @returns PRD 존재 여부
|
|
57
|
+
*/
|
|
58
|
+
export function hasPrd(baseDir = process.cwd()) {
|
|
59
|
+
return findPrd(undefined, baseDir) !== null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* PRD 파일 정보를 가져옵니다
|
|
63
|
+
* @param prdPath PRD 파일 경로
|
|
64
|
+
* @returns 파일 정보
|
|
65
|
+
*/
|
|
66
|
+
export function getPrdInfo(prdPath) {
|
|
67
|
+
const stats = fs.statSync(prdPath);
|
|
68
|
+
const baseDir = process.cwd();
|
|
69
|
+
return {
|
|
70
|
+
path: prdPath,
|
|
71
|
+
relativePath: path.relative(baseDir, prdPath),
|
|
72
|
+
size: stats.size,
|
|
73
|
+
sizeKB: (stats.size / 1024).toFixed(1),
|
|
74
|
+
lastModified: stats.mtime,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=prd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd.js","sourceRoot":"","sources":["../../src/utils/prd.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ;IACR,iBAAiB;IACjB,aAAa;IACb,aAAa;IACb,sBAAsB;IACtB,sBAAsB;IACtB,cAAc;IACd,aAAa;IACb,sBAAsB;CACvB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,aAAsB,EAAE,UAAkB,OAAO,CAAC,GAAG,EAAE;IAC7E,iBAAiB;IACjB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,iCAAiC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;IACR,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,UAAkB,OAAO,CAAC,GAAG,EAAE;IACpD,OAAO,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IAOxC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,OAAO;QACb,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC7C,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACtC,YAAY,EAAE,KAAK,CAAC,KAAK;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Feature, FeatureList } from '../types.js';
|
|
2
|
+
export interface SessionFeatureContext {
|
|
3
|
+
feature: Feature;
|
|
4
|
+
attemptNumber: number;
|
|
5
|
+
previousError?: string;
|
|
6
|
+
status: 'in_progress' | 'failed';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* session_context.md에서 진행 중이거나 실패한 작업을 찾아 반환
|
|
10
|
+
*/
|
|
11
|
+
export declare function getInterruptedWork(baseDir: string, featureList: FeatureList): SessionFeatureContext | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Update session_context.md with feature info and failure context
|
|
14
|
+
*/
|
|
15
|
+
export declare function updateSessionContext(baseDir: string, feature: Feature, context: {
|
|
16
|
+
status: 'in_progress' | 'failed';
|
|
17
|
+
attempts: number;
|
|
18
|
+
error?: string;
|
|
19
|
+
failureAnalysis?: {
|
|
20
|
+
category: string;
|
|
21
|
+
shouldRetry: boolean;
|
|
22
|
+
suggestion: string;
|
|
23
|
+
};
|
|
24
|
+
}): void;
|
|
25
|
+
/**
|
|
26
|
+
* Clear session context (on successful completion or manual clear)
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearSessionContext(baseDir: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Check if there is any interrupted work
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasInterruptedWork(baseDir: string): boolean;
|
|
33
|
+
//# sourceMappingURL=sessionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionContext.d.ts","sourceRoot":"","sources":["../../src/utils/sessionContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,WAAW,GACvB,qBAAqB,GAAG,SAAS,CAgDnC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,OAAO,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,GACA,IAAI,CAmDN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAezD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAa3D"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* session_context.md에서 진행 중이거나 실패한 작업을 찾아 반환
|
|
5
|
+
*/
|
|
6
|
+
export function getInterruptedWork(baseDir, featureList) {
|
|
7
|
+
const sessionContextPath = path.join(baseDir, '.aiag', 'session_context.md');
|
|
8
|
+
if (!fs.existsSync(sessionContextPath)) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const content = fs.readFileSync(sessionContextPath, 'utf-8');
|
|
13
|
+
// "No Active Feature" 체크
|
|
14
|
+
if (content.includes('## No Active Feature')) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
// ID 추출: "- ID: FEATURE-001" 패턴
|
|
18
|
+
const idMatch = content.match(/- ID:\s*(\S+)/);
|
|
19
|
+
if (!idMatch)
|
|
20
|
+
return undefined;
|
|
21
|
+
const featureId = idMatch[1];
|
|
22
|
+
// Status 추출: "- Status: in_progress" 패턴
|
|
23
|
+
const statusMatch = content.match(/- Status:\s*(in_progress|failed)/);
|
|
24
|
+
const status = statusMatch?.[1] || 'in_progress';
|
|
25
|
+
// Attempts 추출
|
|
26
|
+
const attemptsMatch = content.match(/- Attempts:\s*(\d+)/);
|
|
27
|
+
const attemptNumber = attemptsMatch ? parseInt(attemptsMatch[1], 10) : 1;
|
|
28
|
+
// Previous error 추출
|
|
29
|
+
const errorMatch = content.match(/## Previous Error\s*```\s*(.+?)\s*```/s);
|
|
30
|
+
const previousError = errorMatch ? errorMatch[1].trim() : undefined;
|
|
31
|
+
// 해당 feature가 아직 완료되지 않았는지 확인
|
|
32
|
+
const feature = featureList.features.find((f) => f.id === featureId);
|
|
33
|
+
if (feature && !feature.passes) {
|
|
34
|
+
return {
|
|
35
|
+
feature,
|
|
36
|
+
attemptNumber,
|
|
37
|
+
previousError,
|
|
38
|
+
status,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Update session_context.md with feature info and failure context
|
|
49
|
+
*/
|
|
50
|
+
export function updateSessionContext(baseDir, feature, context) {
|
|
51
|
+
const sessionContextPath = path.join(baseDir, '.aiag', 'session_context.md');
|
|
52
|
+
const timestamp = new Date().toISOString();
|
|
53
|
+
let content = `# Current Session Context
|
|
54
|
+
|
|
55
|
+
## Active Feature
|
|
56
|
+
|
|
57
|
+
- ID: ${feature.id}
|
|
58
|
+
- Description: ${feature.description}
|
|
59
|
+
- Status: ${context.status}
|
|
60
|
+
- Started: ${timestamp}
|
|
61
|
+
- Attempts: ${context.attempts}
|
|
62
|
+
|
|
63
|
+
`;
|
|
64
|
+
if (context.error) {
|
|
65
|
+
content += `## Previous Error
|
|
66
|
+
|
|
67
|
+
\`\`\`
|
|
68
|
+
${context.error}
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
`;
|
|
72
|
+
// Add failure analysis if available
|
|
73
|
+
if (context.failureAnalysis && context.failureAnalysis.category !== 'unknown') {
|
|
74
|
+
content += `## Failure Analysis
|
|
75
|
+
|
|
76
|
+
- **Category**: ${context.failureAnalysis.category}
|
|
77
|
+
- **Suggested Fix**: ${context.failureAnalysis.suggestion}
|
|
78
|
+
- **Should Retry**: ${context.failureAnalysis.shouldRetry ? 'Yes' : 'No (manual fix recommended)'}
|
|
79
|
+
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
content += `## Acceptance Criteria
|
|
84
|
+
|
|
85
|
+
${feature.acceptanceCriteria.map((c, i) => `${i + 1}. [ ] ${c}`).join('\n')}
|
|
86
|
+
|
|
87
|
+
## Next Action
|
|
88
|
+
|
|
89
|
+
${context.status === 'failed' ? '- Retry with different approach based on error analysis' : '- Continue implementation or verify completion'}
|
|
90
|
+
`;
|
|
91
|
+
try {
|
|
92
|
+
fs.writeFileSync(sessionContextPath, content, 'utf-8');
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error('Failed to update session context:', error);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Clear session context (on successful completion or manual clear)
|
|
100
|
+
*/
|
|
101
|
+
export function clearSessionContext(baseDir) {
|
|
102
|
+
const sessionContextPath = path.join(baseDir, '.aiag', 'session_context.md');
|
|
103
|
+
const content = `# Current Session Context
|
|
104
|
+
|
|
105
|
+
## No Active Feature
|
|
106
|
+
|
|
107
|
+
Last updated: ${new Date().toISOString()}
|
|
108
|
+
`;
|
|
109
|
+
try {
|
|
110
|
+
fs.writeFileSync(sessionContextPath, content, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('Failed to clear session context:', error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if there is any interrupted work
|
|
118
|
+
*/
|
|
119
|
+
export function hasInterruptedWork(baseDir) {
|
|
120
|
+
const sessionContextPath = path.join(baseDir, '.aiag', 'session_context.md');
|
|
121
|
+
if (!fs.existsSync(sessionContextPath)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const content = fs.readFileSync(sessionContextPath, 'utf-8');
|
|
126
|
+
return !content.includes('## No Active Feature') && content.includes('## Active Feature');
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=sessionContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionContext.js","sourceRoot":"","sources":["../../src/utils/sessionContext.ts"],"names":[],"mappings":"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"}
|