@tienne/gestalt 0.122.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/plugin/.codex-plugin/plugin.json +1 -1
- package/dist/plugin/skills/_shared/pr-base.md +169 -0
- package/dist/plugin/skills/_shared/proactive-routing.md +1 -1
- package/dist/plugin/skills/jira-create/SKILL.md +39 -4
- package/dist/plugin/skills/pr/SKILL.md +32 -12
- package/dist/plugin/skills/review/SKILL.md +94 -29
- package/dist/plugin/skills/review/references/approve-when-no-blocking.md +7 -0
- package/dist/plugin/skills/review/references/post-confirm.md +30 -0
- package/dist/plugin/skills/review/references/result-lines.md +32 -0
- package/dist/plugin/skills/review/references/user-profile.md +19 -0
- package/dist/plugin/skills/review-loop/SKILL.md +83 -20
- package/dist/plugin/skills/review-reply/SKILL.md +4 -0
- package/dist/plugin/skills/ship/SKILL.md +276 -29
- package/dist/src/architecture/ir-schema.d.ts +26 -26
- package/dist/src/cli/commands/profile.d.ts +13 -0
- package/dist/src/cli/commands/profile.d.ts.map +1 -0
- package/dist/src/cli/commands/profile.js +26 -0
- package/dist/src/cli/commands/profile.js.map +1 -0
- package/dist/src/cli/commands/ship.d.ts +35 -0
- package/dist/src/cli/commands/ship.d.ts.map +1 -0
- package/dist/src/cli/commands/ship.js +146 -0
- package/dist/src/cli/commands/ship.js.map +1 -0
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +52 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/config.d.ts +12 -12
- package/dist/src/core/types.d.ts +64 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/user-profile.d.ts +29 -0
- package/dist/src/core/user-profile.d.ts.map +1 -0
- package/dist/src/core/user-profile.js +97 -0
- package/dist/src/core/user-profile.js.map +1 -0
- package/dist/src/digest/blocks.d.ts +34 -34
- package/dist/src/digest/comments.d.ts +6 -6
- package/dist/src/digest/lens-schema.d.ts +2 -2
- package/dist/src/digest/lint-lens-context.d.ts +4 -4
- package/dist/src/digest/schema.d.ts +55 -55
- package/dist/src/lens/attach.d.ts +10 -10
- package/dist/src/mcp/schemas.d.ts +238 -225
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +86 -16
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +61 -2
- package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/status.d.ts +1 -1
- package/dist/src/research/schema.d.ts +66 -66
- package/dist/src/research/target.d.ts +6 -6
- package/dist/src/review/consensus-input.d.ts +11 -0
- package/dist/src/review/consensus-input.d.ts.map +1 -0
- package/dist/src/review/consensus-input.js +102 -0
- package/dist/src/review/consensus-input.js.map +1 -0
- package/dist/src/review/passthrough-engine.d.ts +9 -2
- package/dist/src/review/passthrough-engine.d.ts.map +1 -1
- package/dist/src/review/passthrough-engine.js +58 -10
- package/dist/src/review/passthrough-engine.js.map +1 -1
- package/dist/src/review/verification.d.ts +48 -7
- package/dist/src/review/verification.d.ts.map +1 -1
- package/dist/src/review/verification.js +109 -23
- package/dist/src/review/verification.js.map +1 -1
- package/dist/src/review/verifier-record.d.ts +55 -0
- package/dist/src/review/verifier-record.d.ts.map +1 -0
- package/dist/src/review/verifier-record.js +228 -0
- package/dist/src/review/verifier-record.js.map +1 -0
- package/dist/src/ship/checkpoint.d.ts +145 -0
- package/dist/src/ship/checkpoint.d.ts.map +1 -0
- package/dist/src/ship/checkpoint.js +282 -0
- package/dist/src/ship/checkpoint.js.map +1 -0
- package/dist/src/ship/ci.d.ts +110 -0
- package/dist/src/ship/ci.d.ts.map +1 -0
- package/dist/src/ship/ci.js +270 -0
- package/dist/src/ship/ci.js.map +1 -0
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/mcp.json +1 -1
- package/plugin/skills/_shared/pr-base.md +169 -0
- package/plugin/skills/_shared/proactive-routing.md +1 -1
- package/plugin/skills/jira-create/SKILL.md +39 -4
- package/plugin/skills/pr/SKILL.md +32 -12
- package/plugin/skills/review/SKILL.md +94 -29
- package/plugin/skills/review/references/approve-when-no-blocking.md +7 -0
- package/plugin/skills/review/references/post-confirm.md +30 -0
- package/plugin/skills/review/references/result-lines.md +32 -0
- package/plugin/skills/review/references/user-profile.md +19 -0
- package/plugin/skills/review-loop/SKILL.md +83 -20
- package/plugin/skills/review-reply/SKILL.md +4 -0
- package/plugin/skills/ship/SKILL.md +276 -29
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { type CmdRunner } from './ci.js';
|
|
2
|
+
/**
|
|
3
|
+
* ship 이 단계와 라운드가 끝날 때마다 남기는 체크포인트.
|
|
4
|
+
*
|
|
5
|
+
* 라운드가 길면 대화가 압축되거나 세션이 끊기고 다시 부르면 처음부터 돌았다. 어디까지
|
|
6
|
+
* 갔는지는 로컬 PR 과 GitHub PR 에 흩어져 있어 사람이 맞춰야 했다. 다시 부르면 이 파일을
|
|
7
|
+
* 읽고 git 과 PR 상태가 그대로인지 확인한 뒤 이어서 돈다.
|
|
8
|
+
*
|
|
9
|
+
* 자리는 ship 이 이미 쓰는 git 디렉토리 아래 상태 자리다. 워크트리 안(`.gestalt/`)에 두면
|
|
10
|
+
* 그걸 무시 목록에 안 넣은 남의 레포에서 커밋에 딸려 들어간다.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SHIP_PHASES: readonly ["0", "1", "2", "a", "3", "4", "ci"];
|
|
13
|
+
export type ShipPhase = (typeof SHIP_PHASES)[number];
|
|
14
|
+
export type StopKind = 'blocked' | 'escalated';
|
|
15
|
+
export interface RoundRecord {
|
|
16
|
+
phase: ShipPhase;
|
|
17
|
+
round: number;
|
|
18
|
+
issues: number;
|
|
19
|
+
head: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ShipCheckpoint {
|
|
22
|
+
version: 1;
|
|
23
|
+
branch: string;
|
|
24
|
+
phase: ShipPhase;
|
|
25
|
+
round: number | null;
|
|
26
|
+
localPrId: string | null;
|
|
27
|
+
prNumber: number | null;
|
|
28
|
+
prUrl: string | null;
|
|
29
|
+
base: string | null;
|
|
30
|
+
verifyCmd: string | null;
|
|
31
|
+
/** 저장할 때의 HEAD. 다시 부를 때 이 커밋에서 이어지는지 본다 */
|
|
32
|
+
head: string;
|
|
33
|
+
/** 다음에 할 일 한 줄. 이어서 돌 자리를 사람과 에이전트가 같이 읽는다 */
|
|
34
|
+
next: string;
|
|
35
|
+
stopped: StopKind | null;
|
|
36
|
+
/** 라운드별 이슈 수. 완료 보고의 "7 → 2 → 0" 이 여기서 나온다 */
|
|
37
|
+
history: RoundRecord[];
|
|
38
|
+
savedAt: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CheckpointPatch {
|
|
41
|
+
phase: ShipPhase;
|
|
42
|
+
next: string;
|
|
43
|
+
round?: number;
|
|
44
|
+
localPrId?: string;
|
|
45
|
+
prNumber?: number;
|
|
46
|
+
prUrl?: string;
|
|
47
|
+
base?: string;
|
|
48
|
+
verifyCmd?: string;
|
|
49
|
+
stopped?: StopKind;
|
|
50
|
+
issues?: number;
|
|
51
|
+
}
|
|
52
|
+
export declare const CHECKPOINT_FILE = "checkpoint.json";
|
|
53
|
+
export declare function checkpointPath(dir: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* 상대 경로를 막는다. 스킬 문서의 Bash 블록은 서로 변수를 안 나눠서 `$shipTmp` 가 빈
|
|
56
|
+
* 문자열로 풀릴 수 있는데, 그러면 작업 디렉토리에 파일이 생겨 커밋에 섞인다.
|
|
57
|
+
*/
|
|
58
|
+
export declare function assertDir(dir: string | undefined): string;
|
|
59
|
+
export declare function isShipPhase(v: string): v is ShipPhase;
|
|
60
|
+
export type CheckpointRead = {
|
|
61
|
+
kind: 'none';
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'ok';
|
|
64
|
+
checkpoint: ShipCheckpoint;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'unreadable';
|
|
67
|
+
error: string;
|
|
68
|
+
};
|
|
69
|
+
/** pr-base 0절의 이름 검사와 같은 규칙. base 는 셸 명령의 큰따옴표 안에 들어간다 */
|
|
70
|
+
export declare const BRANCH_NAME_RE: RegExp;
|
|
71
|
+
/** 로컬 PR id 는 randomUUID().slice(0, 8) 로 만든다. `gestalt pr close <id>` 처럼 셸 명령에 들어간다 */
|
|
72
|
+
export declare const LOCAL_PR_ID_RE: RegExp;
|
|
73
|
+
/** 완료 보고에 그대로 옮겨 사용자에게 보이는 값이라 링크로 열리는 꼴만 받는다 */
|
|
74
|
+
export declare const PR_URL_RE: RegExp;
|
|
75
|
+
export declare function readCheckpoint(dir: string): CheckpointRead;
|
|
76
|
+
/**
|
|
77
|
+
* 앞 체크포인트에 이번 값을 덧씌운다. 단계마다 아는 값이 달라서(로컬 PR id 는 1단계,
|
|
78
|
+
* GitHub PR 번호는 3단계) 매번 전부 넘기게 하면 뒤 단계에서 앞 값을 잃는다.
|
|
79
|
+
*
|
|
80
|
+
* 라운드는 같은 단계에서만 이어받는다. 단계가 바뀌면 앞 단계의 라운드 번호는 뜻이 없다.
|
|
81
|
+
* 멈춤 표시는 이어받지 않는다. 다시 저장했다면 멈췄던 자리를 이미 넘어선 것이다.
|
|
82
|
+
*/
|
|
83
|
+
export declare function mergeCheckpoint(prev: ShipCheckpoint | null, patch: CheckpointPatch, observed: {
|
|
84
|
+
branch: string;
|
|
85
|
+
head: string;
|
|
86
|
+
}, savedAt: string): ShipCheckpoint;
|
|
87
|
+
export declare function writeCheckpoint(dir: string, cp: ShipCheckpoint): string;
|
|
88
|
+
export interface ObservedState {
|
|
89
|
+
branch: string;
|
|
90
|
+
head: string;
|
|
91
|
+
/** 추적 중인 파일에 커밋 안 한 변경이 있는지. 새 파일은 안 본다 */
|
|
92
|
+
dirty: boolean;
|
|
93
|
+
/** 체크포인트의 head 가 지금 HEAD 의 조상인지(같으면 true) */
|
|
94
|
+
cpHeadIsAncestor: boolean;
|
|
95
|
+
/** 체크포인트 뒤에 쌓인 커밋 수 */
|
|
96
|
+
aheadBy: number;
|
|
97
|
+
localPr?: {
|
|
98
|
+
found: false;
|
|
99
|
+
} | {
|
|
100
|
+
found: true;
|
|
101
|
+
status: string;
|
|
102
|
+
headSha: string;
|
|
103
|
+
};
|
|
104
|
+
pr?: {
|
|
105
|
+
ok: false;
|
|
106
|
+
error: string;
|
|
107
|
+
} | {
|
|
108
|
+
ok: true;
|
|
109
|
+
state: string;
|
|
110
|
+
isDraft: boolean;
|
|
111
|
+
headRefOid: string;
|
|
112
|
+
url: string;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export type MismatchKind = 'branch' | 'head-ahead' | 'head-diverged' | 'dirty' | 'local-pr-missing' | 'local-pr-closed' | 'local-pr-head' | 'pr-closed' | 'pr-head' | 'pr-lookup-failed' | 'unreadable';
|
|
116
|
+
export interface Mismatch {
|
|
117
|
+
kind: MismatchKind;
|
|
118
|
+
detail: string;
|
|
119
|
+
}
|
|
120
|
+
export declare function compareCheckpoint(cp: ShipCheckpoint, obs: ObservedState): Mismatch[];
|
|
121
|
+
export interface ObserveDeps {
|
|
122
|
+
run: CmdRunner;
|
|
123
|
+
localPr: (id: string) => {
|
|
124
|
+
status: string;
|
|
125
|
+
headSha: string;
|
|
126
|
+
} | null;
|
|
127
|
+
}
|
|
128
|
+
export declare function observeState(cp: ShipCheckpoint, deps: ObserveDeps): ObservedState;
|
|
129
|
+
export declare function defaultObserveDeps(run?: CmdRunner): ObserveDeps;
|
|
130
|
+
export type CheckReport = {
|
|
131
|
+
status: 'none';
|
|
132
|
+
} | {
|
|
133
|
+
status: 'match';
|
|
134
|
+
checkpoint: ShipCheckpoint;
|
|
135
|
+
observed: ObservedState;
|
|
136
|
+
mismatches: [];
|
|
137
|
+
} | {
|
|
138
|
+
status: 'mismatch';
|
|
139
|
+
checkpoint: ShipCheckpoint | null;
|
|
140
|
+
observed: ObservedState | null;
|
|
141
|
+
mismatches: Mismatch[];
|
|
142
|
+
};
|
|
143
|
+
export declare function checkCheckpoint(dir: string, deps: ObserveDeps): CheckReport;
|
|
144
|
+
export declare function saveCheckpoint(dir: string, patch: CheckpointPatch, run?: CmdRunner, now?: Date): ShipCheckpoint;
|
|
145
|
+
//# sourceMappingURL=checkpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../../src/ship/checkpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { isAbsolute, join } from 'node:path';
|
|
3
|
+
import { LocalPrEngine } from '../local-pr/engine.js';
|
|
4
|
+
import { defaultRunner } from './ci.js';
|
|
5
|
+
/**
|
|
6
|
+
* ship 이 단계와 라운드가 끝날 때마다 남기는 체크포인트.
|
|
7
|
+
*
|
|
8
|
+
* 라운드가 길면 대화가 압축되거나 세션이 끊기고 다시 부르면 처음부터 돌았다. 어디까지
|
|
9
|
+
* 갔는지는 로컬 PR 과 GitHub PR 에 흩어져 있어 사람이 맞춰야 했다. 다시 부르면 이 파일을
|
|
10
|
+
* 읽고 git 과 PR 상태가 그대로인지 확인한 뒤 이어서 돈다.
|
|
11
|
+
*
|
|
12
|
+
* 자리는 ship 이 이미 쓰는 git 디렉토리 아래 상태 자리다. 워크트리 안(`.gestalt/`)에 두면
|
|
13
|
+
* 그걸 무시 목록에 안 넣은 남의 레포에서 커밋에 딸려 들어간다.
|
|
14
|
+
*/
|
|
15
|
+
export const SHIP_PHASES = ['0', '1', '2', 'a', '3', '4', 'ci'];
|
|
16
|
+
export const CHECKPOINT_FILE = 'checkpoint.json';
|
|
17
|
+
export function checkpointPath(dir) {
|
|
18
|
+
return join(dir, CHECKPOINT_FILE);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 상대 경로를 막는다. 스킬 문서의 Bash 블록은 서로 변수를 안 나눠서 `$shipTmp` 가 빈
|
|
22
|
+
* 문자열로 풀릴 수 있는데, 그러면 작업 디렉토리에 파일이 생겨 커밋에 섞인다.
|
|
23
|
+
*/
|
|
24
|
+
export function assertDir(dir) {
|
|
25
|
+
if (!dir || !isAbsolute(dir)) {
|
|
26
|
+
throw new Error(`--dir 는 절대 경로여야 해요 (받은 값: ${JSON.stringify(dir ?? '')})`);
|
|
27
|
+
}
|
|
28
|
+
return dir;
|
|
29
|
+
}
|
|
30
|
+
export function isShipPhase(v) {
|
|
31
|
+
return SHIP_PHASES.includes(v);
|
|
32
|
+
}
|
|
33
|
+
/** pr-base 0절의 이름 검사와 같은 규칙. base 는 셸 명령의 큰따옴표 안에 들어간다 */
|
|
34
|
+
export const BRANCH_NAME_RE = /^[A-Za-z0-9._][A-Za-z0-9._/-]*$/;
|
|
35
|
+
/** 로컬 PR id 는 randomUUID().slice(0, 8) 로 만든다. `gestalt pr close <id>` 처럼 셸 명령에 들어간다 */
|
|
36
|
+
export const LOCAL_PR_ID_RE = /^[0-9a-f]{8}$/i;
|
|
37
|
+
/** 완료 보고에 그대로 옮겨 사용자에게 보이는 값이라 링크로 열리는 꼴만 받는다 */
|
|
38
|
+
export const PR_URL_RE = /^https:\/\/\S+$/;
|
|
39
|
+
export function readCheckpoint(dir) {
|
|
40
|
+
const path = checkpointPath(dir);
|
|
41
|
+
if (!existsSync(path))
|
|
42
|
+
return { kind: 'none' };
|
|
43
|
+
try {
|
|
44
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
45
|
+
if (raw.version !== 1 ||
|
|
46
|
+
typeof raw.phase !== 'string' ||
|
|
47
|
+
!isShipPhase(raw.phase) ||
|
|
48
|
+
typeof raw.head !== 'string' ||
|
|
49
|
+
// git 인자로 넘기는 값이라 `-` 로 시작하면 옵션으로 읽힌다
|
|
50
|
+
!/^[0-9a-f]{7,64}$/i.test(raw.head)) {
|
|
51
|
+
return { kind: 'unreadable', error: '알 수 없는 형식이에요' };
|
|
52
|
+
}
|
|
53
|
+
if (raw.base != null && (typeof raw.base !== 'string' || !BRANCH_NAME_RE.test(raw.base))) {
|
|
54
|
+
return { kind: 'unreadable', error: 'base 이름이 형식에 안 맞아요' };
|
|
55
|
+
}
|
|
56
|
+
if (raw.localPrId != null &&
|
|
57
|
+
(typeof raw.localPrId !== 'string' || !LOCAL_PR_ID_RE.test(raw.localPrId))) {
|
|
58
|
+
return { kind: 'unreadable', error: 'localPrId 형식에 안 맞아요' };
|
|
59
|
+
}
|
|
60
|
+
if (raw.prNumber != null &&
|
|
61
|
+
(typeof raw.prNumber !== 'number' || !Number.isInteger(raw.prNumber) || raw.prNumber <= 0)) {
|
|
62
|
+
return { kind: 'unreadable', error: 'prNumber 형식에 안 맞아요' };
|
|
63
|
+
}
|
|
64
|
+
if (raw.prUrl != null && (typeof raw.prUrl !== 'string' || !PR_URL_RE.test(raw.prUrl))) {
|
|
65
|
+
return { kind: 'unreadable', error: 'prUrl 형식에 안 맞아요' };
|
|
66
|
+
}
|
|
67
|
+
return { kind: 'ok', checkpoint: raw };
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
return { kind: 'unreadable', error: e instanceof Error ? e.message : String(e) };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 앞 체크포인트에 이번 값을 덧씌운다. 단계마다 아는 값이 달라서(로컬 PR id 는 1단계,
|
|
75
|
+
* GitHub PR 번호는 3단계) 매번 전부 넘기게 하면 뒤 단계에서 앞 값을 잃는다.
|
|
76
|
+
*
|
|
77
|
+
* 라운드는 같은 단계에서만 이어받는다. 단계가 바뀌면 앞 단계의 라운드 번호는 뜻이 없다.
|
|
78
|
+
* 멈춤 표시는 이어받지 않는다. 다시 저장했다면 멈췄던 자리를 이미 넘어선 것이다.
|
|
79
|
+
*/
|
|
80
|
+
export function mergeCheckpoint(prev, patch, observed, savedAt) {
|
|
81
|
+
const round = patch.round ?? (prev?.phase === patch.phase ? prev.round : null);
|
|
82
|
+
const history = [...(prev?.history ?? [])];
|
|
83
|
+
if (patch.issues !== undefined) {
|
|
84
|
+
if (round === null)
|
|
85
|
+
throw new Error('--issues 는 --round 와 함께 줘야 해요');
|
|
86
|
+
const entry = {
|
|
87
|
+
phase: patch.phase,
|
|
88
|
+
round,
|
|
89
|
+
issues: patch.issues,
|
|
90
|
+
head: observed.head,
|
|
91
|
+
};
|
|
92
|
+
const at = history.findIndex((h) => h.phase === entry.phase && h.round === entry.round);
|
|
93
|
+
if (at >= 0)
|
|
94
|
+
history[at] = entry;
|
|
95
|
+
else
|
|
96
|
+
history.push(entry);
|
|
97
|
+
}
|
|
98
|
+
const stopped = patch.stopped ?? null;
|
|
99
|
+
return {
|
|
100
|
+
version: 1,
|
|
101
|
+
branch: observed.branch,
|
|
102
|
+
phase: patch.phase,
|
|
103
|
+
round,
|
|
104
|
+
localPrId: patch.localPrId ?? prev?.localPrId ?? null,
|
|
105
|
+
prNumber: patch.prNumber ?? prev?.prNumber ?? null,
|
|
106
|
+
prUrl: patch.prUrl ?? prev?.prUrl ?? null,
|
|
107
|
+
base: patch.base ?? prev?.base ?? null,
|
|
108
|
+
verifyCmd: patch.verifyCmd ?? prev?.verifyCmd ?? null,
|
|
109
|
+
head: observed.head,
|
|
110
|
+
next: patch.next,
|
|
111
|
+
stopped,
|
|
112
|
+
history,
|
|
113
|
+
savedAt,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function writeCheckpoint(dir, cp) {
|
|
117
|
+
mkdirSync(dir, { recursive: true });
|
|
118
|
+
const path = checkpointPath(dir);
|
|
119
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
120
|
+
writeFileSync(tmp, `${JSON.stringify(cp, null, 2)}\n`);
|
|
121
|
+
renameSync(tmp, path);
|
|
122
|
+
return path;
|
|
123
|
+
}
|
|
124
|
+
/** 로컬 PR head 를 맞춰 보는 단계. 4단계부터는 GitHub 에서 고치므로 로컬 PR head 가 뒤처지는 게 정상이다 */
|
|
125
|
+
const LOCAL_PR_HEAD_PHASES = ['1', '2', 'a'];
|
|
126
|
+
const GITHUB_PHASES = ['3', '4', 'ci'];
|
|
127
|
+
const short = (sha) => sha.slice(0, 7);
|
|
128
|
+
export function compareCheckpoint(cp, obs) {
|
|
129
|
+
const out = [];
|
|
130
|
+
if (cp.branch !== obs.branch) {
|
|
131
|
+
out.push({
|
|
132
|
+
kind: 'branch',
|
|
133
|
+
detail: `체크포인트는 ${cp.branch} 브랜치인데 지금은 ${obs.branch}예요`,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (!obs.cpHeadIsAncestor) {
|
|
137
|
+
out.push({
|
|
138
|
+
kind: 'head-diverged',
|
|
139
|
+
detail: `체크포인트 커밋 ${short(cp.head)}가 지금 HEAD ${short(obs.head)}의 조상이 아니에요 (rebase나 reset)`,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
else if (obs.aheadBy > 0) {
|
|
143
|
+
out.push({
|
|
144
|
+
kind: 'head-ahead',
|
|
145
|
+
detail: `체크포인트 뒤에 커밋이 ${obs.aheadBy}개 더 있어요 (${short(cp.head)} → ${short(obs.head)})`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (obs.dirty)
|
|
149
|
+
out.push({ kind: 'dirty', detail: '커밋 안 한 변경이 있어요' });
|
|
150
|
+
if (cp.localPrId && obs.localPr) {
|
|
151
|
+
if (!obs.localPr.found) {
|
|
152
|
+
out.push({ kind: 'local-pr-missing', detail: `로컬 PR ${cp.localPrId}를 못 찾았어요` });
|
|
153
|
+
}
|
|
154
|
+
else if (obs.localPr.status === 'merged' || obs.localPr.status === 'closed') {
|
|
155
|
+
out.push({
|
|
156
|
+
kind: 'local-pr-closed',
|
|
157
|
+
detail: `로컬 PR ${cp.localPrId}가 ${obs.localPr.status} 상태예요`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else if (LOCAL_PR_HEAD_PHASES.includes(cp.phase) && obs.localPr.headSha !== obs.head) {
|
|
161
|
+
out.push({
|
|
162
|
+
kind: 'local-pr-head',
|
|
163
|
+
detail: `로컬 PR head ${short(obs.localPr.headSha)}가 지금 HEAD ${short(obs.head)}와 달라요`,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (cp.prNumber !== null && GITHUB_PHASES.includes(cp.phase) && obs.pr) {
|
|
168
|
+
if (!obs.pr.ok) {
|
|
169
|
+
out.push({
|
|
170
|
+
kind: 'pr-lookup-failed',
|
|
171
|
+
detail: `GitHub PR #${cp.prNumber}를 못 읽었어요: ${obs.pr.error}`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else if (obs.pr.state !== 'OPEN') {
|
|
175
|
+
out.push({
|
|
176
|
+
kind: 'pr-closed',
|
|
177
|
+
detail: `GitHub PR #${cp.prNumber}가 ${obs.pr.state} 상태예요`,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else if (obs.pr.headRefOid !== obs.head) {
|
|
181
|
+
out.push({
|
|
182
|
+
kind: 'pr-head',
|
|
183
|
+
detail: `GitHub PR head ${short(obs.pr.headRefOid)}가 지금 HEAD ${short(obs.head)}와 달라요 (push 안 했거나 원격이 바뀜)`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
function git(run, args) {
|
|
190
|
+
const r = run('git', args);
|
|
191
|
+
if (r.status !== 0)
|
|
192
|
+
throw new Error(`git ${args.join(' ')} 실패: ${r.stderr.trim()}`);
|
|
193
|
+
return r.stdout.trim();
|
|
194
|
+
}
|
|
195
|
+
export function observeState(cp, deps) {
|
|
196
|
+
const branch = git(deps.run, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
197
|
+
const head = git(deps.run, ['rev-parse', 'HEAD']);
|
|
198
|
+
const dirty = git(deps.run, ['status', '--porcelain', '--untracked-files=no']).length > 0;
|
|
199
|
+
// 128 은 커밋을 못 찾은 경우다(gc 됐거나 다른 클론). 조상이 아닌 것과 똑같이 다룬다
|
|
200
|
+
const anc = deps.run('git', ['merge-base', '--is-ancestor', cp.head, 'HEAD']);
|
|
201
|
+
const cpHeadIsAncestor = anc.status === 0;
|
|
202
|
+
const aheadBy = cpHeadIsAncestor
|
|
203
|
+
? Number(git(deps.run, ['rev-list', '--count', `${cp.head}..HEAD`]))
|
|
204
|
+
: 0;
|
|
205
|
+
const obs = { branch, head, dirty, cpHeadIsAncestor, aheadBy };
|
|
206
|
+
if (cp.localPrId) {
|
|
207
|
+
const pr = deps.localPr(cp.localPrId);
|
|
208
|
+
obs.localPr = pr ? { found: true, ...pr } : { found: false };
|
|
209
|
+
}
|
|
210
|
+
if (cp.prNumber !== null && GITHUB_PHASES.includes(cp.phase)) {
|
|
211
|
+
const r = deps.run('gh', [
|
|
212
|
+
'pr',
|
|
213
|
+
'view',
|
|
214
|
+
String(cp.prNumber),
|
|
215
|
+
'--json',
|
|
216
|
+
'state,isDraft,headRefOid,url',
|
|
217
|
+
]);
|
|
218
|
+
if (r.status !== 0) {
|
|
219
|
+
obs.pr = { ok: false, error: r.stderr.trim().split(/\r?\n/)[0] || `종료 코드 ${r.status}` };
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
try {
|
|
223
|
+
const v = JSON.parse(r.stdout);
|
|
224
|
+
obs.pr = {
|
|
225
|
+
ok: true,
|
|
226
|
+
state: String(v.state ?? ''),
|
|
227
|
+
isDraft: v.isDraft === true,
|
|
228
|
+
headRefOid: String(v.headRefOid ?? ''),
|
|
229
|
+
url: String(v.url ?? ''),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
obs.pr = { ok: false, error: 'gh pr view 출력을 JSON으로 못 읽었어요' };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return obs;
|
|
238
|
+
}
|
|
239
|
+
export function defaultObserveDeps(run = defaultRunner) {
|
|
240
|
+
return {
|
|
241
|
+
run,
|
|
242
|
+
localPr: (id) => {
|
|
243
|
+
const root = git(run, ['rev-parse', '--show-toplevel']);
|
|
244
|
+
const engine = new LocalPrEngine(root);
|
|
245
|
+
try {
|
|
246
|
+
const pr = engine.get(id);
|
|
247
|
+
return pr ? { status: pr.status, headSha: pr.headSha } : null;
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
engine.dispose();
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
export function checkCheckpoint(dir, deps) {
|
|
256
|
+
const read = readCheckpoint(dir);
|
|
257
|
+
if (read.kind === 'none')
|
|
258
|
+
return { status: 'none' };
|
|
259
|
+
if (read.kind === 'unreadable') {
|
|
260
|
+
return {
|
|
261
|
+
status: 'mismatch',
|
|
262
|
+
checkpoint: null,
|
|
263
|
+
observed: null,
|
|
264
|
+
mismatches: [{ kind: 'unreadable', detail: `체크포인트를 못 읽었어요: ${read.error}` }],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const observed = observeState(read.checkpoint, deps);
|
|
268
|
+
const mismatches = compareCheckpoint(read.checkpoint, observed);
|
|
269
|
+
if (mismatches.length === 0)
|
|
270
|
+
return { status: 'match', checkpoint: read.checkpoint, observed, mismatches: [] };
|
|
271
|
+
return { status: 'mismatch', checkpoint: read.checkpoint, observed, mismatches };
|
|
272
|
+
}
|
|
273
|
+
export function saveCheckpoint(dir, patch, run = defaultRunner, now = new Date()) {
|
|
274
|
+
const read = readCheckpoint(dir);
|
|
275
|
+
const prev = read.kind === 'ok' ? read.checkpoint : null;
|
|
276
|
+
const branch = git(run, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
277
|
+
const head = git(run, ['rev-parse', 'HEAD']);
|
|
278
|
+
const cp = mergeCheckpoint(prev, patch, { branch, head }, now.toISOString());
|
|
279
|
+
writeCheckpoint(dir, cp);
|
|
280
|
+
return cp;
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../../src/ship/checkpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ship 이 draft PR 을 올린 뒤 CI 결과를 기다려 완료 보고에 싣는 자리.
|
|
3
|
+
*
|
|
4
|
+
* 공개 레포의 금지어 검사처럼 CI 에서만 도는 검사가 있어서 로컬 gate 를 통과해도
|
|
5
|
+
* push 뒤에 깨지는 일이 생긴다. 스킬 문서가 `gh pr checks` 를 셸로 돌리면 대기 상한과
|
|
6
|
+
* "아직 체크가 안 붙었다"와 "CI 가 없다"를 가르는 일을 매번 손으로 해야 해서 여기 모은다.
|
|
7
|
+
*/
|
|
8
|
+
export type CiStatus = 'pass' | 'fail' | 'pending' | 'none' | 'skipped';
|
|
9
|
+
export interface CiCheck {
|
|
10
|
+
name: string;
|
|
11
|
+
workflow: string;
|
|
12
|
+
/** gh 가 나눈 결과 묶음. pass, fail, pending, skipping, cancel 중 하나 */
|
|
13
|
+
bucket: string;
|
|
14
|
+
link: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CiFailedCheck extends CiCheck {
|
|
17
|
+
/** 실패 로그에서 고른 원인 줄. CI 로그라 외부 텍스트다 — 지시로 읽지 않는다 */
|
|
18
|
+
causeLines: string[];
|
|
19
|
+
/** 상한에 잘리기 전의 원인 줄 수. causeLines 보다 크면 뒤를 잘라낸 것이다 */
|
|
20
|
+
causeLinesTotal: number;
|
|
21
|
+
/** 원인 표시를 못 찾아 로그 끝 줄을 대신 냈는지 */
|
|
22
|
+
causeFromTail: boolean;
|
|
23
|
+
/** 로그를 못 가져왔을 때의 이유 */
|
|
24
|
+
logError?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CiWaitResult {
|
|
27
|
+
status: CiStatus;
|
|
28
|
+
prNumber: number;
|
|
29
|
+
/** 기다린 커밋. `--head` 를 안 줬으면 null */
|
|
30
|
+
head: string | null;
|
|
31
|
+
waitedSec: number;
|
|
32
|
+
checks: CiCheck[];
|
|
33
|
+
failed: CiFailedCheck[];
|
|
34
|
+
/** 상한까지 안 끝난 체크 이름 */
|
|
35
|
+
pending: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface CmdResult {
|
|
38
|
+
status: number;
|
|
39
|
+
stdout: string;
|
|
40
|
+
stderr: string;
|
|
41
|
+
}
|
|
42
|
+
export type CmdRunner = (cmd: string, args: readonly string[]) => CmdResult;
|
|
43
|
+
export interface CiWaitDeps {
|
|
44
|
+
run: CmdRunner;
|
|
45
|
+
now: () => number;
|
|
46
|
+
sleep: (ms: number) => Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export interface CiWaitOptions {
|
|
49
|
+
prNumber: number;
|
|
50
|
+
/** 이 커밋이 PR head 가 될 때까지 먼저 기다린다. push 직후 옛 커밋의 결과를 읽지 않으려고 둔다 */
|
|
51
|
+
head?: string;
|
|
52
|
+
/** owner/repo. 비우면 gh 가 현재 레포를 쓴다 */
|
|
53
|
+
repo?: string;
|
|
54
|
+
timeoutSec: number;
|
|
55
|
+
/** 체크가 하나도 안 붙은 상태를 "CI 없음"으로 판정하기까지 기다리는 시간 */
|
|
56
|
+
graceSec: number;
|
|
57
|
+
intervalSec: number;
|
|
58
|
+
maxCauseLines?: number;
|
|
59
|
+
}
|
|
60
|
+
export declare const defaultRunner: CmdRunner;
|
|
61
|
+
export declare const defaultDeps: CiWaitDeps;
|
|
62
|
+
type ChecksRead = {
|
|
63
|
+
kind: 'checks';
|
|
64
|
+
checks: CiCheck[];
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'none';
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'error';
|
|
69
|
+
message: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* `gh pr checks --json` 결과를 읽는다.
|
|
73
|
+
*
|
|
74
|
+
* 종료 코드로 판정하지 않는다. gh 는 체크가 실패하거나 진행 중이어도 0 이 아닌 코드로
|
|
75
|
+
* 끝나면서 stdout 에는 JSON 을 낸다. 체크가 하나도 없으면 stdout 이 비고 stderr 에
|
|
76
|
+
* "no checks reported" 가 온다 — push 직후 체크가 붙기 전에도 같은 모양이라 이것만으로는
|
|
77
|
+
* CI 가 없다고 못 정한다. 빈 배열(`[]`)도 체크가 없는 것으로 읽는다. 체크로 읽으면 진행 중인
|
|
78
|
+
* 게 없어 통과로 판정된다.
|
|
79
|
+
*/
|
|
80
|
+
export declare function readChecks(r: CmdResult): ChecksRead;
|
|
81
|
+
/** Actions 잡 링크에서 레포와 잡 id 를 읽는다. 외부 앱이 단 체크면 null */
|
|
82
|
+
export declare function parseJobLink(link: string): {
|
|
83
|
+
repo: string;
|
|
84
|
+
jobId: string;
|
|
85
|
+
} | null;
|
|
86
|
+
export interface CausePick {
|
|
87
|
+
lines: string[];
|
|
88
|
+
/** 상한에 잘리기 전의 원인 줄 수 */
|
|
89
|
+
total: number;
|
|
90
|
+
fromTail: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 실패 로그에서 사람이 먼저 봐야 할 줄을 고른다.
|
|
94
|
+
*
|
|
95
|
+
* GitHub 주석(`##[error]`)을 가장 믿는다. 러너가 실패 자리에 직접 단 표시라서다. 그다음이
|
|
96
|
+
* 테스트 러너와 컴파일러, 린터의 실패 표시다. 둘을 함께 모으되 주석을 앞에 두고 상한까지
|
|
97
|
+
* 채운다. 둘 다 없으면 끝에서 다섯 줄을 낸다 — 대개 거기 마지막 오류가 있다.
|
|
98
|
+
*/
|
|
99
|
+
export declare function extractCauseLines(log: string, max?: number): CausePick;
|
|
100
|
+
/**
|
|
101
|
+
* CI 가 끝나거나 상한에 닿을 때까지 기다린다.
|
|
102
|
+
*
|
|
103
|
+
* 판정은 넷이다. 체크가 안 붙은 채 유예가 지나면 `none`, 하나라도 실패하면 `fail`,
|
|
104
|
+
* 상한에 닿았는데 실패 없이 진행 중인 게 남으면 `pending`, 나머지는 `pass` 다.
|
|
105
|
+
* 실패가 보이면 진행 중인 체크가 남아도 더 기다리지 않는다. 남은 건 `pending` 에 싣는다.
|
|
106
|
+
* gh 호출이 연달아 실패하면 판정을 지어내지 않고 던진다.
|
|
107
|
+
*/
|
|
108
|
+
export declare function waitForCi(opts: CiWaitOptions, deps?: CiWaitDeps): Promise<CiWaitResult>;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=ci.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../../src/ship/ci.ts"],"names":[],"mappings":"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"}
|