@tienne/gestalt 0.120.1 → 0.121.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.
Files changed (132) hide show
  1. package/README.ko.md +22 -3
  2. package/README.md +33 -3
  3. package/dist/package.json +4 -3
  4. package/dist/plugin/.codex-plugin/plugin.json +40 -0
  5. package/dist/plugin/review-agents/writing-reviewer/AGENT.md +4 -2
  6. package/dist/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +2 -1
  7. package/dist/plugin/role-agents/humanize-monolith/AGENT.md +5 -2
  8. package/dist/plugin/scripts/acquisition.mjs +96 -0
  9. package/dist/plugin/scripts/gestalt-cli.mjs +144 -0
  10. package/dist/plugin/scripts/npm-environment.mjs +64 -0
  11. package/dist/plugin/scripts/package-owner.mjs +20 -0
  12. package/dist/plugin/scripts/resolve-cli.mjs +22 -0
  13. package/dist/plugin/skills/_shared/agent-delegation.md +2 -0
  14. package/dist/plugin/skills/_shared/agent-model.md +2 -0
  15. package/dist/plugin/skills/_shared/cli-launcher.md +47 -36
  16. package/dist/plugin/skills/_shared/host-runtime.md +47 -0
  17. package/dist/plugin/skills/agent/SKILL.md +2 -0
  18. package/dist/plugin/skills/architecture/SKILL.md +2 -0
  19. package/dist/plugin/skills/blast-radius/SKILL.md +2 -0
  20. package/dist/plugin/skills/brief/SKILL.md +2 -0
  21. package/dist/plugin/skills/build-graph/SKILL.md +2 -0
  22. package/dist/plugin/skills/diff-radius/SKILL.md +2 -0
  23. package/dist/plugin/skills/dispatch/SKILL.md +2 -0
  24. package/dist/plugin/skills/doubt/SKILL.md +2 -0
  25. package/dist/plugin/skills/execute/SKILL.md +3 -1
  26. package/dist/plugin/skills/explain/SKILL.md +2 -0
  27. package/dist/plugin/skills/handoff/SKILL.md +2 -0
  28. package/dist/plugin/skills/interview/SKILL.md +2 -0
  29. package/dist/plugin/skills/jira-create/SKILL.md +2 -0
  30. package/dist/plugin/skills/lens/SKILL.md +2 -0
  31. package/dist/plugin/skills/local-pr/SKILL.md +4 -2
  32. package/dist/plugin/skills/market-scan/SKILL.md +2 -0
  33. package/dist/plugin/skills/pr/SKILL.md +6 -14
  34. package/dist/plugin/skills/presentation/SKILL.md +2 -0
  35. package/dist/plugin/skills/research/SKILL.md +2 -0
  36. package/dist/plugin/skills/reverse-plan/SKILL.md +2 -0
  37. package/dist/plugin/skills/review/SKILL.md +15 -18
  38. package/dist/plugin/skills/review-loop/SKILL.md +13 -10
  39. package/dist/plugin/skills/review-reply/SKILL.md +7 -15
  40. package/dist/plugin/skills/screen-ref/SKILL.md +2 -0
  41. package/dist/plugin/skills/setup/SKILL.md +9 -6
  42. package/dist/plugin/skills/share/SKILL.md +4 -2
  43. package/dist/plugin/skills/ship/SKILL.md +3 -1
  44. package/dist/plugin/skills/slack-send/SKILL.md +2 -0
  45. package/dist/plugin/skills/solve/SKILL.md +2 -0
  46. package/dist/plugin/skills/spec/SKILL.md +3 -1
  47. package/dist/plugin/skills/ux-research/SKILL.md +2 -0
  48. package/dist/plugin/skills/video-digest/SKILL.md +2 -0
  49. package/dist/schemas/gestalt.schema.json +25 -4
  50. package/dist/src/cli/commands/init.d.ts +2 -0
  51. package/dist/src/cli/commands/init.d.ts.map +1 -1
  52. package/dist/src/cli/commands/init.js +6 -2
  53. package/dist/src/cli/commands/init.js.map +1 -1
  54. package/dist/src/cli/commands/setup.d.ts +4 -1
  55. package/dist/src/cli/commands/setup.d.ts.map +1 -1
  56. package/dist/src/cli/commands/setup.js +2 -1
  57. package/dist/src/cli/commands/setup.js.map +1 -1
  58. package/dist/src/cli/index.d.ts.map +1 -1
  59. package/dist/src/cli/index.js +15 -3
  60. package/dist/src/cli/index.js.map +1 -1
  61. package/dist/src/core/config.d.ts +169 -150
  62. package/dist/src/core/config.d.ts.map +1 -1
  63. package/dist/src/core/config.js +41 -11
  64. package/dist/src/core/config.js.map +1 -1
  65. package/dist/src/core/model-diagnostics.d.ts +9 -0
  66. package/dist/src/core/model-diagnostics.d.ts.map +1 -0
  67. package/dist/src/core/model-diagnostics.js +47 -0
  68. package/dist/src/core/model-diagnostics.js.map +1 -0
  69. package/dist/src/core/types.d.ts +3 -3
  70. package/dist/src/execute/prompts.d.ts.map +1 -1
  71. package/dist/src/execute/prompts.js +4 -1
  72. package/dist/src/execute/prompts.js.map +1 -1
  73. package/dist/src/mcp/client-host.d.ts +12 -0
  74. package/dist/src/mcp/client-host.d.ts.map +1 -0
  75. package/dist/src/mcp/client-host.js +41 -0
  76. package/dist/src/mcp/client-host.js.map +1 -0
  77. package/dist/src/mcp/server.d.ts.map +1 -1
  78. package/dist/src/mcp/server.js +20 -6
  79. package/dist/src/mcp/server.js.map +1 -1
  80. package/dist/src/mcp/tools/status.d.ts +22 -7
  81. package/dist/src/mcp/tools/status.d.ts.map +1 -1
  82. package/dist/src/mcp/tools/status.js +8 -3
  83. package/dist/src/mcp/tools/status.js.map +1 -1
  84. package/package.json +4 -3
  85. package/plugin/.codex-plugin/plugin.json +2 -2
  86. package/plugin/.mcp.json +1 -1
  87. package/plugin/mcp.json +1 -1
  88. package/plugin/review-agents/writing-reviewer/AGENT.md +4 -2
  89. package/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +2 -1
  90. package/plugin/role-agents/humanize-monolith/AGENT.md +5 -2
  91. package/plugin/scripts/acquisition.mjs +96 -0
  92. package/plugin/scripts/gestalt-cli.mjs +144 -0
  93. package/plugin/scripts/npm-environment.mjs +64 -0
  94. package/plugin/scripts/package-owner.mjs +20 -0
  95. package/plugin/scripts/resolve-cli.mjs +22 -0
  96. package/plugin/skills/_shared/agent-delegation.md +2 -0
  97. package/plugin/skills/_shared/agent-model.md +2 -0
  98. package/plugin/skills/_shared/cli-launcher.md +47 -36
  99. package/plugin/skills/_shared/host-runtime.md +47 -0
  100. package/plugin/skills/agent/SKILL.md +2 -0
  101. package/plugin/skills/architecture/SKILL.md +2 -0
  102. package/plugin/skills/blast-radius/SKILL.md +2 -0
  103. package/plugin/skills/brief/SKILL.md +2 -0
  104. package/plugin/skills/build-graph/SKILL.md +2 -0
  105. package/plugin/skills/diff-radius/SKILL.md +2 -0
  106. package/plugin/skills/dispatch/SKILL.md +2 -0
  107. package/plugin/skills/doubt/SKILL.md +2 -0
  108. package/plugin/skills/execute/SKILL.md +3 -1
  109. package/plugin/skills/explain/SKILL.md +2 -0
  110. package/plugin/skills/handoff/SKILL.md +2 -0
  111. package/plugin/skills/interview/SKILL.md +2 -0
  112. package/plugin/skills/jira-create/SKILL.md +2 -0
  113. package/plugin/skills/lens/SKILL.md +2 -0
  114. package/plugin/skills/local-pr/SKILL.md +4 -2
  115. package/plugin/skills/market-scan/SKILL.md +2 -0
  116. package/plugin/skills/pr/SKILL.md +6 -14
  117. package/plugin/skills/presentation/SKILL.md +2 -0
  118. package/plugin/skills/research/SKILL.md +2 -0
  119. package/plugin/skills/reverse-plan/SKILL.md +2 -0
  120. package/plugin/skills/review/SKILL.md +15 -18
  121. package/plugin/skills/review-loop/SKILL.md +13 -10
  122. package/plugin/skills/review-reply/SKILL.md +7 -15
  123. package/plugin/skills/screen-ref/SKILL.md +2 -0
  124. package/plugin/skills/setup/SKILL.md +9 -6
  125. package/plugin/skills/share/SKILL.md +4 -2
  126. package/plugin/skills/ship/SKILL.md +3 -1
  127. package/plugin/skills/slack-send/SKILL.md +2 -0
  128. package/plugin/skills/solve/SKILL.md +2 -0
  129. package/plugin/skills/spec/SKILL.md +3 -1
  130. package/plugin/skills/ux-research/SKILL.md +2 -0
  131. package/plugin/skills/video-digest/SKILL.md +2 -0
  132. package/schemas/gestalt.schema.json +25 -4
@@ -1,45 +1,56 @@
1
- # gestalt CLI를 어떻게 부르는지 먼저 판정한다
1
+ # 플러그인과 같은 버전의 CLI 실행
2
2
 
3
- 이 문서는 여러 스킬이 공유하는 규칙이다. `gestalt` CLI(`humanize-scan`, `pr`, `review-loop`, `setup` 등)를 셸로 부르는 단계에서 적용한다.
4
-
5
- ## 왜 필요한가
6
-
7
- 플러그인으로 설치되면 호스트가 복사해 가는 건 `plugin/` 아래뿐이다. `bin/`도 `package.json`도 `node_modules`도 그 안에 없다. 그래서 스킬 본문에 `pnpm tsx bin/gestalt.ts ...`만 적혀 있으면 게슈탈트 레포 밖에서는 그 명령이 원리상 안 돈다.
8
-
9
- 그때 읽는 쪽이 하는 말이 "의존성이 안 깔려 있어서 못 돌립니다"다. 실제로는 전역 `gestalt`가 깔려 있어 돌릴 수 있는데도 스킬이 적어준 형태 하나가 막혀서 포기한다. 어투 검사처럼 **필수 검사인 단계가 이렇게 조용히 건너뛰어지면** 막으려던 문장이 그대로 나간다.
10
-
11
- 그래서 호출 형태를 스킬마다 박아두지 않고 한 번 판정해서 쓴다.
12
-
13
- ## 판정
14
-
15
- CLI를 처음 부르기 전에 한 번 돌린다.
3
+ 스킬 본문의 `gestalt ...` 예시는 아래 런처로 실행한다. 전역 `gestalt` 설치는 필요하지 않다.
4
+ 이 문서가 있는 디렉토리(`.../skills/_shared`)에서 두 단계 위가 플러그인 루트다.
5
+ 런처는 그 아래 `scripts/gestalt-cli.mjs`에 있다. 예를 들어 문서가 `/cache/gestalt/skills/_shared/cli-launcher.md`이면 런처는 `/cache/gestalt/scripts/gestalt-cli.mjs`다.
6
+ 현재 작업 레포의 동명 파일이나 `bin/gestalt.ts`를 찾아 실행하지 않는다.
16
7
 
17
8
  ```bash
18
- if gestalt --version >/dev/null 2>&1; then
19
- echo "OK gestalt"
20
- elif pnpm tsx bin/gestalt.ts --version >/dev/null 2>&1; then
21
- echo "OK pnpm"
22
- else
23
- echo "MISSING"
24
- fi
9
+ node "/플러그인/절대경로/scripts/gestalt-cli.mjs" humanize-scan --file "$scanTmp/report.md" --register report
25
10
  ```
26
11
 
27
- - **`OK gestalt`** — 스킬 본문의 예시를 그대로 쓴다. 본문은 전부 `gestalt ...` 형태로 적혀 있다.
28
- - **`OK pnpm`** — 게슈탈트 레포 안이라는 뜻이다. 그 뒤로 모든 호출의 `gestalt`를 `pnpm tsx bin/gestalt.ts`로 바꿔 쓴다.
29
- - **`MISSING`** — 아래 "없을 때"를 따른다.
30
-
31
- 한 번 확인하고 그 뒤로는 같은 형태를 쓴다. 단계마다 다시 찌르지 않는다.
12
+ 루트 `skills` 심링크로 읽었다면 먼저 이 문서 경로를 `realpath`로 풀고 부모 경로를 계산한다.
13
+ 런처는 자신의 위치를 기준으로 다음을 수행한다.
14
+
15
+ 1. `.codex-plugin/plugin.json`에서 설치된 플러그인의 버전을 읽는다. 버전을 모르면 중단한다.
16
+ 2. 로컬 의존성이 있는 게슈탈트 개발 체크아웃이면 그 TypeScript 엔트리를 사용한다.
17
+ 같은 버전의 npm 설치본 안에 빌드된 CLI가 있으면 그 엔트리를 사용한다.
18
+ 소스만 있고 의존성이 없는 플러그인 설치본은 다음 npm 해석 단계로 진행한다.
19
+ 3. 설치된 복사본이면 npm 캐시에서 정확히 같은 `@tienne/gestalt@<version>`을 해석하고
20
+ 캐시가 없으면 같은 버전을 다운로드한다. 패키지 이름과 버전, 실제 CLI 버전을 확인한다.
21
+ 4. 실제 명령은 원래 작업 디렉토리에서 실행하며 stdin, 인자, 종료 코드를 보존한다.
22
+ 터미널 Ctrl-C는 자식도 함께 받으므로 중복 전달하지 않는다. 래퍼 pid만 지정해 취소할 때는 SIGTERM을 사용한다.
23
+ SIGTERM과 SIGHUP은 npm 실행과 버전 확인, 실제 명령에 전달하고 자식 종료를 기다린다.
24
+ npm 실행과 버전 확인 중에는 SIGTERM이나 SIGHUP을 보낸 뒤 5초간 자식이 끝나지 않으면 SIGKILL을 보낸다.
25
+ SIGKILL은 직접 실행한 프로세스 하나에만 보낸다. npm이 신호를 자식에게 넘기지 못하고 멈추면 설치 스크립트 같은 자손은 남을 수 있다.
26
+ 이 두 단계에서 SIGINT를 받으면 SIGINT를 다시 전달하지 않고 2초 동안 자식이 스스로 끝나기를 기다린다.
27
+ 그래도 남아 있으면 SIGTERM을 보낸다. 래퍼 pid만 받은 SIGINT도 이 경로로 정리된다.
28
+ 취소한 뒤에는 임시 디렉토리를 지운다. 오프라인 해석이나 버전 확인이 실패하거나 시간을 넘기면 같은 버전을 온라인으로 한 번 더 시도한다.
29
+ 온라인 시도도 실패하거나 시간을 넘기면 사용자 취소가 아닌 오류로 알린다.
30
+
31
+ npm 해석은 별도의 임시 디렉토리에서 한다. 작업 레포의 로컬 패키지나 다른 버전의 전역 CLI를
32
+ 선택하지 않으며 `latest`로 떨어지지 않는다.
33
+ npm으로 CLI 패키지를 받는 동안에는 알려진 비밀 환경 변수를 npm에 넘기지 않는다.
34
+ 모델 공급자 접두어(`ANTHROPIC_`, `OPENAI_` 등)로 시작하는 변수와 클라우드, GitHub의 인증 변수(`AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN` 등)가 여기에 든다.
35
+ 이름이 `_API_KEY`, `_PASSWORD`, `_SECRET`, `_AUTH_TOKEN` 등으로 끝나는 변수도 대소문자 구분 없이 제외한다. 이 필터는 알려진 이름과 패턴만 검사한다.
36
+ `NPM_*`, `NODE_AUTH_TOKEN`과 `npm_config_*`는 보존한다. 사용자 `.npmrc`와 전역 설정 파일에서 `${NAME}` 또는 `${NAME?}`으로 참조한 변수도 인증에 필요하므로 예외로 남긴다.
37
+ 사용자 설정 경로는 `npm_config_userconfig` 또는 홈의 `.npmrc`다. 전역 설정은 `npm_config_globalconfig` 또는 npm prefix의 `etc/npmrc`에서 읽는다. prefix를 지정하지 않았으면 Node 설치 경로를 기준으로 한다.
38
+ 프록시와 CA 설정은 유지하며 최종 CLI에는 원래 환경을 전달한다. 처음 실행할 때 Node.js >=22와 npm, 네트워크가 필요할 수 있다.
39
+ 셸 함수가 필요하면 명령을 문자열 변수로 합치지 말고 인자를 그대로 넘긴다.
32
40
 
33
- **쓰려는 하위 명령이 최근에 생긴 것이면 그 하위 명령으로 찌른다.** `--version`은 설치본이 뒤처져 하위 명령만 없는 경우를 못 잡는다. 그 상태로 라운드를 돌다 `unknown option`으로 죽으면 앞선 단계가 통째로 헛돈다.
34
-
35
- **명령을 변수에 담아 함수로 넘기지 않는다.** zsh는 인용 안 한 변수 전개에서 단어 분리를 안 해 `$cmd`가 통째로 명령 이름이 된다. 실제로 깔려 있어도 `MISSING`이 나온다. 같은 코드가 bash에서는 도는 탓에 눈으로는 안 걸린다.
36
-
37
- ## 없을 때
41
+ ```bash
42
+ gestalt() { node "/플러그인/절대경로/scripts/gestalt-cli.mjs" "$@"; }
43
+ ```
38
44
 
39
- `MISSING`이면 **그 단계가 필수 검사인지로 갈린다.**
45
+ 셸 함수는 `xargs`의 외부 실행 파일이 아니다. **파이프라인과 `xargs`를 포함한 모든 예시**에서도
46
+ `gestalt`를 `node`와 런처의 절대 경로로 치환한다. 함수 선언만 하고 `xargs gestalt`를 실행하지 않는다.
40
47
 
41
- - **필수 검사면 멈춘다.** 어투 검사(`humanize-scan`)가 그렇다. 검사를 못 돌린 걸 통과로 읽으면 검사가 없는 것과 같다. 무엇을 못 돌렸는지와 `npm i -g @tienne/gestalt`를 함께 알리고 사용자가 그대로 진행할지 정하게 둔다.
42
- - **판정에 쓰는 수를 그 명령이 내면 멈춘다.** `review-loop`처럼 모든 단계가 한 명령에 매달린 자리다.
43
- - **그 밖에는 알리고 건너뛴다.** 없다고 스킬 전체를 막을 이유는 없다. 대신 완료 보고에 어느 단계를 안 돌렸는지 적는다.
48
+ ```bash
49
+ find "$scanTmp" -name '*.md' -print0 | xargs -0 node "/플러그인/절대경로/scripts/gestalt-cli.mjs" humanize-scan --register chat
50
+ ```
44
51
 
45
- 어느 쪽이든 **직접 흉내내지 않는다.** 스캔 결과를 지어내거나 룰북을 눈으로 훑어 "깨끗합니다"로 답하지 않는다 ([`tool-availability.md`](./tool-availability.md)와 같은 규칙이다).
52
+ `humanize-scan`의 종료 코드 `10`은 검사 실행 실패가 아니라 탐지 없음이다. 그 명령의 계약대로 읽는다.
53
+ `xargs`는 자식의 종료 코드 `10`을 그대로 전달하지 않는다. 검사 판정에는 파일별 출력의 `EXIT=` 값을 사용한다. 단일 파일처럼 파일별 표지가 없는 호출에서 종료 코드가 필요하면 `xargs` 대신 런처를 직접 실행한다.
54
+ 런처를 찾지 못했거나 버전 해석이 실패하면 필수 검사와 그 수치에 의존하는 단계는 중단하고 오류를 알린다.
55
+ 그 밖의 선택적 단계는 실행하지 못한 단계를 완료 보고에 적는다. 검사 결과를 직접 지어내거나
56
+ 다른 버전의 실행을 같은 결과로 보고하지 않는다. MCP 도구는 [`tool-availability.md`](./tool-availability.md)를 따른다.
@@ -0,0 +1,47 @@
1
+ # 호스트별 도구 호출
2
+
3
+ 스킬 본문의 `Agent`, `Explore`, `AskUserQuestion`, `TaskCreate`는 Claude Code 표기다.
4
+ 실행 전에 이 문서를 읽고 **현재 호스트가 실제로 제공한 도구**로 옮긴다. Codex에서는 이 문서가
5
+ 다른 문서의 Claude 전용 타입, 모델 필수 인자, `sonnet` 폴백 지시보다 우선한다.
6
+ MCP 도구의 입력과 2-Call 제출 계약은 호스트가 바뀌어도 그대로다.
7
+
8
+ 모든 호스트에서 스킬의 `gestalt ...` 예시는 먼저 [CLI 실행 지침](./cli-launcher.md)을 읽고
9
+ 버전 고정 런처로 실행한다. 개별 스킬에 이 링크가 없어도 적용하며 파이프라인과 `xargs` 호출도 포함한다.
10
+
11
+ ## Codex
12
+
13
+ `ges_status {}`의 `hostClient`가 `codex`이면 Codex 모델 기본값은 `inherit`다.
14
+ `client`는 실행 컨텍스트를 기록할 파일의 선택이라 `both`일 수도 있다. 이 값을 호스트 판정과 혼동하지 않는다.
15
+ `hostClient`가 없는 이전 서버와 연결돼 있어도 현재 호스트가 Codex이면 서버의 Claude 별칭을 그대로 모델 인자로 보내지 않는다. `fable`, `haiku`, `sonnet`, `opus`는 이때 `inherit`로 취급한다. 명시한 다른 모델 ID는 유지한다. 이전 서버에는 `ges_execute` 요청의 `client: "codex"`도 명시해 컨텍스트 기록 대상을 맞추고 플러그인 갱신을 안내한다.
16
+ 사용자가 명시한 모델 ID와 실제 도구의 지원 여부를 우선한다. Claude 모델 별칭을 GPT 모델로 추측해서 바꾸지 않는다.
17
+ 실행 태스크의 자동 `task.model`이 `haiku`, `sonnet`, `opus`이면 기존 tier 힌트다. 각각 `ges_status`의
18
+ `tierModels.frugal`, `tierModels.standard`, `tierModels.frontier`로 해석한 뒤 아래 모델 규칙을 적용한다.
19
+ 명시적인 Codex 모델 ID는 다시 매핑하지 않는다.
20
+
21
+ | 본문의 표기 | Codex에서 수행할 일 |
22
+ |---|---|
23
+ | `Agent`의 `gestalt:` 에이전트 타입 | [`agent-delegation.md`](./agent-delegation.md)의 Explore 폴백 프롬프트를 사용해 범용 서브에이전트 안에서 `ges_agent get`으로 페르소나를 받는다. 해당 문서의 절차대로 룰북 디렉토리를 절대 경로로 풀어 프롬프트에 직접 넣는다. 경로를 못 풀었으면 그 사실을 보고한다. `subagent_type`은 전달하지 않는다. |
24
+ | `Explore` | 읽기 전용 조사를 위임한다. 실제 읽기 전용 타입이 없으면 파일 수정, 커밋, 외부 전송 금지를 프롬프트에 명시하고 도구로 강제된 제한이라고 말하지 않는다. |
25
+ | `Agent.model`, `reasoningModel`, `tierModels` | `inherit`이면 모델 인자를 생략한다. 명시 모델 ID는 스폰 도구가 받는 경우에만 전달한다. |
26
+ | `effort` | 해당 도구가 받는 `reasoning_effort` 또는 동등한 인자로 옮긴다. 지원하지 않는 인자는 보내지 않는다. |
27
+ | `AskUserQuestion` | 현재 모드의 질문 도구가 있으면 쓰고, 없으면 일반 대화로 묻는다. 필수 답변과 승인 없이 종속 단계를 실행하지 않는다. |
28
+ | `TaskCreate`, `TaskUpdate`, `TaskList` | 호스트의 진행 계획 도구가 있으면 쓰고, 없으면 짧은 진행 메시지로 알린다. 진행 패널 부재는 작업을 막지 않는다. |
29
+ | `Bash`, `Read`, `Grep`, `Glob`, `Edit`, `Write` | 호스트의 셸, 파일 읽기, 검색, 패치 도구를 사용한다. 명령 인자와 쓰기 범위는 그대로 지킨다. |
30
+
31
+ `spawn_agent`, `send_message`, `followup_task`, `wait_agent`가 제공되면 그 도구로 위임하고 결과를 기다린다.
32
+ 스폰 스키마가 `fork_turns: "all"`일 때 모델 재지정을 금지하면, 상속 모델은 그대로 두고
33
+ 모델이나 effort를 명시해야 할 때만 `fork_turns: "none"`으로 필수 맥락과 절대 경로를 직접 전달한다.
34
+ 이 매개변수가 없는 호스트에는 그 인자를 보내지 않는다. 특정 Codex 버전의 도구명을 필수 조건으로 삼지 않는다.
35
+
36
+ 스폰 도구가 명시한 모델을 거절했을 때만 아래 순서로 재시도한다.
37
+ `ges_status.hostClient`가 `codex`인 새 서버에서는 `reasoningModelFallback`이 `inherit`가 아니면 그 값으로 한 번 재시도한다. `hostClient`가 없는 이전 서버에서는 Claude 기본 별칭이 아닌 폴백 ID만 사용한다. 그것도 거절되거나 별도 폴백 ID가 없으면 세션 상속으로 한 번 재시도하고 끝낸다. 서버 기본값인 Claude 별칭으로 재시도하지 않는다. `inherit`를 지원 모델 이름처럼 전달하지 않는다. 모델 선택을 지원하지 않는 호스트에서는
38
+ 상속으로 실행하고 완료 보고에 모델 지정이 적용되지 않았음을 적는다.
39
+
40
+ 서브에이전트가 없으면 메인이 `ges_agent get`으로 페르소나를 받아 직접 수행할 수 있다.
41
+ 이때 컨텍스트가 메인에 실렸음을 완료 보고에 밝힌다. **독립된 판정자가 필요한 단계**는 `doubt`, review의 3.5 `continuity-judge`, 3.7 `suggestion-verifier`다. 이 셋은 메인의 자기 검토로 대체하지 않는다. 제안 검증을 못 돌렸으면 review 지침에 따라 미실행을 알린다. 정합 심급을 못 돌렸으면 그 사실을 적고 Pass를 승인으로 게시하지 않는다. MCP 자체의 부재는
42
+ [`tool-availability.md`](./tool-availability.md)를 따르며 도구 없이 세션이나 검사 결과를 만들지 않는다.
43
+
44
+ ## Claude Code와 그 밖의 호스트
45
+
46
+ Claude Code는 기존 `Agent` 타입과 모델 별칭을 그대로 쓴다. `inherit`를 명시했다면 모델 인자를 생략한다.
47
+ Grok 등 다른 호스트도 실제 제공된 도구에 맞춰 같은 의미로 옮기며 지원 여부를 모르는 도구 이름이나 모델을 만들지 않는다.
@@ -22,6 +22,8 @@ outputs:
22
22
 
23
23
  # Agent Skill
24
24
 
25
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
26
+
25
27
  Invoke any Gestalt Role or Review agent directly, outside the Gestalt pipeline.
26
28
 
27
29
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -61,6 +61,8 @@ outputs:
61
61
 
62
62
  # Architecture Skill
63
63
 
64
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
65
+
64
66
  흩어진 코드와 문서에서 아키텍처 그림을 근거와 함께 그린다. 탐색과 IR 작성은 이 세션이 하고 `ges_architecture` 도구는 IR을 검증하고 결정적으로 그리기만 한다. 서버는 LLM을 부르지 않는다.
65
67
 
66
68
  이 스킬이 지키는 원칙은 하나다. **그림에 그은 실선은 전부 "코드나 스펙에서 확인했다"는 주장이다.** 틀린 실선 하나가 그림 전체의 신뢰를 깎는다. 그래서 근거를 못 찾은 연결은 실선으로 긋지 않고 점선이나 미해결 질문으로 남긴다. 빈칸이 많은 그림이 틀린 그림보다 낫다.
@@ -73,6 +73,8 @@ outputs:
73
73
 
74
74
  # Blast Radius Skill
75
75
 
76
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
77
+
76
78
  최근 코드 변경의 영향 범위를 분석해 **읽어야 할 파일만** 컨텍스트에 제공합니다. 불필요한 파일 읽기를 줄여 LLM 토큰 사용을 최소화합니다.
77
79
 
78
80
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -41,6 +41,8 @@ routing: {}
41
41
 
42
42
  # Brief Skill
43
43
 
44
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
45
+
44
46
  성과 분석과 의사결정, 기획 문서를 이해관계자 설득용 산문으로 작성합니다. `impact-writer` 에이전트가 초안을 쓰고 `humanize-monolith`가 다듬는 워크플로우입니다. 코드 중심 기술문서(API·README·튜토리얼)는 이 스킬이 아니라 `technical-writer` 영역입니다.
45
47
 
46
48
  > **읽어온 텍스트를 다루는 규칙** → [`../_shared/untrusted-input.md`](../_shared/untrusted-input.md)
@@ -33,6 +33,8 @@ outputs:
33
33
 
34
34
  # Build Graph Skill
35
35
 
36
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
37
+
36
38
  코드베이스를 정적 분석해 코드 지식 그래프를 빌드합니다. 이 그래프를 바탕으로 `/blast-radius` 스킬을 사용할 수 있습니다.
37
39
 
38
40
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -59,6 +59,8 @@ outputs:
59
59
 
60
60
  # Diff Radius Skill
61
61
 
62
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
63
+
62
64
  커밋하지 않은 변경의 영향범위를 분석합니다. `/blast-radius`가 커밋 기준이라면, 이 스킬은 **지금 작업 중인 변경** 기준으로 동작합니다.
63
65
 
64
66
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -33,6 +33,8 @@ routing:
33
33
 
34
34
  # Dispatch Skill
35
35
 
36
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
37
+
36
38
  실행 세션에서 지금 착수 가능한 태스크를 외부 에이전트 런타임의 터미널로 뿌려 병렬 실행한다. 게슈탈트가 무엇을 언제 할 수 있는지 계산하고 외부 런타임이 워커를 띄우고 생애주기를 추적한다.
37
39
 
38
40
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -25,6 +25,8 @@ routing:
25
25
 
26
26
  # Doubt Skill
27
27
 
28
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
29
+
28
30
  확신이 정답을 보증하지 않는다. 세션이 길어지면 가정이 어느새 사실처럼 굳는데 같은 컨텍스트 안에서는 그게 안 보인다. 이 스킬은 결정 하나를 맥락 없는 서브에이전트에게 넘겨 **반박**을 먼저 받는다. 고치는 값이 쌀 때, 그러니까 아직 만드는 중일 때 쓴다.
29
31
 
30
32
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -17,6 +17,8 @@ outputs:
17
17
 
18
18
  # Execute Skill
19
19
 
20
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
21
+
20
22
  This skill transforms a validated Spec specification into a concrete, dependency-aware Execution Plan, executes it with multi-perspective Role Agent guidance, and validates the result through a 2-stage evaluation pipeline.
21
23
 
22
24
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -245,7 +247,7 @@ ges_status() → { reasoningModel: "fable", reasoningModelFallback: "opus", ..
245
247
 
246
248
  **스폰.** 각 `plan_step`(그리고 `plan_complete` 조립을 위한 추론이 필요하면 그 단계)에서 Agent 도구로 서브에이전트를 띄우되 `model` 파라미터에 `reasoningModel` 값을 넘긴다. 서브에이전트에는 해당 단계의 `executeContext`(`systemPrompt`, `planningPrompt`, `currentStage`, `spec`, `previousSteps`)를 전달하고 그 단계의 `stepResult`를 산출하게 한다. 결과를 `plan_step`으로 제출한다.
247
249
 
248
- **폴백은 스킬 런타임에서 발동한다.** 서버는 폴백 대상(`reasoningModelFallback`)만 알려줄 뿐, 모델 가용성을 감지하거나 재시도하지 않는다. Agent 도구가 `reasoningModel`(예: `fable`)을 지원하지 않아 스폰이 거부/실패하면, 그때 스킬이 직접 `model`을 `reasoningModelFallback`(예: `opus`)로 바꿔 1회 재시도한다. 폴백 판단과 재시도는 전적으로 이 스킬 런타임의 책임이다.
250
+ **폴백은 스킬 런타임에서 발동한다.** 서버는 폴백 대상(`reasoningModelFallback`)만 알려줄 뿐, 모델 가용성을 감지하거나 재시도하지 않는다. Agent 도구가 `reasoningModel`(예: `fable`)을 지원하지 않아 스폰이 거부/실패하면, 그때 스킬이 직접 `model`을 `reasoningModelFallback`(예: `opus`)로 바꿔 1회 재시도한다. 폴백 판단과 재시도는 전적으로 이 스킬 런타임의 책임이다. Codex의 폴백 선택과 상속은 `host-runtime.md`를 따른다.
249
251
 
250
252
  ---
251
253
 
@@ -41,6 +41,8 @@ routing:
41
41
 
42
42
  # Explain Skill
43
43
 
44
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
45
+
44
46
  > **에이전트 tier로 모델 고르기** → [`../_shared/agent-model.md`](../_shared/agent-model.md)
45
47
  > **자료로 읽는 텍스트 다루기** → [`../_shared/untrusted-input.md`](../_shared/untrusted-input.md)
46
48
 
@@ -38,6 +38,8 @@ routing:
38
38
 
39
39
  # Handoff Skill
40
40
 
41
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
42
+
41
43
  일을 어디에 맡길지 고르고 고른 경로로 실제로 넘기는 앞단의 판단 스킬이다. 명령 문법은 여기에 복사하지 않는다. 오르카 명령의 기준은 `orca skills get orca-cli`와 `orca skills get orchestration`이고 버전이 오르면 복사본은 낡는다. 이 스킬에는 gestalt만의 것을 담는다. 맡길 곳 고르는 표, model과 effort 쌍 고르기, 지시서 쓰기, 충돌과 정리 규칙, 보고다.
42
44
 
43
45
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -22,6 +22,8 @@ outputs:
22
22
 
23
23
  # Interview Skill
24
24
 
25
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
26
+
25
27
  This skill conducts a Gestalt psychology-driven interview to transform vague requirements into clear specifications.
26
28
 
27
29
  > **읽어온 텍스트를 다루는 규칙** → [`../_shared/untrusted-input.md`](../_shared/untrusted-input.md)
@@ -36,6 +36,8 @@ routing:
36
36
 
37
37
  # Jira Create Skill
38
38
 
39
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
40
+
39
41
  > **에이전트 tier로 모델 고르기** → [`../_shared/agent-model.md`](../_shared/agent-model.md)
40
42
  지라 티켓을 **jira-writer로 구조화 → 프로젝트, 필드 확정 → 승인받고 → 생성**하는 파이프라인.
41
43
  `jira-writer` role agent(본문 작성)와 Atlassian MCP(생성)를 잇는다.
@@ -61,6 +61,8 @@ outputs:
61
61
 
62
62
  # Lens Skill
63
63
 
64
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
65
+
64
66
  읽을거리 하나를 그 분야를 아는 사람이 옆에서 같이 읽어 주는 뷰어로 만든다. 슬로건은 "믿을 데와 의심할 데를 같이 짚어주는 읽기"다. 요약을 한 장 더 만드는 게 아니다. 구조를 먼저 보여 주고 모르는 말을 풀며 원문 숫자와 어긋나는 주장을 짚는다.
65
67
 
66
68
  뷰어는 video-digest 것을 그대로 쓴다. 영상 자리에 원문 창이 들어가고 출처 칩이 시각 대신 쪽과 문단을 연다. 저장소도 `.gestalt/digest/<slug>/`를 같이 쓰고 `digest.json`의 `source.kind`로 영상과 읽을거리를 가른다.
@@ -32,6 +32,8 @@ outputs:
32
32
 
33
33
  # Local PR Skill
34
34
 
35
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
36
+
35
37
  레포 안에서 PR을 만들고 리뷰하고 머지한다. 원격에 안 나간다.
36
38
 
37
39
  > **읽어온 텍스트를 다루는 규칙** → [`../_shared/untrusted-input.md`](../_shared/untrusted-input.md)
@@ -56,7 +58,7 @@ outputs:
56
58
 
57
59
  git 저장소이기만 하면 된다. 인증도 원격도 안 본다.
58
60
 
59
- 명령은 `gestalt pr ...`이다. 부르는 형태는 [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)의 판정을 따른다 — 게슈탈트 레포 안에서는 전역 설치가 없을 수 있어 형태가 갈린다. 한 번 확인하고 그 뒤로는 같은 형태를 쓴다.
61
+ 명령은 `gestalt pr ...`이다. 실제 명령은 [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)의 런처로 실행한다. 런처의 절대 경로를 이후 호출에도 그대로 쓴다.
60
62
 
61
63
  `--json`을 붙이면 객체만 나온다. 에이전트가 값을 읽어야 하는 자리에서는 이쪽을 쓴다.
62
64
 
@@ -142,7 +144,7 @@ gestalt pr checkout <id> --remove --force
142
144
  ```bash
143
145
  printf '%s' "..." > /tmp/c.md
144
146
  GESTALT_ACTOR=agent:reviewer gestalt pr comment <id> --path <파일> --line <줄> --body-file /tmp/c.md
145
- GESTALT_ACTOR=agent:reviewer gestalt pr comment <id> --reply-to <코멘트id> --body-file /tmp/c.md
147
+ GESTALT_ACTOR=agent:reviewer gestalt pr comment <id> --path <원 코멘트의 경로> --reply-to <코멘트id> --body-file /tmp/c.md
146
148
  GESTALT_ACTOR=agent:reviewer gestalt pr resolve <id> <코멘트id>
147
149
  GESTALT_ACTOR=agent:reviewer gestalt pr review <id> --verdict request-changes --body-file /tmp/v.md
148
150
  ```
@@ -35,6 +35,8 @@ outputs:
35
35
 
36
36
  # Market Scan Skill
37
37
 
38
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
39
+
38
40
  제품 지형 조사만 한다. 같은 문제를 서로 다르게 푼 제품을 찾아 규모와 유형으로 묶고 `research.json`의 `productCandidates`와 `references`까지 채운다. 화면을 열거나 캡처하지 않는다.
39
41
 
40
42
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -31,10 +31,12 @@ routing:
31
31
 
32
32
  # PR Skill
33
33
 
34
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
35
+
34
36
  > **에이전트 tier로 모델 고르기** → [`../_shared/agent-model.md`](../_shared/agent-model.md)
35
37
  >
36
38
  > **`gestalt` CLI를 부르는 형태** → [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)
37
- > 본문의 셸 예시는 `gestalt ...`입니다. 게슈탈트 레포 안에서는 `pnpm tsx bin/gestalt.ts ...`로 바꿔 부릅니다. description 어투 검사가 이 CLI에 매달려 있고 **그건 필수 검사라 못 돌리면 멈춥니다.**
39
+ > 본문의 셸 예시는 `gestalt ...`입니다. 설치 위치의 버전 고정 런처로 실행합니다. description 어투 검사가 이 CLI에 매달려 있고 **그건 필수 검사라 못 돌리면 멈춥니다.**
38
40
  레포의 PR 규칙을 먼저 탐색하고 미니 인터뷰로 컨텍스트를 수집한 뒤, diff를 분석해 레포 규칙에 맞는 PR description을 생성하고 `gh pr create`로 제출합니다.
39
41
 
40
42
  ## 사용 방법
@@ -304,19 +306,9 @@ echo "$scanTmp"
304
306
 
305
307
  윤문된 제목과 본문을 합쳐 `"$scanTmp/description.md"`에 씁니다.
306
308
 
307
- ```bash
308
- if gestalt --version >/dev/null 2>&1; then
309
- echo "OK gestalt"
310
- elif pnpm tsx bin/gestalt.ts --version >/dev/null 2>&1; then
311
- echo "OK pnpm"
312
- else
313
- echo "MISSING"
314
- fi
315
- ```
316
-
317
- `OK pnpm`이면 아래 호출의 `gestalt`를 `pnpm tsx bin/gestalt.ts`로 바꿔 부릅니다.
318
-
319
- **`MISSING`이면 검사를 건너뛰지 않고 멈춥니다.** 못 돌린 걸 통과로 읽으면 검사가 없는 것과 같습니다. `npm i -g @tienne/gestalt`를 함께 알리고 그대로 진행할지 사용자가 정하게 둡니다.
309
+ [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)에 따라 이 플러그인의 버전 고정 런처를 사용한다.
310
+ 아래 `gestalt` 호출은 `node`와 런처의 절대 경로로 바꿔 실행한다. 이후 단계와 파이프라인에도 같은 규칙을 적용한다.
311
+ 런처 실행이 실패하면 필수 검사를 건너뛰지 않고 오류를 알린 뒤 멈춘다. 전역 CLI 설치를 요구하거나 다른 버전으로 대신 실행하지 않는다.
320
312
 
321
313
  ```bash
322
314
  gestalt humanize-scan --file "$scanTmp/description.md" --register report
@@ -35,6 +35,8 @@ routing:
35
35
 
36
36
  # Presentation Skill
37
37
 
38
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
39
+
38
40
  > **에이전트 tier로 모델 고르기** → [`../_shared/agent-model.md`](../_shared/agent-model.md)
39
41
  발표 자료를 **콘텐츠 먼저, 디자인 나중** 순서로 만드는 파이프라인.
40
42
  `presentation-writer`(슬라이드 콘텐츠)와 `presentation-designer`(Reveal.js HTML)를 잇고 산출 전 승인 단계를 둔다.
@@ -52,6 +52,8 @@ outputs:
52
52
 
53
53
  # Research Skill
54
54
 
55
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
56
+
55
57
  경쟁사와 시장 레퍼런스를 조사하고 역기획까지 해서 기획 판단의 근거를 만든다. 조사와 `research.json` 작성은 이 세션이 하고 `ges_research` 도구는 출처 상태 확인, 개인정보 치환, 검증, 렌더만 한다. 서버는 LLM을 부르지 않는다.
56
58
 
57
59
  이 스킬이 지키는 원칙은 하나다. **관찰과 해석을 나눈다.** 화면에서 보이는 것과 숫자는 출처를 댈 수 있어야 한다. 추론과 효과 예측은 문장 끝에 `(해석)`을 붙인다. 근거를 못 찾은 칸은 그럴싸하게 채우지 않고 확인 못함으로 적는다. 빈칸이 있는 결과가 지어낸 결과보다 낫다.
@@ -26,6 +26,8 @@ outputs:
26
26
 
27
27
  # Reverse Plan Skill
28
28
 
29
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
30
+
29
31
  이미 모은 화면에서 한 걸음 더 나가 레퍼런스가 그 화면을 만든 이유를 쓴다. `reasons`(섹션 5)만 채운다. 새 화면을 캡처하지 않는다.
30
32
 
31
33
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
@@ -52,6 +52,8 @@ routing: {}
52
52
 
53
53
  # Review Skill
54
54
 
55
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
56
+
55
57
  execute 세션 없이 PR, 브랜치, 커밋의 변경사항을 직접 리뷰 파이프라인에 주입해 검토합니다.
56
58
  변경 파일을 수집하고 리뷰 에이전트(보안, 성능, 품질, 주석, 문서와 문자열이 바뀌었으면 라이팅, 스킬이나 에이전트 문서가 바뀌었으면 하네스)로 다각도 리뷰한 뒤(**결함 심급**), `continuity-judge`가 변경 전체의 목표 정합성과 일관성을 감독하고(**정합 심급**), `suggestion-verifier`가 리뷰어 제안을 반영하면 무엇이 깨지는지 게시 전에 확인한 뒤(**제안 검증**), Pass/Block 판정과 마크다운 리포트를 생성합니다. 리뷰 대상이 PR이면 — GitHub PR이든 로컬 `gestalt pr` PR이든 — `code-review-writer` 에이전트가 작성한 인라인 코멘트로 그 PR에 게시까지 이어집니다.
57
59
 
@@ -61,7 +63,7 @@ execute 세션 없이 PR, 브랜치, 커밋의 변경사항을 직접 리뷰 파
61
63
  > **도구가 없을 때** → [`../_shared/tool-availability.md`](../_shared/tool-availability.md)
62
64
  >
63
65
  > **`gestalt` CLI를 부르는 형태** → [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)
64
- > 본문의 셸 예시는 전부 `gestalt ...`입니다. 게슈탈트 레포 안에서는 `pnpm tsx bin/gestalt.ts ...`로 바꿔 부릅니다. 어투 검사(1.5, 4.5, 4.7단계)가 이 CLI에 매달려 있고 **그 셋은 필수 검사라 못 돌리면 멈춥니다.**
66
+ > 본문의 셸 예시는 전부 `gestalt ...`입니다. 설치 위치의 버전 고정 런처로 실행합니다. 어투 검사(1.5, 4.5, 4.7단계)가 이 CLI에 매달려 있고 **그 셋은 필수 검사라 못 돌리면 멈춥니다.**
65
67
  >
66
68
  > **에이전트 tier로 모델 고르기** → [`../_shared/agent-model.md`](../_shared/agent-model.md)
67
69
  >
@@ -615,19 +617,9 @@ echo "$scanTmp"
615
617
 
616
618
  작성된 컨텍스트 문서를 `"$scanTmp/change-context.md"`에 쓴다 (파일 쓰기 도구 사용, 셸로 넘기지 않는다).
617
619
 
618
- ```bash
619
- if gestalt --version >/dev/null 2>&1; then
620
- echo "OK gestalt"
621
- elif pnpm tsx bin/gestalt.ts --version >/dev/null 2>&1; then
622
- echo "OK pnpm"
623
- else
624
- echo "MISSING"
625
- fi
626
- ```
627
-
628
- `OK pnpm`이면 아래 호출의 `gestalt`를 `pnpm tsx bin/gestalt.ts`로 바꿔 부릅니다. 한 번 확인하고 그 뒤로는(4.5, 4.7단계 포함) 같은 형태를 씁니다.
629
-
630
- **`MISSING`이면 검사를 건너뛰지 않고 멈춥니다.** 못 돌린 걸 통과로 읽으면 검사가 없는 것과 같습니다. `npm i -g @tienne/gestalt`를 함께 알리고 그대로 진행할지 사용자가 정하게 둡니다.
620
+ [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)에 따라 이 플러그인의 버전 고정 런처를 사용한다.
621
+ 아래 `gestalt` 호출은 `node`와 런처의 절대 경로로 바꿔 실행한다. 이후 단계와 파이프라인에도 같은 규칙을 적용한다.
622
+ 런처 실행이 실패하면 필수 검사를 건너뛰지 않고 오류를 알린 뒤 멈춘다. 전역 CLI 설치를 요구하거나 다른 버전으로 대신 실행하지 않는다.
631
623
 
632
624
  ```bash
633
625
  gestalt humanize-scan --file "$scanTmp/change-context.md" --register report
@@ -1392,15 +1384,20 @@ echo "파일 $found 개"
1392
1384
 
1393
1385
  # 파일마다 프로세스를 새로 띄우지 않고 한 번의 호출에 전부 실어 보냅니다.
1394
1386
  # humanize-scan 은 넘겨받은 파일 각각을 읽고 스캔을 따로 돌리므로 결과는 파일별로 갈립니다.
1395
- find "$scanTmp" -maxdepth 1 -name '*.md' | sort | sed 's/^/--file /' \
1396
- | xargs gestalt humanize-scan --register chat
1387
+ if [ "$found" -eq 1 ]; then
1388
+ scanFile=$(find "$scanTmp" -maxdepth 1 -name '*.md')
1389
+ gestalt humanize-scan --file "$scanFile" --register chat
1390
+ elif [ "$found" -gt 1 ]; then
1391
+ find "$scanTmp" -maxdepth 1 -name '*.md' | sort | sed 's/^/--file /' \
1392
+ | xargs gestalt humanize-scan --register chat
1393
+ fi
1397
1394
  ```
1398
1395
 
1399
1396
  `found` 가 코멘트 수와 다르면 **검사 실패입니다.** 그 자리에서 멈추고 무엇이 어긋났는지 알립니다. 파일 쓰기가 어긋났는데 조용히 넘어가면 이 검사가 막으려던 상황이 그대로 재현됩니다.
1400
1397
 
1401
1398
  이 호출이 답하는 질문은 두 층입니다.
1402
1399
 
1403
- - **프로세스 종료 코드**는 파일 전체를 합친 값입니다 — 하나라도 0이면 0, 아니면 하나라도 12면 12, 아니면 하나라도 11이면 11, 나머지는 10입니다. "게시를 미뤄야 하는가"는 이 값 하나로 답이 납니다.
1400
+ - **스캐너 프로세스 종료 코드**는 파일 전체를 합친 값입니다 — 하나라도 0이면 0, 아니면 하나라도 12면 12, 아니면 하나라도 11이면 11, 나머지는 10입니다. `xargs`는 이 값을 다른 코드로 바꾸므로 여러 파일 호출에서는 셸의 종료 코드로 게시 여부를 판단하지 않습니다.
1404
1401
  - **어느 코멘트를 다시 써야 하는가**는 출력에 파일마다 찍히는 `== <경로> EXIT=<코드>` 줄로 답이 납니다. 파일별로 스캔을 따로 돌린 결과라 이 코드는 코멘트 단위 그대로입니다.
1405
1402
 
1406
1403
  각 줄의 EXIT 값이 뜻하는 바는 다음과 같습니다.
@@ -1410,7 +1407,7 @@ find "$scanTmp" -maxdepth 1 -name '*.md' | sort | sed 's/^/--file /' \
1410
1407
  - **11** — 어투는 깨끗하고 맞춤법만 걸렸습니다. 그것만 고칩니다.
1411
1408
  - **12** — **검사할 산문이 없습니다.** 코멘트가 인용줄뿐이라 검사가 안 된 것이지 통과가 아닙니다. 자기 문장을 인용 밖에 두고 다시 쓰게 합니다.
1412
1409
  - 재작성은 **한 번만** 돕니다. 두 번째도 걸리면 무엇이 남았는지 사용자에게 알리고 게시할지 묻습니다.
1413
- - 프로세스 종료 코드가 10이나 11이면 게시합니다. 게시가 끝나면 `rm -rf "$scanTmp"`로 그 실행 칸만 치웁니다 — 상위 `gestalt-review`나 PR 칸을 통째로 지우면 다른 세션이 쓰는 중인 파일까지 날아갑니다.
1410
+ - 여러 파일이면 파일별 EXIT가 모두 10이나 11일 때 게시합니다. 표지가 없는 단일 파일 직접 호출은 그 프로세스의 종료 코드를 씁니다. 게시가 끝나면 `rm -rf "$scanTmp"`로 그 실행 칸만 치웁니다 — 상위 `gestalt-review`나 PR 칸을 통째로 지우면 다른 세션이 쓰는 중인 파일까지 날아갑니다.
1414
1411
 
1415
1412
  **코멘트 여러 개를 파일 하나에 모아 담으면 이 검사가 무력화됩니다.** 인용 판정이 그 파일 전체를 한 덩어리로 보기 때문에 코멘트 하나를 통째로 인용으로 감싸도 같은 파일 안 다른 코멘트의 산문에 묻혀 안 걸립니다. 파일 하나에 코멘트 하나가 이 검사가 서는 조건입니다.
1416
1413
 
@@ -44,6 +44,8 @@ routing:
44
44
 
45
45
  # Review Loop Skill
46
46
 
47
+ > **호스트별 도구와 모델 호출** → [`../_shared/host-runtime.md`](../_shared/host-runtime.md). 실행 전에 읽고 현재 호스트에 맞게 적용한다.
48
+
47
49
  남의 GitHub PR 하나를 **리뷰어로 끝까지 따라간다.** 리뷰하고 판정을 남기고 작성자가 고칠 때까지 지켜보다가 다시 리뷰한다.
48
50
 
49
51
  ```
@@ -220,11 +222,12 @@ gh repo view --json owner,name,nameWithOwner
220
222
 
221
223
  **판정에 쓰는 수를 전부 이 명령이 낸다.** 없으면 첫 단계부터 아무것도 못 한다 — 설치본이 뒤처져 있으면 `unknown option` 으로 죽는데, 그걸 라운드를 돌다가 알면 늦다.
222
224
 
223
- 먼저 [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)의 판정을 돌려 `gestalt`를 어떤 형태로 부르는지 정한다. 그다음 그 형태로 하위 명령을 찌른다.
225
+ 먼저 [`../_shared/cli-launcher.md`](../_shared/cli-launcher.md)에 따라 플러그인 버전에 맞는 런처가 설치된 절대 경로를 구한다.
226
+ 아래 경로 자리에 실제 값을 직접 넣는다. 도구 호출 사이에 셸 변수가 남는다고 가정하지 않는다.
224
227
 
225
228
  ```bash
226
- if gestalt review-loop parse 1 >/dev/null 2>&1 \
227
- && gestalt review-loop dir >/dev/null 2>&1; then
229
+ if node "<공유 지침으로 구한 런처 절대 경로>" review-loop parse 1 >/dev/null 2>&1 \
230
+ && node "<공유 지침으로 구한 런처 절대 경로>" review-loop dir >/dev/null 2>&1; then
228
231
  echo "OK"
229
232
  else
230
233
  echo "MISSING"
@@ -234,14 +237,14 @@ fi
234
237
 
235
238
  **명령을 변수에 담아 함수로 넘기지 않는다.** zsh는 인용 안 한 변수 전개에서 단어 분리를 안 해 `$cmd`가 통째로 명령 이름이 된다. 그러면 실제로 깔려 있어도 `MISSING`이 나온다. 같은 코드가 bash에서는 도는 탓에 눈으로는 안 걸린다.
236
239
 
237
- `OK`면 아래 예시를 앞의 판정에서 정한 형태로 쓴다. **`MISSING`이면 라운드를 시작하지 않는다.**
240
+ `OK`면 이후 모든 CLI 예시의 `gestalt`를 `node "<공유 지침으로 구한 런처 절대 경로>"`로 바꿔 실행한다. **`MISSING`이면 라운드를 시작하지 않는다.**
238
241
 
239
242
  **하위 명령을 둘 다 찔러본다.** 하나만 보면 그것만 있고 나머지가 없는 중간 설치본이 통과해 라운드 중간에 죽는다. 1.1이 입력 하나가 아니라 셋을 보는 이유와 같다.
240
243
 
241
244
  ```
242
245
  이 버전에는 `gestalt review-loop` 명령이 없네요. 판정에 쓰는 수를 낼 방법이 없어요.
243
246
 
244
- `/plugin install gestalt@gestalt`로 플러그인을 올린 뒤 다시 불러주세요.
247
+ 먼저 Node.js >=22, npm과 네트워크 연결을 확인해요. 그래도 이 버전에 하위 명령이 없으면 플러그인을 갱신한 뒤 다시 불러주세요.
245
248
  ```
246
249
 
247
250
  1.1의 `review` 스킬 검사와 같은 격이다. 둘 다 없으면 루프가 성립하지 않는 전제라 시작 전에 본다.
@@ -391,7 +394,7 @@ done
391
394
  설치된 `review` 스킬이 `postVerdict`를 안 받네요. 그대로 돌리면 라운드마다 판정이 두 번 나가요.
392
395
  이슈가 남았는데 승인으로 끝나는 경우도 생기고요.
393
396
 
394
- `/plugin install gestalt@gestalt`로 플러그인을 올린 뒤 다시 불러주세요.
397
+ 플러그인이 최신인지 확인하고 아니면 갱신한 뒤 다시 불러주세요.
395
398
  ```
396
399
 
397
400
  **이 스킬을 새로 부른 세션마다 한 번 돈다.** 같은 세션 안에서는 설치본이 안 바뀌므로 라운드 2부터 건너뛴다. 다만 `round` 파일이 있어 **이어서 도는 세션은 다시 돈다** — 지난 세션 뒤에 플러그인이 올라갔을 수 있다.
@@ -413,10 +416,10 @@ postVerdict: false
413
416
 
414
417
  ```
415
418
  #{prNumber}에 이미 판정이 게시됐어요 — {postedReview}.
416
- `postVerdict: false`로 불렀는데 설치된 review 가 그걸 못 읽은 것 같습니다.
419
+ `postVerdict: false`로 불렀는데 설치된 review가 그 입력을 못 읽었어요.
417
420
 
418
421
  이 라운드는 여기서 멈출게요. 제가 판정을 또 내면 두 번 나갑니다.
419
- `/plugin install gestalt@gestalt`로 플러그인을 올린 뒤 다시 불러주세요.
422
+ 플러그인이 최신인지 확인하고 아니면 갱신한 뒤 다시 불러주세요.
420
423
  ```
421
424
 
422
425
  `loopState`를 `blocked`로 두고 끝낸다. **2.5로 내려가지 않는다** — 이미 나간 판정 위에 하나 더 얹는 게 이 계약이 막으려던 바로 그 일이다.
@@ -608,7 +611,7 @@ gestalt humanize-scan --file "$stateDir/verdict-r<N>.md" --register chat
608
611
  echo "EXIT=$?"
609
612
  ```
610
613
 
611
- 부르는 형태는 위 "조회 명령이 있는지 먼저 본다"에서 판정한 것을 그대로 쓴다.
614
+ 위 "조회 명령이 있는지 먼저 본다"에서 구한 런처의 절대 경로를 그대로 쓴다.
612
615
 
613
616
  | 종료 코드 | 무엇 |
614
617
  | --- | --- |
@@ -619,7 +622,7 @@ echo "EXIT=$?"
619
622
 
620
623
  **ⓦ 두 번째도 걸리면** 무엇이 남았는지 알리고 게시할지 묻는다.
621
624
 
622
- 어느 형태로 부를지는 Phase 0의 `OK gestalt`와 `OK pnpm`에서 이미 정해졌다.
625
+ Phase 0에서 정한 버전 고정 런처를 여기서도 사용한다. `gestalt` 예시는 `node "<공유 지침으로 구한 런처 절대 경로>"`로 바꿔 실행한다.
623
626
 
624
627
  ### 2.5 게시
625
628