aiag-cli 1.0.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/LICENSE +41 -0
- package/README.md +150 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/commit.d.ts +6 -0
- package/dist/commands/commit.d.ts.map +1 -0
- package/dist/commands/commit.js +90 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/complete.d.ts +6 -0
- package/dist/commands/complete.d.ts.map +1 -0
- package/dist/commands/complete.js +73 -0
- package/dist/commands/complete.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +164 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/next.d.ts +7 -0
- package/dist/commands/next.d.ts.map +1 -0
- package/dist/commands/next.js +77 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +65 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +78 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/test.d.ts +7 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +170 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/agentSelection.d.ts +28 -0
- package/dist/utils/agentSelection.d.ts.map +1 -0
- package/dist/utils/agentSelection.js +66 -0
- package/dist/utils/agentSelection.js.map +1 -0
- package/dist/utils/featureList.d.ts +109 -0
- package/dist/utils/featureList.d.ts.map +1 -0
- package/dist/utils/featureList.js +465 -0
- package/dist/utils/featureList.js.map +1 -0
- package/dist/utils/output.d.ts +71 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +115 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/progress.d.ts +31 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +165 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/prompts.d.ts +50 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +111 -0
- package/dist/utils/prompts.js.map +1 -0
- package/package.json +56 -0
- package/templates/coding.md +142 -0
- package/templates/initializer.md +125 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
MIT 라이선스
|
|
26
|
+
|
|
27
|
+
저작권 (c) 2025
|
|
28
|
+
|
|
29
|
+
이 소프트웨어와 관련 문서 파일("소프트웨어")의 사본을 취득하는 모든 사람에게
|
|
30
|
+
무료로 다음의 권한을 제한 없이 부여합니다: 소프트웨어를 사용, 복사, 수정,
|
|
31
|
+
병합, 게시, 배포, 재라이선스 부여 및/또는 판매할 권리, 그리고 소프트웨어를
|
|
32
|
+
제공받은 사람에게 이러한 행위를 허용할 권리. 단, 다음 조건을 따릅니다:
|
|
33
|
+
|
|
34
|
+
위의 저작권 고지와 본 허가 고지는 소프트웨어의 모든 사본 또는 상당 부분에
|
|
35
|
+
포함되어야 합니다.
|
|
36
|
+
|
|
37
|
+
본 소프트웨어는 상품성, 특정 목적에의 적합성 및 비침해에 대한 보증을 포함하여
|
|
38
|
+
명시적이든 묵시적이든 어떠한 종류의 보증도 없이 "있는 그대로" 제공됩니다.
|
|
39
|
+
어떠한 경우에도 저작자 또는 저작권 보유자는 소프트웨어 또는 소프트웨어의
|
|
40
|
+
사용이나 기타 거래와 관련하여 발생하는 계약, 불법 행위 또는 기타 사유로 인한
|
|
41
|
+
청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다.
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# aiag-cli
|
|
2
|
+
|
|
3
|
+
AI 에이전트 하네스 CLI - Anthropic의 접근 방식을 기반으로 한 장기 실행 에이전트 개발 도구
|
|
4
|
+
|
|
5
|
+
## 개요
|
|
6
|
+
|
|
7
|
+
`aiag-cli`는 Anthropic의 "Long-Running Agent" 아키텍처를 사용하여 AI 에이전트 개발 세션을 관리하는 커맨드라인 도구입니다. 다음 기능을 제공합니다:
|
|
8
|
+
|
|
9
|
+
- **상태 외부화**: AI 메모리가 아닌 파일에 진행 상황 추적
|
|
10
|
+
- **점진적 진행**: 테스트와 함께 한 번에 하나의 기능
|
|
11
|
+
- **세션 관리**: 명확한 시작/종료 시퀀스
|
|
12
|
+
- **기능 추적**: 테스트 명령이 포함된 JSON 기반 기능 목록
|
|
13
|
+
|
|
14
|
+
## 설치
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# npm
|
|
18
|
+
npm install -g aiag-cli
|
|
19
|
+
|
|
20
|
+
# 또는 npx로 직접 사용
|
|
21
|
+
npx aiag-cli init
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 빠른 시작
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 1. 프로젝트에서 초기화
|
|
28
|
+
aiag init
|
|
29
|
+
|
|
30
|
+
# 2. .aiag/feature_list.json에 기능 편집
|
|
31
|
+
|
|
32
|
+
# 3. 상태 확인
|
|
33
|
+
aiag status
|
|
34
|
+
|
|
35
|
+
# 4. 다음 작업할 기능 가져오기
|
|
36
|
+
aiag next
|
|
37
|
+
|
|
38
|
+
# 5. 구현 후 완료 표시
|
|
39
|
+
aiag complete FEATURE-001
|
|
40
|
+
|
|
41
|
+
# 6. 변경사항 커밋
|
|
42
|
+
aiag commit
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 명령어
|
|
46
|
+
|
|
47
|
+
| 명령어 | 설명 |
|
|
48
|
+
| -------------------- | --------------------------- |
|
|
49
|
+
| `aiag init` | 현재 디렉토리에 AIAG 초기화 |
|
|
50
|
+
| `aiag status` | 프로젝트 진행 상황 표시 |
|
|
51
|
+
| `aiag next` | 다음 기능 추천 받기 |
|
|
52
|
+
| `aiag test [id]` | 기능 테스트 실행 |
|
|
53
|
+
| `aiag complete <id>` | 기능을 완료로 표시 |
|
|
54
|
+
| `aiag commit` | 자동 메시지로 변경사항 커밋 |
|
|
55
|
+
| `aiag session start` | 코딩 세션 시작 |
|
|
56
|
+
| `aiag session end` | 현재 세션 종료 |
|
|
57
|
+
|
|
58
|
+
## 디렉토리 구조
|
|
59
|
+
|
|
60
|
+
`aiag init` 실행 후:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
.aiag/
|
|
64
|
+
├── feature_list.json # 상태가 포함된 모든 기능
|
|
65
|
+
├── progress.md # 세션 로그 (추가 전용)
|
|
66
|
+
├── init.sh # 환경 설정 스크립트
|
|
67
|
+
├── session_context.md # 현재 세션 정보
|
|
68
|
+
└── templates/ # 에이전트 프롬프트 템플릿
|
|
69
|
+
├── initializer.md
|
|
70
|
+
└── coding.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 기능 형식
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"id": "CORE-001",
|
|
78
|
+
"category": "core",
|
|
79
|
+
"priority": "critical",
|
|
80
|
+
"description": "기능 설명",
|
|
81
|
+
"acceptanceCriteria": ["기준 1", "기준 2"],
|
|
82
|
+
"testCommand": "bun test",
|
|
83
|
+
"passes": false,
|
|
84
|
+
"lastTestedAt": null,
|
|
85
|
+
"implementedBy": null
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 세션 워크플로우
|
|
90
|
+
|
|
91
|
+
### 세션 시작
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
aiag session start
|
|
95
|
+
# 1. 컨텍스트 확인을 위해 progress.md 확인
|
|
96
|
+
# 2. init.sh 실행
|
|
97
|
+
# 3. aiag next로 작업 찾기
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 세션 종료
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
aiag session end
|
|
104
|
+
# 체크리스트:
|
|
105
|
+
# □ 기능 완료 또는 클린 상태
|
|
106
|
+
# □ 모든 테스트 통과
|
|
107
|
+
# □ 변경사항 커밋됨
|
|
108
|
+
# □ progress.md 업데이트됨
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 카테고리
|
|
112
|
+
|
|
113
|
+
| 카테고리 | 설명 |
|
|
114
|
+
| -------- | ----------------- |
|
|
115
|
+
| `core` | 핵심 인프라 |
|
|
116
|
+
| `cli` | CLI 명령어 |
|
|
117
|
+
| `api` | API 엔드포인트 |
|
|
118
|
+
| `ui` | 사용자 인터페이스 |
|
|
119
|
+
| `test` | 테스트 인프라 |
|
|
120
|
+
| `data` | 데이터 처리 |
|
|
121
|
+
| `docs` | 문서화 |
|
|
122
|
+
| `devops` | 빌드/배포 |
|
|
123
|
+
|
|
124
|
+
## 우선순위 레벨
|
|
125
|
+
|
|
126
|
+
1. **critical** - 다른 기능의 선행 조건
|
|
127
|
+
2. **high** - 핵심 사용자 가치
|
|
128
|
+
3. **medium** - 중요하지만 연기 가능
|
|
129
|
+
4. **low** - 있으면 좋은 것
|
|
130
|
+
|
|
131
|
+
## 핵심 원칙
|
|
132
|
+
|
|
133
|
+
Anthropic의 Long-Running Agent 아키텍처 기반:
|
|
134
|
+
|
|
135
|
+
1. **하나의 기능 규칙** - 한 번에 하나의 기능만 작업
|
|
136
|
+
2. **완료 전 테스트** - passes: true 표시 전 항상 테스트
|
|
137
|
+
3. **클린 상태** - 코드를 절대 깨진 상태로 두지 않음
|
|
138
|
+
4. **진행 상황 문서화** - 매 세션마다 progress.md 업데이트
|
|
139
|
+
|
|
140
|
+
## Author
|
|
141
|
+
|
|
142
|
+
**주식회사 기반 (Giban Co., Ltd.)**
|
|
143
|
+
|
|
144
|
+
- Website: [aiag.co.kr](https://aiag.co.kr)
|
|
145
|
+
- Email: help.aiag@gmail.com
|
|
146
|
+
- Maintainer: Yunchan Park
|
|
147
|
+
|
|
148
|
+
## 라이선스
|
|
149
|
+
|
|
150
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { init } from './commands/init.js';
|
|
4
|
+
import { status } from './commands/status.js';
|
|
5
|
+
import { next } from './commands/next.js';
|
|
6
|
+
import { test } from './commands/test.js';
|
|
7
|
+
import { complete } from './commands/complete.js';
|
|
8
|
+
import { commit } from './commands/commit.js';
|
|
9
|
+
import { sessionStart, sessionEnd } from './commands/session.js';
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program.name('aiag').description('AIAG CLI - Long-Running Agent Harness Tool').version('1.0.0');
|
|
12
|
+
// aiag init
|
|
13
|
+
program
|
|
14
|
+
.command('init')
|
|
15
|
+
.description('Initialize a new AIAG project')
|
|
16
|
+
.option('-f, --force', 'Force reinitialize')
|
|
17
|
+
.option('--from-prd <file>', 'Generate features from PRD file')
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
await init(options);
|
|
20
|
+
});
|
|
21
|
+
// aiag status
|
|
22
|
+
program
|
|
23
|
+
.command('status')
|
|
24
|
+
.description('Show feature progress status')
|
|
25
|
+
.option('--json', 'Output as JSON')
|
|
26
|
+
.option('-v, --verbose', 'Show all features')
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
await status(options);
|
|
29
|
+
});
|
|
30
|
+
// aiag next
|
|
31
|
+
program
|
|
32
|
+
.command('next')
|
|
33
|
+
.description('Show next feature to work on')
|
|
34
|
+
.option('-c, --category <category>', 'Filter by category')
|
|
35
|
+
.option('-p, --priority <priority>', 'Filter by priority')
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
await next(options);
|
|
38
|
+
});
|
|
39
|
+
// aiag test
|
|
40
|
+
program
|
|
41
|
+
.command('test [featureId]')
|
|
42
|
+
.description('Run tests for a feature or all features')
|
|
43
|
+
.option('-a, --all', 'Test all features')
|
|
44
|
+
.option('--failed', 'Only test previously failed')
|
|
45
|
+
.action(async (featureId, options) => {
|
|
46
|
+
await test(featureId, options);
|
|
47
|
+
});
|
|
48
|
+
// aiag complete
|
|
49
|
+
program
|
|
50
|
+
.command('complete <featureId>')
|
|
51
|
+
.description('Mark a feature as complete')
|
|
52
|
+
.option('--skip-test', 'Skip test verification')
|
|
53
|
+
.action(async (featureId, options) => {
|
|
54
|
+
await complete(featureId, options);
|
|
55
|
+
});
|
|
56
|
+
// aiag commit
|
|
57
|
+
program
|
|
58
|
+
.command('commit')
|
|
59
|
+
.description('Commit changes with progress update')
|
|
60
|
+
.option('-m, --message <message>', 'Custom commit message')
|
|
61
|
+
.action(async (options) => {
|
|
62
|
+
await commit(options);
|
|
63
|
+
});
|
|
64
|
+
// aiag session
|
|
65
|
+
const session = program.command('session').description('Manage coding sessions');
|
|
66
|
+
session
|
|
67
|
+
.command('start [featureId]')
|
|
68
|
+
.description('Start a new coding session')
|
|
69
|
+
.action(async (featureId) => {
|
|
70
|
+
await sessionStart(featureId);
|
|
71
|
+
});
|
|
72
|
+
session
|
|
73
|
+
.command('end')
|
|
74
|
+
.description('End the current coding session')
|
|
75
|
+
.action(async () => {
|
|
76
|
+
await sessionEnd();
|
|
77
|
+
});
|
|
78
|
+
// Parse arguments
|
|
79
|
+
program.parse();
|
|
80
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiEvE"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { updateLastUpdated } from '../utils/progress.js';
|
|
3
|
+
import { getProgress, getRecentlyCompleted } from '../utils/featureList.js';
|
|
4
|
+
import { printHeader, colors, printError, printSuccess, printWarning } from '../utils/output.js';
|
|
5
|
+
export async function commit(options = {}) {
|
|
6
|
+
printHeader('AIAG Commit');
|
|
7
|
+
// Check git status
|
|
8
|
+
const { stdout: statusOutput } = await runGit(['status', '--porcelain']);
|
|
9
|
+
if (!statusOutput.trim()) {
|
|
10
|
+
printWarning('No changes to commit.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log('');
|
|
14
|
+
console.log(colors.dim('Changes to commit:'));
|
|
15
|
+
console.log(colors.dim(statusOutput));
|
|
16
|
+
// Stage all changes
|
|
17
|
+
console.log('Staging changes...');
|
|
18
|
+
await runGit(['add', '.']);
|
|
19
|
+
printSuccess('Changes staged');
|
|
20
|
+
// Generate commit message
|
|
21
|
+
let message = options.message;
|
|
22
|
+
if (!message) {
|
|
23
|
+
// Auto-generate message based on progress
|
|
24
|
+
const progress = getProgress();
|
|
25
|
+
const recent = getRecentlyCompleted(1);
|
|
26
|
+
if (recent.length > 0) {
|
|
27
|
+
const feature = recent[0];
|
|
28
|
+
message = `feat: complete ${feature.id} - ${feature.description}`;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
message = `chore: update progress (${progress.completed}/${progress.total} complete)`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Create commit
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(`Commit message: ${colors.dim(message)}`);
|
|
37
|
+
const { success, stderr } = await runGit(['commit', '-m', message]);
|
|
38
|
+
if (!success) {
|
|
39
|
+
printError('Commit failed');
|
|
40
|
+
if (stderr) {
|
|
41
|
+
console.log(colors.dim(stderr));
|
|
42
|
+
}
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
// Update progress.md
|
|
46
|
+
updateLastUpdated();
|
|
47
|
+
// Get commit hash
|
|
48
|
+
const { stdout: hashOutput } = await runGit(['rev-parse', '--short', 'HEAD']);
|
|
49
|
+
const hash = hashOutput.trim();
|
|
50
|
+
console.log('');
|
|
51
|
+
printSuccess(`Created commit: ${hash}`);
|
|
52
|
+
// Show git log
|
|
53
|
+
console.log('');
|
|
54
|
+
console.log(colors.dim('Recent commits:'));
|
|
55
|
+
const { stdout: logOutput } = await runGit(['log', '--oneline', '-5', '--no-decorate']);
|
|
56
|
+
console.log(colors.dim(logOutput));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Run a git command
|
|
60
|
+
*/
|
|
61
|
+
async function runGit(args) {
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
let stdout = '';
|
|
64
|
+
let stderr = '';
|
|
65
|
+
const proc = spawn('git', args, {
|
|
66
|
+
cwd: process.cwd(),
|
|
67
|
+
});
|
|
68
|
+
proc.stdout.on('data', (data) => {
|
|
69
|
+
stdout += data.toString();
|
|
70
|
+
});
|
|
71
|
+
proc.stderr.on('data', (data) => {
|
|
72
|
+
stderr += data.toString();
|
|
73
|
+
});
|
|
74
|
+
proc.on('close', (code) => {
|
|
75
|
+
resolve({
|
|
76
|
+
success: code === 0,
|
|
77
|
+
stdout,
|
|
78
|
+
stderr,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
proc.on('error', (err) => {
|
|
82
|
+
resolve({
|
|
83
|
+
success: false,
|
|
84
|
+
stdout: '',
|
|
85
|
+
stderr: err.message,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/commands/complete.ts"],"names":[],"mappings":"AAcA,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D9F"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { getFeatureById, updateFeaturePasses } from '../utils/featureList.js';
|
|
3
|
+
import { updateLastUpdated } from '../utils/progress.js';
|
|
4
|
+
import { printHeader, printSection, colors, icons, printError, printSuccess, printWarning, printInfo, } from '../utils/output.js';
|
|
5
|
+
export async function complete(featureId, options = {}) {
|
|
6
|
+
const feature = getFeatureById(featureId);
|
|
7
|
+
if (!feature) {
|
|
8
|
+
printError(`Feature "${featureId}" not found.`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
if (feature.passes) {
|
|
12
|
+
printWarning(`Feature "${featureId}" is already marked as complete.`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
printHeader(`Verifying Feature: ${featureId}`);
|
|
16
|
+
// Run tests unless skipped
|
|
17
|
+
if (!options.skipTest && feature.testCommand) {
|
|
18
|
+
printSection('Running tests...');
|
|
19
|
+
console.log(` ${colors.dim('$')} ${feature.testCommand}`);
|
|
20
|
+
const testPassed = await runTest(feature.testCommand);
|
|
21
|
+
if (!testPassed) {
|
|
22
|
+
console.log('');
|
|
23
|
+
printError(`Tests failed for ${featureId}`);
|
|
24
|
+
console.log(colors.dim('Fix the issues before marking as complete, or use --skip-test'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
printSuccess('All tests passing');
|
|
28
|
+
}
|
|
29
|
+
else if (options.skipTest) {
|
|
30
|
+
printWarning('Tests skipped (--skip-test)');
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
printInfo('No test command defined');
|
|
34
|
+
}
|
|
35
|
+
// Mark as complete
|
|
36
|
+
const success = updateFeaturePasses(featureId, true);
|
|
37
|
+
if (!success) {
|
|
38
|
+
printError('Failed to update feature_list.json');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
console.log('');
|
|
42
|
+
printSuccess(`Feature ${featureId} marked as complete`);
|
|
43
|
+
// Update progress
|
|
44
|
+
updateLastUpdated();
|
|
45
|
+
printSection('Updated:');
|
|
46
|
+
console.log(` ${icons.bullet} .aiag/feature_list.json (passes: true)`);
|
|
47
|
+
console.log(` ${icons.bullet} .aiag/progress.md (last updated)`);
|
|
48
|
+
// Show next steps
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(colors.dim('Next steps:'));
|
|
51
|
+
console.log(colors.dim(' 1. Run "aiag commit" to commit your changes'));
|
|
52
|
+
console.log(colors.dim(' 2. Run "aiag next" to see the next feature'));
|
|
53
|
+
console.log('');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Run a test command and return success status
|
|
57
|
+
*/
|
|
58
|
+
async function runTest(command) {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
const [cmd, ...args] = command.split(' ');
|
|
61
|
+
const proc = spawn(cmd, args, {
|
|
62
|
+
stdio: 'inherit',
|
|
63
|
+
shell: true,
|
|
64
|
+
});
|
|
65
|
+
proc.on('close', (code) => {
|
|
66
|
+
resolve(code === 0);
|
|
67
|
+
});
|
|
68
|
+
proc.on('error', () => {
|
|
69
|
+
resolve(false);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=complete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/commands/complete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgLnE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { aiagExists } from '../utils/featureList.js';
|
|
6
|
+
import { printHeader, colors, icons, printError, printSuccess, printWarning, } from '../utils/output.js';
|
|
7
|
+
// ESM compatible __dirname
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const AIAG_DIR = '.aiag';
|
|
11
|
+
export async function init(options = {}) {
|
|
12
|
+
const baseDir = process.cwd();
|
|
13
|
+
// Check if already initialized
|
|
14
|
+
if (aiagExists(baseDir) && !options.force) {
|
|
15
|
+
printWarning('AIAG is already initialized in this directory.');
|
|
16
|
+
console.log(colors.dim('Use --force to reinitialize.'));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
printHeader('AIAG Project Initializer');
|
|
20
|
+
console.log('');
|
|
21
|
+
console.log('Creating .aiag/ directory structure...');
|
|
22
|
+
try {
|
|
23
|
+
// Create directories
|
|
24
|
+
fs.mkdirSync(path.join(baseDir, AIAG_DIR, 'templates'), { recursive: true });
|
|
25
|
+
// Create feature_list.json template
|
|
26
|
+
const featureListTemplate = {
|
|
27
|
+
project: {
|
|
28
|
+
name: path.basename(baseDir),
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
description: 'Project description',
|
|
31
|
+
totalFeatures: 0,
|
|
32
|
+
completedFeatures: 0,
|
|
33
|
+
},
|
|
34
|
+
features: [
|
|
35
|
+
{
|
|
36
|
+
id: 'CORE-001',
|
|
37
|
+
category: 'core',
|
|
38
|
+
priority: 'critical',
|
|
39
|
+
description: 'Example feature - replace with your features',
|
|
40
|
+
acceptanceCriteria: ['First acceptance criterion', 'Second acceptance criterion'],
|
|
41
|
+
testCommand: 'bun test',
|
|
42
|
+
passes: false,
|
|
43
|
+
lastTestedAt: null,
|
|
44
|
+
implementedBy: null,
|
|
45
|
+
notes: '',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'feature_list.json'), JSON.stringify(featureListTemplate, null, 2));
|
|
50
|
+
console.log(` ${icons.success} .aiag/feature_list.json`);
|
|
51
|
+
// Create progress.md
|
|
52
|
+
const today = new Date().toISOString().split('T')[0];
|
|
53
|
+
const progressTemplate = `# AIAG Progress Log
|
|
54
|
+
|
|
55
|
+
## Project: ${path.basename(baseDir)}
|
|
56
|
+
|
|
57
|
+
**Description:** Project description
|
|
58
|
+
|
|
59
|
+
**Started:** ${today}
|
|
60
|
+
**Last Updated:** ${today}
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Session: ${new Date().toISOString()}
|
|
65
|
+
|
|
66
|
+
### Context
|
|
67
|
+
- Project initialized with AIAG harness
|
|
68
|
+
|
|
69
|
+
### Work Done
|
|
70
|
+
- [x] Created .aiag/ directory structure
|
|
71
|
+
- [ ] Define features in feature_list.json
|
|
72
|
+
|
|
73
|
+
### Commits
|
|
74
|
+
- (Initial setup)
|
|
75
|
+
|
|
76
|
+
### Next Session
|
|
77
|
+
- Edit feature_list.json with actual features
|
|
78
|
+
- Start implementing first feature
|
|
79
|
+
|
|
80
|
+
### Notes
|
|
81
|
+
- Run 'aiag status' to see progress
|
|
82
|
+
- Run 'aiag next' to get next feature recommendation
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
`;
|
|
86
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'progress.md'), progressTemplate);
|
|
87
|
+
console.log(` ${icons.success} .aiag/progress.md`);
|
|
88
|
+
// Create init.sh
|
|
89
|
+
const initShTemplate = `#!/bin/bash
|
|
90
|
+
|
|
91
|
+
# AIAG Project Initialization Script
|
|
92
|
+
set -e
|
|
93
|
+
|
|
94
|
+
echo "Starting AIAG development environment..."
|
|
95
|
+
|
|
96
|
+
# Check Node.js
|
|
97
|
+
if ! command -v node &> /dev/null; then
|
|
98
|
+
echo "Node.js is required but not installed."
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
echo "✓ Node.js: $(node --version)"
|
|
102
|
+
|
|
103
|
+
# Install dependencies
|
|
104
|
+
if [ ! -d "node_modules" ]; then
|
|
105
|
+
echo "Installing dependencies..."
|
|
106
|
+
bun install
|
|
107
|
+
fi
|
|
108
|
+
echo "✓ Dependencies installed"
|
|
109
|
+
|
|
110
|
+
# Build (if applicable)
|
|
111
|
+
if grep -q '"build"' package.json 2>/dev/null; then
|
|
112
|
+
bun run build --silent 2>/dev/null || true
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
echo ""
|
|
116
|
+
echo "Environment ready!"
|
|
117
|
+
echo "Run 'aiag status' to see progress"
|
|
118
|
+
echo "Run 'aiag next' to get next feature"
|
|
119
|
+
`;
|
|
120
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'init.sh'), initShTemplate);
|
|
121
|
+
fs.chmodSync(path.join(baseDir, AIAG_DIR, 'init.sh'), '755');
|
|
122
|
+
console.log(` ${icons.success} .aiag/init.sh`);
|
|
123
|
+
// Create session_context.md
|
|
124
|
+
const sessionContextTemplate = `# Current Session Context
|
|
125
|
+
|
|
126
|
+
## Active Feature
|
|
127
|
+
- ID: (none)
|
|
128
|
+
- Status: Not started
|
|
129
|
+
|
|
130
|
+
## Environment Status
|
|
131
|
+
- Last checked: ${new Date().toISOString()}
|
|
132
|
+
- Status: Ready
|
|
133
|
+
|
|
134
|
+
## Notes
|
|
135
|
+
- (Add session-specific notes here)
|
|
136
|
+
`;
|
|
137
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'session_context.md'), sessionContextTemplate);
|
|
138
|
+
console.log(` ${icons.success} .aiag/session_context.md`);
|
|
139
|
+
// Create template files - look in package's templates directory
|
|
140
|
+
const templatesDir = path.join(__dirname, '../../templates');
|
|
141
|
+
const initializerTemplate = fs.existsSync(path.join(templatesDir, 'initializer.md'))
|
|
142
|
+
? fs.readFileSync(path.join(templatesDir, 'initializer.md'), 'utf-8')
|
|
143
|
+
: '# Initializer Agent Template\n\n(See documentation for details)';
|
|
144
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'templates', 'initializer.md'), initializerTemplate);
|
|
145
|
+
const codingTemplate = fs.existsSync(path.join(templatesDir, 'coding.md'))
|
|
146
|
+
? fs.readFileSync(path.join(templatesDir, 'coding.md'), 'utf-8')
|
|
147
|
+
: '# Coding Agent Template\n\n(See documentation for details)';
|
|
148
|
+
fs.writeFileSync(path.join(baseDir, AIAG_DIR, 'templates', 'coding.md'), codingTemplate);
|
|
149
|
+
console.log(` ${icons.success} .aiag/templates/`);
|
|
150
|
+
console.log('');
|
|
151
|
+
printSuccess('AIAG initialized successfully!');
|
|
152
|
+
console.log('');
|
|
153
|
+
console.log(colors.bold('Next steps:'));
|
|
154
|
+
console.log(' 1. Edit .aiag/feature_list.json with your features');
|
|
155
|
+
console.log(" 2. Run 'aiag status' to verify setup");
|
|
156
|
+
console.log(" 3. Run 'aiag next' to start working");
|
|
157
|
+
console.log('');
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
printError(`Failed to initialize: ${error}`);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=init.js.map
|