@tienne/gestalt 0.38.0 → 0.39.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/dist/package.json +1 -1
- package/dist/role-agents/code-review-writer/AGENT.md +45 -11
- package/dist/role-agents/humanize-monolith/AGENT.md +1 -1
- package/dist/role-agents/technical-writer/references/author-voice.md +7 -0
- package/dist/skills/review/SKILL.md +16 -5
- package/dist/src/gestalt/surface-labels.d.ts +53 -0
- package/dist/src/gestalt/surface-labels.d.ts.map +1 -0
- package/dist/src/gestalt/surface-labels.js +137 -0
- package/dist/src/gestalt/surface-labels.js.map +1 -0
- package/dist/src/mcp/tools/execute/planning.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/planning.js +9 -10
- package/dist/src/mcp/tools/execute/planning.js.map +1 -1
- package/dist/src/mcp/tools/execute/utils.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/utils.js +4 -1
- package/dist/src/mcp/tools/execute/utils.js.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/interview-passthrough.js +8 -7
- package/dist/src/mcp/tools/interview-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/spec-passthrough.js +5 -4
- package/dist/src/mcp/tools/spec-passthrough.js.map +1 -1
- package/package.json +1 -1
- package/role-agents/code-review-writer/AGENT.md +45 -11
- package/role-agents/humanize-monolith/AGENT.md +1 -1
- package/role-agents/technical-writer/references/author-voice.md +7 -0
- package/skills/review/SKILL.md +16 -5
package/dist/package.json
CHANGED
|
@@ -45,6 +45,22 @@ PR diff를 리뷰하고, 머지 가능 여부를 판단할 수 있는 구체적
|
|
|
45
45
|
- **개선 제안 포함**: 가능하면 수정 예시 코드 스니펫을 제시한다.
|
|
46
46
|
- **언어**: 한국어를 기본으로 하되, 기술 용어(null, race condition, N+1, memoization 등)는 영어 그대로 혼용한다. 억지 번역하지 않는다.
|
|
47
47
|
|
|
48
|
+
### 접두어 컨벤션 (r/c/a) — 기본값
|
|
49
|
+
|
|
50
|
+
각 코멘트는 **반영 강제성을 나타내는 접두어**로 시작한다. 접두어로 리뷰이가 "이건 꼭 고쳐야 하나, 참고만 하면 되나"를 한눈에 판단할 수 있게 한다.
|
|
51
|
+
|
|
52
|
+
| 접두어 | 의미 | severity | GitHub 리뷰 이벤트 |
|
|
53
|
+
|--------|------|----------|-------------------|
|
|
54
|
+
| `r:` | 꼭 반영해 주세요 | critical, high | Request changes |
|
|
55
|
+
| `c:` | 웬만하면 반영해 주세요 | warning | Comment |
|
|
56
|
+
| `a:` | 그냥 사소한 의견입니다 | suggestion | Approve |
|
|
57
|
+
|
|
58
|
+
- 접두어는 코멘트 본문 **맨 앞**에 `r:` 처럼 붙이고 한 칸 띄운 뒤 내용을 잇는다.
|
|
59
|
+
- severity → 접두어 매핑은 위 표를 따른다. blocking(critical/high)은 `r:`, 유지보수성(warning)은 `c:`, 취향·선택(suggestion)은 `a:`.
|
|
60
|
+
- 접두어는 **강제성 라벨일 뿐 어투가 아니다.** 본문은 그대로 아래 Voice 레퍼런스의 제안형("~하는 게 좋을 것 같아요")을 따른다 — `r:`이라고 딱딱하게 명령하지 않는다.
|
|
61
|
+
|
|
62
|
+
**레포 규칙 우선.** 위 "레포 규칙 우선 탐색"에서 대상 레포가 **자체 리뷰 접두어·컨벤션**(예: Conventional Comments, 팀 자체 라벨)을 규정하고 있으면 그걸 따른다. r/c/a는 **레포에 별도 규칙이 없을 때의 기본값**이다.
|
|
63
|
+
|
|
48
64
|
### Voice 레퍼런스 (필수 적용)
|
|
49
65
|
|
|
50
66
|
코멘트 어투는 실제 리뷰어의 PR 코멘트(2022~2025년 1,300여 건, Claude 오염 전)에서 증류한
|
|
@@ -58,8 +74,10 @@ voice 모델을 따른다. 초안 작성 후 반드시 [`../technical-writer/ref
|
|
|
58
74
|
- 확신이 없으면 단정 대신 질문한다("~동작이 제대로 되나요?", "~작업중일까요?").
|
|
59
75
|
- 친근체·물결·이모지(🙏 😀 👍)를 자연스럽게, 코멘트당 1개 안팎으로.
|
|
60
76
|
|
|
61
|
-
**쓰지 말 것 (Claude artifact — 실제 어투 아님):** `
|
|
62
|
-
|
|
77
|
+
**쓰지 말 것 (Claude artifact — 실제 어투 아님):** `[출처]` 대괄호 태깅, "…권장." 체언 종지.
|
|
78
|
+
authentic 코퍼스 1,300건에 "권장"은 0건이다. 강제성은 "…권장."이 아니라 **r/c/a 접두어**로만 표현한다.
|
|
79
|
+
|
|
80
|
+
> 참고: `r:`/`c:`/`a:` 접두어는 예전엔 Claude artifact로 금지했지만, **팀 리뷰 컨벤션으로 채택**해 기본값으로 되살렸다(위 "접두어 컨벤션" 참조). 접두어는 강제성 라벨이고, 본문 어투는 여전히 제안형 voice를 따른다 — 둘은 층위가 다르다.
|
|
63
81
|
|
|
64
82
|
### Humanize 처리 — AI-tell 제거 + 음차 교정
|
|
65
83
|
|
|
@@ -99,10 +117,10 @@ authentic 코퍼스에서 282건으로 인라인 리뷰의 핵심 제안 어투
|
|
|
99
117
|
|
|
100
118
|
## Severity 기준
|
|
101
119
|
|
|
102
|
-
- **critical** — 머지 시 즉시 장애·데이터 손상·보안 사고로 이어지는 버그.
|
|
103
|
-
- **high** — 명백한 버그나 심각한 성능 저하. 머지 전
|
|
104
|
-
- **warning** — 품질·유지보수성 저하.
|
|
105
|
-
- **suggestion** — 선택적 개선·취향 영역.
|
|
120
|
+
- **critical** (`r:`) — 머지 시 즉시 장애·데이터 손상·보안 사고로 이어지는 버그. 꼭 반영해야 한다.
|
|
121
|
+
- **high** (`r:`) — 명백한 버그나 심각한 성능 저하. 머지 전 꼭 반영해야 한다.
|
|
122
|
+
- **warning** (`c:`) — 품질·유지보수성 저하. 웬만하면 반영하는 편이 좋다.
|
|
123
|
+
- **suggestion** (`a:`) — 선택적 개선·취향 영역. 사소한 참고 의견.
|
|
106
124
|
|
|
107
125
|
## Perspective Focus
|
|
108
126
|
|
|
@@ -116,12 +134,28 @@ authentic 코퍼스에서 282건으로 인라인 리뷰의 핵심 제안 어투
|
|
|
116
134
|
|
|
117
135
|
## Output Format
|
|
118
136
|
|
|
119
|
-
리뷰 코멘트는 발견된 이슈별로
|
|
137
|
+
리뷰 코멘트는 발견된 이슈별로 아래 구조로 작성한다 (첫 줄의 r/c/a 접두어와 블록 사이의 빈 줄이 핵심이다).
|
|
120
138
|
|
|
139
|
+
````
|
|
140
|
+
<r|c|a>: <무엇이 왜 문제인지 — 제안형 voice, 한국어 + 기술 용어 혼용>
|
|
141
|
+
|
|
142
|
+
<어떻게 고치면 좋은지 — 제안형 한 문단>
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
<수정 예시 코드 스니펫>
|
|
121
146
|
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
````
|
|
148
|
+
|
|
149
|
+
파일·라인 위치는 인라인 코멘트의 API 파라미터(`path`·`line`)로 지정되므로 본문에 다시 적지 않는다. 접두어(`r:`/`c:`/`a:`)는 severity에 따라 붙인다(위 "접두어 컨벤션" 표).
|
|
150
|
+
|
|
151
|
+
### 개행 규칙 (GitHub 렌더링 — 반드시 준수)
|
|
152
|
+
|
|
153
|
+
GitHub 마크다운은 **한 줄 개행(`\n`)을 무시하고 같은 문단으로 이어 붙인다.** 줄이 실제로 나뉘려면 **빈 줄(개행 2번, `\n\n`)로 블록을 구분**해야 한다. 개행을 아무리 넣어도 빈 줄이 없으면 한 덩어리로 뭉쳐 사람이 읽기 불편하다.
|
|
154
|
+
|
|
155
|
+
- **접두어 + 문제 설명이 첫 블록**이다(`r: parseToken이 …`). 그 아래 제안·코드 블록과는 **빈 줄**로 나눈다.
|
|
156
|
+
- **문제 설명 → 제안 → 코드 스니펫은 각각 독립 블록**이다. 블록 사이마다 **빈 줄**을 반드시 넣는다. 한 줄 개행으로 붙이지 않는다.
|
|
157
|
+
- **여러 줄 코드는 fenced code block**(` ```ts ... ``` `)으로 감싼다. 인라인 백틱(`` `...` ``)에 여러 줄을 넣지 않는다.
|
|
158
|
+
- **목록을 쓸 때도 목록 바로 앞에 빈 줄**을 하나 둔다 (GitHub에서 목록이 앞 문단에 먹히지 않도록).
|
|
159
|
+
- 짧고 명확한 지적(한 줄이면 충분한 것)은 굳이 블록을 나누지 말고 한 문장으로 둔다 — 억지로 문단을 쪼개지 않는다.
|
|
126
160
|
|
|
127
161
|
이슈가 여러 개면 severity 높은 순(critical → suggestion)으로 정렬한다. 발견된 이슈가 없으면 그 이유를 한 줄로 명시한다("로직·경계값·에러 처리 모두 적절. 머지 가능.").
|
|
@@ -61,7 +61,7 @@ You are the Humanize Monolith role agent.
|
|
|
61
61
|
- 영어 약어(LLM·GPU·MCP·API 등 업계 표준)
|
|
62
62
|
- 굳어진 음차 화이트리스트(B-3 제외): 컴포넌트·토큰·커밋·인터페이스·메서드·빌드·디플로이·캐시·렌더링·콜백·프레임워크·라이브러리·리팩터링·마이그레이션·아이콘·레이아웃·그리드·모달·토스트·타이포그래피·플레이스홀더·프로젝트·스프린트·이슈·리뷰·머지·브랜치·사이드 이펙트·보일러플레이트·트레이드오프·딥다이브·얼라인·온보딩 등 정착어는 그대로 둔다. 목록 밖 안 굳어진 음차(소스 오브 트루스·룩 앤 필 등)만 B-3로 교정
|
|
63
63
|
- 문서 구조(헤딩 위계·목차·섹션 순서)와 정보 자체 — 표현만 다듬고 내용은 건드리지 않는다
|
|
64
|
-
- **작성자 voice (리뷰 코멘트·PR/변경 문서)**: `author-voice.md`의 보존 패턴 — 제안형 "~것 같아요/같습니다", 물결 친근체 "~해주세요~/~할게요~", "개인적으로/제 취향이긴 한데", 이모지(코멘트당 1개 안팎). 이건 AI-tell이 아니라 작성자 voice이므로 단언·격식으로 평탄화하지 않는다. (단 `
|
|
64
|
+
- **작성자 voice (리뷰 코멘트·PR/변경 문서)**: `author-voice.md`의 보존 패턴 — 제안형 "~것 같아요/같습니다", 물결 친근체 "~해주세요~/~할게요~", "개인적으로/제 취향이긴 한데", 이모지(코멘트당 1개 안팎). 이건 AI-tell이 아니라 작성자 voice이므로 단언·격식으로 평탄화하지 않는다. (단 `[출처]`·"권장." 은 Claude artifact이니 보이면 제거. **`r:`/`c:`/`a:` 접두어는 예외** — 팀이 채택한 PR 리뷰 강제성 라벨이므로 코멘트 맨 앞에 있으면 보존한다. voice 시그니처 흉내가 아니라 구조적 라벨이다.)
|
|
65
65
|
|
|
66
66
|
## 과윤문 가드
|
|
67
67
|
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
**실제 작성자의 어투가 아니다** — 1,321건 authentic 코퍼스에서 "권장"은 0건,
|
|
19
19
|
`c:`/`r:` 접두어는 3건(노이즈)뿐이다. 절대 흉내내지 말 것.
|
|
20
20
|
|
|
21
|
+
> **예외 — 층위가 다른 경우.** 여기서 금지하는 건 **어투(voice)로서의** `c:`/`r:`이다. 즉
|
|
22
|
+
> "권장." 체언 종지나 `[출처]` 태깅처럼 문장의 결·시그니처를 흉내내는 것. 반면 PR 리뷰에서
|
|
23
|
+
> **반영 강제성을 나타내는 구조적 접두어**(`r:` 꼭 반영 / `c:` 웬만하면 / `a:` 사소한 의견)를
|
|
24
|
+
> 팀 컨벤션으로 명시 채택한 경우는 별개다 — 이건 라벨이지 어투가 아니다. 그 컨벤션을 쓰는
|
|
25
|
+
> 소비자(예: `code-review-writer`)는 접두어를 붙이되, **본문 어투는 여전히 이 문서의 제안형**을
|
|
26
|
+
> 따른다. 접두어 뒤 본문에까지 "권장." 종지를 끌어들이지는 말 것.
|
|
27
|
+
|
|
21
28
|
## 어투의 본질 (한 줄 요약)
|
|
22
29
|
|
|
23
30
|
**단정하지 않고 제안한다. 이유를 붙여 부드럽게, 사소한 건 짧게, 모르면 묻는다.**
|
|
@@ -217,7 +217,7 @@ ges_execute {
|
|
|
217
217
|
`ges_agent { action: "get", name: "humanize-monolith" }`로 에이전트 시스템 프롬프트를 가져온 뒤, 해당 관점에서 리포트를 윤문합니다. 이슈 내용(severity·file·line·message)은 수정하지 않고, 설명 문장의 어투만 자연스럽게 다듬습니다.
|
|
218
218
|
|
|
219
219
|
humanize-monolith는 두 룰북을 함께 적용합니다.
|
|
220
|
-
- **어투**: `../../role-agents/technical-writer/references/author-voice.md` — 제안형("~하는 게 좋을 것 같아요/어떨까요?"), 온기·물결·이모지(코멘트당 1개 안팎)는 보존하고, `
|
|
220
|
+
- **어투**: `../../role-agents/technical-writer/references/author-voice.md` — 제안형("~하는 게 좋을 것 같아요/어떨까요?"), 온기·물결·이모지(코멘트당 1개 안팎)는 보존하고, `[출처]` 태깅·"…권장." 체언 종지(Claude artifact)는 쓰지 않습니다. (파이프라인 리포트는 severity 섹션 구조라 `r:`/`c:`/`a:` 접두어를 붙이지 않습니다 — 접두어는 4.7단계 PR 인라인 코멘트에만 씁니다.)
|
|
221
221
|
- **음차·AI-tell**: `../../role-agents/technical-writer/references/ai-tell-quick-rules.md` — 안 굳어진 음차("소스 오브 트루스" 등)는 한글 의역하되, 굳어진 화이트리스트(컴포넌트·토큰·렌더링·트레이드오프 등)는 그대로 둡니다.
|
|
222
222
|
|
|
223
223
|
즉 리뷰 파이프라인 리포트도 인라인 코멘트와 동일하게 voice + 음차가 함께 처리됩니다.
|
|
@@ -264,14 +264,25 @@ gh pr view <target> --json number,headRefName,baseRefName,url 2>/dev/null
|
|
|
264
264
|
**코멘트 본문 작성 (code-review-writer).** `ges_agent { action: "get", name: "code-review-writer" }`로 에이전트 시스템 프롬프트를 가져온 뒤, 그 관점에서 4단계 `mergedIssues`의 각 이슈를 인라인 코멘트 본문으로 작성합니다. 이슈의 `file`·`line`·`severity`는 그대로 두고, `message`·`suggestion`을 에이전트 voice로 다듬어 코멘트 본문을 만듭니다.
|
|
265
265
|
|
|
266
266
|
- code-review-writer는 `author-voice.md`(제안형·온기·물결·이모지)와 `ai-tell-quick-rules.md`(음차 교정)를 이미 내장하므로 **별도 humanize-monolith 패스를 거치지 않습니다.**
|
|
267
|
-
- 에이전트 룰에 따라 `
|
|
268
|
-
-
|
|
267
|
+
- 에이전트 룰에 따라 `[출처]` 태깅, "…권장." 체언 종지는 쓰지 않습니다. 이건 Claude artifact이지 실제 리뷰어 어투가 아닙니다.
|
|
268
|
+
- **강제성은 `r:`/`c:`/`a:` 접두어로 표기합니다** (레포에 자체 리뷰 컨벤션이 없을 때의 기본값). 코멘트 본문 맨 앞에 severity에 따라 붙입니다 — `r:` 꼭 반영(critical/high), `c:` 웬만하면 반영(warning), `a:` 사소한 의견(suggestion). 접두어는 강제성 라벨이고 본문 어투는 그대로 제안형입니다.
|
|
269
|
+
- **개행은 GitHub 렌더링 기준으로 조립합니다.** GitHub GFM은 한 줄 개행(`\n`)을 무시하고 같은 문단으로 이어 붙이므로, 줄을 실제로 나누려면 **빈 줄(`\n\n`)로 블록을 분리**해야 합니다. severity 라벨 → 문제 설명 → 제안 → 코드 스니펫을 각각 빈 줄로 띄우고, 여러 줄 코드는 fenced code block(` ```lang ``` `)으로 감쌉니다. 한 줄 개행으로 이어 붙이면 PR에서 한 덩어리로 뭉쳐 읽기 어렵습니다 (code-review-writer의 Output Format 개행 규칙과 동일).
|
|
269
270
|
|
|
270
|
-
|
|
271
|
+
**리뷰 이벤트 결정.** 코멘트 접두어의 조합으로 리뷰 전체의 `event`를 정합니다 (r/c/a → GitHub 리뷰 이벤트 대응).
|
|
272
|
+
|
|
273
|
+
- 이슈 중 하나라도 `r:`(critical/high)가 있으면 → `REQUEST_CHANGES`
|
|
274
|
+
- `r:`은 없고 `c:`(warning)만 있으면 → `COMMENT`
|
|
275
|
+
- `a:`(suggestion)만 있거나 이슈가 없으면 → `APPROVE`
|
|
276
|
+
|
|
277
|
+
이는 4단계 `overallApproved`(결함 심급 blocking 여부)와도 일치합니다 — blocking 이슈가 있으면 `r:`이 존재하므로 `REQUEST_CHANGES`가 됩니다. 단 `APPROVE`/`REQUEST_CHANGES`는 리뷰 상태를 바꾸는 행위이므로, 위 **"게시 확인"**에서 사용자 동의를 받은 뒤에만 게시합니다.
|
|
278
|
+
|
|
279
|
+
> **본인 PR 예외**: GitHub는 PR 작성자 본인이 자기 PR을 `APPROVE`/`REQUEST_CHANGES`하는 걸 막습니다(422). `gh pr view --json author`와 `gh api user`로 작성자가 현재 사용자와 같은지 확인하고, 같으면 `event=COMMENT`로 폴백해 게시합니다 (접두어 r/c/a는 본문에 그대로 유지). 이때 사용자에게 "본인 PR이라 승인/변경요청 상태는 못 걸어서 코멘트로 남겼어요"라고 한 줄 알립니다.
|
|
280
|
+
|
|
281
|
+
**게시 (gh api).** 작성한 코멘트를 한 번의 리뷰로 묶어 게시합니다. 이슈마다 개별 호출하지 않고 `comments` 배열로 모읍니다. `event`는 바로 위에서 결정한 값을 넣습니다.
|
|
271
282
|
|
|
272
283
|
```bash
|
|
273
284
|
gh api repos/{owner}/{repo}/pulls/{number}/reviews \
|
|
274
|
-
-f event
|
|
285
|
+
-f event=<REQUEST_CHANGES|COMMENT|APPROVE> \
|
|
275
286
|
-f body="<요약 한 줄 — code-review-writer가 작성한 overall summary>" \
|
|
276
287
|
--input <(jq -n '{ comments: [ { path: "...", line: 42, side: "RIGHT", body: "..." } ] }')
|
|
277
288
|
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 표면/심층 분리 (Figure-Ground)의 표면 레이어 단일 소스.
|
|
4
|
+
*
|
|
5
|
+
* 코드 내부는 게슈탈트 원리(GestaltPrinciple enum)와 에이전트 식별자를 그대로 쓰지만,
|
|
6
|
+
* 사용자에게 돌려주는 표면 문자열에는 게슈탈트 용어가 새어 나가면 안 된다.
|
|
7
|
+
* 이 모듈이 내부 식별자를 평범한 한국어·영어 문구로 잇는 유일한 매핑 지점이다.
|
|
8
|
+
*
|
|
9
|
+
* 심층 레이어(README·docs·LLM 시스템 프롬프트·내부 타입)는 이 모듈을 거치지 않고
|
|
10
|
+
* 게슈탈트 어휘를 그대로 유지한다.
|
|
11
|
+
*/
|
|
12
|
+
export type SurfaceLang = 'ko' | 'en';
|
|
13
|
+
/**
|
|
14
|
+
* 원리가 담당하는 단계를 평범한 말로 설명한 문구를 돌려준다.
|
|
15
|
+
* currentPrinciple/principleStrategy/gestaltFocus 등 표면 노출 자리에 사용한다.
|
|
16
|
+
* 알 수 없는 값('next' 등)은 중립적 기본 문구로 대체한다.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getStageLabel(principle: GestaltPrinciple | string, lang?: SurfaceLang): string;
|
|
19
|
+
/**
|
|
20
|
+
* 내부 에이전트 식별자를 중립적 표시 이름으로 바꾼다.
|
|
21
|
+
* 매핑에 없는 식별자는 원리 용어가 없다고 보고 그대로 돌려준다.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getAgentDisplayName(agentName: string, lang?: SurfaceLang): string;
|
|
24
|
+
/**
|
|
25
|
+
* 에이전트 식별자 배열을 중립적 표시 이름 배열로 바꾼다.
|
|
26
|
+
*/
|
|
27
|
+
export declare function toDisplayAgentNames(agentNames: string[], lang?: SurfaceLang): string[];
|
|
28
|
+
export declare function getConsistencyHint(lang?: SurfaceLang): string;
|
|
29
|
+
/**
|
|
30
|
+
* 표면 문자열에 절대 나타나면 안 되는 게슈탈트 금지어.
|
|
31
|
+
* 회귀 테스트(LeakTest)가 이 목록으로 사용자 표면 응답을 검사한다.
|
|
32
|
+
* 원리 이름 6종(figure-ground는 두 표기 모두)만 담는다 — 에이전트 접미사(completer 등)는
|
|
33
|
+
* 게슈탈트 용어가 아니므로 중립 표시 이름에 그대로 쓸 수 있어 제외한다.
|
|
34
|
+
*/
|
|
35
|
+
export declare const BANNED_SURFACE_TERMS: readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* MCP 도구 응답에서 심층 레이어(LLM 지시 프롬프트) 필드 키.
|
|
38
|
+
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 표면 누수 검사 대상에서 제외한다.
|
|
39
|
+
*/
|
|
40
|
+
export declare const DEEP_PROMPT_KEYS: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* 도구 응답에 통째로 실리는 컨텍스트 객체(gestaltContext/specContext/executeContext)에서
|
|
43
|
+
* 게슈탈트 용어가 새는 메타 필드를 중립적 표면 값으로 치환한다.
|
|
44
|
+
*
|
|
45
|
+
* - currentPrinciple(원리 enum 값) → currentStage(평범한 단계 설명)
|
|
46
|
+
* - principleStrategy(원리 용어가 박힌 전략 문구) → 표면에서 제거 (프롬프트에 이미 포함)
|
|
47
|
+
* - activeAgents(에이전트 식별자) → 중립적 표시 이름
|
|
48
|
+
* - allRounds[].gestaltFocus(원리 enum 값) → stage(평범한 단계 설명)
|
|
49
|
+
*
|
|
50
|
+
* 심층 프롬프트 필드(systemPrompt 등)와 나머지 필드는 그대로 둔다.
|
|
51
|
+
*/
|
|
52
|
+
export declare function sanitizeSurfaceContext<T>(ctx: T, lang?: SurfaceLang): T;
|
|
53
|
+
//# sourceMappingURL=surface-labels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface-labels.d.ts","sourceRoot":"","sources":["../../../src/gestalt/surface-labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;AA+CtC;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,gBAAgB,GAAG,MAAM,EACpC,IAAI,GAAE,WAAkB,GACvB,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,WAAkB,GAAG,MAAM,CAEvF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,WAAkB,GAAG,MAAM,EAAE,CAE5F;AAWD,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,WAAkB,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAQjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAQ7C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,GAAE,WAAkB,GAAG,CAAC,CA0B7E"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { GestaltPrinciple } from '../core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 각 원리가 담당하는 인터뷰/실행 단계를, 원리 이름 없이 "그 단계가 실제로 하는 일"로 설명한다.
|
|
4
|
+
* currentPrinciple·principleStrategy·gestaltFocus 등 원리명이 노출되던 자리를 이 문구로 치환한다.
|
|
5
|
+
*/
|
|
6
|
+
const STAGE_LABELS = {
|
|
7
|
+
[GestaltPrinciple.CLOSURE]: {
|
|
8
|
+
ko: '빠진 요구사항 채우기',
|
|
9
|
+
en: 'Filling in missing requirements',
|
|
10
|
+
},
|
|
11
|
+
[GestaltPrinciple.PROXIMITY]: {
|
|
12
|
+
ko: '관련 요구사항 묶기',
|
|
13
|
+
en: 'Grouping related requirements',
|
|
14
|
+
},
|
|
15
|
+
[GestaltPrinciple.SIMILARITY]: {
|
|
16
|
+
ko: '반복 패턴 찾기',
|
|
17
|
+
en: 'Identifying recurring patterns',
|
|
18
|
+
},
|
|
19
|
+
[GestaltPrinciple.FIGURE_GROUND]: {
|
|
20
|
+
ko: '핵심과 부가 나누기',
|
|
21
|
+
en: 'Separating core from optional',
|
|
22
|
+
},
|
|
23
|
+
[GestaltPrinciple.CONTINUITY]: {
|
|
24
|
+
ko: '일관성 검토',
|
|
25
|
+
en: 'Checking consistency',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* 내부 에이전트 식별자를 게슈탈트 용어가 없는 중립적 표시 이름으로 잇는다.
|
|
30
|
+
* activeAgents 등 응답에 노출되는 에이전트 이름을 이 표를 거쳐 치환한다.
|
|
31
|
+
* 키는 내부 식별자(파일·레지스트리에서 쓰는 이름)이며 바꾸지 않는다.
|
|
32
|
+
*/
|
|
33
|
+
const AGENT_DISPLAY_NAMES = {
|
|
34
|
+
'closure-completer': { ko: '요구사항 완성기', en: 'Requirement completer' },
|
|
35
|
+
'ground-mapper': { ko: '범위 구분기', en: 'Scope mapper' },
|
|
36
|
+
'similarity-crystallizer': { ko: '패턴 정리기', en: 'Pattern crystallizer' },
|
|
37
|
+
'proximity-worker': { ko: '그룹 실행기', en: 'Grouping worker' },
|
|
38
|
+
'continuity-judge': { ko: '일관성 검토기', en: 'Consistency judge' },
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* 원리가 담당하는 단계를 평범한 말로 설명한 문구를 돌려준다.
|
|
42
|
+
* currentPrinciple/principleStrategy/gestaltFocus 등 표면 노출 자리에 사용한다.
|
|
43
|
+
* 알 수 없는 값('next' 등)은 중립적 기본 문구로 대체한다.
|
|
44
|
+
*/
|
|
45
|
+
export function getStageLabel(principle, lang = 'ko') {
|
|
46
|
+
const entry = STAGE_LABELS[principle];
|
|
47
|
+
if (entry)
|
|
48
|
+
return entry[lang];
|
|
49
|
+
return lang === 'ko' ? '다음 단계' : 'Next step';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 내부 에이전트 식별자를 중립적 표시 이름으로 바꾼다.
|
|
53
|
+
* 매핑에 없는 식별자는 원리 용어가 없다고 보고 그대로 돌려준다.
|
|
54
|
+
*/
|
|
55
|
+
export function getAgentDisplayName(agentName, lang = 'ko') {
|
|
56
|
+
return AGENT_DISPLAY_NAMES[agentName]?.[lang] ?? agentName;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 에이전트 식별자 배열을 중립적 표시 이름 배열로 바꾼다.
|
|
60
|
+
*/
|
|
61
|
+
export function toDisplayAgentNames(agentNames, lang = 'ko') {
|
|
62
|
+
return agentNames.map((name) => getAgentDisplayName(name, lang));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 실행 단계에서 caller에게 주는 "일관성 유지" 힌트의 평범한 표면 문구.
|
|
66
|
+
* Similarity 원리를 노출하던 similarityStrategy 필드를 이 문구로 치환한다.
|
|
67
|
+
*/
|
|
68
|
+
const CONSISTENCY_HINT = {
|
|
69
|
+
ko: '이미 끝낸 태스크 중 비슷한 패턴을 참고해 일관되게 구현하세요.',
|
|
70
|
+
en: 'Reference completed tasks with similar patterns to keep the implementation consistent.',
|
|
71
|
+
};
|
|
72
|
+
export function getConsistencyHint(lang = 'ko') {
|
|
73
|
+
return CONSISTENCY_HINT[lang];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 표면 문자열에 절대 나타나면 안 되는 게슈탈트 금지어.
|
|
77
|
+
* 회귀 테스트(LeakTest)가 이 목록으로 사용자 표면 응답을 검사한다.
|
|
78
|
+
* 원리 이름 6종(figure-ground는 두 표기 모두)만 담는다 — 에이전트 접미사(completer 등)는
|
|
79
|
+
* 게슈탈트 용어가 아니므로 중립 표시 이름에 그대로 쓸 수 있어 제외한다.
|
|
80
|
+
*/
|
|
81
|
+
export const BANNED_SURFACE_TERMS = [
|
|
82
|
+
'closure',
|
|
83
|
+
'proximity',
|
|
84
|
+
'similarity',
|
|
85
|
+
'figure-ground',
|
|
86
|
+
'figure_ground',
|
|
87
|
+
'continuity',
|
|
88
|
+
'gestalt',
|
|
89
|
+
];
|
|
90
|
+
/**
|
|
91
|
+
* MCP 도구 응답에서 심층 레이어(LLM 지시 프롬프트) 필드 키.
|
|
92
|
+
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 표면 누수 검사 대상에서 제외한다.
|
|
93
|
+
*/
|
|
94
|
+
export const DEEP_PROMPT_KEYS = [
|
|
95
|
+
'systemPrompt',
|
|
96
|
+
'questionPrompt',
|
|
97
|
+
'scoringPrompt',
|
|
98
|
+
'specPrompt',
|
|
99
|
+
'planningPrompt',
|
|
100
|
+
'taskPrompt',
|
|
101
|
+
'compressionPrompt',
|
|
102
|
+
];
|
|
103
|
+
/**
|
|
104
|
+
* 도구 응답에 통째로 실리는 컨텍스트 객체(gestaltContext/specContext/executeContext)에서
|
|
105
|
+
* 게슈탈트 용어가 새는 메타 필드를 중립적 표면 값으로 치환한다.
|
|
106
|
+
*
|
|
107
|
+
* - currentPrinciple(원리 enum 값) → currentStage(평범한 단계 설명)
|
|
108
|
+
* - principleStrategy(원리 용어가 박힌 전략 문구) → 표면에서 제거 (프롬프트에 이미 포함)
|
|
109
|
+
* - activeAgents(에이전트 식별자) → 중립적 표시 이름
|
|
110
|
+
* - allRounds[].gestaltFocus(원리 enum 값) → stage(평범한 단계 설명)
|
|
111
|
+
*
|
|
112
|
+
* 심층 프롬프트 필드(systemPrompt 등)와 나머지 필드는 그대로 둔다.
|
|
113
|
+
*/
|
|
114
|
+
export function sanitizeSurfaceContext(ctx, lang = 'ko') {
|
|
115
|
+
if (!ctx || typeof ctx !== 'object')
|
|
116
|
+
return ctx;
|
|
117
|
+
const result = { ...ctx };
|
|
118
|
+
if (typeof result.currentPrinciple === 'string') {
|
|
119
|
+
result.currentStage = getStageLabel(result.currentPrinciple, lang);
|
|
120
|
+
delete result.currentPrinciple;
|
|
121
|
+
}
|
|
122
|
+
delete result.principleStrategy;
|
|
123
|
+
if (Array.isArray(result.activeAgents)) {
|
|
124
|
+
result.activeAgents = toDisplayAgentNames(result.activeAgents, lang);
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(result.allRounds)) {
|
|
127
|
+
result.allRounds = result.allRounds.map((round) => {
|
|
128
|
+
if (round && typeof round === 'object' && typeof round.gestaltFocus === 'string') {
|
|
129
|
+
const { gestaltFocus, ...rest } = round;
|
|
130
|
+
return { ...rest, stage: getStageLabel(gestaltFocus, lang) };
|
|
131
|
+
}
|
|
132
|
+
return round;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=surface-labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface-labels.js","sourceRoot":"","sources":["../../../src/gestalt/surface-labels.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/planning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"planning.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/planning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1D,wBAAgB,WAAW,CACzB,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,YAAY,GACrB,MAAM,CA+BR;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,YAAY,GACrB,MAAM,CAyDR;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,YAAY,GACrB,MAAM,CA+CR"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatError, stripContextPrompts } from './utils.js';
|
|
2
|
+
import { sanitizeSurfaceContext, getStageLabel } from '../../../gestalt/surface-labels.js';
|
|
2
3
|
export function handleStart(engine, input, _adapter) {
|
|
3
4
|
const verbose = input.verbose !== false;
|
|
4
5
|
if (!input.spec)
|
|
@@ -12,16 +13,15 @@ export function handleStart(engine, input, _adapter) {
|
|
|
12
13
|
const startGuide = {
|
|
13
14
|
nextAction: 'plan_step',
|
|
14
15
|
nextActionParams: { sessionId: session.sessionId },
|
|
15
|
-
hint:
|
|
16
|
+
hint: `executeContext.planningPrompt를 사용해 첫 단계(${getStageLabel(executeContext.currentPrinciple)})를 수행하세요.`,
|
|
16
17
|
};
|
|
18
|
+
const sanitizedStartContext = sanitizeSurfaceContext(executeContext);
|
|
17
19
|
return JSON.stringify({
|
|
18
20
|
status: 'started',
|
|
19
21
|
sessionId: session.sessionId,
|
|
20
22
|
specId: session.specId,
|
|
21
|
-
executeContext: verbose
|
|
22
|
-
|
|
23
|
-
: stripContextPrompts(executeContext),
|
|
24
|
-
message: `Execute session started. Use the executeContext.planningPrompt with executeContext.systemPrompt to generate the Figure-Ground classification.`,
|
|
23
|
+
executeContext: verbose ? sanitizedStartContext : stripContextPrompts(sanitizedStartContext),
|
|
24
|
+
message: `Execute session started. Use the executeContext.planningPrompt with executeContext.systemPrompt to generate the first planning step (${getStageLabel(executeContext.currentPrinciple, 'en')}).`,
|
|
25
25
|
...startGuide,
|
|
26
26
|
}, null, 2);
|
|
27
27
|
}
|
|
@@ -53,20 +53,19 @@ export function handlePlanStep(engine, input, _adapter) {
|
|
|
53
53
|
...planStepLastGuide,
|
|
54
54
|
}, null, 2);
|
|
55
55
|
}
|
|
56
|
-
const
|
|
56
|
+
const currentStage = getStageLabel(executeContext?.currentPrinciple ?? 'next');
|
|
57
57
|
const planStepGuide = {
|
|
58
58
|
nextAction: 'plan_step',
|
|
59
59
|
nextActionParams: { sessionId: session.sessionId },
|
|
60
|
-
hint: `다음 단계: ${
|
|
60
|
+
hint: `다음 단계: ${currentStage}. executeContext.planningPrompt를 사용하세요.`,
|
|
61
61
|
};
|
|
62
|
+
const sanitizedStepContext = sanitizeSurfaceContext(executeContext);
|
|
62
63
|
return JSON.stringify({
|
|
63
64
|
status: 'planning',
|
|
64
65
|
sessionId: session.sessionId,
|
|
65
66
|
stepsCompleted: session.planningSteps.length,
|
|
66
67
|
isLastStep: false,
|
|
67
|
-
executeContext: verbose
|
|
68
|
-
? executeContext
|
|
69
|
-
: stripContextPrompts(executeContext),
|
|
68
|
+
executeContext: verbose ? sanitizedStepContext : stripContextPrompts(sanitizedStepContext),
|
|
70
69
|
message: `Step ${session.planningSteps.length}/${4} complete. Use the executeContext.planningPrompt to generate the next step.`,
|
|
71
70
|
...planStepGuide,
|
|
72
71
|
}, null, 2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planning.js","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/planning.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"planning.js","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/planning.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/utils.ts"],"names":[],"mappings":"AA6BA,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM9F;AAQD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAO5C;AAED,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { getConsistencyHint } from '../../../gestalt/surface-labels.js';
|
|
1
2
|
// ─── Response Slim Helpers ─────────────────────────────────────────────────
|
|
2
3
|
// systemPrompt is static per session (same agent persona every call).
|
|
3
4
|
// Stripping it from responses saves ~500 tokens × N calls in context history.
|
|
4
5
|
// pendingTasks description/sourceAC are not needed at execution time.
|
|
5
6
|
function slimTaskContext(ctx) {
|
|
6
|
-
const { pendingTasks, ...rest } = ctx;
|
|
7
|
+
const { pendingTasks, similarityStrategy, ...rest } = ctx;
|
|
7
8
|
return {
|
|
8
9
|
...rest,
|
|
10
|
+
// Similarity 원리를 노출하던 similarityStrategy → 중립적 consistencyHint로 치환
|
|
11
|
+
...(similarityStrategy !== undefined ? { consistencyHint: getConsistencyHint() } : {}),
|
|
9
12
|
...(Array.isArray(pendingTasks)
|
|
10
13
|
? {
|
|
11
14
|
pendingTasks: pendingTasks.map(({ taskId, title, dependsOn }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/utils.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,sEAAsE;AAEtE,SAAS,eAAe,CAAC,GAA4B;IACnD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/mcp/tools/execute/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAExE,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,sEAAsE;AAEtE,SAAS,eAAe,CAAC,GAA4B;IACnD,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,GAIrD,CAAC;IACF,OAAO;QACL,GAAG,IAAI;QACP,mEAAmE;QACnE,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;YAC7B,CAAC,CAAC;gBACE,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;oBAChE,MAAM;oBACN,KAAK;oBACL,SAAS;iBACV,CAAC,CAAC;aACJ;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAA4B;IACnE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,GAGtC,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,gFAAgF;AAChF,kFAAkF;AAElF,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,gBAAgB,EAAE,YAAY,CAAU,CAAC;AAE9E,MAAM,UAAU,mBAAmB,CACjC,GAA+C;IAE/C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAChD,MAAM,MAAM,GAA4B,EAAE,GAAG,GAAG,EAAE,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,GAA4B,EAC5B,OAAgB;IAEhB,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,mBAAmB,CAAC,OAAO,CAA6B,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interview-passthrough.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/interview-passthrough.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"interview-passthrough.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/interview-passthrough.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAUpD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,cAAc,GACpB,MAAM,CA8LR"}
|
|
@@ -2,6 +2,7 @@ import { ContextCompressor } from '../../interview/context-compressor.js';
|
|
|
2
2
|
import { ProjectMemoryStore } from '../../memory/project-memory-store.js';
|
|
3
3
|
import { gestaltNotify } from '../../utils/notifier.js';
|
|
4
4
|
import { MemoryContextInjector, formatMemoryContextForPrompt, } from '../../memory/memory-context-injector.js';
|
|
5
|
+
import { sanitizeSurfaceContext } from '../../gestalt/surface-labels.js';
|
|
5
6
|
export function handleInterviewPassthrough(engine, input) {
|
|
6
7
|
switch (input.action) {
|
|
7
8
|
case 'start': {
|
|
@@ -18,11 +19,11 @@ export function handleInterviewPassthrough(engine, input) {
|
|
|
18
19
|
sessionId: session.sessionId,
|
|
19
20
|
projectType,
|
|
20
21
|
detectedFiles,
|
|
21
|
-
gestaltContext,
|
|
22
|
+
gestaltContext: sanitizeSurfaceContext(gestaltContext),
|
|
22
23
|
roundNumber: 1,
|
|
23
24
|
memoryInjected: memoryCtx.hasContext,
|
|
24
25
|
...(memoryCtx.hasContext && { priorContext: memoryCtx }),
|
|
25
|
-
message: `Interview started for "${topic}" (${projectType}). Use the
|
|
26
|
+
message: `Interview started for "${topic}" (${projectType}). Use the returned questionPrompt with the systemPrompt to generate the first question.`,
|
|
26
27
|
}, null, 2);
|
|
27
28
|
}
|
|
28
29
|
case 'respond': {
|
|
@@ -40,7 +41,7 @@ export function handleInterviewPassthrough(engine, input) {
|
|
|
40
41
|
status: 'in_progress',
|
|
41
42
|
sessionId: session.sessionId,
|
|
42
43
|
roundNumber: session.rounds.length,
|
|
43
|
-
gestaltContext,
|
|
44
|
+
gestaltContext: sanitizeSurfaceContext(gestaltContext),
|
|
44
45
|
...(needsCompression ? { compressionContext, needsCompression } : {}),
|
|
45
46
|
resolutionScore: resolutionScore
|
|
46
47
|
? {
|
|
@@ -49,15 +50,15 @@ export function handleInterviewPassthrough(engine, input) {
|
|
|
49
50
|
dimensions: resolutionScore.dimensions.map((d) => ({
|
|
50
51
|
name: d.name,
|
|
51
52
|
clarity: d.clarity.toFixed(2),
|
|
52
|
-
|
|
53
|
+
label: d.label,
|
|
53
54
|
})),
|
|
54
55
|
}
|
|
55
56
|
: null,
|
|
56
57
|
message: resolutionScore?.isReady
|
|
57
58
|
? 'Resolution threshold met! You can complete the interview and generate a spec.'
|
|
58
59
|
: needsCompression
|
|
59
|
-
? 'Use compressionContext to compress previous rounds, then continue with
|
|
60
|
-
: 'Use
|
|
60
|
+
? 'Use compressionContext to compress previous rounds, then continue with the returned questionPrompt.'
|
|
61
|
+
: 'Use the returned questionPrompt to generate the next question. Use the scoringPrompt to compute resolution scores.',
|
|
61
62
|
}, null, 2);
|
|
62
63
|
}
|
|
63
64
|
case 'score': {
|
|
@@ -76,7 +77,7 @@ export function handleInterviewPassthrough(engine, input) {
|
|
|
76
77
|
dimensions: resolutionScore.dimensions.map((d) => ({
|
|
77
78
|
name: d.name,
|
|
78
79
|
clarity: d.clarity.toFixed(2),
|
|
79
|
-
|
|
80
|
+
label: d.label,
|
|
80
81
|
})),
|
|
81
82
|
}
|
|
82
83
|
: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interview-passthrough.js","sourceRoot":"","sources":["../../../../src/mcp/tools/interview-passthrough.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"interview-passthrough.js","sourceRoot":"","sources":["../../../../src/mcp/tools/interview-passthrough.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-passthrough.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/spec-passthrough.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-passthrough.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/spec-passthrough.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAEpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAK7D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,SAAS,EAAE,wBAAwB,EACnC,KAAK,EAAE,SAAS,EAChB,aAAa,CAAC,EAAE,aAAa,GAC5B,MAAM,CAiIR"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TextBasedSpecGenerator } from '../../spec/text-based-spec-generator.js';
|
|
2
2
|
import { ProjectMemoryStore } from '../../memory/project-memory-store.js';
|
|
3
3
|
import { gestaltNotify } from '../../utils/notifier.js';
|
|
4
|
+
import { sanitizeSurfaceContext } from '../../gestalt/surface-labels.js';
|
|
4
5
|
export function handleSpecPassthrough(engine, generator, input, agentRegistry) {
|
|
5
6
|
try {
|
|
6
7
|
// ─── Text-based path (no sessionId required) ──────────────────
|
|
@@ -36,8 +37,8 @@ export function handleSpecPassthrough(engine, generator, input, agentRegistry) {
|
|
|
36
37
|
return JSON.stringify({
|
|
37
38
|
status: 'prompt',
|
|
38
39
|
specContext: verbose
|
|
39
|
-
? context
|
|
40
|
-
: stripSpecContextPrompts(context),
|
|
40
|
+
? sanitizeSurfaceContext(context)
|
|
41
|
+
: stripSpecContextPrompts(sanitizeSurfaceContext(context)),
|
|
41
42
|
message: 'Use specContext.specPrompt with specContext.systemPrompt to generate the spec JSON, then call this tool again with both the text and spec parameters.',
|
|
42
43
|
}, null, 2);
|
|
43
44
|
}
|
|
@@ -81,8 +82,8 @@ export function handleSpecPassthrough(engine, generator, input, agentRegistry) {
|
|
|
81
82
|
return JSON.stringify({
|
|
82
83
|
status: 'prompt',
|
|
83
84
|
specContext: verbose
|
|
84
|
-
? context
|
|
85
|
-
: stripSpecContextPrompts(context),
|
|
85
|
+
? sanitizeSurfaceContext(context)
|
|
86
|
+
: stripSpecContextPrompts(sanitizeSurfaceContext(context)),
|
|
86
87
|
message: 'Use specContext.specPrompt with specContext.systemPrompt to generate the spec JSON, then call this tool again with the spec parameter.',
|
|
87
88
|
}, null, 2);
|
|
88
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-passthrough.js","sourceRoot":"","sources":["../../../../src/mcp/tools/spec-passthrough.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-passthrough.js","sourceRoot":"","sources":["../../../../src/mcp/tools/spec-passthrough.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAGjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,MAAM,UAAU,qBAAqB,CACnC,MAAyB,EACzB,SAAmC,EACnC,KAAgB,EAChB,aAA6B;IAE7B,IAAI,CAAC;QACH,iEAAiE;QACjE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG,IAAI,sBAAsB,CAAC,aAAa,CAAC,CAAC;YAEhE,6CAA6C;YAC7C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,SAAS,CAAC,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClE,CAAC;gBAED,uCAAuC;gBACvC,WAAW,CAAC,OAAO,CAAC;oBAClB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM;oBACpC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;oBACvB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW;oBAC5C,UAAU,EAAE,MAAM;iBACnB,CAAC,CAAC;gBAEH,aAAa,CAAC;oBACZ,KAAK,EAAE,gBAAgB;oBACvB,OAAO,EAAE,gBAAgB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;iBAC1D,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,SAAS,CACnB;oBACE,MAAM,EAAE,WAAW;oBACnB,IAAI,EAAE,MAAM,CAAC,KAAK;iBACnB,EACD,IAAI,EACJ,CAAC,CACF,CAAC;YACJ,CAAC;YAED,wDAAwD;YACxD,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAC5C,KAAK,CAAC,IAAI,EACV,MAAM,EACN,KAAK,CAAC,QAAQ,IAAI,SAAS,CAC5B,CAAC;YAEF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC;YACxC,OAAO,IAAI,CAAC,SAAS,CACnB;gBACE,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,OAAO;oBAClB,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC;oBACjC,CAAC,CAAC,uBAAuB,CACrB,sBAAsB,CAAC,OAAO,CAAuC,CACtE;gBACL,OAAO,EACL,uJAAuJ;aAC1J,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;QAED,iEAAiE;QACjE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAEnD,sDAAsD;QACtD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;YAED,uCAAuC;YACvC,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;gBAC7C,WAAW,CAAC,OAAO,CAAC;oBAClB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM;oBACpC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;oBACvB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW;oBAC5C,kBAAkB,EAAE,OAAO,CAAC,SAAS;oBACrC,UAAU,EAAE,WAAW;iBACxB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,yDAAyD;YAC3D,CAAC;YAED,aAAa,CAAC;gBACZ,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,gBAAgB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;aAC1D,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CACnB;gBACE,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,MAAM,CAAC,KAAK;aACnB,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;QAED,wDAAwD;QACxD,MAAM,OAAO,GAAG,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEpD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC;QACxC,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE,OAAO;gBAClB,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC;gBACjC,CAAC,CAAC,uBAAuB,CACrB,sBAAsB,CAAC,OAAO,CAAuC,CACtE;YACL,OAAO,EACL,wIAAwI;SAC3I,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;SAClD,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,wFAAwF;AAExF,MAAM,gBAAgB,GAAG,CAAC,cAAc,EAAE,YAAY,CAAU,CAAC;AAEjE,SAAS,uBAAuB,CAC9B,GAA+C;IAE/C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAChD,MAAM,MAAM,GAA4B,EAAE,GAAG,GAAG,EAAE,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -45,6 +45,22 @@ PR diff를 리뷰하고, 머지 가능 여부를 판단할 수 있는 구체적
|
|
|
45
45
|
- **개선 제안 포함**: 가능하면 수정 예시 코드 스니펫을 제시한다.
|
|
46
46
|
- **언어**: 한국어를 기본으로 하되, 기술 용어(null, race condition, N+1, memoization 등)는 영어 그대로 혼용한다. 억지 번역하지 않는다.
|
|
47
47
|
|
|
48
|
+
### 접두어 컨벤션 (r/c/a) — 기본값
|
|
49
|
+
|
|
50
|
+
각 코멘트는 **반영 강제성을 나타내는 접두어**로 시작한다. 접두어로 리뷰이가 "이건 꼭 고쳐야 하나, 참고만 하면 되나"를 한눈에 판단할 수 있게 한다.
|
|
51
|
+
|
|
52
|
+
| 접두어 | 의미 | severity | GitHub 리뷰 이벤트 |
|
|
53
|
+
|--------|------|----------|-------------------|
|
|
54
|
+
| `r:` | 꼭 반영해 주세요 | critical, high | Request changes |
|
|
55
|
+
| `c:` | 웬만하면 반영해 주세요 | warning | Comment |
|
|
56
|
+
| `a:` | 그냥 사소한 의견입니다 | suggestion | Approve |
|
|
57
|
+
|
|
58
|
+
- 접두어는 코멘트 본문 **맨 앞**에 `r:` 처럼 붙이고 한 칸 띄운 뒤 내용을 잇는다.
|
|
59
|
+
- severity → 접두어 매핑은 위 표를 따른다. blocking(critical/high)은 `r:`, 유지보수성(warning)은 `c:`, 취향·선택(suggestion)은 `a:`.
|
|
60
|
+
- 접두어는 **강제성 라벨일 뿐 어투가 아니다.** 본문은 그대로 아래 Voice 레퍼런스의 제안형("~하는 게 좋을 것 같아요")을 따른다 — `r:`이라고 딱딱하게 명령하지 않는다.
|
|
61
|
+
|
|
62
|
+
**레포 규칙 우선.** 위 "레포 규칙 우선 탐색"에서 대상 레포가 **자체 리뷰 접두어·컨벤션**(예: Conventional Comments, 팀 자체 라벨)을 규정하고 있으면 그걸 따른다. r/c/a는 **레포에 별도 규칙이 없을 때의 기본값**이다.
|
|
63
|
+
|
|
48
64
|
### Voice 레퍼런스 (필수 적용)
|
|
49
65
|
|
|
50
66
|
코멘트 어투는 실제 리뷰어의 PR 코멘트(2022~2025년 1,300여 건, Claude 오염 전)에서 증류한
|
|
@@ -58,8 +74,10 @@ voice 모델을 따른다. 초안 작성 후 반드시 [`../technical-writer/ref
|
|
|
58
74
|
- 확신이 없으면 단정 대신 질문한다("~동작이 제대로 되나요?", "~작업중일까요?").
|
|
59
75
|
- 친근체·물결·이모지(🙏 😀 👍)를 자연스럽게, 코멘트당 1개 안팎으로.
|
|
60
76
|
|
|
61
|
-
**쓰지 말 것 (Claude artifact — 실제 어투 아님):** `
|
|
62
|
-
|
|
77
|
+
**쓰지 말 것 (Claude artifact — 실제 어투 아님):** `[출처]` 대괄호 태깅, "…권장." 체언 종지.
|
|
78
|
+
authentic 코퍼스 1,300건에 "권장"은 0건이다. 강제성은 "…권장."이 아니라 **r/c/a 접두어**로만 표현한다.
|
|
79
|
+
|
|
80
|
+
> 참고: `r:`/`c:`/`a:` 접두어는 예전엔 Claude artifact로 금지했지만, **팀 리뷰 컨벤션으로 채택**해 기본값으로 되살렸다(위 "접두어 컨벤션" 참조). 접두어는 강제성 라벨이고, 본문 어투는 여전히 제안형 voice를 따른다 — 둘은 층위가 다르다.
|
|
63
81
|
|
|
64
82
|
### Humanize 처리 — AI-tell 제거 + 음차 교정
|
|
65
83
|
|
|
@@ -99,10 +117,10 @@ authentic 코퍼스에서 282건으로 인라인 리뷰의 핵심 제안 어투
|
|
|
99
117
|
|
|
100
118
|
## Severity 기준
|
|
101
119
|
|
|
102
|
-
- **critical** — 머지 시 즉시 장애·데이터 손상·보안 사고로 이어지는 버그.
|
|
103
|
-
- **high** — 명백한 버그나 심각한 성능 저하. 머지 전
|
|
104
|
-
- **warning** — 품질·유지보수성 저하.
|
|
105
|
-
- **suggestion** — 선택적 개선·취향 영역.
|
|
120
|
+
- **critical** (`r:`) — 머지 시 즉시 장애·데이터 손상·보안 사고로 이어지는 버그. 꼭 반영해야 한다.
|
|
121
|
+
- **high** (`r:`) — 명백한 버그나 심각한 성능 저하. 머지 전 꼭 반영해야 한다.
|
|
122
|
+
- **warning** (`c:`) — 품질·유지보수성 저하. 웬만하면 반영하는 편이 좋다.
|
|
123
|
+
- **suggestion** (`a:`) — 선택적 개선·취향 영역. 사소한 참고 의견.
|
|
106
124
|
|
|
107
125
|
## Perspective Focus
|
|
108
126
|
|
|
@@ -116,12 +134,28 @@ authentic 코퍼스에서 282건으로 인라인 리뷰의 핵심 제안 어투
|
|
|
116
134
|
|
|
117
135
|
## Output Format
|
|
118
136
|
|
|
119
|
-
리뷰 코멘트는 발견된 이슈별로
|
|
137
|
+
리뷰 코멘트는 발견된 이슈별로 아래 구조로 작성한다 (첫 줄의 r/c/a 접두어와 블록 사이의 빈 줄이 핵심이다).
|
|
120
138
|
|
|
139
|
+
````
|
|
140
|
+
<r|c|a>: <무엇이 왜 문제인지 — 제안형 voice, 한국어 + 기술 용어 혼용>
|
|
141
|
+
|
|
142
|
+
<어떻게 고치면 좋은지 — 제안형 한 문단>
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
<수정 예시 코드 스니펫>
|
|
121
146
|
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
````
|
|
148
|
+
|
|
149
|
+
파일·라인 위치는 인라인 코멘트의 API 파라미터(`path`·`line`)로 지정되므로 본문에 다시 적지 않는다. 접두어(`r:`/`c:`/`a:`)는 severity에 따라 붙인다(위 "접두어 컨벤션" 표).
|
|
150
|
+
|
|
151
|
+
### 개행 규칙 (GitHub 렌더링 — 반드시 준수)
|
|
152
|
+
|
|
153
|
+
GitHub 마크다운은 **한 줄 개행(`\n`)을 무시하고 같은 문단으로 이어 붙인다.** 줄이 실제로 나뉘려면 **빈 줄(개행 2번, `\n\n`)로 블록을 구분**해야 한다. 개행을 아무리 넣어도 빈 줄이 없으면 한 덩어리로 뭉쳐 사람이 읽기 불편하다.
|
|
154
|
+
|
|
155
|
+
- **접두어 + 문제 설명이 첫 블록**이다(`r: parseToken이 …`). 그 아래 제안·코드 블록과는 **빈 줄**로 나눈다.
|
|
156
|
+
- **문제 설명 → 제안 → 코드 스니펫은 각각 독립 블록**이다. 블록 사이마다 **빈 줄**을 반드시 넣는다. 한 줄 개행으로 붙이지 않는다.
|
|
157
|
+
- **여러 줄 코드는 fenced code block**(` ```ts ... ``` `)으로 감싼다. 인라인 백틱(`` `...` ``)에 여러 줄을 넣지 않는다.
|
|
158
|
+
- **목록을 쓸 때도 목록 바로 앞에 빈 줄**을 하나 둔다 (GitHub에서 목록이 앞 문단에 먹히지 않도록).
|
|
159
|
+
- 짧고 명확한 지적(한 줄이면 충분한 것)은 굳이 블록을 나누지 말고 한 문장으로 둔다 — 억지로 문단을 쪼개지 않는다.
|
|
126
160
|
|
|
127
161
|
이슈가 여러 개면 severity 높은 순(critical → suggestion)으로 정렬한다. 발견된 이슈가 없으면 그 이유를 한 줄로 명시한다("로직·경계값·에러 처리 모두 적절. 머지 가능.").
|
|
@@ -61,7 +61,7 @@ You are the Humanize Monolith role agent.
|
|
|
61
61
|
- 영어 약어(LLM·GPU·MCP·API 등 업계 표준)
|
|
62
62
|
- 굳어진 음차 화이트리스트(B-3 제외): 컴포넌트·토큰·커밋·인터페이스·메서드·빌드·디플로이·캐시·렌더링·콜백·프레임워크·라이브러리·리팩터링·마이그레이션·아이콘·레이아웃·그리드·모달·토스트·타이포그래피·플레이스홀더·프로젝트·스프린트·이슈·리뷰·머지·브랜치·사이드 이펙트·보일러플레이트·트레이드오프·딥다이브·얼라인·온보딩 등 정착어는 그대로 둔다. 목록 밖 안 굳어진 음차(소스 오브 트루스·룩 앤 필 등)만 B-3로 교정
|
|
63
63
|
- 문서 구조(헤딩 위계·목차·섹션 순서)와 정보 자체 — 표현만 다듬고 내용은 건드리지 않는다
|
|
64
|
-
- **작성자 voice (리뷰 코멘트·PR/변경 문서)**: `author-voice.md`의 보존 패턴 — 제안형 "~것 같아요/같습니다", 물결 친근체 "~해주세요~/~할게요~", "개인적으로/제 취향이긴 한데", 이모지(코멘트당 1개 안팎). 이건 AI-tell이 아니라 작성자 voice이므로 단언·격식으로 평탄화하지 않는다. (단 `
|
|
64
|
+
- **작성자 voice (리뷰 코멘트·PR/변경 문서)**: `author-voice.md`의 보존 패턴 — 제안형 "~것 같아요/같습니다", 물결 친근체 "~해주세요~/~할게요~", "개인적으로/제 취향이긴 한데", 이모지(코멘트당 1개 안팎). 이건 AI-tell이 아니라 작성자 voice이므로 단언·격식으로 평탄화하지 않는다. (단 `[출처]`·"권장." 은 Claude artifact이니 보이면 제거. **`r:`/`c:`/`a:` 접두어는 예외** — 팀이 채택한 PR 리뷰 강제성 라벨이므로 코멘트 맨 앞에 있으면 보존한다. voice 시그니처 흉내가 아니라 구조적 라벨이다.)
|
|
65
65
|
|
|
66
66
|
## 과윤문 가드
|
|
67
67
|
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
**실제 작성자의 어투가 아니다** — 1,321건 authentic 코퍼스에서 "권장"은 0건,
|
|
19
19
|
`c:`/`r:` 접두어는 3건(노이즈)뿐이다. 절대 흉내내지 말 것.
|
|
20
20
|
|
|
21
|
+
> **예외 — 층위가 다른 경우.** 여기서 금지하는 건 **어투(voice)로서의** `c:`/`r:`이다. 즉
|
|
22
|
+
> "권장." 체언 종지나 `[출처]` 태깅처럼 문장의 결·시그니처를 흉내내는 것. 반면 PR 리뷰에서
|
|
23
|
+
> **반영 강제성을 나타내는 구조적 접두어**(`r:` 꼭 반영 / `c:` 웬만하면 / `a:` 사소한 의견)를
|
|
24
|
+
> 팀 컨벤션으로 명시 채택한 경우는 별개다 — 이건 라벨이지 어투가 아니다. 그 컨벤션을 쓰는
|
|
25
|
+
> 소비자(예: `code-review-writer`)는 접두어를 붙이되, **본문 어투는 여전히 이 문서의 제안형**을
|
|
26
|
+
> 따른다. 접두어 뒤 본문에까지 "권장." 종지를 끌어들이지는 말 것.
|
|
27
|
+
|
|
21
28
|
## 어투의 본질 (한 줄 요약)
|
|
22
29
|
|
|
23
30
|
**단정하지 않고 제안한다. 이유를 붙여 부드럽게, 사소한 건 짧게, 모르면 묻는다.**
|
package/skills/review/SKILL.md
CHANGED
|
@@ -217,7 +217,7 @@ ges_execute {
|
|
|
217
217
|
`ges_agent { action: "get", name: "humanize-monolith" }`로 에이전트 시스템 프롬프트를 가져온 뒤, 해당 관점에서 리포트를 윤문합니다. 이슈 내용(severity·file·line·message)은 수정하지 않고, 설명 문장의 어투만 자연스럽게 다듬습니다.
|
|
218
218
|
|
|
219
219
|
humanize-monolith는 두 룰북을 함께 적용합니다.
|
|
220
|
-
- **어투**: `../../role-agents/technical-writer/references/author-voice.md` — 제안형("~하는 게 좋을 것 같아요/어떨까요?"), 온기·물결·이모지(코멘트당 1개 안팎)는 보존하고, `
|
|
220
|
+
- **어투**: `../../role-agents/technical-writer/references/author-voice.md` — 제안형("~하는 게 좋을 것 같아요/어떨까요?"), 온기·물결·이모지(코멘트당 1개 안팎)는 보존하고, `[출처]` 태깅·"…권장." 체언 종지(Claude artifact)는 쓰지 않습니다. (파이프라인 리포트는 severity 섹션 구조라 `r:`/`c:`/`a:` 접두어를 붙이지 않습니다 — 접두어는 4.7단계 PR 인라인 코멘트에만 씁니다.)
|
|
221
221
|
- **음차·AI-tell**: `../../role-agents/technical-writer/references/ai-tell-quick-rules.md` — 안 굳어진 음차("소스 오브 트루스" 등)는 한글 의역하되, 굳어진 화이트리스트(컴포넌트·토큰·렌더링·트레이드오프 등)는 그대로 둡니다.
|
|
222
222
|
|
|
223
223
|
즉 리뷰 파이프라인 리포트도 인라인 코멘트와 동일하게 voice + 음차가 함께 처리됩니다.
|
|
@@ -264,14 +264,25 @@ gh pr view <target> --json number,headRefName,baseRefName,url 2>/dev/null
|
|
|
264
264
|
**코멘트 본문 작성 (code-review-writer).** `ges_agent { action: "get", name: "code-review-writer" }`로 에이전트 시스템 프롬프트를 가져온 뒤, 그 관점에서 4단계 `mergedIssues`의 각 이슈를 인라인 코멘트 본문으로 작성합니다. 이슈의 `file`·`line`·`severity`는 그대로 두고, `message`·`suggestion`을 에이전트 voice로 다듬어 코멘트 본문을 만듭니다.
|
|
265
265
|
|
|
266
266
|
- code-review-writer는 `author-voice.md`(제안형·온기·물결·이모지)와 `ai-tell-quick-rules.md`(음차 교정)를 이미 내장하므로 **별도 humanize-monolith 패스를 거치지 않습니다.**
|
|
267
|
-
- 에이전트 룰에 따라 `
|
|
268
|
-
-
|
|
267
|
+
- 에이전트 룰에 따라 `[출처]` 태깅, "…권장." 체언 종지는 쓰지 않습니다. 이건 Claude artifact이지 실제 리뷰어 어투가 아닙니다.
|
|
268
|
+
- **강제성은 `r:`/`c:`/`a:` 접두어로 표기합니다** (레포에 자체 리뷰 컨벤션이 없을 때의 기본값). 코멘트 본문 맨 앞에 severity에 따라 붙입니다 — `r:` 꼭 반영(critical/high), `c:` 웬만하면 반영(warning), `a:` 사소한 의견(suggestion). 접두어는 강제성 라벨이고 본문 어투는 그대로 제안형입니다.
|
|
269
|
+
- **개행은 GitHub 렌더링 기준으로 조립합니다.** GitHub GFM은 한 줄 개행(`\n`)을 무시하고 같은 문단으로 이어 붙이므로, 줄을 실제로 나누려면 **빈 줄(`\n\n`)로 블록을 분리**해야 합니다. severity 라벨 → 문제 설명 → 제안 → 코드 스니펫을 각각 빈 줄로 띄우고, 여러 줄 코드는 fenced code block(` ```lang ``` `)으로 감쌉니다. 한 줄 개행으로 이어 붙이면 PR에서 한 덩어리로 뭉쳐 읽기 어렵습니다 (code-review-writer의 Output Format 개행 규칙과 동일).
|
|
269
270
|
|
|
270
|
-
|
|
271
|
+
**리뷰 이벤트 결정.** 코멘트 접두어의 조합으로 리뷰 전체의 `event`를 정합니다 (r/c/a → GitHub 리뷰 이벤트 대응).
|
|
272
|
+
|
|
273
|
+
- 이슈 중 하나라도 `r:`(critical/high)가 있으면 → `REQUEST_CHANGES`
|
|
274
|
+
- `r:`은 없고 `c:`(warning)만 있으면 → `COMMENT`
|
|
275
|
+
- `a:`(suggestion)만 있거나 이슈가 없으면 → `APPROVE`
|
|
276
|
+
|
|
277
|
+
이는 4단계 `overallApproved`(결함 심급 blocking 여부)와도 일치합니다 — blocking 이슈가 있으면 `r:`이 존재하므로 `REQUEST_CHANGES`가 됩니다. 단 `APPROVE`/`REQUEST_CHANGES`는 리뷰 상태를 바꾸는 행위이므로, 위 **"게시 확인"**에서 사용자 동의를 받은 뒤에만 게시합니다.
|
|
278
|
+
|
|
279
|
+
> **본인 PR 예외**: GitHub는 PR 작성자 본인이 자기 PR을 `APPROVE`/`REQUEST_CHANGES`하는 걸 막습니다(422). `gh pr view --json author`와 `gh api user`로 작성자가 현재 사용자와 같은지 확인하고, 같으면 `event=COMMENT`로 폴백해 게시합니다 (접두어 r/c/a는 본문에 그대로 유지). 이때 사용자에게 "본인 PR이라 승인/변경요청 상태는 못 걸어서 코멘트로 남겼어요"라고 한 줄 알립니다.
|
|
280
|
+
|
|
281
|
+
**게시 (gh api).** 작성한 코멘트를 한 번의 리뷰로 묶어 게시합니다. 이슈마다 개별 호출하지 않고 `comments` 배열로 모읍니다. `event`는 바로 위에서 결정한 값을 넣습니다.
|
|
271
282
|
|
|
272
283
|
```bash
|
|
273
284
|
gh api repos/{owner}/{repo}/pulls/{number}/reviews \
|
|
274
|
-
-f event
|
|
285
|
+
-f event=<REQUEST_CHANGES|COMMENT|APPROVE> \
|
|
275
286
|
-f body="<요약 한 줄 — code-review-writer가 작성한 overall summary>" \
|
|
276
287
|
--input <(jq -n '{ comments: [ { path: "...", line: 42, side: "RIGHT", body: "..." } ] }')
|
|
277
288
|
```
|