@tienne/gestalt 0.67.0 → 0.69.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/CLAUDE.md +12 -5
- package/README.ko.md +9 -5
- package/README.md +10 -5
- package/dist/package.json +2 -1
- package/dist/plugin/review-agents/comment-reviewer/AGENT.md +2 -0
- package/dist/plugin/review-agents/quality-reviewer/AGENT.md +1 -1
- package/dist/plugin/review-agents/writing-reviewer/AGENT.md +123 -0
- package/dist/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +1 -1
- package/dist/plugin/role-agents/_shared/references/comment-rules.md +14 -0
- package/dist/plugin/skills/_shared/agent-model.md +15 -0
- package/dist/plugin/skills/blast-radius/SKILL.md +31 -0
- package/dist/plugin/skills/diff-radius/SKILL.md +1 -1
- package/dist/plugin/skills/execute/SKILL.md +15 -0
- package/dist/plugin/skills/local-pr/SKILL.md +201 -0
- package/dist/plugin/skills/pr/SKILL.md +73 -4
- package/dist/plugin/skills/review/SKILL.md +236 -22
- package/dist/plugin/skills/review-reply/SKILL.md +160 -7
- package/dist/src/agent/role-match-engine.d.ts +8 -0
- package/dist/src/agent/role-match-engine.d.ts.map +1 -1
- package/dist/src/agent/role-match-engine.js +1 -1
- package/dist/src/agent/role-match-engine.js.map +1 -1
- package/dist/src/cli/commands/interview.js +2 -2
- package/dist/src/cli/commands/interview.js.map +1 -1
- package/dist/src/cli/commands/pr.d.ts +133 -0
- package/dist/src/cli/commands/pr.d.ts.map +1 -0
- package/dist/src/cli/commands/pr.js +489 -0
- package/dist/src/cli/commands/pr.js.map +1 -0
- package/dist/src/cli/commands/spec.js +2 -2
- package/dist/src/cli/commands/spec.js.map +1 -1
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +85 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +4 -3
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/home.d.ts +20 -0
- package/dist/src/core/home.d.ts.map +1 -0
- package/dist/src/core/home.js +52 -0
- package/dist/src/core/home.js.map +1 -0
- package/dist/src/core/types.d.ts +38 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/version.d.ts.map +1 -1
- package/dist/src/core/version.js +4 -7
- package/dist/src/core/version.js.map +1 -1
- package/dist/src/events/store.d.ts +32 -0
- package/dist/src/events/store.d.ts.map +1 -1
- package/dist/src/events/store.js +68 -3
- package/dist/src/events/store.js.map +1 -1
- package/dist/src/humanize/detectors.d.ts.map +1 -1
- package/dist/src/humanize/detectors.js +3 -1
- package/dist/src/humanize/detectors.js.map +1 -1
- package/dist/src/interview/engine.d.ts +6 -1
- package/dist/src/interview/engine.d.ts.map +1 -1
- package/dist/src/interview/engine.js +7 -2
- package/dist/src/interview/engine.js.map +1 -1
- package/dist/src/knowledge-base/summarizer.d.ts +22 -0
- package/dist/src/knowledge-base/summarizer.d.ts.map +1 -0
- package/dist/src/knowledge-base/summarizer.js +179 -0
- package/dist/src/knowledge-base/summarizer.js.map +1 -0
- package/dist/src/llm/factory.d.ts +9 -0
- package/dist/src/llm/factory.d.ts.map +1 -1
- package/dist/src/llm/factory.js +13 -0
- package/dist/src/llm/factory.js.map +1 -1
- package/dist/src/local-pr/engine.d.ts +176 -0
- package/dist/src/local-pr/engine.d.ts.map +1 -0
- package/dist/src/local-pr/engine.js +373 -0
- package/dist/src/local-pr/engine.js.map +1 -0
- package/dist/src/local-pr/git.d.ts +190 -0
- package/dist/src/local-pr/git.d.ts.map +1 -0
- package/dist/src/local-pr/git.js +580 -0
- package/dist/src/local-pr/git.js.map +1 -0
- package/dist/src/local-pr/index.d.ts +6 -0
- package/dist/src/local-pr/index.d.ts.map +1 -0
- package/dist/src/local-pr/index.js +8 -0
- package/dist/src/local-pr/index.js.map +1 -0
- package/dist/src/local-pr/policy.d.ts +77 -0
- package/dist/src/local-pr/policy.d.ts.map +1 -0
- package/dist/src/local-pr/policy.js +80 -0
- package/dist/src/local-pr/policy.js.map +1 -0
- package/dist/src/local-pr/registry.d.ts +79 -0
- package/dist/src/local-pr/registry.d.ts.map +1 -0
- package/dist/src/local-pr/registry.js +307 -0
- package/dist/src/local-pr/registry.js.map +1 -0
- package/dist/src/local-pr/repository.d.ts +67 -0
- package/dist/src/local-pr/repository.d.ts.map +1 -0
- package/dist/src/local-pr/repository.js +251 -0
- package/dist/src/local-pr/repository.js.map +1 -0
- package/dist/src/local-pr/types.d.ts +151 -0
- package/dist/src/local-pr/types.d.ts.map +1 -0
- package/dist/src/local-pr/types.js +9 -0
- package/dist/src/local-pr/types.js.map +1 -0
- package/dist/src/local-pr-web/engine.d.ts +24 -0
- package/dist/src/local-pr-web/engine.d.ts.map +1 -0
- package/dist/src/local-pr-web/engine.js +112 -0
- package/dist/src/local-pr-web/engine.js.map +1 -0
- package/dist/src/local-pr-web/html-generator.d.ts +24 -0
- package/dist/src/local-pr-web/html-generator.d.ts.map +1 -0
- package/dist/src/local-pr-web/html-generator.js +385 -0
- package/dist/src/local-pr-web/html-generator.js.map +1 -0
- package/dist/src/local-pr-web/index.d.ts +5 -0
- package/dist/src/local-pr-web/index.d.ts.map +1 -0
- package/dist/src/local-pr-web/index.js +5 -0
- package/dist/src/local-pr-web/index.js.map +1 -0
- package/dist/src/local-pr-web/server.d.ts +126 -0
- package/dist/src/local-pr-web/server.d.ts.map +1 -0
- package/dist/src/local-pr-web/server.js +394 -0
- package/dist/src/local-pr-web/server.js.map +1 -0
- package/dist/src/local-pr-web/types.d.ts +11 -0
- package/dist/src/local-pr-web/types.d.ts.map +1 -0
- package/dist/src/local-pr-web/types.js +2 -0
- package/dist/src/local-pr-web/types.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +79 -4
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +80 -2
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +23 -10
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/generate-kb.d.ts +10 -1
- package/dist/src/mcp/tools/generate-kb.d.ts.map +1 -1
- package/dist/src/mcp/tools/generate-kb.js +17 -1
- package/dist/src/mcp/tools/generate-kb.js.map +1 -1
- package/dist/src/mcp/tools/pr.d.ts +5 -0
- package/dist/src/mcp/tools/pr.d.ts.map +1 -0
- package/dist/src/mcp/tools/pr.js +165 -0
- package/dist/src/mcp/tools/pr.js.map +1 -0
- package/dist/src/mcp/tools/review-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +264 -15
- package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/search-kb.d.ts.map +1 -1
- package/dist/src/mcp/tools/search-kb.js +5 -0
- package/dist/src/mcp/tools/search-kb.js.map +1 -1
- package/dist/src/mcp/tools/status.d.ts +16 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -1
- package/dist/src/mcp/tools/status.js +19 -4
- package/dist/src/mcp/tools/status.js.map +1 -1
- package/dist/src/memory/user-profile-store.d.ts.map +1 -1
- package/dist/src/memory/user-profile-store.js +3 -4
- package/dist/src/memory/user-profile-store.js.map +1 -1
- package/dist/src/review/context-collector.d.ts +1 -1
- package/dist/src/review/context-collector.js +1 -1
- package/dist/src/review/passthrough-engine.d.ts +1 -0
- package/dist/src/review/passthrough-engine.d.ts.map +1 -1
- package/dist/src/review/passthrough-engine.js +7 -2
- package/dist/src/review/passthrough-engine.js.map +1 -1
- package/dist/src/spec/text-based-spec-generator.d.ts.map +1 -1
- package/dist/src/spec/text-based-spec-generator.js +5 -2
- package/dist/src/spec/text-based-spec-generator.js.map +1 -1
- package/package.json +2 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/review-agents/comment-reviewer/AGENT.md +2 -0
- package/plugin/review-agents/quality-reviewer/AGENT.md +1 -1
- package/plugin/review-agents/writing-reviewer/AGENT.md +123 -0
- package/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +1 -1
- package/plugin/role-agents/_shared/references/comment-rules.md +14 -0
- package/plugin/skills/_shared/agent-model.md +15 -0
- package/plugin/skills/blast-radius/SKILL.md +31 -0
- package/plugin/skills/diff-radius/SKILL.md +1 -1
- package/plugin/skills/execute/SKILL.md +15 -0
- package/plugin/skills/local-pr/SKILL.md +201 -0
- package/plugin/skills/pr/SKILL.md +73 -4
- package/plugin/skills/review/SKILL.md +236 -22
- package/plugin/skills/review-reply/SKILL.md +160 -7
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { LocalPrEngine, PrError } from '../../local-pr/engine.js';
|
|
4
|
+
import { openThreads, resolveActor, unresolvedComments, unresolvedCount, } from '../../local-pr/policy.js';
|
|
5
|
+
import { listRepos, repoKey, unregisterRepo } from '../../local-pr/registry.js';
|
|
6
|
+
import { PrWebEngine } from '../../local-pr-web/engine.js';
|
|
7
|
+
/**
|
|
8
|
+
* 본문을 파일이나 stdin에서 읽는다.
|
|
9
|
+
*
|
|
10
|
+
* 인자로 받지 않는 이유는 셸을 타면 한글과 백틱, 줄바꿈이 깨지기 때문이다.
|
|
11
|
+
* `-`면 stdin이다 — gh가 --body-file에 쓰는 방식과 같다.
|
|
12
|
+
*/
|
|
13
|
+
function readBody(bodyFile) {
|
|
14
|
+
if (bodyFile === undefined)
|
|
15
|
+
return '';
|
|
16
|
+
// 빈 문자열은 "안 줬다"가 아니라 "빈 경로를 줬다"다. 안 갈라 두면 셸에서 안 풀린
|
|
17
|
+
// `--body-file "$F"`가 본문을 조용히 지운다 — 없는 경로는 ENOENT로 죽는데
|
|
18
|
+
// 이 자리만 성공으로 끝난다
|
|
19
|
+
if (bodyFile === '')
|
|
20
|
+
throw new PrError('--body-file에 경로가 비어 있어요', 1);
|
|
21
|
+
return readFileSync(bodyFile === '-' ? 0 : bodyFile, 'utf-8');
|
|
22
|
+
}
|
|
23
|
+
function actorOf(opts) {
|
|
24
|
+
return resolveActor(opts.author);
|
|
25
|
+
}
|
|
26
|
+
function engineOf(opts) {
|
|
27
|
+
return new LocalPrEngine(resolve(opts.repoRoot ?? process.cwd()));
|
|
28
|
+
}
|
|
29
|
+
/** 에이전트가 파싱할 자리라 --json이면 객체만 내보낸다 */
|
|
30
|
+
function emit(value, json, human) {
|
|
31
|
+
if (json) {
|
|
32
|
+
console.log(JSON.stringify(value, null, 2));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
human();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function summarize(pr) {
|
|
39
|
+
const unresolved = unresolvedCount(pr);
|
|
40
|
+
const round = pr.rounds[pr.rounds.length - 1].number;
|
|
41
|
+
return `${pr.id} [${pr.status}] ${pr.title} (라운드 ${round}, 미해결 ${unresolved})`;
|
|
42
|
+
}
|
|
43
|
+
/** 오류를 종료 코드로 옮긴다. 에이전트가 stdout을 안 읽고도 갈래를 탄다 */
|
|
44
|
+
function run(fn) {
|
|
45
|
+
try {
|
|
46
|
+
fn();
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
// `process.exit`이 여기서 흐름을 끊는 건 런타임의 성질이지 이 갈래가 한 약속이
|
|
50
|
+
// 아니다. 갈라 두지 않으면 테스트가 exit을 가로챌 때 두 번 나간다
|
|
51
|
+
if (e instanceof PrError) {
|
|
52
|
+
console.error(e.message);
|
|
53
|
+
process.exit(e.exitCode);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.error(e instanceof Error ? e.message : String(e));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export function prCreateCommand(opts) {
|
|
62
|
+
run(() => {
|
|
63
|
+
const engine = engineOf(opts);
|
|
64
|
+
try {
|
|
65
|
+
const pr = engine.create({
|
|
66
|
+
title: opts.title,
|
|
67
|
+
body: readBody(opts.bodyFile),
|
|
68
|
+
author: actorOf(opts),
|
|
69
|
+
base: opts.base,
|
|
70
|
+
head: opts.head,
|
|
71
|
+
});
|
|
72
|
+
emit(pr, opts.json, () => {
|
|
73
|
+
console.log(`PR을 만들었어요: ${pr.id}`);
|
|
74
|
+
console.log(` base ${pr.baseSha.slice(0, 8)} → head ${pr.headSha.slice(0, 8)}`);
|
|
75
|
+
console.log(` 리뷰: gestalt pr show ${pr.id}`);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
engine.dispose();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
export function prListCommand(opts) {
|
|
84
|
+
run(() => {
|
|
85
|
+
const engine = engineOf(opts);
|
|
86
|
+
try {
|
|
87
|
+
const prs = engine.list(opts.status);
|
|
88
|
+
emit(prs, opts.json, () => {
|
|
89
|
+
if (prs.length === 0) {
|
|
90
|
+
console.log('PR이 없어요');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
for (const pr of prs)
|
|
94
|
+
console.log(summarize(pr));
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
engine.dispose();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function prShowCommand(opts) {
|
|
103
|
+
run(() => {
|
|
104
|
+
const engine = engineOf(opts);
|
|
105
|
+
try {
|
|
106
|
+
const pr = engine.get(opts.id);
|
|
107
|
+
if (!pr)
|
|
108
|
+
throw new PrError(`PR을 못 찾았어요: ${opts.id}`, 3);
|
|
109
|
+
emit(pr, opts.json, () => {
|
|
110
|
+
console.log(summarize(pr));
|
|
111
|
+
console.log(` 작성 ${pr.author}`);
|
|
112
|
+
if (pr.body)
|
|
113
|
+
console.log(`\n${pr.body}\n`);
|
|
114
|
+
for (const round of pr.rounds) {
|
|
115
|
+
const verdict = round.verdict ?? '진행 중';
|
|
116
|
+
console.log(`\n라운드 ${round.number} — ${verdict} (코멘트 ${round.commentCount})`);
|
|
117
|
+
for (const review of pr.reviews.filter((r) => r.round === round.number)) {
|
|
118
|
+
console.log(` ${review.reviewer}: ${review.verdict} — ${review.summary}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 머리글의 "미해결 N"과 이 목록이 같은 함수에서 나온다. 따로 세면 머리글은
|
|
122
|
+
// 스레드를, 목록은 코멘트를 세어 한 화면에서 수가 갈린다
|
|
123
|
+
const threads = openThreads(pr);
|
|
124
|
+
if (threads.length > 0) {
|
|
125
|
+
console.log('\n미해결 스레드');
|
|
126
|
+
for (const { root, comments } of threads) {
|
|
127
|
+
const at = root.line === null ? root.path : `${root.path}:${root.line}`;
|
|
128
|
+
const replies = comments.length - 1;
|
|
129
|
+
const tail = replies > 0 ? ` (답글 ${replies}개)` : '';
|
|
130
|
+
console.log(` [${root.id}] ${at} (${root.author})${tail}`);
|
|
131
|
+
console.log(` ${root.body.split('\n')[0]}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
engine.dispose();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
export function prDiffCommand(opts) {
|
|
142
|
+
run(() => {
|
|
143
|
+
const engine = engineOf(opts);
|
|
144
|
+
try {
|
|
145
|
+
const diff = engine.diff(opts.id);
|
|
146
|
+
emit({ diff }, opts.json, () => console.log(diff));
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
engine.dispose();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* `gestalt pr checkout <id>` — PR head를 임시 워크트리로 떼어낸다.
|
|
155
|
+
*
|
|
156
|
+
* `--remove`면 지운다. 붙였다 뗐다를 한 명령에 둔 이유는 경로 규칙이 하나라서다.
|
|
157
|
+
* 리뷰어는 id만 알면 되고 경로를 적어둘 필요가 없다.
|
|
158
|
+
*/
|
|
159
|
+
export function prCheckoutCommand(opts) {
|
|
160
|
+
run(() => {
|
|
161
|
+
const engine = engineOf(opts);
|
|
162
|
+
try {
|
|
163
|
+
if (opts.remove) {
|
|
164
|
+
const result = engine.removeCheckout(opts.id, { force: opts.force });
|
|
165
|
+
emit(result, opts.json, () => {
|
|
166
|
+
if (result.removed) {
|
|
167
|
+
console.log(`워크트리를 지웠어요: ${result.path}`);
|
|
168
|
+
if (result.savedRef) {
|
|
169
|
+
console.log(` 여기서 커밋한 변경은 ${result.savedRef}로 붙잡아 뒀어요`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
console.log(`안 지웠어요 — ${result.reason}`);
|
|
174
|
+
console.log(` ${result.path}`);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// 안 지운 건 실패가 아니라 판단을 되돌려준 것이다. 에이전트가 종료 코드로
|
|
178
|
+
// 갈래를 타게 4(상태 충돌)를 준다. 지킨 갈래는 `dirty`, `diverged`, `stale`
|
|
179
|
+
// 셋이고 앞으로 늘 수 있다. 그 셋을 나열하는 대신 "지운 두 갈래가 아니면"으로
|
|
180
|
+
// 적는다. `absent`를 뺀 이유는 지울 자리가 없는 게 정리의 목표가 이미 이뤄진
|
|
181
|
+
// 상태여서다. 4로 주면 `--remove`를 두 번 부르는 `set -e` 스크립트가 두 번째에
|
|
182
|
+
// 죽는다. 이 갈림은 --json의 status로도 읽을 수 있다 — 산문 reason을 부분
|
|
183
|
+
// 문자열로 긁을 필요가 없다
|
|
184
|
+
if (result.status !== 'removed' && result.status !== 'absent')
|
|
185
|
+
process.exit(4);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const checkout = engine.checkout(opts.id);
|
|
189
|
+
emit(checkout, opts.json, () => {
|
|
190
|
+
console.log(checkout.created ? '워크트리를 뗐어요' : '이미 떼어둔 워크트리가 있어요');
|
|
191
|
+
console.log(` ${checkout.path}`);
|
|
192
|
+
console.log(` head ${checkout.headSha.slice(0, 8)}`);
|
|
193
|
+
console.log(` 정리: gestalt pr checkout ${opts.id} --remove`);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
engine.dispose();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
export function prCommentCommand(opts) {
|
|
202
|
+
run(() => {
|
|
203
|
+
const engine = engineOf(opts);
|
|
204
|
+
try {
|
|
205
|
+
const body = readBody(opts.bodyFile);
|
|
206
|
+
if (!body.trim())
|
|
207
|
+
throw new PrError('본문이 비었어요. --body-file로 넘겨주세요', 1);
|
|
208
|
+
const pr = engine.comment(opts.id, {
|
|
209
|
+
author: actorOf(opts),
|
|
210
|
+
path: opts.path,
|
|
211
|
+
line: opts.line ? Number(opts.line) : undefined,
|
|
212
|
+
body,
|
|
213
|
+
replyTo: opts.replyTo,
|
|
214
|
+
});
|
|
215
|
+
const added = pr.comments[pr.comments.length - 1];
|
|
216
|
+
emit(added, opts.json, () => console.log(`코멘트 ${added.id} 추가`));
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
engine.dispose();
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
export function prCommentsCommand(opts) {
|
|
224
|
+
run(() => {
|
|
225
|
+
const engine = engineOf(opts);
|
|
226
|
+
try {
|
|
227
|
+
const pr = engine.get(opts.id);
|
|
228
|
+
if (!pr)
|
|
229
|
+
throw new PrError(`PR을 못 찾았어요: ${opts.id}`, 3);
|
|
230
|
+
const comments = opts.unresolved ? unresolvedComments(pr) : pr.comments;
|
|
231
|
+
emit(comments, opts.json, () => {
|
|
232
|
+
for (const c of comments) {
|
|
233
|
+
const at = c.line === null ? c.path : `${c.path}:${c.line}`;
|
|
234
|
+
const mark = c.resolved ? '해결' : '열림';
|
|
235
|
+
console.log(`[${c.id}] ${at} (${c.author}, ${mark})`);
|
|
236
|
+
console.log(c.body);
|
|
237
|
+
console.log('');
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
engine.dispose();
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
export function prResolveCommand(opts) {
|
|
247
|
+
run(() => {
|
|
248
|
+
const engine = engineOf(opts);
|
|
249
|
+
try {
|
|
250
|
+
const pr = engine.resolve(opts.id, opts.commentId, actorOf(opts));
|
|
251
|
+
emit(pr, opts.json, () => console.log(`코멘트 ${opts.commentId} 스레드를 닫았어요`));
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
engine.dispose();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const VERDICTS = {
|
|
259
|
+
approve: 'approve',
|
|
260
|
+
'request-changes': 'request_changes',
|
|
261
|
+
comment: 'comment',
|
|
262
|
+
};
|
|
263
|
+
export function prReviewCommand(opts) {
|
|
264
|
+
run(() => {
|
|
265
|
+
const verdict = VERDICTS[opts.verdict];
|
|
266
|
+
if (!verdict) {
|
|
267
|
+
throw new PrError('판정은 approve, request-changes, comment 중 하나예요', 1);
|
|
268
|
+
}
|
|
269
|
+
const engine = engineOf(opts);
|
|
270
|
+
try {
|
|
271
|
+
const pr = engine.review(opts.id, {
|
|
272
|
+
reviewer: actorOf(opts),
|
|
273
|
+
verdict,
|
|
274
|
+
summary: readBody(opts.bodyFile).trim(),
|
|
275
|
+
});
|
|
276
|
+
emit(pr, opts.json, () => {
|
|
277
|
+
console.log(`판정을 남겼어요: ${opts.verdict} — 상태 ${pr.status}`);
|
|
278
|
+
console.log(` 라운드 ${pr.rounds[pr.rounds.length - 1].number}`);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
finally {
|
|
282
|
+
engine.dispose();
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
export function prUpdateCommand(opts) {
|
|
287
|
+
run(() => {
|
|
288
|
+
const engine = engineOf(opts);
|
|
289
|
+
try {
|
|
290
|
+
const pr = engine.update(opts.id, opts.head);
|
|
291
|
+
emit(pr, opts.json, () => {
|
|
292
|
+
console.log(`head를 ${pr.headSha.slice(0, 8)}로 옮겼어요 — 상태 ${pr.status}`);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
finally {
|
|
296
|
+
engine.dispose();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* `gestalt pr edit <id>` — 제목과 본문을 고친다.
|
|
302
|
+
*
|
|
303
|
+
* 본문은 `--body-file`로만 받는다. `pr create`와 `pr comment`가 같은 이유로 그렇게
|
|
304
|
+
* 받는다 — 인자로 넘기면 셸이 한글과 백틱과 줄바꿈을 건드린다. 제목은 원래 인자로
|
|
305
|
+
* 받던 값이라 `--title` 그대로다.
|
|
306
|
+
*
|
|
307
|
+
* `--body-file`을 준 순간 본문은 그 파일 내용이다. 빈 파일이면 본문을 비운다 —
|
|
308
|
+
* 코멘트와 달리 여기서 빈 본문을 막지 않는 건 "잘못 쓴 본문을 지운다"가 실제로
|
|
309
|
+
* 있는 쓰임이어서다.
|
|
310
|
+
*/
|
|
311
|
+
export function prEditCommand(opts) {
|
|
312
|
+
run(() => {
|
|
313
|
+
if (opts.title === undefined && opts.bodyFile === undefined) {
|
|
314
|
+
throw new PrError('고칠 것을 주세요 — --title이나 --body-file 중 하나는 있어야 해요', 1);
|
|
315
|
+
}
|
|
316
|
+
const engine = engineOf(opts);
|
|
317
|
+
try {
|
|
318
|
+
const pr = engine.edit(opts.id, {
|
|
319
|
+
...(opts.title !== undefined ? { title: opts.title } : {}),
|
|
320
|
+
...(opts.bodyFile !== undefined ? { body: readBody(opts.bodyFile) } : {}),
|
|
321
|
+
}, actorOf(opts));
|
|
322
|
+
emit(pr, opts.json, () => {
|
|
323
|
+
console.log(`PR ${pr.id}을 고쳤어요 — 상태 ${pr.status}`);
|
|
324
|
+
console.log(` ${pr.title}`);
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
finally {
|
|
328
|
+
engine.dispose();
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
export function prMergeCommand(opts) {
|
|
333
|
+
run(() => {
|
|
334
|
+
const engine = engineOf(opts);
|
|
335
|
+
try {
|
|
336
|
+
const before = engine.get(opts.id);
|
|
337
|
+
const unresolved = before ? unresolvedCount(before) : 0;
|
|
338
|
+
const pr = engine.merge(opts.id, actorOf(opts), { deleteBranch: opts.deleteBranch });
|
|
339
|
+
emit(pr, opts.json, () => {
|
|
340
|
+
console.log(`PR을 머지했어요: ${pr.id}`);
|
|
341
|
+
if (unresolved > 0)
|
|
342
|
+
console.log(` 미해결 스레드 ${unresolved}개가 남은 채로 머지했어요`);
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
finally {
|
|
346
|
+
engine.dispose();
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
export function prCloseCommand(opts) {
|
|
351
|
+
run(() => {
|
|
352
|
+
const engine = engineOf(opts);
|
|
353
|
+
try {
|
|
354
|
+
const pr = engine.closePr(opts.id, actorOf(opts), opts.reason ?? '');
|
|
355
|
+
emit(pr, opts.json, () => console.log(`PR을 닫았어요: ${opts.id}`));
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
engine.dispose();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* `gestalt pr prune` — 붙잡아 둘 이유가 끝난 ref를 놓는다.
|
|
364
|
+
*
|
|
365
|
+
* `refs/gestalt/` 아래는 지금까지 늘기만 했다. 무엇을 언제 놓는지는 엔진의 `prune`
|
|
366
|
+
* 주석에 있다. 되돌릴 수 없는 갈래(체크아웃 자국)는 `--checkouts`로 뜻을 밝혀야 놓는다.
|
|
367
|
+
*/
|
|
368
|
+
export function prPruneCommand(opts) {
|
|
369
|
+
run(() => {
|
|
370
|
+
const engine = engineOf(opts);
|
|
371
|
+
try {
|
|
372
|
+
const result = engine.prune({ checkouts: opts.checkouts, dryRun: opts.dryRun });
|
|
373
|
+
emit(result, opts.json, () => {
|
|
374
|
+
const verb = result.dryRun ? '놓을 참이에요' : '놓았어요';
|
|
375
|
+
console.log(`ref ${result.released.length}개를 ${verb}`);
|
|
376
|
+
for (const ref of result.released)
|
|
377
|
+
console.log(` ${ref}`);
|
|
378
|
+
for (const k of result.kept)
|
|
379
|
+
console.log(` 남김 ${k.prId} — ${k.reason}`);
|
|
380
|
+
if (!opts.checkouts) {
|
|
381
|
+
console.log(' 체크아웃 자국은 그대로예요. 놓으려면 --checkouts를 붙여주세요');
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
finally {
|
|
386
|
+
engine.dispose();
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* `--repo-root`가 지금 자리와 다른 레포를 가리키면 막는다.
|
|
392
|
+
*
|
|
393
|
+
* `pr serve`는 뜨면서 그 경로를 뷰어 목록에 영구히 넣는다. 목록에 넣는 문을 좁게
|
|
394
|
+
* 둔 근거가 "사람이 그 레포에서 웹 UI를 직접 띄운 순간"인데, `--repo-root`를 그대로
|
|
395
|
+
* 받으면 그 전제가 깨진다 — 에이전트가 셸로 `pr serve --repo-root /남의/레포
|
|
396
|
+
* --no-browser`를 한 번 돌리면 그 레포가 인증 없는 뷰어 목록에 들어간다. 이후 전혀
|
|
397
|
+
* 다른 레포에서 serve를 띄워도 그 레포의 diff와 코멘트가 계속 나간다.
|
|
398
|
+
*
|
|
399
|
+
* 그래서 `--repo-root`는 지금 자리와 같은 레포를 가리킬 때만 받는다. 워크트리나
|
|
400
|
+
* 하위 디렉토리를 가리키는 쓰임은 그대로 살고(키가 같다), 남의 레포를 넣는 쓰임만
|
|
401
|
+
* 닫힌다. 다른 레포를 보려면 거기서 한 번 띄우면 된다.
|
|
402
|
+
*
|
|
403
|
+
* 목록에 넣는 호출 자체는 `local-pr-web/engine.ts`에 있다. 거기서 "cwd만 등록하고
|
|
404
|
+
* 나머지는 조회만"으로 가르는 게 더 좁은 문이지만 그건 이 파일 밖이다.
|
|
405
|
+
*
|
|
406
|
+
* 서버를 안 띄우고 이 판단만 볼 수 있게 내보낸다. 통과 갈래를 `prServeCommand`로
|
|
407
|
+
* 확인하려면 진짜 서버가 떠 버린다.
|
|
408
|
+
*/
|
|
409
|
+
export function assertServeRoot(repoRoot) {
|
|
410
|
+
const cwd = process.cwd();
|
|
411
|
+
if (resolve(repoRoot) === resolve(cwd))
|
|
412
|
+
return;
|
|
413
|
+
let same;
|
|
414
|
+
try {
|
|
415
|
+
same = repoKey(repoRoot) === repoKey(cwd);
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
same = false;
|
|
419
|
+
}
|
|
420
|
+
if (same)
|
|
421
|
+
return;
|
|
422
|
+
throw new PrError(`--repo-root가 지금 자리와 다른 레포를 가리켜요: ${repoRoot}\n` +
|
|
423
|
+
'웹 UI는 띄우는 순간 그 레포를 인증 없는 뷰어 목록에 넣어요. 그 레포로 옮겨가서 띄워주세요', 4);
|
|
424
|
+
}
|
|
425
|
+
/** `gestalt pr serve` — 브라우저에서 PR을 읽는 읽기 전용 웹 UI. 코멘트 작성은 CLI 몫으로 남긴다 */
|
|
426
|
+
export async function prServeCommand(opts) {
|
|
427
|
+
const repoRoot = resolve(opts.repoRoot ?? process.cwd());
|
|
428
|
+
if (opts.repoRoot !== undefined) {
|
|
429
|
+
try {
|
|
430
|
+
assertServeRoot(repoRoot);
|
|
431
|
+
}
|
|
432
|
+
catch (e) {
|
|
433
|
+
console.error(e instanceof Error ? e.message : String(e));
|
|
434
|
+
process.exit(e instanceof PrError ? e.exitCode : 1);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const engine = new PrWebEngine();
|
|
439
|
+
try {
|
|
440
|
+
const result = await engine.start({
|
|
441
|
+
repoRoot,
|
|
442
|
+
port: opts.port,
|
|
443
|
+
openBrowser: !opts.noBrowser,
|
|
444
|
+
});
|
|
445
|
+
console.log(`\n로컬 PR 웹 UI: ${result.url}`);
|
|
446
|
+
console.log(result.message);
|
|
447
|
+
console.log('\nCtrl+C로 멈춥니다.\n');
|
|
448
|
+
// 서버의 SIGINT 핸들러가 프로세스를 끝낼 때까지 살려둔다
|
|
449
|
+
await new Promise(() => {
|
|
450
|
+
/* Ctrl+C까지 대기 */
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
455
|
+
console.error(`웹 UI를 못 띄웠어요: ${msg}`);
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* `gestalt pr repos` — 웹 UI가 열어 주는 레포 목록.
|
|
461
|
+
*
|
|
462
|
+
* `unregister`가 키를 받으므로 그 키를 어디선가 볼 수 있어야 한다. 무엇이 인증 없는
|
|
463
|
+
* 뷰어에 실려 있는지 확인하는 자리이기도 하다.
|
|
464
|
+
*/
|
|
465
|
+
export function prReposCommand(opts) {
|
|
466
|
+
run(() => {
|
|
467
|
+
const repos = listRepos();
|
|
468
|
+
emit(repos, opts.json, () => {
|
|
469
|
+
if (repos.length === 0) {
|
|
470
|
+
console.log('등록된 레포가 없어요');
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
for (const r of repos)
|
|
474
|
+
console.log(`${r.key} ${r.name} ${r.path}`);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
/** `gestalt pr unregister <key>` — 그 레포를 웹 UI 목록에서 뺀다. 레포 자체는 안 건드린다 */
|
|
479
|
+
export function prUnregisterCommand(opts) {
|
|
480
|
+
run(() => {
|
|
481
|
+
const gone = unregisterRepo(opts.key);
|
|
482
|
+
if (!gone)
|
|
483
|
+
throw new PrError(`목록에 없는 키예요: ${opts.key}`, 3);
|
|
484
|
+
emit({ key: opts.key, removed: true }, opts.json, () => {
|
|
485
|
+
console.log(`목록에서 뺐어요: ${opts.key}`);
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../../../src/cli/commands/pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from '../../core/config.js';
|
|
2
2
|
import { EventStore } from '../../events/store.js';
|
|
3
|
-
import { createAdapter } from '../../llm/factory.js';
|
|
3
|
+
import { createAdapter, createTierAdapter } from '../../llm/factory.js';
|
|
4
4
|
import { InterviewEngine } from '../../interview/engine.js';
|
|
5
5
|
import { SpecGenerator } from '../../spec/generator.js';
|
|
6
6
|
import { logger } from '../../core/logger.js';
|
|
@@ -13,7 +13,7 @@ export async function specCommand(sessionId, options) {
|
|
|
13
13
|
}
|
|
14
14
|
const eventStore = new EventStore(config.dbPath);
|
|
15
15
|
const llm = createAdapter(config.llm);
|
|
16
|
-
const engine = new InterviewEngine(llm, eventStore);
|
|
16
|
+
const engine = new InterviewEngine(llm, eventStore, createTierAdapter(config.llm, 'frugal'));
|
|
17
17
|
const generator = new SpecGenerator(llm, eventStore);
|
|
18
18
|
try {
|
|
19
19
|
const session = engine.getSession(sessionId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../src/cli/commands/spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../src/cli/commands/spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,OAA4B;IAC/E,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;IAE1F,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CACX,+FAA+F,CAChG,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7F,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,qCAAqC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,wBAAgB,SAAS,IAAI,OAAO,CAiNnC"}
|
package/dist/src/cli/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { updateCommand } from './commands/update.js';
|
|
|
10
10
|
import { usageReportCommand } from './commands/usage-report.js';
|
|
11
11
|
import { humanizeCheckCommand } from './commands/humanize-check.js';
|
|
12
12
|
import { getVersion } from '../core/version.js';
|
|
13
|
+
import { prCheckoutCommand, prCloseCommand, prCommentCommand, prCommentsCommand, prCreateCommand, prDiffCommand, prEditCommand, prListCommand, prMergeCommand, prReposCommand, prResolveCommand, prReviewCommand, prPruneCommand, prServeCommand, prShowCommand, prUnregisterCommand, prUpdateCommand, } from './commands/pr.js';
|
|
13
14
|
export function createCli() {
|
|
14
15
|
const program = new Command();
|
|
15
16
|
program
|
|
@@ -74,6 +75,90 @@ export function createCli() {
|
|
|
74
75
|
noBrowser: options.browser === false,
|
|
75
76
|
});
|
|
76
77
|
});
|
|
78
|
+
const pr = program
|
|
79
|
+
.command('pr')
|
|
80
|
+
.description('로컬 PR 리뷰 — 에이전트끼리 주고받는 자리')
|
|
81
|
+
.option('--repo-root <path>', 'Repository root (defaults to cwd)')
|
|
82
|
+
.option('--author <actor>', '누가 하는지 (예: codex:worker-2). 없으면 GESTALT_ACTOR')
|
|
83
|
+
.option('--json', '에이전트가 파싱할 JSON으로');
|
|
84
|
+
const inherited = (cmd) => (cmd.parent?.opts() ?? {});
|
|
85
|
+
pr.command('create')
|
|
86
|
+
.description('현재 HEAD로 PR을 만든다')
|
|
87
|
+
.requiredOption('--title <title>', 'PR 제목')
|
|
88
|
+
.option('--base <ref>', '갈라져 나온 기준 (기본 main)')
|
|
89
|
+
.option('--head <ref>', '리뷰 대상 (기본 HEAD)')
|
|
90
|
+
.option('--body-file <path>', '본문 파일. -면 stdin')
|
|
91
|
+
.action((o, cmd) => prCreateCommand({ ...inherited(cmd), ...o }));
|
|
92
|
+
pr.command('list')
|
|
93
|
+
.description('PR 목록')
|
|
94
|
+
.option('--status <status>', 'open | changes_requested | merged | closed')
|
|
95
|
+
.action((o, cmd) => prListCommand({ ...inherited(cmd), ...o }));
|
|
96
|
+
pr.command('show <id>')
|
|
97
|
+
.description('PR 상세 — 라운드와 미해결 스레드')
|
|
98
|
+
.action((id, o, cmd) => prShowCommand({ ...inherited(cmd), ...o, id }));
|
|
99
|
+
pr.command('diff <id>')
|
|
100
|
+
.description('PR의 diff')
|
|
101
|
+
.action((id, o, cmd) => prDiffCommand({ ...inherited(cmd), ...o, id }));
|
|
102
|
+
pr.command('checkout <id>')
|
|
103
|
+
.description('PR head를 임시 워크트리로 떼어낸다 — 코드를 일부러 깨고 돌려볼 자리')
|
|
104
|
+
.option('--remove', '떼어둔 워크트리를 지운다')
|
|
105
|
+
.option('--force', '--remove와 함께: 커밋 안 된 변경이 있어도 지운다')
|
|
106
|
+
.action((id, o, cmd) => prCheckoutCommand({ ...inherited(cmd), ...o, id }));
|
|
107
|
+
pr.command('comment <id>')
|
|
108
|
+
.description('인라인 코멘트를 단다')
|
|
109
|
+
.requiredOption('--path <path>', '파일 경로')
|
|
110
|
+
.option('--line <number>', '라인 번호. 없으면 파일 전반')
|
|
111
|
+
.requiredOption('--body-file <path>', '본문 파일. -면 stdin')
|
|
112
|
+
.option('--reply-to <commentId>', '스레드에 답글')
|
|
113
|
+
.action((id, o, cmd) => prCommentCommand({ ...inherited(cmd), ...o, id }));
|
|
114
|
+
pr.command('comments <id>')
|
|
115
|
+
.description('코멘트 목록')
|
|
116
|
+
.option('--unresolved', '안 닫힌 것만')
|
|
117
|
+
.action((id, o, cmd) => prCommentsCommand({ ...inherited(cmd), ...o, id }));
|
|
118
|
+
pr.command('resolve <id> <commentId>')
|
|
119
|
+
.description('코멘트 스레드를 닫는다')
|
|
120
|
+
.action((id, commentId, o, cmd) => prResolveCommand({ ...inherited(cmd), ...o, id, commentId }));
|
|
121
|
+
pr.command('review <id>')
|
|
122
|
+
.description('판정을 남긴다')
|
|
123
|
+
.requiredOption('--verdict <verdict>', 'approve | request-changes | comment')
|
|
124
|
+
.option('--body-file <path>', '요약 파일. -면 stdin')
|
|
125
|
+
.action((id, o, cmd) => prReviewCommand({ ...inherited(cmd), ...o, id }));
|
|
126
|
+
pr.command('update <id>')
|
|
127
|
+
.description('head를 지금 커밋으로 옮긴다')
|
|
128
|
+
.option('--head <ref>', '옮길 대상')
|
|
129
|
+
.action((id, o, cmd) => prUpdateCommand({ ...inherited(cmd), ...o, id }));
|
|
130
|
+
pr.command('edit <id>')
|
|
131
|
+
.description('제목과 본문을 고친다. 리뷰 판정도 라운드도 안 건드린다')
|
|
132
|
+
.option('--title <title>', '새 제목')
|
|
133
|
+
.option('--body-file <path>', '새 본문 파일. -면 stdin')
|
|
134
|
+
.action((id, o, cmd) => prEditCommand({ ...inherited(cmd), ...o, id }));
|
|
135
|
+
pr.command('merge <id>')
|
|
136
|
+
.description('머지한다. 승인이 없어도 막지 않는다')
|
|
137
|
+
.option('--delete-branch', '머지 뒤 브랜치를 지운다')
|
|
138
|
+
.action((id, o, cmd) => prMergeCommand({ ...inherited(cmd), ...o, id }));
|
|
139
|
+
pr.command('close <id>')
|
|
140
|
+
.description('PR을 닫는다')
|
|
141
|
+
.option('--reason <text>', '닫는 이유')
|
|
142
|
+
.action((id, o, cmd) => prCloseCommand({ ...inherited(cmd), ...o, id }));
|
|
143
|
+
pr.command('prune')
|
|
144
|
+
.description('붙잡아 둘 이유가 끝난 ref를 놓는다 — 머지된 PR의 base·head')
|
|
145
|
+
.option('--checkouts', '체크아웃 자국도 놓는다. 되돌릴 수 없어 기본은 남긴다')
|
|
146
|
+
.option('--dry-run', '무엇을 놓을지만 보여준다')
|
|
147
|
+
.action((o, cmd) => prPruneCommand({ ...inherited(cmd), ...o }));
|
|
148
|
+
pr.command('serve')
|
|
149
|
+
.description('브라우저에서 PR을 읽는 웹 UI를 띄운다 (읽기 전용)')
|
|
150
|
+
.option('--port <number>', '서버 포트 (기본 7892)', parseInt)
|
|
151
|
+
.option('--no-browser', '브라우저를 자동으로 열지 않는다')
|
|
152
|
+
.action(async (o, cmd) => {
|
|
153
|
+
const opts = { ...inherited(cmd), ...o };
|
|
154
|
+
await prServeCommand({ ...opts, noBrowser: opts.browser === false });
|
|
155
|
+
});
|
|
156
|
+
pr.command('repos')
|
|
157
|
+
.description('웹 UI가 열어 주는 레포 목록')
|
|
158
|
+
.action((o, cmd) => prReposCommand({ ...inherited(cmd), ...o }));
|
|
159
|
+
pr.command('unregister <key>')
|
|
160
|
+
.description('그 레포를 웹 UI 목록에서 뺀다. 레포 자체는 안 건드린다')
|
|
161
|
+
.action((key, o, cmd) => prUnregisterCommand({ ...inherited(cmd), ...o, key }));
|
|
77
162
|
program
|
|
78
163
|
.command('humanize-check')
|
|
79
164
|
.description('Judge a humanized draft against the rulebook (exit 0 pass / 1 warn / 2 abort)')
|