@tienne/gestalt 0.71.0 → 0.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +2 -2
- package/README.ko.md +4 -4
- package/README.md +3 -3
- package/dist/package.json +1 -1
- package/dist/plugin/role-agents/_shared/references/style-guide.md +19 -1
- package/dist/plugin/skills/_shared/agent-delegation.md +1 -1
- package/dist/plugin/skills/_shared/proactive-routing.md +1 -0
- package/dist/plugin/skills/local-pr/SKILL.md +2 -1
- package/dist/plugin/skills/pr/SKILL.md +2 -0
- package/dist/plugin/skills/review/SKILL.md +3 -1
- package/dist/plugin/skills/review-reply/SKILL.md +3 -1
- package/dist/plugin/skills/ship/SKILL.md +750 -0
- package/dist/src/cli/commands/pr.d.ts +1 -1
- package/dist/src/gestalt/surface-labels.d.ts +12 -12
- package/dist/src/gestalt/surface-labels.js +9 -9
- package/dist/src/humanize/detectors.js +1 -1
- package/dist/src/local-pr/policy.d.ts +7 -7
- package/dist/src/local-pr/policy.d.ts.map +1 -1
- package/dist/src/local-pr/policy.js +5 -5
- package/dist/src/local-pr/policy.js.map +1 -1
- package/dist/src/local-pr-web/engine.d.ts +1 -1
- package/dist/src/local-pr-web/engine.js +1 -1
- package/dist/src/mcp/tools/pr.js +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +1 -1
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +2 -2
- package/plugin/role-agents/_shared/references/style-guide.md +19 -1
- package/plugin/skills/_shared/agent-delegation.md +1 -1
- package/plugin/skills/_shared/proactive-routing.md +1 -0
- package/plugin/skills/local-pr/SKILL.md +2 -1
- package/plugin/skills/pr/SKILL.md +2 -0
- package/plugin/skills/review/SKILL.md +3 -1
- package/plugin/skills/review-reply/SKILL.md +3 -1
- package/plugin/skills/ship/SKILL.md +750 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { GestaltPrinciple } from '../core/types.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* 사용자에게 보이는 문자열을 정의하는 단 한 곳. 게슈탈트 내부와의 경계다 (Figure-Ground).
|
|
4
4
|
*
|
|
5
5
|
* 코드 내부는 게슈탈트 원리(GestaltPrinciple enum)와 에이전트 식별자를 그대로 쓰지만,
|
|
6
|
-
* 사용자에게 돌려주는
|
|
6
|
+
* 사용자에게 돌려주는 문자열에는 게슈탈트 용어가 새어 나가면 안 된다.
|
|
7
7
|
* 이 모듈이 내부 식별자를 평범한 한국어·영어 문구로 잇는 유일한 매핑 지점이다.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* 게슈탈트 내부(README, docs, LLM 시스템 프롬프트, 내부 타입)는 이 모듈을 거치지 않고
|
|
10
|
+
* 그 어휘를 그대로 유지한다.
|
|
11
11
|
*/
|
|
12
12
|
export type SurfaceLang = 'ko' | 'en';
|
|
13
13
|
/**
|
|
14
14
|
* 원리가 담당하는 단계를 평범한 말로 설명한 문구를 돌려준다.
|
|
15
|
-
* currentPrinciple/principleStrategy/gestaltFocus 등
|
|
15
|
+
* currentPrinciple/principleStrategy/gestaltFocus 등 사용자에게 나가는 자리에 쓴다.
|
|
16
16
|
* 알 수 없는 값('next' 등)은 중립적 기본 문구로 대체한다.
|
|
17
17
|
*/
|
|
18
18
|
export declare function getStageLabel(principle: GestaltPrinciple | string, lang?: SurfaceLang): string;
|
|
@@ -27,27 +27,27 @@ export declare function getAgentDisplayName(agentName: string, lang?: SurfaceLan
|
|
|
27
27
|
export declare function toDisplayAgentNames(agentNames: string[], lang?: SurfaceLang): string[];
|
|
28
28
|
export declare function getConsistencyHint(lang?: SurfaceLang): string;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
* 회귀 테스트(LeakTest)가 이 목록으로
|
|
30
|
+
* 사용자에게 나가는 문자열에 절대 나타나면 안 되는 게슈탈트 금지어.
|
|
31
|
+
* 회귀 테스트(LeakTest)가 이 목록으로 사용자에게 나가는 응답을 검사한다.
|
|
32
32
|
* 원리 이름 6종(figure-ground는 두 표기 모두)만 담는다 — 에이전트 접미사(completer 등)는
|
|
33
33
|
* 게슈탈트 용어가 아니므로 중립 표시 이름에 그대로 쓸 수 있어 제외한다.
|
|
34
34
|
*/
|
|
35
35
|
export declare const BANNED_SURFACE_TERMS: readonly string[];
|
|
36
36
|
/**
|
|
37
|
-
* MCP 도구 응답에서
|
|
38
|
-
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로
|
|
37
|
+
* MCP 도구 응답에서 LLM에게만 가는 프롬프트 필드 키.
|
|
38
|
+
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 누수 검사 대상에서 제외한다.
|
|
39
39
|
*/
|
|
40
40
|
export declare const DEEP_PROMPT_KEYS: readonly string[];
|
|
41
41
|
/**
|
|
42
42
|
* 도구 응답에 통째로 실리는 컨텍스트 객체(gestaltContext/specContext/executeContext)에서
|
|
43
|
-
* 게슈탈트 용어가 새는 메타 필드를
|
|
43
|
+
* 게슈탈트 용어가 새는 메타 필드를 중립적인 값으로 치환한다.
|
|
44
44
|
*
|
|
45
45
|
* - currentPrinciple(원리 enum 값) → currentStage(평범한 단계 설명)
|
|
46
|
-
* - principleStrategy(원리 용어가 박힌 전략 문구) →
|
|
46
|
+
* - principleStrategy(원리 용어가 박힌 전략 문구) → 사용자 응답에서 제거 (프롬프트에 이미 포함)
|
|
47
47
|
* - activeAgents(에이전트 식별자) → 중립적 표시 이름
|
|
48
48
|
* - allRounds[].gestaltFocus(원리 enum 값) → stage(평범한 단계 설명)
|
|
49
49
|
*
|
|
50
|
-
*
|
|
50
|
+
* LLM에게만 가는 프롬프트 필드(systemPrompt 등)와 나머지 필드는 그대로 둔다.
|
|
51
51
|
*/
|
|
52
52
|
export declare function sanitizeSurfaceContext<T>(ctx: T, lang?: SurfaceLang): T;
|
|
53
53
|
//# sourceMappingURL=surface-labels.d.ts.map
|
|
@@ -39,7 +39,7 @@ const AGENT_DISPLAY_NAMES = {
|
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
41
|
* 원리가 담당하는 단계를 평범한 말로 설명한 문구를 돌려준다.
|
|
42
|
-
* currentPrinciple/principleStrategy/gestaltFocus 등
|
|
42
|
+
* currentPrinciple/principleStrategy/gestaltFocus 등 사용자에게 나가는 자리에 쓴다.
|
|
43
43
|
* 알 수 없는 값('next' 등)은 중립적 기본 문구로 대체한다.
|
|
44
44
|
*/
|
|
45
45
|
export function getStageLabel(principle, lang = 'ko') {
|
|
@@ -62,7 +62,7 @@ export function toDisplayAgentNames(agentNames, lang = 'ko') {
|
|
|
62
62
|
return agentNames.map((name) => getAgentDisplayName(name, lang));
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* 실행 단계에서 caller에게 주는 "일관성 유지"
|
|
65
|
+
* 실행 단계에서 caller에게 주는 "일관성 유지" 힌트로 사용자에게 보이는 평범한 문구.
|
|
66
66
|
* Similarity 원리를 노출하던 similarityStrategy 필드를 이 문구로 치환한다.
|
|
67
67
|
*/
|
|
68
68
|
const CONSISTENCY_HINT = {
|
|
@@ -73,8 +73,8 @@ export function getConsistencyHint(lang = 'ko') {
|
|
|
73
73
|
return CONSISTENCY_HINT[lang];
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
*
|
|
77
|
-
* 회귀 테스트(LeakTest)가 이 목록으로
|
|
76
|
+
* 사용자에게 나가는 문자열에 절대 나타나면 안 되는 게슈탈트 금지어.
|
|
77
|
+
* 회귀 테스트(LeakTest)가 이 목록으로 사용자에게 나가는 응답을 검사한다.
|
|
78
78
|
* 원리 이름 6종(figure-ground는 두 표기 모두)만 담는다 — 에이전트 접미사(completer 등)는
|
|
79
79
|
* 게슈탈트 용어가 아니므로 중립 표시 이름에 그대로 쓸 수 있어 제외한다.
|
|
80
80
|
*/
|
|
@@ -88,8 +88,8 @@ export const BANNED_SURFACE_TERMS = [
|
|
|
88
88
|
'gestalt',
|
|
89
89
|
];
|
|
90
90
|
/**
|
|
91
|
-
* MCP 도구 응답에서
|
|
92
|
-
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로
|
|
91
|
+
* MCP 도구 응답에서 LLM에게만 가는 프롬프트 필드 키.
|
|
92
|
+
* 이 필드들은 게슈탈트 어휘를 담은 채 유지되므로 누수 검사 대상에서 제외한다.
|
|
93
93
|
*/
|
|
94
94
|
export const DEEP_PROMPT_KEYS = [
|
|
95
95
|
'systemPrompt',
|
|
@@ -102,14 +102,14 @@ export const DEEP_PROMPT_KEYS = [
|
|
|
102
102
|
];
|
|
103
103
|
/**
|
|
104
104
|
* 도구 응답에 통째로 실리는 컨텍스트 객체(gestaltContext/specContext/executeContext)에서
|
|
105
|
-
* 게슈탈트 용어가 새는 메타 필드를
|
|
105
|
+
* 게슈탈트 용어가 새는 메타 필드를 중립적인 값으로 치환한다.
|
|
106
106
|
*
|
|
107
107
|
* - currentPrinciple(원리 enum 값) → currentStage(평범한 단계 설명)
|
|
108
|
-
* - principleStrategy(원리 용어가 박힌 전략 문구) →
|
|
108
|
+
* - principleStrategy(원리 용어가 박힌 전략 문구) → 사용자 응답에서 제거 (프롬프트에 이미 포함)
|
|
109
109
|
* - activeAgents(에이전트 식별자) → 중립적 표시 이름
|
|
110
110
|
* - allRounds[].gestaltFocus(원리 enum 값) → stage(평범한 단계 설명)
|
|
111
111
|
*
|
|
112
|
-
*
|
|
112
|
+
* LLM에게만 가는 프롬프트 필드(systemPrompt 등)와 나머지 필드는 그대로 둔다.
|
|
113
113
|
*/
|
|
114
114
|
export function sanitizeSurfaceContext(ctx, lang = 'ko') {
|
|
115
115
|
if (!ctx || typeof ctx !== 'object')
|
|
@@ -58,7 +58,7 @@ function proseOnly(text, options = {}) {
|
|
|
58
58
|
* 길이도 자른다 — D-9의 (?:\S+\s+)? 처럼 임의 토큰을 삼키는 탐지기가 있어서
|
|
59
59
|
* 매치 하나가 수백 자로 늘어날 수 있다.
|
|
60
60
|
*
|
|
61
|
-
* 어투 탐지기와 맞춤법 검사가 같이 지나는 자리에 둔다. 한쪽만 누르면
|
|
61
|
+
* 어투 탐지기와 맞춤법 검사가 같이 지나는 자리에 둔다. 한쪽만 누르면 걸리는 범위가 넓은
|
|
62
62
|
* 쪽이 그대로 새는데, 실제로 맞춤법만 누른 판이 그랬다.
|
|
63
63
|
*/
|
|
64
64
|
function clampSample(sample) {
|
|
@@ -3,16 +3,16 @@ import type { Actor, Comment, PullRequest, ReviewVerdict } from './types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* 로컬 PR의 판단 규칙.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* 규칙을
|
|
6
|
+
* CLI와 MCP와 웹 셋이 이 규칙을 쓴다. 산문으로 옮겨 적는 스킬 문서도 셋 더 있다.
|
|
7
|
+
* 규칙을 호출하는 쪽마다 다시 구현하면 하나가 반드시 뒤처진다 — 실제로 미해결 수를 스레드로
|
|
8
8
|
* 고친 뒤에도 웹 UI만 옛 계산으로 남아 같은 PR이 CLI에서 2, 웹에서 4로 보였다.
|
|
9
|
-
*
|
|
9
|
+
* 호출하는 쪽은 여기서 값을 가져다 쓰고 스스로 세지 않는다.
|
|
10
10
|
*/
|
|
11
11
|
/**
|
|
12
12
|
* 아직 안 닫힌 코멘트.
|
|
13
13
|
*
|
|
14
14
|
* 미해결을 가르는 술어가 여기 하나뿐이다. 아래 두 함수도 이 목록에서 나온다 —
|
|
15
|
-
*
|
|
15
|
+
* 호출하는 쪽이 헤아릴 때와 늘어놓을 때를 따로 계산하면 같은 화면에서 수가 갈린다.
|
|
16
16
|
* 실제로 `pr show`가 머리글에 스레드 수를, 바로 아래 목록에 코멘트 수를 찍어
|
|
17
17
|
* "미해결 1"이라고 해놓고 세 줄을 늘어놓았다.
|
|
18
18
|
*/
|
|
@@ -24,7 +24,7 @@ export interface Thread {
|
|
|
24
24
|
/** 그중 안 닫힌 것만. 전부 닫혔으면 빈 배열이다 */
|
|
25
25
|
unresolved: Comment[];
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* 한 줄로 접을 때 보여줄 코멘트. 안 닫힌 것 중 첫 번째다.
|
|
28
28
|
* 전부 닫혔으면 맨 처음 코멘트가 온다.
|
|
29
29
|
*/
|
|
30
30
|
head: Comment;
|
|
@@ -43,7 +43,7 @@ export declare function threadsOf(pr: PullRequest): Thread[];
|
|
|
43
43
|
/** 안 닫힌 스레드 하나 */
|
|
44
44
|
export interface OpenThread {
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* 한 줄로 접을 때 보여줄 코멘트. 스레드에서 아직 안 닫힌 것 중 첫 번째다.
|
|
47
47
|
* 뿌리가 닫히고 답글만 열려 있으면 그 답글이 여기 온다.
|
|
48
48
|
*/
|
|
49
49
|
root: Comment;
|
|
@@ -51,7 +51,7 @@ export interface OpenThread {
|
|
|
51
51
|
comments: Comment[];
|
|
52
52
|
}
|
|
53
53
|
export declare function openThreads(pr: PullRequest): OpenThread[];
|
|
54
|
-
/** 안 닫힌 스레드 수.
|
|
54
|
+
/** 안 닫힌 스레드 수. 화면에 찍히는 "미해결 N"이 전부 이 값이다 */
|
|
55
55
|
export declare function unresolvedCount(pr: PullRequest): number;
|
|
56
56
|
/**
|
|
57
57
|
* 누가 했는지.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/local-pr/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,EAAE,CAE7D;AAED,0BAA0B;AAC1B,MAAM,WAAW,MAAM;IACrB,gCAAgC;IAChC,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,iCAAiC;IACjC,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,EAAE,CAYnD;AAED,kBAAkB;AAClB,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,oCAAoC;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,WAAW,GAAG,UAAU,EAAE,CAIzD;AAED,
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/local-pr/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,EAAE,CAE7D;AAED,0BAA0B;AAC1B,MAAM,WAAW,MAAM;IACrB,gCAAgC;IAChC,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,iCAAiC;IACjC,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,EAAE,CAYnD;AAED,kBAAkB;AAClB,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,oCAAoC;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,WAAW,GAAG,UAAU,EAAE,CAIzD;AAED,4CAA4C;AAC5C,wBAAgB,eAAe,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAE,KAAqB,GAAG,KAAK,CAEtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,EAAE,EACrB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,OAAO,CAIT;AAED,uDAAuD;AACvD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EAAE,EACrB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,OAAO,CAAC,aAAa,EAAE,SAAS,GAAG,iBAAiB,CAAC,CAEvD"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 로컬 PR의 판단 규칙.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* 규칙을
|
|
4
|
+
* CLI와 MCP와 웹 셋이 이 규칙을 쓴다. 산문으로 옮겨 적는 스킬 문서도 셋 더 있다.
|
|
5
|
+
* 규칙을 호출하는 쪽마다 다시 구현하면 하나가 반드시 뒤처진다 — 실제로 미해결 수를 스레드로
|
|
6
6
|
* 고친 뒤에도 웹 UI만 옛 계산으로 남아 같은 PR이 CLI에서 2, 웹에서 4로 보였다.
|
|
7
|
-
*
|
|
7
|
+
* 호출하는 쪽은 여기서 값을 가져다 쓰고 스스로 세지 않는다.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* 아직 안 닫힌 코멘트.
|
|
11
11
|
*
|
|
12
12
|
* 미해결을 가르는 술어가 여기 하나뿐이다. 아래 두 함수도 이 목록에서 나온다 —
|
|
13
|
-
*
|
|
13
|
+
* 호출하는 쪽이 헤아릴 때와 늘어놓을 때를 따로 계산하면 같은 화면에서 수가 갈린다.
|
|
14
14
|
* 실제로 `pr show`가 머리글에 스레드 수를, 바로 아래 목록에 코멘트 수를 찍어
|
|
15
15
|
* "미해결 1"이라고 해놓고 세 줄을 늘어놓았다.
|
|
16
16
|
*/
|
|
@@ -44,7 +44,7 @@ export function openThreads(pr) {
|
|
|
44
44
|
.filter((t) => t.open)
|
|
45
45
|
.map((t) => ({ root: t.head, comments: t.unresolved }));
|
|
46
46
|
}
|
|
47
|
-
/** 안 닫힌 스레드 수.
|
|
47
|
+
/** 안 닫힌 스레드 수. 화면에 찍히는 "미해결 N"이 전부 이 값이다 */
|
|
48
48
|
export function unresolvedCount(pr) {
|
|
49
49
|
return openThreads(pr).length;
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/local-pr/policy.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAe;IAChD,OAAO,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAiBD;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,EAAe;IACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC9C,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;YAC5B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC1F,CAAC,CAAC,CAAC;AACL,CAAC;AAaD,MAAM,UAAU,WAAW,CAAC,EAAe;IACzC,OAAO,SAAS,CAAC,EAAE,CAAC;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/local-pr/policy.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAe;IAChD,OAAO,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAiBD;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,EAAe;IACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC9C,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;YAC5B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC1F,CAAC,CAAC,CAAC;AACL,CAAC;AAaD,MAAM,UAAU,WAAW,CAAC,EAAe;IACzC,OAAO,SAAS,CAAC,EAAE,CAAC;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,eAAe,CAAC,EAAe;IAC7C,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB,EAAE,WAAkB,aAAa;IAC7E,OAAO,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,QAAQ,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAqB,EACrB,iBAAqC;IAErC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;IACzF,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IACjF,OAAO,CAAC,SAAS,IAAI,CAAC,gBAAgB,CAAC;AACzC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,gBAAgB,CAC9B,MAAqB,EACrB,iBAAqC;IAErC,OAAO,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACxF,CAAC"}
|
|
@@ -18,7 +18,7 @@ export declare class PrWebEngine {
|
|
|
18
18
|
* 프로세스 하나가 서버를 하나만 띄우도록 공유하는 인스턴스.
|
|
19
19
|
*
|
|
20
20
|
* 아직 부르는 자리가 없다. `pr serve`는 `new PrWebEngine()`으로 직접 만들고 MCP는
|
|
21
|
-
* 이 모듈을 안 가져간다.
|
|
21
|
+
* 이 모듈을 안 가져간다. CLI와 MCP가 같은 서버 인스턴스를 공유해야 할 때를 위해 남겨 둔 진입점이다.
|
|
22
22
|
*/
|
|
23
23
|
export declare function getPrWebEngine(): PrWebEngine;
|
|
24
24
|
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -93,7 +93,7 @@ let _instance = null;
|
|
|
93
93
|
* 프로세스 하나가 서버를 하나만 띄우도록 공유하는 인스턴스.
|
|
94
94
|
*
|
|
95
95
|
* 아직 부르는 자리가 없다. `pr serve`는 `new PrWebEngine()`으로 직접 만들고 MCP는
|
|
96
|
-
* 이 모듈을 안 가져간다.
|
|
96
|
+
* 이 모듈을 안 가져간다. CLI와 MCP가 같은 서버 인스턴스를 공유해야 할 때를 위해 남겨 둔 진입점이다.
|
|
97
97
|
*/
|
|
98
98
|
export function getPrWebEngine() {
|
|
99
99
|
if (!_instance)
|
package/dist/src/mcp/tools/pr.js
CHANGED
|
@@ -111,7 +111,7 @@ export function errorKind(exitCode) {
|
|
|
111
111
|
* update-ref를 쓰고 워크트리를 만든다. `close`는 ref를 지운다. `checkout_remove --force`는
|
|
112
112
|
* 경로를 재귀로 지운다. 인자 하나를 바꿔 부르면 이 머신의 아무 git 레포나 그 대상이
|
|
113
113
|
* 된다. 레지스트리가 `pr create`의 등록 경로를 막은 것과 같은 축인데, 정작 git을
|
|
114
|
-
* 변형하는
|
|
114
|
+
* 변형하는 자리가 열려 있었다.
|
|
115
115
|
*
|
|
116
116
|
* 그래서 지금 자리와 **같은 레포**일 때만 받는다. 판정은 공용 git 디렉토리로 하므로
|
|
117
117
|
* 워크트리와 하위 디렉토리는 그대로 통과한다 — 이 인자가 원래 있는 이유가 그거다.
|
|
@@ -257,7 +257,7 @@ function actorOfAgent(name) {
|
|
|
257
257
|
* PR은 이벤트 소싱이라 그렇게 붙은 중복은 지울 수 없고 사람이 손으로 닫아야 한다.
|
|
258
258
|
* 그래서 어디까지 썼는지를 PR 자신에게도 남긴다 — 재기동해도 여기서 되짚는다.
|
|
259
259
|
*
|
|
260
|
-
* 코멘트의 `marker` 필드에 넣는다. 본문에 실었더니
|
|
260
|
+
* 코멘트의 `marker` 필드에 넣는다. 본문에 실었더니 CLI에서도 웹에서도 그대로 보였다 —
|
|
261
261
|
* 웹은 본문을 이스케이프해서 `<!-- ... -->`를 화면에 그대로 찍고 CLI는 평문으로
|
|
262
262
|
* 내보낸다. 사람이 읽을 이유가 없는 해시 줄이 리뷰 코멘트마다 붙었다.
|
|
263
263
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gestalt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.1",
|
|
4
4
|
"description": "Gestalt psychology-driven AI development harness. Transforms scattered requirements into structured, validated specifications through interactive interviews.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tienne"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"interface": {
|
|
23
23
|
"displayName": "Gestalt",
|
|
24
24
|
"shortDescription": "Requirements-to-spec pipeline with review and PR workflows",
|
|
25
|
-
"longDescription": "Gestalt turns vague ideas into validated specifications through Gestalt-principle interviews, then drives execution, code review, and PR authoring. Bundles
|
|
25
|
+
"longDescription": "Gestalt turns vague ideas into validated specifications through Gestalt-principle interviews, then drives execution, code review, and PR authoring. Bundles 19 workflow skills and 27 role agents over 12 MCP tools.",
|
|
26
26
|
"developerName": "tienne",
|
|
27
27
|
"category": "Developer Tools",
|
|
28
28
|
"capabilities": [
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
|---|---|
|
|
73
73
|
| 규칙·정의가 적힌 문서 | 기준 문서 |
|
|
74
74
|
| 비교 대상이 되는 수치 | 기준값 (목표 대비, 전기 대비 등 — impact-writer 용법) |
|
|
75
|
-
| 여러 사본 중 원본 하나 | 정본 |
|
|
76
75
|
| 조회·대조용 참조 자료 | 참조 기준 |
|
|
77
76
|
| 데이터가 처음 만들어지는 곳 | 원천 데이터 |
|
|
78
77
|
| 값을 담고 있는 데이터 자체 | 기준 데이터 |
|
|
@@ -85,6 +84,8 @@
|
|
|
85
84
|
"룰북과 에이전트 문서가 갈라졌는지 본다"가 "룰북 기준 문서와…"보다 낫다.
|
|
86
85
|
명사를 고르기 전에 동사로 풀 수 있는지 먼저 본다 — "A가 기준이다", "A를 기준으로 삼는다".
|
|
87
86
|
|
|
87
|
+
**여러 사본 중 원본 하나를 가리킬 때가 특히 그렇다.** 이 자리에 명사를 붙이면 뭉개진다. "이 파일만 읽는다", "고칠 일이 있으면 여기를 고친다", "표와 본문이 어긋나 보이면 본문을 따른다"처럼 적는다.
|
|
88
|
+
|
|
88
89
|
### 음차를 옮길 때 — 한 단어로 정하지 않는다
|
|
89
90
|
|
|
90
91
|
같은 영어 단어라도 가리키는 게 다르면 다른 말이 된다. 대체어 하나를 정해놓고 전부 치환하면
|
|
@@ -98,6 +99,23 @@
|
|
|
98
99
|
| layer | 동시에 처리되는 한 덩어리 | 묶음 |
|
|
99
100
|
| layer | 순서대로 밟는 구간 | 단계 |
|
|
100
101
|
| layer | 책임이 갈리는 구분 | 역할 |
|
|
102
|
+
| surface | 에이전트나 사람이 접근하는 창구 | 그 이름을 부른다 (CLI, MCP, 웹) |
|
|
103
|
+
| surface | 그 셋을 아울러야 할 때 | 호출하는 쪽 |
|
|
104
|
+
| surface | 이름 붙이기 애매한 접근 지점 | 자리 |
|
|
105
|
+
| surface | 값이 찍히는 화면 | 화면 |
|
|
106
|
+
| surface | 사용자에게 나가는 응답 | 사용자에게 보이는 / 나가는 |
|
|
107
|
+
| surface | 노출 영역 전체를 개념으로 부를 때 | 사용자 노출 |
|
|
108
|
+
| surface | 탐지기가 걸리는 넓이 | 걸리는 범위 |
|
|
109
|
+
| deep | 게슈탈트 용어를 써도 되는 곳 | 게슈탈트 내부 |
|
|
110
|
+
| deep | LLM 지시 프롬프트를 가리킬 때 | LLM에게만 가는 프롬프트 |
|
|
111
|
+
|
|
112
|
+
**이 표는 한국어 산문에서 음차로 쓴 자리만 다룬다.** 세 가지는 대상이 아니다.
|
|
113
|
+
|
|
114
|
+
- **코드 식별자.** `sanitizeSurfaceContext`, `DEEP_PROMPT_KEYS`, `gateway`는 그대로 둔다. 심볼을 바꾸면 호출부가 전부 딸려 온다.
|
|
115
|
+
- **그 도메인의 정착 용어.** 디자인 시스템의 `surface`와 `onSurface`(Material Design 색 토큰), CI의 gate, API gateway가 그렇다. **이 파일은 플러그인으로 배포돼 다른 레포에서도 읽히므로** 프론트엔드 레포에서 색 토큰을 "표면"으로 옮기라는 말이 되지 않게 조심한다.
|
|
116
|
+
- **이미 나간 CHANGELOG와 릴리즈 노트.** 그때 낸 문장이 아니게 된다.
|
|
117
|
+
|
|
118
|
+
**대비쌍은 짝을 함께 옮긴다.** `surface`와 `deep`처럼 둘이 맞물려 뜻을 이루는 말은 한쪽만 풀면 남은 쪽이 무엇의 반대인지 가리킬 데를 잃는다. 실제로 "표면"만 걷었다가 "심층"이 짝 없이 남아 한 문단 안에서 이름이 둘로 갈렸다.
|
|
101
119
|
|
|
102
120
|
**일괄 치환은 조사를 깨뜨린다.** 받침 유무가 바뀌면 뒤따르는 조사도 바뀐다.
|
|
103
121
|
`레이어라면` → `계층이라면`, `레이어(…)는` → `계층(…)은`. 실제로 이 자리에서 두 번 깨졌다.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 에이전트를 서브에이전트로 위임하기 (공유 규칙)
|
|
2
2
|
|
|
3
|
-
> **현재 적용: `review`, `pr`, `brief`, `presentation`, `review-reply`, `slack-send`, `jira-create`.** 에이전트를 불러 쓰는 스킬은 전부 위임한다. 새 스킬이 `ges_agent get`을 메인에서 하면 그건 예외가 아니라 빠뜨린 것이다.
|
|
3
|
+
> **현재 적용: `review`, `pr`, `brief`, `presentation`, `review-reply`, `slack-send`, `jira-create`, `ship`.** 에이전트를 불러 쓰는 스킬은 전부 위임한다. 새 스킬이 `ges_agent get`을 메인에서 하면 그건 예외가 아니라 빠뜨린 것이다.
|
|
4
4
|
|
|
5
5
|
## 왜 필요한가
|
|
6
6
|
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
| 내 PR에 달린 리뷰 코멘트 답변 본문 작성 (반영·대안·보류·질문) | `code-review-responder` |
|
|
39
39
|
| PR·브랜치·커밋 코드 리뷰 요청 | `/review` 스킬 사용 |
|
|
40
40
|
| 받은 리뷰 반영·답글 게시 요청 ("리뷰 반영해줘", "리뷰 코멘트에 답해줘", "받은 리뷰 처리해줘") | `review-reply` 스킬 사용 (스레드 수집 → 유형 분류 승인 → 수정·커밋 → 답글 승인 → 게시) |
|
|
41
|
+
| 리뷰가 수렴할 때까지 돌려 GitHub까지 내보내는 요청 ("출하해줘", "리뷰 통과할 때까지", "코파일럿 리뷰까지 받아줘") | `ship` 스킬 사용 (로컬 PR → 리뷰 수렴 루프 → 승인 → draft PR → Copilot 수렴 루프 → ready). 리뷰 한 번만이면 `review` |
|
|
41
42
|
| PR 작성·생성 요청 ("PR 만들어줘", "PR 작성해줘", "PR 올려줘") | `gestalt:pr` 스킬 사용 |
|
|
42
43
|
| 실행 태스크를 외부 런타임 워커로 뿌리는 요청 ("orca로 실행", "codex로 실행", "워커 띄워서 실행") | `dispatch` 스킬 사용 (런타임 감지 → 같은 워크트리에 터미널 → worker_done 대기 → ready 재계산). 런타임 없으면 execute의 기본 병렬 경로 |
|
|
43
44
|
|
|
@@ -47,6 +47,7 @@ outputs:
|
|
|
47
47
|
| 에이전트끼리 코드를 주고받는 자리 | **이 스킬** |
|
|
48
48
|
| 이미 있는 변경을 검토받기 | `review` |
|
|
49
49
|
| 받은 리뷰에 답하기 | `review-reply` |
|
|
50
|
+
| 리뷰가 수렴할 때까지 돌려 GitHub까지 내보내기 | `ship` |
|
|
50
51
|
|
|
51
52
|
원격 PR은 사람이 읽고 판단하라고 올린다. 에이전트끼리 주고받는 데는 `gh`도 인증도 원격 왕복도 군더더기다. 워크트리 여럿이 `.gestalt/reviews.db` 하나를 공유하므로 어느 워크트리에서 쳐도 같은 목록을 본다.
|
|
52
53
|
|
|
@@ -179,7 +180,7 @@ gestalt pr prune --checkouts # 체크아웃 자국까지
|
|
|
179
180
|
- 닫힌 PR은 아무것도 안 놓는다.
|
|
180
181
|
- 체크아웃 자국은 기본으로 안 놓는다. 어느 이력에도 없는 커밋이라 놓으면 영영 사라진다. `--checkouts`로 뜻을 밝혀야 하고 그 PR이 이미 머지되거나 닫혔을 때만 놓는다.
|
|
181
182
|
|
|
182
|
-
`prune`은 CLI에만 있다. 되돌릴 수 없게 놓는 자리라
|
|
183
|
+
`prune`은 CLI에만 있다. 되돌릴 수 없게 놓는 자리라 MCP 도구로는 안 뒀다.
|
|
183
184
|
|
|
184
185
|
## 여러 워커로 나눌 때
|
|
185
186
|
|
|
@@ -63,6 +63,8 @@ execute 세션 없이 PR, 브랜치, 커밋의 변경사항을 직접 리뷰 파
|
|
|
63
63
|
/review abc1234 # 특정 커밋
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
리뷰 한 번이 이 스킬의 범위입니다. 이슈가 없어질 때까지 리뷰와 대응을 반복하고 GitHub PR까지 내보내려면 `ship` 스킬을 씁니다 — 그쪽이 라운드마다 이 스킬을 부릅니다.
|
|
67
|
+
|
|
66
68
|
## 전제 조건
|
|
67
69
|
|
|
68
70
|
없습니다. git 저장소이기만 하면 바로 돌아갑니다 — 코드 그래프는 쓰지 않습니다.
|
|
@@ -132,7 +134,7 @@ id를 직접 주면 아래 1번의 첫 수단이 브랜치를 안 따지고 잡
|
|
|
132
134
|
5. `gh pr view <target>`이 성공하면(GitHub PR이 실제로 존재) → `github`입니다.
|
|
133
135
|
6. 여기까지 아무 데도 안 걸렸으면(GitHub에도 로컬에도 대응하는 PR이 없는 브랜치나 커밋 범위 리뷰) → `none`입니다. 4.7단계 전체를 건너뜁니다.
|
|
134
136
|
|
|
135
|
-
|
|
137
|
+
**아래 표는 본문 1~6번을 그대로 펼친 것뿐입니다.** 표와 본문이 어긋나 보이면 본문을 따르고 표를 고칩니다. 각 행은 자기 위의 행에 안 걸린 경우입니다. "—"는 앞 행에서 이미 갈려 볼 필요가 없다는 뜻입니다.
|
|
136
138
|
|
|
137
139
|
"로컬 PR 조회" 열은 1번의 두 수단(`show <id>` 또는 위의 가리는 법)이 대상 PR을 찾았는지입니다. 앞쪽은 브랜치를 안 따지고 뒤쪽만 따집니다. `안 봄`은 1번도 3번도 조회할 일이 없어 CLI를 아예 안 부른 경우입니다.
|
|
138
140
|
|
|
@@ -60,6 +60,8 @@ outputs:
|
|
|
60
60
|
/review-reply feature/auth # 해당 브랜치의 PR
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
받은 코멘트에 한 번 답하는 게 이 스킬의 범위다. 코멘트가 안 나올 때까지 리뷰와 대응을 반복하려면 `ship` 스킬을 쓴다 — 그쪽이 라운드마다 이 스킬을 부른다.
|
|
64
|
+
|
|
63
65
|
## 불변 규칙 두 가지
|
|
64
66
|
|
|
65
67
|
이 스킬은 외부에 나가는 문장을 쓰고 그 문장이 사실 주장이다. 아래 둘은 어떤 경우에도 건너뛰지 않는다.
|
|
@@ -131,7 +133,7 @@ id를 직접 주면 아래 1번의 첫 수단이 브랜치를 안 따지고 잡
|
|
|
131
133
|
|
|
132
134
|
gh 인증이 되고 원격도 있는데 로컬 PR을 지정했으면 1번이 먼저 잡는다. 로컬 PR id 형식이 아닌 값(PR 번호, URL, 브랜치명)은 1번을 그냥 지나친다.
|
|
133
135
|
|
|
134
|
-
|
|
136
|
+
**아래 표는 본문 1~5번을 그대로 펼친 것뿐이다.** 표와 본문이 어긋나 보이면 본문을 따르고 표를 고친다. 각 행은 자기 위의 행에 안 걸린 경우다. "—"는 앞 행에서 이미 갈려 볼 필요가 없다는 뜻이다.
|
|
135
137
|
|
|
136
138
|
"로컬 PR 조회" 열은 1번의 두 수단(`show <id>` 또는 위의 가리는 법)이 대상 PR을 찾았는지다. 앞쪽은 브랜치를 안 따지고 뒤쪽만 따진다. `안 봄`은 1번도 3번도 조회할 일이 없어 CLI를 아예 안 부른 경우다.
|
|
137
139
|
|