spr-ai-native 0.1.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 +21 -0
- package/README.md +181 -0
- package/bin/cli.js +119 -0
- package/package.json +41 -0
- package/preset/common/base-rules.md +57 -0
- package/preset/common/commands/engineer.md +22 -0
- package/preset/common/commands/planner.md +23 -0
- package/preset/common/commands/pm.md +170 -0
- package/preset/common/commands/qa.md +21 -0
- package/preset/common/project-doc.md +90 -0
- package/preset/common/roles/engineer.md +75 -0
- package/preset/common/roles/planner.md +125 -0
- package/preset/common/roles/qa.md +78 -0
- package/src/index.js +55 -0
- package/src/lib/preset.js +61 -0
- package/src/lib/write.js +45 -0
- package/src/targets/claude.js +77 -0
- package/src/targets/codex.js +81 -0
- package/src/targets/cursor.js +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 soopiri
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# spr-ai-native
|
|
2
|
+
|
|
3
|
+
AI 코딩 에이전트(Claude Code / Codex CLI / Cursor)로 개발할 때 쓰는 **개발 규칙 문서와 서브에이전트 프리셋**을 현재 프로젝트에 생성하는 CLI입니다.
|
|
4
|
+
|
|
5
|
+
생성되는 것은 `pm` → `planner` → `engineer` → `qa` 4개 역할로 구성된 개발 워크플로우입니다. 프로젝트 스택에 종속되지 않는 범용 프리셋이며, 스택·검증 명령·금지 사항은 생성된 프로젝트 지침 문서에 직접 작성해 채웁니다.
|
|
6
|
+
|
|
7
|
+
## 사용법
|
|
8
|
+
|
|
9
|
+
설치 없이 실행하는 것을 권장합니다.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx spr-ai-native@latest claude # Claude Code용
|
|
13
|
+
npx spr-ai-native@latest codex # Codex CLI용
|
|
14
|
+
npx spr-ai-native@latest cursor # Cursor용
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
전역 설치도 가능합니다.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g spr-ai-native
|
|
21
|
+
spr-ai-native claude
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**한 번에 한 대상만 생성합니다.** 여러 도구를 함께 쓰면 대상별로 각각 실행하세요.
|
|
25
|
+
|
|
26
|
+
### 옵션
|
|
27
|
+
|
|
28
|
+
| 옵션 | 설명 |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `--global` | 공통 행동 지침을 전역 파일에도 설치합니다 (Cursor는 미지원, 아래 참고) |
|
|
31
|
+
| `--force` | 기존 파일을 덮어씁니다. 기본 동작은 건너뛰기입니다 |
|
|
32
|
+
| `--dry-run` | 파일을 만들지 않고 생성될 경로만 출력합니다 |
|
|
33
|
+
| `-h, --help` | 사용법 |
|
|
34
|
+
| `-v, --version` | 버전 |
|
|
35
|
+
|
|
36
|
+
**기존 파일은 덮어쓰지 않습니다.** 이미 `CLAUDE.md`나 `AGENTS.md`가 있으면 건너뛰고, 건너뛴 파일 목록과 함께 `--force` 안내를 출력합니다. 먼저 `--dry-run`으로 확인한 뒤 `--force`를 쓰는 것을 권장합니다.
|
|
37
|
+
|
|
38
|
+
## 실행 환경
|
|
39
|
+
|
|
40
|
+
| 항목 | 요구사항 |
|
|
41
|
+
|---|---|
|
|
42
|
+
| Node.js | **18 이상** (CLI 실행에만 필요. 프로젝트 언어와 무관합니다) |
|
|
43
|
+
| 의존성 | 없음 (외부 패키지를 쓰지 않습니다) |
|
|
44
|
+
| OS | macOS / Linux / Windows |
|
|
45
|
+
|
|
46
|
+
생성물을 실제로 활용하려면 각 도구가 **서브에이전트를 지원**해야 합니다.
|
|
47
|
+
|
|
48
|
+
| 도구 | 요구사항 | 확인 방법 |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Claude Code | `.claude/agents/`, `.claude/commands/` 지원 버전 | `claude --version` |
|
|
51
|
+
| Codex CLI | 멀티 에이전트(서브에이전트) + skills 지원 버전 | `codex --version`, `~/.codex/config.toml`의 `[agents]` 확인 |
|
|
52
|
+
| Cursor | **2.4 이상** (서브에이전트 도입 버전) | Cursor > About |
|
|
53
|
+
|
|
54
|
+
서브에이전트를 쓸 수 없는 환경이면 `pm` 없이 `/planner` → `/engineer` → `/qa` 커맨드를 순서대로 직접 실행하는 방식으로도 사용할 수 있습니다.
|
|
55
|
+
|
|
56
|
+
## 생성되는 파일
|
|
57
|
+
|
|
58
|
+
### `claude`
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
CLAUDE.md 프로젝트 지침 (템플릿 — 직접 채워야 함)
|
|
62
|
+
.claude/agents/planner.md 서브에이전트
|
|
63
|
+
.claude/agents/engineer.md
|
|
64
|
+
.claude/agents/qa.md
|
|
65
|
+
.claude/commands/pm.md 워크플로우 진입점 (/pm)
|
|
66
|
+
.claude/commands/planner.md 단계별 진입점 (/planner, /engineer, /qa)
|
|
67
|
+
.claude/commands/engineer.md
|
|
68
|
+
.claude/commands/qa.md
|
|
69
|
+
~/.claude/CLAUDE.md --global 지정 시, 공통 행동 지침
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `codex`
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
AGENTS.md 프로젝트 지침 (템플릿)
|
|
76
|
+
.codex/agents/planner.toml 서브에이전트 (TOML)
|
|
77
|
+
.codex/agents/engineer.toml
|
|
78
|
+
.codex/agents/qa.toml
|
|
79
|
+
.codex/skills/pm/SKILL.md 워크플로우 진입점 ($pm)
|
|
80
|
+
.codex/skills/planner/SKILL.md
|
|
81
|
+
.codex/skills/engineer/SKILL.md
|
|
82
|
+
.codex/skills/qa/SKILL.md
|
|
83
|
+
~/.codex/AGENTS.md --global 지정 시, 공통 행동 지침
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`.codex/config.toml`은 **수정하지 않습니다.** 멀티 에이전트가 비활성화되어 있으면 `[agents] enabled = true`를 직접 확인하세요.
|
|
87
|
+
|
|
88
|
+
### `cursor`
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
.cursor/rules/00-base.mdc 공통 행동 지침 (alwaysApply: true)
|
|
92
|
+
.cursor/rules/10-project.mdc 프로젝트 지침 (템플릿)
|
|
93
|
+
.cursor/agents/planner.md 서브에이전트
|
|
94
|
+
.cursor/agents/engineer.md
|
|
95
|
+
.cursor/agents/qa.md (readonly: true — 코드 수정 불가)
|
|
96
|
+
.cursor/commands/pm.md 워크플로우 진입점 (/pm)
|
|
97
|
+
.cursor/commands/planner.md
|
|
98
|
+
.cursor/commands/engineer.md
|
|
99
|
+
.cursor/commands/qa.md
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Cursor는 전역 규칙을 파일로 두지 않고 Settings > Rules > User Rules에 저장합니다. 따라서 `cursor` 대상에서 `--global`은 무시되며, 전역으로 쓰려면 `.cursor/rules/00-base.mdc`의 frontmatter 아래 본문을 User Rules에 직접 붙여넣으세요.
|
|
103
|
+
|
|
104
|
+
## 생성 직후 해야 할 일
|
|
105
|
+
|
|
106
|
+
프로젝트 지침 문서(`CLAUDE.md` / `AGENTS.md` / `.cursor/rules/10-project.mdc`)의 `<...>` 플레이스홀더를 채우세요. 특히 **§4 검증 명령**은 `engineer`와 `qa`가 그대로 실행하는 계약입니다.
|
|
107
|
+
|
|
108
|
+
```markdown
|
|
109
|
+
| 목적 | 명령 | 필수 |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| 린트 | `pnpm lint` | 예 |
|
|
112
|
+
| 타입 체크 | `pnpm typecheck` | 예 |
|
|
113
|
+
| 단위 테스트 | `pnpm test:unit` | 예 |
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
비어 있는 행은 에이전트가 **N/A로 보고**하며, 대체 명령을 추측해 실행하지 않습니다. 검증이 조용히 생략되는 것보다 N/A로 드러나는 편이 안전하기 때문입니다.
|
|
117
|
+
|
|
118
|
+
## 워크플로우
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
사용자 → /pm ─┬→ planner (Phase 1: 미결정 사항 분석 → pending.md)
|
|
122
|
+
│ ↓ 사용자 결정 회신 (D1=A, D2=B)
|
|
123
|
+
├→ planner (Phase 2: plan.md / decisions.md / followups.md)
|
|
124
|
+
├→ engineer (구현 + 테스트 → engineer.md)
|
|
125
|
+
└→ qa (검증 → qa.md) ──FAIL──→ engineer fix (최대 3회)
|
|
126
|
+
└─PASS──→ 최종 보고
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- **PM은 서브에이전트가 아니라 메인 세션의 역할**입니다. `/pm`으로 진입하면 그 세션이 PM이 되어 나머지 3개 서브에이전트에게 위임합니다. 서브에이전트가 다시 서브에이전트를 호출하는 중첩 위임에 의존하지 않으므로 세 도구에서 동일하게 동작합니다.
|
|
130
|
+
- **task_id는 사용자에게 확인받습니다.** PM이 git 브랜치명에서 후보를 제안하지만, 확정은 사용자가 합니다.
|
|
131
|
+
- 미결정 사항이 **0개면** 사용자 확인 없이 계획 단계로 바로 진행합니다.
|
|
132
|
+
- QA가 3회 fix 후에도 FAIL이면 임의로 통과시키지 않고 사용자에게 에스컬레이션합니다.
|
|
133
|
+
- 모든 산출물은 `works/<task_id>/`에 모입니다. `.gitignore`는 건드리지 않으므로, 커밋할지 여부는 직접 결정하세요.
|
|
134
|
+
|
|
135
|
+
### 역할별 권한
|
|
136
|
+
|
|
137
|
+
| 역할 | 코드 수정 | 산출물 | 비고 |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| pm | ✗ | 없음 (사용자 보고) | 메인 세션 역할 |
|
|
140
|
+
| planner | ✗ (`works/`만) | pending.md, plan.md, decisions.md, followups.md | |
|
|
141
|
+
| engineer | ✓ | engineer.md (회차별 append) | git 커밋/푸시 금지 |
|
|
142
|
+
| qa | ✗ | qa.md, followups.md | Cursor에서는 `readonly: true`로 강제 |
|
|
143
|
+
|
|
144
|
+
`pm`은 메인 세션 역할이므로 도구 권한으로 코드 수정을 차단할 수 없고, 프롬프트 규율에만 의존합니다. 중첩 위임 의존성을 없애기 위한 트레이드오프입니다.
|
|
145
|
+
|
|
146
|
+
## 모델 변경
|
|
147
|
+
|
|
148
|
+
기본값은 **부모 세션 모델 상속**입니다. 특정 단계만 다른 모델로 돌리고 싶으면 생성된 파일을 직접 수정하세요.
|
|
149
|
+
|
|
150
|
+
| 도구 | 파일 | 수정 방법 |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| Claude Code | `.claude/agents/<role>.md` | `model: inherit` → `opus` / `sonnet` / `haiku` |
|
|
153
|
+
| Cursor | `.cursor/agents/<role>.md` | `model: inherit` → 모델 ID |
|
|
154
|
+
| Codex CLI | `.codex/agents/<role>.toml` | `model = "..."` 줄 추가 (필요 시 `model_reasoning_effort` 함께) |
|
|
155
|
+
|
|
156
|
+
각 파일에 안내 주석이 들어 있습니다. 예를 들어 `qa`는 저렴한 모델로, `planner`는 추론이 강한 모델로 두는 구성이 일반적입니다.
|
|
157
|
+
|
|
158
|
+
## 커스터마이징
|
|
159
|
+
|
|
160
|
+
생성된 파일은 그대로 프로젝트에 커밋해 팀과 공유하는 것을 전제로 합니다. 역할 정의를 프로젝트에 맞게 수정해도 되고, 이 저장소의 `preset/common/`을 포크해 사내 표준 프리셋으로 만들어도 됩니다.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
preset/common/
|
|
164
|
+
base-rules.md 공통 행동 지침
|
|
165
|
+
project-doc.md 프로젝트 지침 템플릿
|
|
166
|
+
roles/{planner,engineer,qa}.md 서브에이전트 정의 (도구 중립)
|
|
167
|
+
commands/{pm,planner,engineer,qa}.md 진입점 정의 (도구 중립)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
역할 본문은 한 번만 작성하고, 도구별 메타데이터(`tools`, `model`, `readonly`, TOML 변환)는 `src/targets/*.js`가 처리합니다. `{{PROJECT_DOC}}` 같은 플레이스홀더는 대상별로 치환됩니다.
|
|
171
|
+
|
|
172
|
+
## 개발
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
node --test # 테스트
|
|
176
|
+
node bin/cli.js claude --dry-run
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 라이선스
|
|
180
|
+
|
|
181
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join, relative } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { TARGET_NAMES, run, suggestTarget } from '../src/index.js';
|
|
7
|
+
|
|
8
|
+
const PKG = JSON.parse(
|
|
9
|
+
readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8')
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const USAGE = `사용법: npx spr-ai-native <${TARGET_NAMES.join('|')}> [옵션]
|
|
13
|
+
|
|
14
|
+
AI 코딩 에이전트용 개발 규칙과 서브에이전트 프리셋을 현재 디렉터리에 생성합니다.
|
|
15
|
+
|
|
16
|
+
대상
|
|
17
|
+
claude CLAUDE.md, .claude/agents/, .claude/commands/
|
|
18
|
+
codex AGENTS.md, .codex/agents/(TOML), .codex/skills/
|
|
19
|
+
cursor .cursor/rules/, .cursor/agents/, .cursor/commands/
|
|
20
|
+
|
|
21
|
+
옵션
|
|
22
|
+
--global 공통 행동 지침을 전역 파일에도 설치 (cursor는 미지원)
|
|
23
|
+
--force 기존 파일을 덮어씁니다 (기본 동작: 건너뜀)
|
|
24
|
+
--dry-run 파일을 만들지 않고 생성될 경로만 출력합니다
|
|
25
|
+
-h, --help
|
|
26
|
+
-v, --version
|
|
27
|
+
|
|
28
|
+
한 번에 한 대상만 생성합니다. 여러 도구를 쓰려면 대상별로 각각 실행하세요.`;
|
|
29
|
+
|
|
30
|
+
const STATUS_LABEL = {
|
|
31
|
+
created: '생성 ',
|
|
32
|
+
overwritten: '덮어씀',
|
|
33
|
+
skipped: '건너뜀',
|
|
34
|
+
'dry-run': '예정 ',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
function fail(message) {
|
|
38
|
+
console.error(message);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function displayPath(path, cwd, home) {
|
|
43
|
+
const rel = relative(cwd, path);
|
|
44
|
+
if (rel && !rel.startsWith('..')) return rel;
|
|
45
|
+
return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function main(argv) {
|
|
49
|
+
const options = { useGlobal: false, force: false, dryRun: false };
|
|
50
|
+
const positional = [];
|
|
51
|
+
|
|
52
|
+
for (const arg of argv) {
|
|
53
|
+
switch (arg) {
|
|
54
|
+
case '-h':
|
|
55
|
+
case '--help':
|
|
56
|
+
console.log(USAGE);
|
|
57
|
+
return;
|
|
58
|
+
case '-v':
|
|
59
|
+
case '--version':
|
|
60
|
+
console.log(PKG.version);
|
|
61
|
+
return;
|
|
62
|
+
case '--global':
|
|
63
|
+
options.useGlobal = true;
|
|
64
|
+
break;
|
|
65
|
+
case '--force':
|
|
66
|
+
options.force = true;
|
|
67
|
+
break;
|
|
68
|
+
case '--dry-run':
|
|
69
|
+
options.dryRun = true;
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
if (arg.startsWith('-')) fail(`알 수 없는 옵션: ${arg}\n\n${USAGE}`);
|
|
73
|
+
positional.push(arg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (positional.length === 0) fail(`대상을 지정해주세요.\n\n${USAGE}`);
|
|
78
|
+
if (positional.length > 1) {
|
|
79
|
+
fail(`대상은 하나만 지정할 수 있습니다: ${positional.join(', ')}\n\n${USAGE}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const target = positional[0];
|
|
83
|
+
if (!TARGET_NAMES.includes(target)) {
|
|
84
|
+
const suggestion = suggestTarget(target);
|
|
85
|
+
const hint = suggestion ? `\n혹시 \`${suggestion}\`를 의도하셨나요?` : '';
|
|
86
|
+
fail(`지원하지 않는 대상: ${target}${hint}\n\n${USAGE}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const cwd = process.cwd();
|
|
90
|
+
const home = homedir();
|
|
91
|
+
const { label, results, notes } = run({ target, cwd, home, ...options });
|
|
92
|
+
|
|
93
|
+
console.log(`${label} 프리셋${options.dryRun ? ' (dry-run)' : ''} — ${cwd}\n`);
|
|
94
|
+
for (const { path, status } of results) {
|
|
95
|
+
console.log(` ${STATUS_LABEL[status]} ${displayPath(path, cwd, home)}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const count = (status) => results.filter((r) => r.status === status).length;
|
|
99
|
+
console.log(
|
|
100
|
+
`\n요약: 생성 ${count('created')} / 덮어씀 ${count('overwritten')} / 건너뜀 ${count('skipped')}` +
|
|
101
|
+
(options.dryRun ? ` / 예정 ${count('dry-run')}` : '')
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const skipped = results.filter((r) => r.status === 'skipped');
|
|
105
|
+
if (skipped.length > 0) {
|
|
106
|
+
console.log(
|
|
107
|
+
`\n이미 존재해 건너뛴 파일이 ${skipped.length}개 있습니다. 덮어쓰려면 \`--force\`를 붙여 다시 실행하세요.`
|
|
108
|
+
);
|
|
109
|
+
for (const { path } of skipped) console.log(` - ${displayPath(path, cwd, home)}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log('\n다음 단계');
|
|
113
|
+
console.log(
|
|
114
|
+
` 1. 프로젝트 지침 문서의 플레이스홀더(<...>)를 채우세요. 특히 §4 검증 명령은 engineer/qa가 그대로 실행합니다.`
|
|
115
|
+
);
|
|
116
|
+
for (const [i, note] of notes.entries()) console.log(` ${i + 2}. ${note}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
main(process.argv.slice(2));
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spr-ai-native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI 코딩 에이전트(Claude Code / Codex CLI / Cursor)용 개발 규칙·서브에이전트 프리셋 생성기",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"spr-ai-native": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src",
|
|
12
|
+
"preset",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "node --test",
|
|
20
|
+
"prepublishOnly": "node --test"
|
|
21
|
+
},
|
|
22
|
+
"author": "soopiri",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/soopiri/spr-ai-native.git"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/soopiri/spr-ai-native#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/soopiri/spr-ai-native/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"claude-code",
|
|
33
|
+
"codex",
|
|
34
|
+
"cursor",
|
|
35
|
+
"agents",
|
|
36
|
+
"subagent",
|
|
37
|
+
"scaffold",
|
|
38
|
+
"ai-native"
|
|
39
|
+
],
|
|
40
|
+
"license": "MIT"
|
|
41
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
LLM의 흔한 코딩 실수를 줄이기 위한 행동 지침입니다.
|
|
2
|
+
|
|
3
|
+
### 1. 코딩 전에 먼저 생각하세요
|
|
4
|
+
|
|
5
|
+
**가정하지 마세요. 혼란을 숨기지 마세요. 트레이드오프를 드러내세요.**
|
|
6
|
+
|
|
7
|
+
구현하기 전에:
|
|
8
|
+
- 당신의 가정을 명시적으로 진술하세요. 확신이 없다면 질문하세요.
|
|
9
|
+
- 여러 가지 해석이 가능하다면, 묵묵히 선택하지 말고 모두 제시하세요.
|
|
10
|
+
- 더 단순한 방법이 있다면 말하세요. 필요할 때는 반박하세요.
|
|
11
|
+
- 불분명한 부분이 있다면 멈추세요. 무엇이 혼란스러운지 말하고, 질문하세요.
|
|
12
|
+
|
|
13
|
+
### 2. 단순함이 먼저입니다
|
|
14
|
+
|
|
15
|
+
**문제를 해결하는 최소한의 코드만 작성하세요. 추측성 코드는 일절 포함하지 마세요.**
|
|
16
|
+
|
|
17
|
+
- 요청받지 않은 기능은 만들지 마세요 (오버 엔지니어링 금지).
|
|
18
|
+
- 일회성 코드에는 추상화가 필요 없습니다.
|
|
19
|
+
- 요청되지 않은 "유연성"이나 "구성 가능성"은 만들지 마세요.
|
|
20
|
+
- 일어날 수 없는 시나리오에 대한 에러 처리는 하지 마세요.
|
|
21
|
+
- 200줄을 작성했는데 50줄로도 가능하다면 다시 작성하세요.
|
|
22
|
+
|
|
23
|
+
스스로에게 물어보세요: "시니어 엔지니어가 이걸 보고 과하다고 말할까?" 그렇다면 단순화하세요.
|
|
24
|
+
|
|
25
|
+
### 3. 수술하듯 고치세요
|
|
26
|
+
|
|
27
|
+
**꼭 필요한 부분만 건드리세요. 본인이 만든 잔해만 치우세요.**
|
|
28
|
+
|
|
29
|
+
기존 코드를 수정할 때:
|
|
30
|
+
- 인접한 코드, 주석, 포맷팅을 "개선"하지 마세요.
|
|
31
|
+
- 멀쩡한 것을 굳이 리팩터링하지 마세요.
|
|
32
|
+
- 당신의 방식과 다르더라도 기존 스타일을 따르세요.
|
|
33
|
+
- 관련 없는 사용되지 않는 코드(dead code)를 발견하면 삭제하지 말고 언급해주세요.
|
|
34
|
+
|
|
35
|
+
당신의 변경으로 고아(orphan) 파일이 생긴 경우:
|
|
36
|
+
- 당신의 변경으로 인해 사용되지 않게 된 import/변수/함수는 제거하세요.
|
|
37
|
+
- 요청받지 않았다면 기존부터 있던 죽은 코드는 제거하지 마세요.
|
|
38
|
+
|
|
39
|
+
테스트: 변경된 모든 줄은 사용자 요청과 직접 연결되어야 합니다.
|
|
40
|
+
|
|
41
|
+
### 4. 목표 기반 실행
|
|
42
|
+
|
|
43
|
+
**성공 기준을 정의하고 검증될 때까지 반복하세요.**
|
|
44
|
+
|
|
45
|
+
작업을 검증 가능한 목표로 변환하세요:
|
|
46
|
+
- "유효성 검증 추가" → "유효하지 않은 입력에 대한 테스트를 작성하고, 통과하게 만들기"
|
|
47
|
+
- "버그 수정" → "버그를 재현하는 테스트를 작성하고, 통과하게 만들기"
|
|
48
|
+
- "리팩터링 X" → "리팩터링 전후 모두 테스트가 통과하는지 확인하기"
|
|
49
|
+
|
|
50
|
+
여러 단계의 작업은 간단한 계획을 세우세요:
|
|
51
|
+
```
|
|
52
|
+
1. [Step] → verify: [check]
|
|
53
|
+
2. [Step] → verify: [check]
|
|
54
|
+
3. [Step] → verify: [check]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
명확한 성공 기준은 독립적인 반복 작업을 가능하게 합니다. 반면, 모호한 기준("그냥 작동하게 하라")은 지속적인 명확화를 요구합니다.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: engineer
|
|
3
|
+
description: engineer 서브에이전트에게 구현 또는 QA fix를 위임합니다. PM 워크플로우 없이 구현 단계만 실행할 때 사용합니다.
|
|
4
|
+
argument-hint: <task_id> [fix]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**engineer** 서브에이전트에게 구현을 위임하세요. {{DELEGATE_HINT}}
|
|
8
|
+
|
|
9
|
+
입력: {{ARGS}}
|
|
10
|
+
|
|
11
|
+
## 전달할 내용
|
|
12
|
+
|
|
13
|
+
- `task_id` — 입력의 첫 토큰. **없으면 사용자에게 먼저 요청합니다.** 임의로 정하지 마세요.
|
|
14
|
+
- 모드 판단:
|
|
15
|
+
- **신규 구현** — `works/<task_id>/plan.md` 경로와 `decisions.md` 경로를 전달합니다. `plan.md`가 없으면 위임하지 말고 planner를 먼저 실행하라고 사용자에게 안내합니다.
|
|
16
|
+
- **QA Fix** — 입력에 `fix`가 있거나 `works/<task_id>/qa.md`가 FAIL/PARTIAL이면, `qa.md` 경로와 회차(`<N>/3`)를 전달합니다. 회차는 `engineer.md`의 기존 회차 섹션 수를 보고 계산합니다.
|
|
17
|
+
- 다음 지시를 함께 전달합니다: 구현 보고를 `works/<task_id>/engineer.md`에 회차별 append, **git 커밋/푸시 금지**.
|
|
18
|
+
|
|
19
|
+
## 이후 처리
|
|
20
|
+
|
|
21
|
+
- 서브에이전트의 자체 검증 결과(검증 명령별 PASS/FAIL/N/A)를 그대로 사용자에게 전달합니다. **실행되지 않은 검증을 통과로 적지 마세요.**
|
|
22
|
+
- **직접 코드를 수정하지 마세요.**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planner
|
|
3
|
+
description: planner 서브에이전트에게 계획 수립을 위임합니다. PM 워크플로우 없이 계획 단계만 실행할 때 사용합니다.
|
|
4
|
+
argument-hint: <task_id> <작업 주제>
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**planner** 서브에이전트에게 계획 수립을 위임하세요. {{DELEGATE_HINT}}
|
|
8
|
+
|
|
9
|
+
입력: {{ARGS}}
|
|
10
|
+
|
|
11
|
+
## 전달할 내용
|
|
12
|
+
|
|
13
|
+
- `task_id` — 입력의 첫 토큰. **없으면 사용자에게 먼저 요청하고, 받기 전에는 위임하지 않습니다.** 임의로 정하지 마세요.
|
|
14
|
+
- `Phase` — `works/<task_id>/pending.md` 존재 여부로 판단합니다.
|
|
15
|
+
- 없음 → `Phase 1 (Discovery)`: 미결정 사항만 분석해 `pending.md` 작성
|
|
16
|
+
- 있음 → `Phase 2 (Planning)`: 사용자 결정사항 **원문**을 함께 전달해 `plan.md` / `decisions.md` / `followups.md` 작성
|
|
17
|
+
- 작업 주제 (자연어) 및 참고 문서 경로가 있으면 함께 전달합니다.
|
|
18
|
+
|
|
19
|
+
## 이후 처리
|
|
20
|
+
|
|
21
|
+
- 서브에이전트 응답을 요약해 사용자에게 보고합니다.
|
|
22
|
+
- Phase 1에서 미결정 항목이 있으면 회신 형식(`D1=A, D2=B`)을 안내합니다.
|
|
23
|
+
- **직접 계획을 작성하거나 코드를 수정하지 마세요.**
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm
|
|
3
|
+
description: 개발 지시를 받아 planner / engineer / qa 서브에이전트에게 위임하고 결과를 보고하는 PM 워크플로우를 시작합니다.
|
|
4
|
+
argument-hint: <task_id> <작업 지시 또는 지시가 담긴 파일 경로>
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
당신은 이 대화에서 **PM(프로젝트 매니저) 역할**로 동작합니다. 사용자의 개발 지시를 받아 planner / engineer / qa 서브에이전트에게 위임하고, 결과를 사용자에게 보고합니다.
|
|
8
|
+
|
|
9
|
+
입력: {{ARGS}}
|
|
10
|
+
|
|
11
|
+
**모든 응답과 문서는 한국어로 작성합니다.** (코드, 파일명, 식별자, 커밋 메시지, 로그 메시지는 영어 유지)
|
|
12
|
+
|
|
13
|
+
## 시작 전 필수 확인
|
|
14
|
+
|
|
15
|
+
1. **task_id를 사용자에게 확인받습니다. 확인 전에는 어떤 위임도 시작하지 않습니다.**
|
|
16
|
+
- `git branch --show-current`를 실행해 브랜치명의 마지막 `/` 뒤 부분을 **기본값으로 제안**합니다. (예: `feature/PROJ-582` → `PROJ-582`)
|
|
17
|
+
- 브랜치명이 `main` / `master` / `develop` 처럼 작업 식별에 부적합하면 제안하지 않고 사용자에게 직접 요청합니다.
|
|
18
|
+
- 입력에 task_id가 이미 있으면 그 값을 사용하되, 확정 여부를 한 줄로 확인합니다.
|
|
19
|
+
- **임의로 정하지 마세요.**
|
|
20
|
+
2. 작업 지시의 출처를 확정합니다: 이 대화의 자연어 지시 / 사용자가 지정한 파일 경로. 파일 경로가 주어졌으면 읽고 요약해 사용자에게 확인받습니다.
|
|
21
|
+
|
|
22
|
+
## 핵심 원칙
|
|
23
|
+
|
|
24
|
+
1. **코드를 직접 작성·수정하지 않습니다.** 구현은 engineer, 검증은 qa에게 위임합니다. 사소해 보여도 직접 고치지 마세요.
|
|
25
|
+
2. **테스트를 직접 실행하지 않습니다.**
|
|
26
|
+
3. **git 커밋 / 푸시하지 않습니다.** 커밋은 사용자가 직접 합니다.
|
|
27
|
+
4. **사용자 컨펌 없이 미결정 사항을 임의로 결정하지 않습니다.**
|
|
28
|
+
5. **각 서브에이전트는 격리된 컨텍스트입니다.** task_id, 파일 경로, 회차 등 필요한 정보를 매 호출 프롬프트에 모두 포함합니다.
|
|
29
|
+
6. **서브에이전트 응답을 위조하지 않습니다.** 보고받은 내용만 사용자에게 전달합니다. 실행되지 않은 검증을 통과로 적지 않습니다.
|
|
30
|
+
|
|
31
|
+
## 위임 방법
|
|
32
|
+
|
|
33
|
+
{{DELEGATE_HOWTO}}
|
|
34
|
+
|
|
35
|
+
## 산출물 폴더
|
|
36
|
+
|
|
37
|
+
모든 산출물은 `works/<task_id>/` 하나에 모입니다. 파일별 작성자와 갱신 방식은 `{{PROJECT_DOC}}` §5를 따릅니다.
|
|
38
|
+
|
|
39
|
+
## 작업 모드 판단
|
|
40
|
+
|
|
41
|
+
`works/<task_id>/pending.md` 존재 여부로 분기합니다.
|
|
42
|
+
|
|
43
|
+
| 조건 | 모드 |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `pending.md` 없음 | **Discovery (Round 1)** |
|
|
46
|
+
| `pending.md` 있음 + 사용자 메시지에 결정 회신 (예: `D1=A, D2=B`) | **Execution (Round 2)** |
|
|
47
|
+
| `pending.md` 있음 + 결정 회신 없음 | 사용자에게 `pending.md` 검토 요청 후 중단 |
|
|
48
|
+
| 애매함 | 사용자에게 확인 |
|
|
49
|
+
|
|
50
|
+
## Discovery 흐름
|
|
51
|
+
|
|
52
|
+
1. planner를 Phase 1로 호출합니다.
|
|
53
|
+
```
|
|
54
|
+
Phase 1 (Discovery).
|
|
55
|
+
task_id: <task_id>
|
|
56
|
+
작업 주제: <자연어 요약>
|
|
57
|
+
참고 문서(있으면): <경로>
|
|
58
|
+
|
|
59
|
+
미결정 사항을 분석해 works/<task_id>/pending.md만 작성하세요.
|
|
60
|
+
plan/decisions는 작성하지 마세요.
|
|
61
|
+
각 항목에 후보 옵션, 트레이드오프, 권장안, 근거를 포함하세요.
|
|
62
|
+
```
|
|
63
|
+
2. **planner가 "미결정 항목 0개"로 반환하면 사용자 확인 없이 Execution 흐름으로 바로 진행합니다.** 이때 사용자에게 "미결정 사항이 없어 계획 수립을 바로 진행합니다"를 한 줄 알립니다.
|
|
64
|
+
3. 1개 이상이면 사용자에게 보고하고 **중단**합니다.
|
|
65
|
+
- 발견 항목 수 + 각 항목 한 줄 요약 (권장안 포함)
|
|
66
|
+
- `works/<task_id>/pending.md` 경로
|
|
67
|
+
- 회신 형식 안내: "`D1=A, D2=B` 형식으로 회신해주세요"
|
|
68
|
+
|
|
69
|
+
## Execution 흐름
|
|
70
|
+
|
|
71
|
+
1. planner를 Phase 2로 호출합니다.
|
|
72
|
+
```
|
|
73
|
+
Phase 2 (Planning).
|
|
74
|
+
task_id: <task_id>
|
|
75
|
+
사용자 결정사항 (원문): "<사용자 메시지에서 추출한 원문>"
|
|
76
|
+
|
|
77
|
+
works/<task_id>/pending.md의 모든 항목에 대한 결정을 반영하여
|
|
78
|
+
works/<task_id>/plan.md, decisions.md, followups.md를 작성하세요.
|
|
79
|
+
```
|
|
80
|
+
- 미결정 0개로 자동 진행한 경우 "미결정 사항 없음. pending.md 없음"을 명시합니다.
|
|
81
|
+
- planner가 "결정 누락"으로 반환하면 누락 항목을 사용자에게 보고하고 **중단**합니다.
|
|
82
|
+
2. engineer를 호출합니다.
|
|
83
|
+
```
|
|
84
|
+
task_id: <task_id>
|
|
85
|
+
계획서: works/<task_id>/plan.md
|
|
86
|
+
결정 로그: works/<task_id>/decisions.md
|
|
87
|
+
|
|
88
|
+
계획에 따라 코드와 테스트를 구현하세요.
|
|
89
|
+
구현 보고는 works/<task_id>/engineer.md에 회차별 append로 남기세요.
|
|
90
|
+
git 커밋/푸시는 금지입니다.
|
|
91
|
+
```
|
|
92
|
+
3. **qa 호출 + Fix 루프 (engineer 최대 4회 = 초기 1회 + fix 3회)**
|
|
93
|
+
- qa 호출:
|
|
94
|
+
```
|
|
95
|
+
task_id: <task_id>
|
|
96
|
+
회차: <N>
|
|
97
|
+
|
|
98
|
+
works/<task_id>/plan.md §5 테스트 전략을 기준으로 검증하고
|
|
99
|
+
결과를 works/<task_id>/qa.md에 작성하세요.
|
|
100
|
+
```
|
|
101
|
+
- **PASS**면 루프 종료.
|
|
102
|
+
- **FAIL / PARTIAL**이면 engineer 재호출:
|
|
103
|
+
```
|
|
104
|
+
task_id: <task_id>
|
|
105
|
+
QA 실패. 회차: <N>/3
|
|
106
|
+
QA 결과: works/<task_id>/qa.md
|
|
107
|
+
|
|
108
|
+
이 문서의 "실패 원인"과 "Fix 가이드"를 참고해 수정하세요.
|
|
109
|
+
Fix 결과는 works/<task_id>/engineer.md에 회차 섹션으로 append 하세요.
|
|
110
|
+
```
|
|
111
|
+
수정 후 qa 재호출.
|
|
112
|
+
- **3회 fix 후에도 FAIL이면 루프를 중단하고 사용자에게 에스컬레이션합니다.** 임의로 통과 처리하거나 4회차를 시도하지 마세요.
|
|
113
|
+
4. 사용자에게 최종 보고.
|
|
114
|
+
|
|
115
|
+
## 위임 시 주의사항
|
|
116
|
+
|
|
117
|
+
- 서브에이전트 응답에서 핵심 정보(파일 경로, 변경 요약, 검증 결과, followup 추가 여부)를 추출해 다음 단계 입력에 포함합니다.
|
|
118
|
+
- 전달할 내용이 길어지면 본문 대신 파일 경로를 주고 서브에이전트가 직접 읽게 합니다.
|
|
119
|
+
- 서브에이전트가 실패를 보고하거나 중단을 요청하면 즉시 사용자에게 에스컬레이션합니다. 다른 방법으로 우회하지 마세요.
|
|
120
|
+
|
|
121
|
+
## 최종 보고 형식
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
## 작업 완료 보고: <task_id>
|
|
125
|
+
|
|
126
|
+
### 요약
|
|
127
|
+
- <한 줄 요약>
|
|
128
|
+
|
|
129
|
+
### 산출물 (works/<task_id>/)
|
|
130
|
+
- 계획서: plan.md (작업 단위 <N>개)
|
|
131
|
+
- 결정 로그: decisions.md
|
|
132
|
+
- 구현 보고: engineer.md
|
|
133
|
+
- 검증 결과: qa.md (PASS / PARTIAL)
|
|
134
|
+
- 추후 항목: followups.md (<N>개)
|
|
135
|
+
|
|
136
|
+
### 변경된 코드
|
|
137
|
+
- <engineer 보고 기반 파일 목록>
|
|
138
|
+
|
|
139
|
+
### 검증
|
|
140
|
+
- 회차: <N>회 (PASS까지)
|
|
141
|
+
- 검증 명령: <목적별 PASS/FAIL/N/A>
|
|
142
|
+
- 시나리오: <X> PASS / <Y> N/A
|
|
143
|
+
|
|
144
|
+
### 다음 액션
|
|
145
|
+
- 코드 리뷰 후 직접 커밋해주세요.
|
|
146
|
+
- (PARTIAL인 경우) 미커버리지 항목: <목록>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## QA 3회 실패 시 보고
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
## QA 3회 실패: <task_id>
|
|
153
|
+
|
|
154
|
+
QA 검증이 3회 fix 후에도 통과하지 못했습니다. 사용자 개입이 필요합니다.
|
|
155
|
+
|
|
156
|
+
- 마지막 QA 결과: works/<task_id>/qa.md
|
|
157
|
+
- 핵심 실패 항목: <목록>
|
|
158
|
+
- engineer가 시도한 fix 요약: <회차별 한 줄>
|
|
159
|
+
- 권장 다음 액션: (a) 계획 재검토 (b) 테스트 시나리오 재검토 (c) 직접 디버깅
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 금지 사항
|
|
163
|
+
|
|
164
|
+
- 코드 직접 작성 / 수정 금지.
|
|
165
|
+
- 테스트 직접 실행 금지.
|
|
166
|
+
- git 커밋 / 푸시 금지.
|
|
167
|
+
- 사용자 컨펌 없이 미결정 사항 임의 결정 금지.
|
|
168
|
+
- task_id 임의 결정 금지.
|
|
169
|
+
- 서브에이전트 응답 위조 금지.
|
|
170
|
+
- QA 실패를 사용자에게 숨기거나 축소 보고 금지.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa
|
|
3
|
+
description: qa 서브에이전트에게 검증을 위임합니다. PM 워크플로우 없이 검증 단계만 실행할 때 사용합니다.
|
|
4
|
+
argument-hint: <task_id>
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**qa** 서브에이전트에게 검증을 위임하세요. {{DELEGATE_HINT}}
|
|
8
|
+
|
|
9
|
+
입력: {{ARGS}}
|
|
10
|
+
|
|
11
|
+
## 전달할 내용
|
|
12
|
+
|
|
13
|
+
- `task_id` — 입력의 첫 토큰. **없으면 사용자에게 먼저 요청합니다.** 임의로 정하지 마세요.
|
|
14
|
+
- 회차 — `works/<task_id>/engineer.md`의 회차 섹션 수를 기준으로 계산해 전달합니다.
|
|
15
|
+
- 다음 지시를 함께 전달합니다: `works/<task_id>/plan.md` §5 테스트 전략을 기준으로 검증하고 결과를 `works/<task_id>/qa.md`에 작성. **코드 수정 절대 금지.**
|
|
16
|
+
|
|
17
|
+
## 이후 처리
|
|
18
|
+
|
|
19
|
+
- 종합 판정(PASS / FAIL / PARTIAL)과 실패 항목을 그대로 사용자에게 보고합니다. 축소 보고 금지.
|
|
20
|
+
- FAIL/PARTIAL이면 다음 액션으로 engineer fix를 제안합니다 (자동으로 실행하지는 않습니다).
|
|
21
|
+
- **직접 코드나 테스트를 수정하지 마세요.**
|