intentpatch 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +470 -0
- package/README.md +188 -204
- package/package.json +8 -3
package/README.ko.md
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# IntentPatch
|
|
2
|
+
|
|
3
|
+
[English](./README.md) | **한국어**
|
|
4
|
+
|
|
5
|
+
[](https://github.com/xx2xxjaeil/intent-patch/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
> AI 코딩 에이전트가 만든 변경을 근거 중심으로 분석하는 오픈소스 도구
|
|
8
|
+
|
|
9
|
+
Codex, Claude Code, Cursor 같은 AI 코딩 에이전트는 짧은 요청만으로 여러 파일을 빠르게
|
|
10
|
+
수정합니다. 하지만 변경된 파일이 많아질수록 다음 질문에 답하기 어려워집니다.
|
|
11
|
+
|
|
12
|
+
- 요청한 범위보다 많은 파일을 수정하지 않았는가?
|
|
13
|
+
- 기존 코드를 재사용하지 않고 비슷한 로직을 새로 만들지 않았는가?
|
|
14
|
+
- 불필요한 라이브러리나 추상화를 추가하지 않았는가?
|
|
15
|
+
- 이번 변경이 다른 모듈에 어디까지 영향을 주는가?
|
|
16
|
+
- 중요한 동작에 대한 테스트가 함께 추가되었는가?
|
|
17
|
+
|
|
18
|
+
IntentPatch는 이러한 질문에 답하기 위해 **Git diff, 정적 분석, 의존 관계 분석**을 결합합니다.
|
|
19
|
+
LLM 없이도 재현 가능한 분석을 제공하고, AI 설명 기능은 선택적으로 결합하는 것을 목표로
|
|
20
|
+
합니다.
|
|
21
|
+
|
|
22
|
+
## 빠른 시작
|
|
23
|
+
|
|
24
|
+
Node.js 20 이상과 Git이 설치되어 있어야 합니다. 현재 npm 공개 전에는 저장소를 빌드해 바로
|
|
25
|
+
실행할 수 있습니다.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/xx2xxjaeil/intent-patch.git
|
|
29
|
+
cd intent-patch
|
|
30
|
+
npm ci
|
|
31
|
+
npm run build
|
|
32
|
+
node dist/presentation/cli/main.js --version
|
|
33
|
+
node dist/presentation/cli/main.js analyze --cwd /path/to/repository
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
npm 릴리스가 공개된 뒤에는 설치 없이 같은 CLI를 실행할 수 있습니다.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx intentpatch analyze --cwd /path/to/repository
|
|
40
|
+
npx intentpatch analyze --format html --output intentpatch-report.html
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
핵심 분석에는 API key, 유료 AI 모델, 서버 또는 데이터베이스가 필요하지 않습니다. 분석할 Git
|
|
44
|
+
저장소의 파일은 로컬에서 처리하며 LLM 연결은 현재 기본 실행 경로에 포함되지 않습니다.
|
|
45
|
+
|
|
46
|
+
## GitHub Action
|
|
47
|
+
|
|
48
|
+
Pull Request에서 요청 범위와 위험 변경을 자동 검사할 수 있습니다. 정확한 base·head commit을
|
|
49
|
+
사용하도록 checkout의 전체 히스토리를 가져와야 합니다.
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
name: IntentPatch
|
|
53
|
+
|
|
54
|
+
on:
|
|
55
|
+
pull_request:
|
|
56
|
+
|
|
57
|
+
permissions:
|
|
58
|
+
contents: read
|
|
59
|
+
|
|
60
|
+
jobs:
|
|
61
|
+
analyze:
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v6
|
|
65
|
+
with:
|
|
66
|
+
fetch-depth: 0
|
|
67
|
+
|
|
68
|
+
- name: Analyze pull request
|
|
69
|
+
id: intentpatch
|
|
70
|
+
uses: xx2xxjaeil/intent-patch@main
|
|
71
|
+
with:
|
|
72
|
+
fail-on: high
|
|
73
|
+
|
|
74
|
+
- name: Upload reports
|
|
75
|
+
if: always()
|
|
76
|
+
uses: actions/upload-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: intentpatch-report
|
|
79
|
+
path: intentpatch-report
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
현재 개발 버전은 `@main`으로 실행합니다. 첫 번째 정식 릴리스 후에는 불변 SHA 또는 `@v1`
|
|
83
|
+
태그로 고정하는 방식을 권장합니다. Action은 PR·push 이벤트의 commit 범위를 자동으로
|
|
84
|
+
선택하고 다음 결과를 남깁니다.
|
|
85
|
+
|
|
86
|
+
- GitHub Actions Job Summary의 Markdown 보고서
|
|
87
|
+
- 심각도별 workflow annotation
|
|
88
|
+
- artifact 업로드에 사용할 JSON·HTML 보고서
|
|
89
|
+
- `high`, `medium`, `low` 기준의 품질 게이트
|
|
90
|
+
- finding 수와 보고서 경로 Action output
|
|
91
|
+
|
|
92
|
+
입력·출력과 이벤트별 비교 기준은 [GitHub Action 사용 문서](./docs/github-action.md)에서
|
|
93
|
+
확인할 수 있습니다.
|
|
94
|
+
|
|
95
|
+
## 프로젝트가 지향하는 결과
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
IntentPatch Change Report
|
|
99
|
+
|
|
100
|
+
Target HEAD → working tree
|
|
101
|
+
Files changed 12
|
|
102
|
+
Lines +438 / -51
|
|
103
|
+
Direct dependents 2
|
|
104
|
+
Transitive impact 4
|
|
105
|
+
Tests changed 3
|
|
106
|
+
Missing test changes 1
|
|
107
|
+
New dependencies 2
|
|
108
|
+
Risky API changes 1
|
|
109
|
+
Duplicate candidates 1
|
|
110
|
+
Single implementations 1
|
|
111
|
+
|
|
112
|
+
Impacted files
|
|
113
|
+
|
|
114
|
+
→ direct src/api/delete-user.ts
|
|
115
|
+
changed: src/lib/auth.ts
|
|
116
|
+
→ transitive · 2 hops src/app.ts
|
|
117
|
+
changed: src/lib/auth.ts
|
|
118
|
+
|
|
119
|
+
Potential issues
|
|
120
|
+
|
|
121
|
+
HIGH 공개 함수 시그니처 호환성 파괴
|
|
122
|
+
MEDIUM 기존 인증 로직과 동일한 구현 발견
|
|
123
|
+
MEDIUM 요청과 관련성이 낮아 보이는 파일 4개 변경
|
|
124
|
+
LOW 구현체가 하나뿐인 추상화 추가
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
분석 결과는 단순한 경고 문구가 아니라 관련 파일, 규칙 ID, 판단 근거와 함께 제공하는 것을
|
|
128
|
+
원칙으로 합니다.
|
|
129
|
+
|
|
130
|
+
## 현재 구현된 기능
|
|
131
|
+
|
|
132
|
+
현재 버전은 Git 변경사항 수집, 루트 `package.json`의 직접 dependency 분석, TypeScript
|
|
133
|
+
최상위 심볼과 공개 API 변경 분석, 기존 구현 중복·단일 구현 추상화 신호, import graph 기반
|
|
134
|
+
영향 범위와 테스트 동반 변경 분석을 제공합니다.
|
|
135
|
+
|
|
136
|
+
- `HEAD`와 현재 working tree 비교
|
|
137
|
+
- 두 Git reference 또는 브랜치 비교
|
|
138
|
+
- 추가, 수정, 삭제, 이름 변경 등 파일 상태 분류
|
|
139
|
+
- 파일별 추가·삭제 라인 수 계산
|
|
140
|
+
- binary 파일 구분
|
|
141
|
+
- working tree 분석 시 untracked 파일 포함
|
|
142
|
+
- 터미널용 텍스트 보고서
|
|
143
|
+
- 후속 도구 연동을 위한 JSON 보고서
|
|
144
|
+
- 요약 카드, finding, 테스트 신호와 영향 그래프를 담은 단일 HTML 보고서
|
|
145
|
+
- 외부 CDN이나 JavaScript dependency가 필요 없는 인라인 CSS·SVG 시각화
|
|
146
|
+
- production·development dependency 추가 탐지
|
|
147
|
+
- dependency 삭제, 버전 변경, 섹션 이동 탐지
|
|
148
|
+
- 잘못된 `package.json`을 예외 대신 근거가 포함된 finding으로 보고
|
|
149
|
+
- finding 심각도(`high`, `medium`, `low`) 집계
|
|
150
|
+
- CI 품질 게이트를 위한 `--fail-on` 종료 코드
|
|
151
|
+
- 설치된 패키지 버전을 확인하는 `--version` 명령
|
|
152
|
+
- `.ts`·`.tsx` 파일의 최상위 함수·클래스·인터페이스·타입 별칭 추출
|
|
153
|
+
- 심볼 추가·수정·삭제 탐지와 소스 위치 표시
|
|
154
|
+
- 직접 `export`된 선언, 로컬 export 목록과 외부 re-export를 공개 심볼 근거에 보존
|
|
155
|
+
- 공개 심볼 삭제와 `export` 해제를 호환성 위험 `high` finding으로 탐지
|
|
156
|
+
- 공개 함수의 기존 호출 시그니처 제거와 공개 인터페이스의 호환성 파괴를 `high` finding으로 탐지
|
|
157
|
+
- 구현이 추가된 기존 overload는 제외하고 기존 overload가 사라진 경우만 함수 계약 변경으로 판정
|
|
158
|
+
- 공백과 주석을 제외한 구현 토큰이 같은 신규 함수와 기존 함수를 재사용 후보 `medium` finding으로 탐지
|
|
159
|
+
- 신규 인터페이스를 명시적으로 구현하는 클래스가 하나뿐이면 추상화 검토 `low` finding으로 탐지
|
|
160
|
+
- rename 전후 파일 경로를 사용한 심볼 비교
|
|
161
|
+
- 구문 오류가 있는 파일을 누락시키지 않고 분석 불가 근거로 보고
|
|
162
|
+
- `.ts`·`.tsx` 파일의 상대 경로 정적 import와 re-export 관계 수집
|
|
163
|
+
- `.js`·`.jsx`·`.mjs`·`.cjs` specifier를 대응하는 TypeScript 소스로 해석
|
|
164
|
+
- 변경 모듈을 import하는 직접 의존자와 여러 단계를 거친 간접 영향 파일 계산
|
|
165
|
+
- 해결하지 못한 상대 import와 읽기·파싱 실패를 분석 근거로 보존
|
|
166
|
+
- working tree의 tracked·untracked 파일 또는 지정한 head ref를 동일한 결과점에서 분석
|
|
167
|
+
- `.intentpatch.json`에 요청 의도, 예상 경로, 허용 경로와 변경량 예산 선언
|
|
168
|
+
- 예상·허용 패턴을 벗어난 변경 파일을 파일별 `medium` finding으로 탐지
|
|
169
|
+
- 변경 파일 수와 측정 라인 예산 초과를 수치 근거가 있는 `low` finding으로 탐지
|
|
170
|
+
- Contract가 지정한 소스·테스트 경로를 분류하고 파일명 기준으로 관련 변경 연결
|
|
171
|
+
- 테스트 변경 수와 추가·삭제 수를 별도의 분석 사실로 집계
|
|
172
|
+
- 관련 테스트 변경이 없는 소스 파일을 `medium` finding으로 탐지
|
|
173
|
+
- `*`, `**`, `?` 기반의 저장소 상대 경로 패턴 지원
|
|
174
|
+
- Pull Request·push commit 범위를 자동 판별하는 GitHub Action
|
|
175
|
+
- GitHub Job Summary, workflow annotation, JSON·HTML artifact용 보고서 생성
|
|
176
|
+
|
|
177
|
+
아직 lockfile의 전이 dependency 분석, path alias 해석, JavaScript·메서드 구조 분석과 AI 리뷰
|
|
178
|
+
기능은 구현되지 않았습니다.
|
|
179
|
+
|
|
180
|
+
## 상세 사용법
|
|
181
|
+
|
|
182
|
+
현재 저장소의 working tree를 분석합니다.
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
node dist/presentation/cli/main.js analyze
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
다른 Git 저장소를 분석할 수도 있습니다.
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
node dist/presentation/cli/main.js analyze --cwd /path/to/repository
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
두 브랜치를 비교합니다. 내부적으로 merge base 기준의 변경사항을 분석합니다.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
node dist/presentation/cli/main.js analyze \
|
|
198
|
+
--cwd /path/to/repository \
|
|
199
|
+
--base main \
|
|
200
|
+
--head feature/account-deletion
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
JSON으로 출력합니다.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
node dist/presentation/cli/main.js analyze --json
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
브라우저에서 볼 수 있는 HTML 보고서를 파일로 생성합니다.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
node dist/presentation/cli/main.js analyze \
|
|
213
|
+
--format html \
|
|
214
|
+
--output intentpatch-report.html
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
HTML 파일에는 스타일과 dependency 영향 SVG 그래프가 모두 포함되므로 별도 서버나 API key 없이
|
|
218
|
+
바로 열 수 있습니다. `--output`은 텍스트와 JSON 형식에도 사용할 수 있으며 상대 경로는
|
|
219
|
+
IntentPatch를 실행한 현재 디렉터리를 기준으로 해석합니다. 기존 `--json`은
|
|
220
|
+
`--format json`의 단축 옵션입니다.
|
|
221
|
+
|
|
222
|
+
### Change Contract로 요청 범위 검사
|
|
223
|
+
|
|
224
|
+
분석할 저장소의 `.intentpatch.json`에 이번 요청의 기대 범위를 선언할 수 있습니다.
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"intent": "회원 탈퇴 기능 구현",
|
|
229
|
+
"scope": {
|
|
230
|
+
"include": ["src/user/**", "tests/user/**"],
|
|
231
|
+
"allow": ["package.json", "package-lock.json"],
|
|
232
|
+
"maxFiles": 8,
|
|
233
|
+
"maxLines": 300
|
|
234
|
+
},
|
|
235
|
+
"tests": {
|
|
236
|
+
"requireFor": ["src/**/*.ts", "src/**/*.tsx"],
|
|
237
|
+
"include": ["tests/**/*.test.ts", "tests/**/*.test.tsx"],
|
|
238
|
+
"exclude": ["src/**/*.d.ts"]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- `include`: 요청 수행 중 변경될 것으로 예상한 경로
|
|
244
|
+
- `allow`: 설정이나 lockfile처럼 함께 변경되어도 허용하는 예외 경로
|
|
245
|
+
- `maxFiles`: 변경 파일 수의 상한
|
|
246
|
+
- `maxLines`: 측정 가능한 추가·삭제 라인 합의 상한
|
|
247
|
+
- `tests.requireFor`: 테스트 동반 변경을 확인할 소스 경로
|
|
248
|
+
- `tests.include`: 테스트 파일로 분류할 경로
|
|
249
|
+
- `tests.exclude`: 생성 파일이나 선언 파일처럼 검사에서 제외할 소스 경로
|
|
250
|
+
|
|
251
|
+
테스트 연결은 결정적인 결과를 위해 파일명을 사용합니다. 예를 들어 `src/user.ts`는
|
|
252
|
+
`tests/user.test.ts`, `user.spec.ts`, `user.integration.test.ts` 같은 변경과 연결됩니다.
|
|
253
|
+
|
|
254
|
+
기본 파일 대신 별도 계약을 사용하려면 `--config`를 지정합니다. 상대 경로는 `--cwd`를 기준으로
|
|
255
|
+
해석합니다.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
node dist/presentation/cli/main.js analyze \
|
|
259
|
+
--cwd /path/to/repository \
|
|
260
|
+
--config contracts/delete-user.json
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
복사해서 시작할 수 있는 설정은 [`.intentpatch.example.json`](./.intentpatch.example.json)에
|
|
264
|
+
있습니다. Contract가 없으면 기존 분석은 그대로 실행되고 scope 규칙만 비활성화됩니다.
|
|
265
|
+
|
|
266
|
+
지정한 심각도 이상의 finding이 있으면 보고서를 출력한 뒤 종료 코드 `1`을 반환합니다.
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
node dist/presentation/cli/main.js analyze --fail-on medium
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`medium`은 `medium`과 `high` finding에 반응하며, `low`를 지정하면 모든 finding을 품질
|
|
273
|
+
게이트 대상으로 취급합니다. 잘못된 CLI 사용은 종료 코드 `2`를 반환합니다.
|
|
274
|
+
|
|
275
|
+
dependency 변경과 코드 영향 범위를 다음과 같이 근거와 함께 출력합니다.
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
IntentPatch Change Report
|
|
279
|
+
|
|
280
|
+
Files changed 2
|
|
281
|
+
Changed symbols 2
|
|
282
|
+
Import edges 18
|
|
283
|
+
Direct dependents 1
|
|
284
|
+
Transitive impact 2
|
|
285
|
+
Tests changed 1
|
|
286
|
+
Tests added 0
|
|
287
|
+
Missing test changes 1
|
|
288
|
+
New dependencies 1
|
|
289
|
+
Risky API changes 1
|
|
290
|
+
Duplicate candidates 1
|
|
291
|
+
Single implementations 1
|
|
292
|
+
Findings 6
|
|
293
|
+
|
|
294
|
+
Changed symbols
|
|
295
|
+
|
|
296
|
+
M Class UserService src/user/service.ts:12
|
|
297
|
+
A Function deleteUser src/user/service.ts:48
|
|
298
|
+
|
|
299
|
+
Impacted files
|
|
300
|
+
|
|
301
|
+
→ direct src/api/delete-user.ts
|
|
302
|
+
changed: src/user/service.ts
|
|
303
|
+
→ transitive · 2 hops src/app.ts
|
|
304
|
+
changed: src/user/service.ts
|
|
305
|
+
|
|
306
|
+
Potential issues
|
|
307
|
+
|
|
308
|
+
HIGH Public export removed
|
|
309
|
+
src/user/service.ts · api/export-removed
|
|
310
|
+
The function deleteUser is no longer exported.
|
|
311
|
+
|
|
312
|
+
MEDIUM New production dependency
|
|
313
|
+
package.json · dependency/new-production
|
|
314
|
+
dayjs@^1.11.0 was added to dependencies.
|
|
315
|
+
|
|
316
|
+
MEDIUM Change outside expected scope
|
|
317
|
+
src/payment/billing.ts · scope/outside-expected-path
|
|
318
|
+
src/payment/billing.ts does not match any expected or allowed path pattern.
|
|
319
|
+
|
|
320
|
+
MEDIUM Source change without matching test change
|
|
321
|
+
src/payment/billing.ts · tests/missing-related-change
|
|
322
|
+
src/payment/billing.ts changed without a changed test sharing the same basename.
|
|
323
|
+
|
|
324
|
+
MEDIUM New function duplicates existing implementation
|
|
325
|
+
src/user/service.ts · structure/duplicate-implementation
|
|
326
|
+
The new function verifySession has the same normalized implementation as authorize.
|
|
327
|
+
|
|
328
|
+
LOW New interface has one implementation
|
|
329
|
+
src/user/service.ts · structure/single-implementation-abstraction
|
|
330
|
+
The new interface DeletionStrategy is implemented only by DefaultDeletionStrategy.
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
개발 중에는 빌드 없이 실행할 수 있습니다.
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
npm run dev -- analyze --cwd /path/to/repository
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## 아키텍처
|
|
340
|
+
|
|
341
|
+
기능이 늘어나도 Git, UI, 분석 규칙이 서로 강하게 결합되지 않도록 클린 아키텍처의 의존성
|
|
342
|
+
방향을 적용했습니다.
|
|
343
|
+
|
|
344
|
+
```text
|
|
345
|
+
presentation ───────▶ application ───────▶ domain
|
|
346
|
+
│ ▲
|
|
347
|
+
└──▶ infrastructure ──┘
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
| 계층 | 책임 |
|
|
351
|
+
| --- | --- |
|
|
352
|
+
| `domain` | 변경 파일, Change Contract, finding, 심볼 변경, dependency 영향 등 핵심 모델 |
|
|
353
|
+
| `application` | 분석 유스케이스, 규칙 엔진, 심볼·영향 계산과 외부 데이터 포트 |
|
|
354
|
+
| `infrastructure` | Git 명령·diff 파싱·프로젝트 파일 공급·TypeScript AST 파싱 |
|
|
355
|
+
| `presentation` | CLI 인자 처리, 의존성 조립, 텍스트·JSON·HTML 출력 |
|
|
356
|
+
|
|
357
|
+
하위 계층이 외부 구현을 참조하지 않도록 아키텍처 테스트가 import 방향을 검사합니다.
|
|
358
|
+
구현상의 주요 판단과 확장 지점은 [상세 아키텍처 문서](./docs/architecture.md)에서 설명합니다.
|
|
359
|
+
|
|
360
|
+
## 설계 원칙
|
|
361
|
+
|
|
362
|
+
- **Deterministic first:** 핵심 분석은 동일한 입력에 동일한 결과를 반환합니다.
|
|
363
|
+
- **Evidence over claims:** 확실하지 않은 판단을 사실처럼 단정하지 않습니다.
|
|
364
|
+
- **LLM optional:** AI 연결 없이도 기본 분석 기능을 사용할 수 있어야 합니다.
|
|
365
|
+
- **Dependency minimalism:** 편의를 위한 라이브러리를 무분별하게 추가하지 않습니다.
|
|
366
|
+
- **Explicit boundaries:** 도메인 로직과 Git·CLI 같은 외부 기술을 분리합니다.
|
|
367
|
+
|
|
368
|
+
## 테스트와 품질 검사
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
npm run check
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
위 명령은 다음 검사를 순서대로 실행합니다.
|
|
375
|
+
|
|
376
|
+
- 엄격한 TypeScript 타입 검사
|
|
377
|
+
- Biome 린트 및 포맷 검사
|
|
378
|
+
- 도메인과 유스케이스 단위 테스트
|
|
379
|
+
- 실제 임시 Git 저장소를 사용하는 통합 테스트
|
|
380
|
+
- 생성한 npm tarball을 임시 프로젝트에 설치하고 실행하는 패키지 통합 테스트
|
|
381
|
+
- 계층 간 의존 방향을 검증하는 아키텍처 테스트
|
|
382
|
+
|
|
383
|
+
프로덕션 빌드만 확인하려면 다음 명령을 사용합니다.
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
npm run build
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
npm에 포함될 파일과 패키지 생성을 확인하려면 실제 공개 없이 dry-run을 실행합니다.
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
npm pack --dry-run
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## 릴리스
|
|
396
|
+
|
|
397
|
+
`v0.1.0`처럼 `package.json` 버전과 일치하는 태그를 기본 브랜치의 커밋에 push하면 릴리스
|
|
398
|
+
워크플로가 다음 작업을 순서대로 수행합니다.
|
|
399
|
+
|
|
400
|
+
1. 태그·버전·기본 브랜치 포함 여부 검증
|
|
401
|
+
2. 전체 품질 검사와 npm 패키지 내용 dry-run
|
|
402
|
+
3. npm Trusted Publishing(OIDC)을 이용한 공개 배포
|
|
403
|
+
4. 자동 생성한 변경 내역을 포함하는 GitHub Release 생성
|
|
404
|
+
|
|
405
|
+
장기 npm token을 GitHub secret으로 저장하지 않으며, 공개 저장소에서 OIDC로 배포한 패키지에는
|
|
406
|
+
npm provenance가 자동 생성됩니다. 아직 npm에 존재하지 않는 신규 패키지는 Trusted Publisher를
|
|
407
|
+
연결하기 전에 최초 1회 등록이 필요합니다. 초기 등록과 이후 버전 배포 절차는
|
|
408
|
+
[릴리스 운영 가이드](./docs/releasing.md)에 정리했습니다.
|
|
409
|
+
|
|
410
|
+
## 로드맵
|
|
411
|
+
|
|
412
|
+
1. ✅ `package.json` 직접 dependency 변경 탐지와 규칙 엔진
|
|
413
|
+
2. ✅ TypeScript AST 기반 함수·클래스·인터페이스·타입 변경 분석
|
|
414
|
+
3. ✅ 상대 경로 정적 import graph 기반 변경 영향 범위 계산
|
|
415
|
+
4. ✅ Change Contract 기반 예상 범위 이탈과 변경량 예산 탐지
|
|
416
|
+
5. ✅ Contract 기반 관련 테스트 변경 누락 탐지
|
|
417
|
+
6. lockfile과 workspace를 고려한 package manager adapter
|
|
418
|
+
7. ✅ 직접 export된 공개 심볼 삭제와 export 해제 탐지
|
|
419
|
+
8. ✅ 단일 HTML 대시보드와 SVG 기반 dependency 영향 그래프
|
|
420
|
+
9. ✅ re-export·함수/인터페이스 호환성과 기존 코드 중복 가능성 탐지
|
|
421
|
+
10. ✅ 구현체가 하나뿐인 신규 인터페이스 탐지
|
|
422
|
+
11. ✅ PR·push 비교, Job Summary와 artifact 출력을 제공하는 GitHub Action
|
|
423
|
+
12. Codex·Claude Code·Cursor adapter
|
|
424
|
+
13. 근거 기반 결과에 대한 선택적 LLM 설명
|
|
425
|
+
|
|
426
|
+
## 현재 제한사항
|
|
427
|
+
|
|
428
|
+
- 분석 대상은 최소 한 번 이상 커밋된 Git 저장소여야 합니다.
|
|
429
|
+
- untracked symbolic link는 안전을 위해 내용을 읽지 않습니다.
|
|
430
|
+
- 10 MiB를 초과하는 untracked 파일은 라인 수를 측정하지 않습니다.
|
|
431
|
+
- dependency 분석은 저장소 루트의 npm `package.json`에 선언된 `dependencies`와
|
|
432
|
+
`devDependencies`를 대상으로 합니다.
|
|
433
|
+
- lockfile의 전이 dependency, workspace package, 코드에서의 실제 사용 여부는 아직 분석하지 않습니다.
|
|
434
|
+
- 심볼 분석은 `.ts`와 `.tsx`의 이름이 있는 최상위 함수, 클래스, 인터페이스, 타입
|
|
435
|
+
별칭만 지원합니다.
|
|
436
|
+
- 공개 API 분석은 이름이 있는 최상위 함수·인터페이스, 로컬 `export { name }`, 외부
|
|
437
|
+
`export { name } from`, `export * from`을 지원합니다. package `exports`, 익명 default export,
|
|
438
|
+
클래스·타입 별칭의 세부 계약은 아직 해석하지 않습니다.
|
|
439
|
+
- 함수 호환성은 명시된 파라미터·반환 타입 텍스트를 비교합니다. 추론된 반환 타입 변화나
|
|
440
|
+
TypeScript의 구조적 타입 할당 가능성까지 판정하지 않습니다.
|
|
441
|
+
- 중복 구현 후보는 새로 추가된 최상위 함수와 기존 최상위 함수의 토큰이 공백·주석을 제외하고
|
|
442
|
+
완전히 같으며 본문이 12토큰 이상일 때만 보고합니다. 식별자 이름이 바뀐 유사 코드, 메서드,
|
|
443
|
+
의미적으로만 같은 구현은 탐지하지 않습니다.
|
|
444
|
+
- 단일 구현 추상화는 새 인터페이스를 `implements`로 명시한 이름 있는 클래스가 정확히 하나일 때만
|
|
445
|
+
보고합니다. TypeScript의 구조적 구현, factory 반환 타입과 런타임 등록은 계산하지 않습니다.
|
|
446
|
+
- 메서드, 변수 선언, enum, 중첩 선언, JavaScript 파일은 아직 심볼 분석 대상이 아닙니다.
|
|
447
|
+
- 선언 내부의 포맷이나 주석 변경도 심볼 수정으로 집계될 수 있습니다.
|
|
448
|
+
- 영향 분석은 `.ts`·`.tsx` 파일의 상대 경로 정적 `import`, side-effect import,
|
|
449
|
+
`export ... from`, `import = require()`를 대상으로 합니다.
|
|
450
|
+
- 외부 package import는 그래프에서 제외하며 path alias, dynamic `import()`, 일반 `require()`는
|
|
451
|
+
아직 해석하지 않습니다.
|
|
452
|
+
- 영향 그래프는 비교 결과점(working tree 또는 head ref)의 파일을 기준으로 만듭니다. 따라서
|
|
453
|
+
삭제된 모듈을 가리키던 과거 import의 영향은 현재 단계에서 계산할 수 없습니다.
|
|
454
|
+
- 영향 분석용 소스 파일은 파일당 1 MiB로 제한하며, symbolic link는 읽지 않습니다.
|
|
455
|
+
- IntentPatch는 자연어 intent만으로 예상 경로를 추측하지 않습니다. 범위 판단은 Contract에 명시한
|
|
456
|
+
`include`와 `allow`를 기준으로 수행합니다.
|
|
457
|
+
- 경로 패턴은 저장소 상대 경로와 `*`, `**`, `?`만 지원합니다. 부정 패턴과 brace 확장은 아직
|
|
458
|
+
지원하지 않습니다.
|
|
459
|
+
- `maxLines`는 측정 가능한 텍스트 파일의 추가·삭제 라인만 합산합니다. Binary와 측정 불가 파일을
|
|
460
|
+
0줄이라고 간주하지 않지만, 해당 파일의 크기를 라인 예산에 포함하지도 않습니다.
|
|
461
|
+
- 테스트 분석은 실행 결과나 코드 커버리지를 측정하지 않고 Contract에 지정된 변경 파일만
|
|
462
|
+
비교합니다.
|
|
463
|
+
- 관련 테스트는 현재 소스와 테스트의 파일명이 같은지로 판단하므로 이름이 다른 통합 테스트나
|
|
464
|
+
하나의 테스트가 여러 소스를 검증하는 관계는 자동으로 연결하지 못합니다.
|
|
465
|
+
- HTML 영향 그래프는 변경 모듈과 영향 파일을 결정적인 두 열 레이아웃으로 표시합니다. 노드 이동,
|
|
466
|
+
확대·축소와 필터링을 제공하는 대화형 웹 UI는 아직 구현하지 않았습니다.
|
|
467
|
+
|
|
468
|
+
## 라이선스
|
|
469
|
+
|
|
470
|
+
[MIT](./LICENSE)
|
package/README.md
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
# IntentPatch
|
|
2
2
|
|
|
3
|
+
**English** | [한국어](./README.ko.md)
|
|
4
|
+
|
|
3
5
|
[](https://github.com/xx2xxjaeil/intent-patch/actions/workflows/ci.yml)
|
|
4
6
|
|
|
5
|
-
>
|
|
7
|
+
> Evidence-based change-scope analysis for code written by AI coding agents
|
|
6
8
|
|
|
7
|
-
Codex, Claude Code, Cursor
|
|
8
|
-
수정합니다. 하지만 변경된 파일이 많아질수록 다음 질문에 답하기 어려워집니다.
|
|
9
|
+
AI coding agents such as Codex, Claude Code, and Cursor can change many files from a short request. As the patch grows, it becomes harder to answer a few important questions:
|
|
9
10
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- Did the agent change files outside the requested scope?
|
|
12
|
+
- Did it recreate logic that already existed?
|
|
13
|
+
- Did it add an unnecessary dependency or abstraction?
|
|
14
|
+
- How far can the change affect other modules?
|
|
15
|
+
- Were relevant tests changed with the production code?
|
|
15
16
|
|
|
16
|
-
IntentPatch
|
|
17
|
-
LLM 없이도 재현 가능한 분석을 제공하고, AI 설명 기능은 선택적으로 결합하는 것을 목표로
|
|
18
|
-
합니다.
|
|
17
|
+
IntentPatch combines **Git diff analysis, static analysis, and dependency analysis** to answer those questions. Its core analysis is deterministic and works without an LLM. Optional AI explanations can be added later without making the core tool dependent on a model provider.
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## Quick start
|
|
21
20
|
|
|
22
|
-
Node.js 20
|
|
23
|
-
실행할 수 있습니다.
|
|
21
|
+
IntentPatch requires Node.js 20 or later and Git. Until the first public npm release is approved, build and run it directly from the repository:
|
|
24
22
|
|
|
25
23
|
```bash
|
|
26
24
|
git clone https://github.com/xx2xxjaeil/intent-patch.git
|
|
@@ -31,20 +29,18 @@ node dist/presentation/cli/main.js --version
|
|
|
31
29
|
node dist/presentation/cli/main.js analyze --cwd /path/to/repository
|
|
32
30
|
```
|
|
33
31
|
|
|
34
|
-
npm
|
|
32
|
+
After the npm release becomes public, run the same CLI without installing it globally:
|
|
35
33
|
|
|
36
34
|
```bash
|
|
37
35
|
npx intentpatch analyze --cwd /path/to/repository
|
|
38
36
|
npx intentpatch analyze --format html --output intentpatch-report.html
|
|
39
37
|
```
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
저장소의 파일은 로컬에서 처리하며 LLM 연결은 현재 기본 실행 경로에 포함되지 않습니다.
|
|
39
|
+
The core analyzer needs no API key, paid AI model, server, or database. Repository files are processed locally, and no LLM is used in the default execution path.
|
|
43
40
|
|
|
44
41
|
## GitHub Action
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
사용하도록 checkout의 전체 히스토리를 가져와야 합니다.
|
|
43
|
+
Use IntentPatch in pull requests to check scope and risky changes automatically. The checkout must include the full Git history so the action can compare the exact base and head commits.
|
|
48
44
|
|
|
49
45
|
```yaml
|
|
50
46
|
name: IntentPatch
|
|
@@ -77,20 +73,19 @@ jobs:
|
|
|
77
73
|
path: intentpatch-report
|
|
78
74
|
```
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
The development version currently runs from `@main`. After the first stable release, pin the action to an immutable commit SHA or a major tag such as `@v1`.
|
|
77
|
+
|
|
78
|
+
The action detects the comparison range for pull request and push events and produces:
|
|
83
79
|
|
|
84
|
-
- GitHub Actions Job Summary
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
- `high`, `medium`, `low`
|
|
88
|
-
- finding
|
|
80
|
+
- a Markdown report in the GitHub Actions Job Summary;
|
|
81
|
+
- workflow annotations grouped by severity;
|
|
82
|
+
- JSON and HTML reports that can be uploaded as artifacts;
|
|
83
|
+
- a quality gate at the `high`, `medium`, or `low` threshold;
|
|
84
|
+
- action outputs containing finding counts and report paths.
|
|
89
85
|
|
|
90
|
-
|
|
91
|
-
확인할 수 있습니다.
|
|
86
|
+
See the [GitHub Action guide](./docs/github-action.md) for inputs, outputs, and event-specific comparison behavior.
|
|
92
87
|
|
|
93
|
-
##
|
|
88
|
+
## What the report looks like
|
|
94
89
|
|
|
95
90
|
```text
|
|
96
91
|
IntentPatch Change Report
|
|
@@ -116,80 +111,81 @@ Impacted files
|
|
|
116
111
|
|
|
117
112
|
Potential issues
|
|
118
113
|
|
|
119
|
-
HIGH
|
|
120
|
-
MEDIUM
|
|
121
|
-
MEDIUM
|
|
122
|
-
LOW
|
|
114
|
+
HIGH Breaking change to a public function signature
|
|
115
|
+
MEDIUM Implementation duplicates existing authentication logic
|
|
116
|
+
MEDIUM Four files changed outside the expected scope
|
|
117
|
+
LOW New abstraction has only one implementation
|
|
123
118
|
```
|
|
124
119
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
-
|
|
165
|
-
- `.
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
120
|
+
Every finding includes the relevant file, a stable rule ID, and evidence for the decision instead of only presenting an unexplained warning.
|
|
121
|
+
|
|
122
|
+
## Implemented capabilities
|
|
123
|
+
|
|
124
|
+
The current version analyzes Git changes, direct dependencies in the root `package.json`, top-level TypeScript symbols and public API changes, possible duplicate implementations, single-implementation abstractions, import-graph impact, and related test changes.
|
|
125
|
+
|
|
126
|
+
### Git and reporting
|
|
127
|
+
|
|
128
|
+
- Compare `HEAD` with the current working tree.
|
|
129
|
+
- Compare two Git references or branches from their merge base.
|
|
130
|
+
- Classify added, modified, deleted, and renamed files.
|
|
131
|
+
- Count added and deleted lines per file.
|
|
132
|
+
- Distinguish binary files.
|
|
133
|
+
- Include untracked files in working-tree analysis.
|
|
134
|
+
- Render terminal-friendly text and machine-readable JSON reports.
|
|
135
|
+
- Generate a standalone HTML report containing summary cards, findings, test signals, and an impact graph.
|
|
136
|
+
- Render the visualization with inline CSS and SVG, without a CDN or runtime JavaScript dependency.
|
|
137
|
+
- Aggregate findings by `high`, `medium`, and `low` severity.
|
|
138
|
+
- Return a CI-friendly exit code through `--fail-on`.
|
|
139
|
+
- Print the installed package version through `--version`.
|
|
140
|
+
|
|
141
|
+
### Dependencies and TypeScript structure
|
|
142
|
+
|
|
143
|
+
- Detect additions to production and development dependencies.
|
|
144
|
+
- Detect dependency removal, version changes, and section moves.
|
|
145
|
+
- Report malformed `package.json` files as evidence-backed findings instead of crashing.
|
|
146
|
+
- Extract top-level named functions, classes, interfaces, and type aliases from `.ts` and `.tsx` files.
|
|
147
|
+
- Detect symbol additions, modifications, and removals with source locations.
|
|
148
|
+
- Preserve direct exports, local export lists, and external re-exports as public-symbol evidence.
|
|
149
|
+
- Report removed public symbols and removed exports as high-severity compatibility risks.
|
|
150
|
+
- Detect removed public function call signatures and incompatible public interface changes.
|
|
151
|
+
- Exclude overloads that only gain an implementation while reporting previously available overloads that disappear.
|
|
152
|
+
- Find newly added functions whose normalized implementation matches an existing function.
|
|
153
|
+
- Report a newly added interface when exactly one class explicitly implements it.
|
|
154
|
+
- Compare symbols correctly across renamed files.
|
|
155
|
+
- Preserve syntax errors as analysis evidence instead of silently dropping a file.
|
|
156
|
+
|
|
157
|
+
### Impact, scope, and tests
|
|
158
|
+
|
|
159
|
+
- Build relative static import and re-export relationships for `.ts` and `.tsx` files.
|
|
160
|
+
- Resolve `.js`, `.jsx`, `.mjs`, and `.cjs` import specifiers to matching TypeScript sources.
|
|
161
|
+
- Calculate direct importers and transitively impacted files for changed modules.
|
|
162
|
+
- Preserve unresolved relative imports and file read or parse failures as evidence.
|
|
163
|
+
- Build the graph at the same result point as the diff: the working tree or the selected head ref.
|
|
164
|
+
- Read intent, expected paths, allowed paths, and change budgets from `.intentpatch.json`.
|
|
165
|
+
- Report each file outside expected and allowed patterns as a medium-severity finding.
|
|
166
|
+
- Report file-count and measurable-line budget overruns with numeric evidence.
|
|
167
|
+
- Classify source and test paths declared by the contract and connect related changes by basename.
|
|
168
|
+
- Report test file counts and added or deleted tests as separate facts.
|
|
169
|
+
- Report source files without a related test change as medium-severity findings.
|
|
170
|
+
- Support repository-relative `*`, `**`, and `?` path patterns.
|
|
171
|
+
|
|
172
|
+
Lockfile transitive dependency analysis, path aliases, JavaScript and method-level structure analysis, and optional AI review are not implemented yet.
|
|
173
|
+
|
|
174
|
+
## CLI usage
|
|
175
|
+
|
|
176
|
+
Analyze the current repository's working tree:
|
|
181
177
|
|
|
182
178
|
```bash
|
|
183
179
|
node dist/presentation/cli/main.js analyze
|
|
184
180
|
```
|
|
185
181
|
|
|
186
|
-
|
|
182
|
+
Analyze another Git repository:
|
|
187
183
|
|
|
188
184
|
```bash
|
|
189
185
|
node dist/presentation/cli/main.js analyze --cwd /path/to/repository
|
|
190
186
|
```
|
|
191
187
|
|
|
192
|
-
|
|
188
|
+
Compare two branches. IntentPatch analyzes their changes from the merge base:
|
|
193
189
|
|
|
194
190
|
```bash
|
|
195
191
|
node dist/presentation/cli/main.js analyze \
|
|
@@ -198,13 +194,13 @@ node dist/presentation/cli/main.js analyze \
|
|
|
198
194
|
--head feature/account-deletion
|
|
199
195
|
```
|
|
200
196
|
|
|
201
|
-
JSON
|
|
197
|
+
Write JSON output:
|
|
202
198
|
|
|
203
199
|
```bash
|
|
204
200
|
node dist/presentation/cli/main.js analyze --json
|
|
205
201
|
```
|
|
206
202
|
|
|
207
|
-
|
|
203
|
+
Create a standalone HTML report:
|
|
208
204
|
|
|
209
205
|
```bash
|
|
210
206
|
node dist/presentation/cli/main.js analyze \
|
|
@@ -212,18 +208,15 @@ node dist/presentation/cli/main.js analyze \
|
|
|
212
208
|
--output intentpatch-report.html
|
|
213
209
|
```
|
|
214
210
|
|
|
215
|
-
HTML
|
|
216
|
-
바로 열 수 있습니다. `--output`은 텍스트와 JSON 형식에도 사용할 수 있으며 상대 경로는
|
|
217
|
-
IntentPatch를 실행한 현재 디렉터리를 기준으로 해석합니다. 기존 `--json`은
|
|
218
|
-
`--format json`의 단축 옵션입니다.
|
|
211
|
+
The HTML file contains all styles and the dependency-impact SVG, so it opens directly without a server or API key. `--output` also works with text and JSON formats. Relative output paths are resolved from the directory where IntentPatch is executed. `--json` is an alias for `--format json`.
|
|
219
212
|
|
|
220
|
-
###
|
|
213
|
+
### Check request scope with a Change Contract
|
|
221
214
|
|
|
222
|
-
|
|
215
|
+
Create `.intentpatch.json` in the repository being analyzed and declare the expected scope of the request:
|
|
223
216
|
|
|
224
217
|
```json
|
|
225
218
|
{
|
|
226
|
-
"intent": "
|
|
219
|
+
"intent": "Implement account deletion",
|
|
227
220
|
"scope": {
|
|
228
221
|
"include": ["src/user/**", "tests/user/**"],
|
|
229
222
|
"allow": ["package.json", "package-lock.json"],
|
|
@@ -238,19 +231,17 @@ IntentPatch를 실행한 현재 디렉터리를 기준으로 해석합니다.
|
|
|
238
231
|
}
|
|
239
232
|
```
|
|
240
233
|
|
|
241
|
-
- `include`:
|
|
242
|
-
- `allow`:
|
|
243
|
-
- `maxFiles`:
|
|
244
|
-
- `maxLines`:
|
|
245
|
-
- `tests.requireFor`:
|
|
246
|
-
- `tests.include`:
|
|
247
|
-
- `tests.exclude`:
|
|
234
|
+
- `include`: paths expected to change for the request;
|
|
235
|
+
- `allow`: exceptional paths such as configuration or lockfiles;
|
|
236
|
+
- `maxFiles`: maximum number of changed files;
|
|
237
|
+
- `maxLines`: maximum total of measurable added and deleted lines;
|
|
238
|
+
- `tests.requireFor`: source paths that require a related test change;
|
|
239
|
+
- `tests.include`: paths classified as tests;
|
|
240
|
+
- `tests.exclude`: generated or declaration files excluded from the source check.
|
|
248
241
|
|
|
249
|
-
|
|
250
|
-
`tests/user.test.ts`, `user.spec.ts`, `user.integration.test.ts` 같은 변경과 연결됩니다.
|
|
242
|
+
Test matching uses basenames for deterministic results. For example, `src/user.ts` can match changed files such as `tests/user.test.ts`, `user.spec.ts`, or `user.integration.test.ts`.
|
|
251
243
|
|
|
252
|
-
|
|
253
|
-
해석합니다.
|
|
244
|
+
Use `--config` to select another contract. Relative paths are resolved from `--cwd`:
|
|
254
245
|
|
|
255
246
|
```bash
|
|
256
247
|
node dist/presentation/cli/main.js analyze \
|
|
@@ -258,19 +249,19 @@ node dist/presentation/cli/main.js analyze \
|
|
|
258
249
|
--config contracts/delete-user.json
|
|
259
250
|
```
|
|
260
251
|
|
|
261
|
-
|
|
262
|
-
|
|
252
|
+
Start with [`.intentpatch.example.json`](./.intentpatch.example.json). Without a contract, all existing analysis still runs and only the scope rules are disabled.
|
|
253
|
+
|
|
254
|
+
### Quality gates
|
|
263
255
|
|
|
264
|
-
|
|
256
|
+
Return exit code `1` after rendering the report when a finding meets or exceeds the selected severity:
|
|
265
257
|
|
|
266
258
|
```bash
|
|
267
259
|
node dist/presentation/cli/main.js analyze --fail-on medium
|
|
268
260
|
```
|
|
269
261
|
|
|
270
|
-
`medium
|
|
271
|
-
게이트 대상으로 취급합니다. 잘못된 CLI 사용은 종료 코드 `2`를 반환합니다.
|
|
262
|
+
`medium` reacts to both medium- and high-severity findings. `low` treats every finding as a quality-gate failure. Invalid CLI usage returns exit code `2`.
|
|
272
263
|
|
|
273
|
-
|
|
264
|
+
An evidence-rich result looks like this:
|
|
274
265
|
|
|
275
266
|
```text
|
|
276
267
|
IntentPatch Change Report
|
|
@@ -328,16 +319,15 @@ LOW New interface has one implementation
|
|
|
328
319
|
The new interface DeletionStrategy is implemented only by DefaultDeletionStrategy.
|
|
329
320
|
```
|
|
330
321
|
|
|
331
|
-
|
|
322
|
+
Run the TypeScript entry point directly during development:
|
|
332
323
|
|
|
333
324
|
```bash
|
|
334
325
|
npm run dev -- analyze --cwd /path/to/repository
|
|
335
326
|
```
|
|
336
327
|
|
|
337
|
-
##
|
|
328
|
+
## Architecture
|
|
338
329
|
|
|
339
|
-
|
|
340
|
-
방향을 적용했습니다.
|
|
330
|
+
IntentPatch applies Clean Architecture dependency direction so Git, presentation, and analysis rules do not become tightly coupled as the project grows.
|
|
341
331
|
|
|
342
332
|
```text
|
|
343
333
|
presentation ───────▶ application ───────▶ domain
|
|
@@ -345,109 +335,103 @@ presentation ───────▶ application ───────▶ domai
|
|
|
345
335
|
└──▶ infrastructure ──┘
|
|
346
336
|
```
|
|
347
337
|
|
|
348
|
-
|
|
|
338
|
+
| Layer | Responsibility |
|
|
349
339
|
| --- | --- |
|
|
350
|
-
| `domain` |
|
|
351
|
-
| `application` |
|
|
352
|
-
| `infrastructure` | Git
|
|
353
|
-
| `presentation` | CLI
|
|
340
|
+
| `domain` | Core models for changed files, Change Contracts, findings, symbol changes, and dependency impact |
|
|
341
|
+
| `application` | Analysis use cases, rule engine, symbol and impact calculations, and ports for external data |
|
|
342
|
+
| `infrastructure` | Git commands, diff parsing, project-file access, and TypeScript AST parsing |
|
|
343
|
+
| `presentation` | CLI argument handling, dependency composition, and text, JSON, and HTML output |
|
|
354
344
|
|
|
355
|
-
|
|
356
|
-
구현상의 주요 판단과 확장 지점은 [상세 아키텍처 문서](./docs/architecture.md)에서 설명합니다.
|
|
345
|
+
Architecture tests enforce the import direction so inner layers never depend on external implementations. See the [architecture document](./docs/architecture.md) for design decisions and extension points.
|
|
357
346
|
|
|
358
|
-
##
|
|
347
|
+
## Design principles
|
|
359
348
|
|
|
360
|
-
- **Deterministic first:**
|
|
361
|
-
- **Evidence over claims:**
|
|
362
|
-
- **LLM optional:**
|
|
363
|
-
- **Dependency minimalism:**
|
|
364
|
-
- **Explicit boundaries:**
|
|
349
|
+
- **Deterministic first:** the same input produces the same core analysis result.
|
|
350
|
+
- **Evidence over claims:** uncertain signals are not presented as facts.
|
|
351
|
+
- **LLM optional:** useful analysis remains available without an AI provider.
|
|
352
|
+
- **Dependency minimalism:** convenience alone does not justify another library.
|
|
353
|
+
- **Explicit boundaries:** domain logic stays separate from external details such as Git and CLI frameworks.
|
|
365
354
|
|
|
366
|
-
##
|
|
355
|
+
## Testing and quality checks
|
|
367
356
|
|
|
368
357
|
```bash
|
|
369
358
|
npm run check
|
|
370
359
|
```
|
|
371
360
|
|
|
372
|
-
|
|
361
|
+
This command runs:
|
|
373
362
|
|
|
374
|
-
-
|
|
375
|
-
- Biome
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
379
|
-
-
|
|
363
|
+
- strict TypeScript type checking;
|
|
364
|
+
- Biome lint and format checks;
|
|
365
|
+
- domain and use-case unit tests;
|
|
366
|
+
- integration tests against real temporary Git repositories;
|
|
367
|
+
- a package integration test that installs the generated npm tarball in a temporary project and executes it;
|
|
368
|
+
- architecture tests that enforce dependency direction;
|
|
369
|
+
- a reproducibility check for the bundled GitHub Action.
|
|
380
370
|
|
|
381
|
-
|
|
371
|
+
Run only the production build with:
|
|
382
372
|
|
|
383
373
|
```bash
|
|
384
374
|
npm run build
|
|
385
375
|
```
|
|
386
376
|
|
|
387
|
-
|
|
377
|
+
Inspect the files that would be published without creating a public release:
|
|
388
378
|
|
|
389
379
|
```bash
|
|
390
380
|
npm pack --dry-run
|
|
391
381
|
```
|
|
392
382
|
|
|
393
|
-
##
|
|
394
|
-
|
|
395
|
-
1.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
-
|
|
423
|
-
|
|
424
|
-
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
-
|
|
428
|
-
|
|
429
|
-
-
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
|
|
433
|
-
-
|
|
434
|
-
|
|
435
|
-
-
|
|
436
|
-
|
|
437
|
-
-
|
|
438
|
-
- IntentPatch
|
|
439
|
-
|
|
440
|
-
-
|
|
441
|
-
|
|
442
|
-
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
- 관련 테스트는 현재 소스와 테스트의 파일명이 같은지로 판단하므로 이름이 다른 통합 테스트나
|
|
447
|
-
하나의 테스트가 여러 소스를 검증하는 관계는 자동으로 연결하지 못합니다.
|
|
448
|
-
- HTML 영향 그래프는 변경 모듈과 영향 파일을 결정적인 두 열 레이아웃으로 표시합니다. 노드 이동,
|
|
449
|
-
확대·축소와 필터링을 제공하는 대화형 웹 UI는 아직 구현하지 않았습니다.
|
|
450
|
-
|
|
451
|
-
## 라이선스
|
|
383
|
+
## Release process
|
|
384
|
+
|
|
385
|
+
Pushing a tag such as `v0.1.0`, matching the version in `package.json`, from a commit contained in the default branch triggers the release workflow:
|
|
386
|
+
|
|
387
|
+
1. Validate the tag, package version, and default-branch ancestry.
|
|
388
|
+
2. Run the full quality suite and inspect the npm package with a dry run.
|
|
389
|
+
3. Publish through npm Trusted Publishing with OpenID Connect.
|
|
390
|
+
4. Create a GitHub Release with automatically generated notes.
|
|
391
|
+
|
|
392
|
+
No long-lived npm token is stored as a GitHub secret. Public packages published through OIDC receive npm provenance automatically. A package that does not yet exist on npm needs a one-time bootstrap before a Trusted Publisher can be configured. See the [release operations guide](./docs/releasing.md) for bootstrap and subsequent release procedures.
|
|
393
|
+
|
|
394
|
+
## Roadmap
|
|
395
|
+
|
|
396
|
+
1. ✅ Direct `package.json` dependency detection and rule engine
|
|
397
|
+
2. ✅ TypeScript AST analysis for functions, classes, interfaces, and types
|
|
398
|
+
3. ✅ Relative static import graph and change-impact calculation
|
|
399
|
+
4. ✅ Change Contract scope and change-budget analysis
|
|
400
|
+
5. ✅ Contract-based detection of missing related test changes
|
|
401
|
+
6. Package-manager adapters for lockfiles and workspaces
|
|
402
|
+
7. ✅ Detection of removed public exports
|
|
403
|
+
8. ✅ Standalone HTML dashboard and SVG dependency-impact graph
|
|
404
|
+
9. ✅ Re-export and function/interface compatibility checks plus possible code duplication
|
|
405
|
+
10. ✅ Detection of newly introduced single-implementation interfaces
|
|
406
|
+
11. ✅ GitHub Action with PR/push comparison, Job Summary, annotations, and artifacts
|
|
407
|
+
12. Codex, Claude Code, and Cursor adapters
|
|
408
|
+
13. Optional LLM explanations grounded in deterministic evidence
|
|
409
|
+
|
|
410
|
+
## Current limitations
|
|
411
|
+
|
|
412
|
+
- The target must be a Git repository with at least one commit.
|
|
413
|
+
- Untracked symbolic links are not read for safety.
|
|
414
|
+
- Line counts are skipped for untracked files larger than 10 MiB.
|
|
415
|
+
- Dependency analysis covers only `dependencies` and `devDependencies` in the root npm `package.json`.
|
|
416
|
+
- Transitive lockfile dependencies, workspace packages, and real dependency usage in source code are not analyzed yet.
|
|
417
|
+
- Symbol analysis supports named top-level functions, classes, interfaces, and type aliases in `.ts` and `.tsx` files.
|
|
418
|
+
- Public API analysis supports named top-level functions and interfaces, local `export { name }`, external `export { name } from`, and `export * from`. Package `exports`, anonymous default exports, and detailed class or type-alias contracts are not interpreted yet.
|
|
419
|
+
- Function compatibility compares explicitly written parameter and return-type text. It does not evaluate inferred return types or full TypeScript structural assignability.
|
|
420
|
+
- Duplicate candidates require a newly added top-level function and an existing top-level function to have exactly the same normalized tokens after comments and whitespace are removed, with at least 12 body tokens. Renamed identifiers, methods, and semantically equivalent implementations are not detected.
|
|
421
|
+
- A single-implementation abstraction is reported only when exactly one named class explicitly uses `implements` for a new interface. Structural implementation, factory return types, and runtime registration are not calculated.
|
|
422
|
+
- Methods, variable declarations, enums, nested declarations, and JavaScript files are not included in symbol analysis.
|
|
423
|
+
- Formatting or comment changes inside a declaration can be counted as symbol modifications.
|
|
424
|
+
- Impact analysis covers relative static `import`, side-effect imports, `export ... from`, and `import = require()` in `.ts` and `.tsx` files.
|
|
425
|
+
- External package imports, path aliases, dynamic `import()`, and ordinary `require()` are not included in the graph.
|
|
426
|
+
- The graph is built from files at the comparison result point: the working tree or head ref. Impact from historical imports that referenced a deleted module cannot be calculated yet.
|
|
427
|
+
- Source files used for impact analysis are limited to 1 MiB per file, and symbolic links are not read.
|
|
428
|
+
- IntentPatch does not infer expected paths from natural-language intent. Scope decisions use the contract's explicit `include` and `allow` patterns.
|
|
429
|
+
- Path patterns support only repository-relative `*`, `**`, and `?`; negation and brace expansion are not supported.
|
|
430
|
+
- `maxLines` sums only measurable added and deleted lines in text files. Binary or unmeasurable files are not treated as zero lines, but their size is not included in the budget.
|
|
431
|
+
- Test analysis compares only the changed paths declared in the contract; it does not execute tests or measure coverage.
|
|
432
|
+
- Related tests are matched by basename. Integration tests with different names or one test covering several source files cannot be linked automatically yet.
|
|
433
|
+
- The HTML impact graph uses a deterministic two-column layout. Interactive node movement, zooming, and filtering are not implemented yet.
|
|
434
|
+
|
|
435
|
+
## License
|
|
452
436
|
|
|
453
437
|
[MIT](./LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intentpatch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Evidence-based change scope analysis for AI-authored code patches.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,10 +21,14 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"README.md",
|
|
24
|
+
"README.ko.md",
|
|
24
25
|
"LICENSE"
|
|
25
26
|
],
|
|
26
27
|
"bin": {
|
|
27
|
-
"intentpatch": "
|
|
28
|
+
"intentpatch": "dist/presentation/cli/main.js"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
28
32
|
},
|
|
29
33
|
"scripts": {
|
|
30
34
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -35,7 +39,8 @@
|
|
|
35
39
|
"lint": "biome check .",
|
|
36
40
|
"lint:fix": "biome check --write .",
|
|
37
41
|
"prepack": "npm run build",
|
|
38
|
-
"
|
|
42
|
+
"release:verify": "node scripts/verify-release.mjs",
|
|
43
|
+
"test": "node --import tsx --test tests/**/*.test.ts tests/**/*.test.mjs",
|
|
39
44
|
"test:watch": "node --import tsx --test --watch tests/**/*.test.ts",
|
|
40
45
|
"typecheck": "tsc --noEmit"
|
|
41
46
|
},
|