difit 3.1.8 → 3.1.10
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.ja.md +31 -14
- package/README.ko.md +31 -14
- package/README.md +31 -14
- package/README.zh.md +31 -14
- package/dist/cli/index.js +55 -40
- package/dist/cli/index.test.js +114 -56
- package/dist/cli/utils.d.ts +14 -4
- package/dist/cli/utils.js +40 -98
- package/dist/cli/utils.test.js +99 -1
- package/dist/client/assets/{index-C3dUtNTw.js → index-CH5h4Jfu.js} +40 -40
- package/dist/client/assets/{prism-csharp-CBHytnk2.js → prism-csharp-omuTcU4j.js} +1 -1
- package/dist/client/assets/{prism-hcl-Dg0qCBz9.js → prism-hcl-BVGrHlPv.js} +1 -1
- package/dist/client/assets/{prism-java-qbAyqoLL.js → prism-java-BjHLe7qM.js} +1 -1
- package/dist/client/assets/{prism-perl-C5wGhuJd.js → prism-perl-Cl4F-f2r.js} +1 -1
- package/dist/client/assets/{prism-php-BAMztFi0.js → prism-php-BbsdsICU.js} +1 -1
- package/dist/client/assets/{prism-ruby-BVXH3cUk.js → prism-ruby-CSLiFfIy.js} +1 -1
- package/dist/client/assets/{prism-solidity-DLMGfXyj.js → prism-solidity-C3yStBME.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/server/git-diff.js +38 -22
- package/dist/server/server.d.ts +1 -0
- package/dist/server/server.js +16 -10
- package/dist/server/server.test.js +76 -0
- package/dist/tui/App.js +7 -10
- package/dist/tui/components/SideBySideDiffViewer.js +8 -8
- package/dist/tui/components/StatusBar.js +1 -5
- package/dist/utils/commentFormatting.js +1 -3
- package/package.json +9 -19
package/README.ja.md
CHANGED
|
@@ -32,7 +32,6 @@ difit # 最新コミットのdiffをWebUIで表示
|
|
|
32
32
|
```bash
|
|
33
33
|
difit <target> # 単一コミットのdiffを表示
|
|
34
34
|
difit <target> [compare-with] # 2つのコミット/ブランチを比較
|
|
35
|
-
difit --pr <github-pr-url> # GitHubプルリクエストをレビュー
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
### 単一コミットのレビュー
|
|
@@ -67,19 +66,19 @@ difit working # 未ステージ差分のみ
|
|
|
67
66
|
difit --pr https://github.com/owner/repo/pull/123
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
`--pr` モードでは、内部で `gh pr diff --patch` を実行してパッチを取得します。
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
認証は GitHub CLI が処理します:
|
|
72
|
+
|
|
73
|
+
1. **一度ログイン**(推奨):`gh auth login`
|
|
74
|
+
2. **トークン認証**(CI/非対話環境):`GH_TOKEN` または `GITHUB_TOKEN` を設定
|
|
75
75
|
|
|
76
76
|
#### GitHub Enterprise Server
|
|
77
77
|
|
|
78
|
-
Enterprise ServerのPR
|
|
78
|
+
Enterprise Server の PR を表示する場合は、GitHub CLI を Enterprise ホスト向けに認証してください:
|
|
79
79
|
|
|
80
|
-
1. `
|
|
81
|
-
2.
|
|
82
|
-
3. `GITHUB_TOKEN`環境変数として設定
|
|
80
|
+
1. `gh auth login --hostname YOUR-ENTERPRISE-SERVER`
|
|
81
|
+
2. または `GH_HOST=YOUR-ENTERPRISE-SERVER` と `GH_TOKEN` / `GITHUB_TOKEN` を設定
|
|
83
82
|
|
|
84
83
|
### 標準入力
|
|
85
84
|
|
|
@@ -97,8 +96,17 @@ git diff --merge-base main feature | difit
|
|
|
97
96
|
|
|
98
97
|
# 既存ファイル全体を新規追加として確認
|
|
99
98
|
git diff -- /dev/null path/to/file | difit
|
|
99
|
+
|
|
100
|
+
# 明示的に標準入力モードを使う
|
|
101
|
+
git diff --cached | difit -
|
|
100
102
|
```
|
|
101
103
|
|
|
104
|
+
標準入力モードは、意図を優先して次のルールで選択されます。
|
|
105
|
+
|
|
106
|
+
- `-` を指定した場合は常に標準入力モード
|
|
107
|
+
- positional 引数(`<target>` / `[compare-with]`)、`--pr`、`--tui` のいずれかがある場合は Git/PR/TUI モードとして扱い、標準入力を自動読み取りしない
|
|
108
|
+
- 明示モード指定がない場合のみ、stdin が pipe/file/socket のときに自動で標準入力モードになる
|
|
109
|
+
|
|
102
110
|
## ⚙️ CLIオプション
|
|
103
111
|
|
|
104
112
|
| フラグ | デフォルト | 説明 |
|
|
@@ -113,6 +121,7 @@ git diff -- /dev/null path/to/file | difit
|
|
|
113
121
|
| `--tui` | false | WebUIの代わりにターミナルUIを使用 |
|
|
114
122
|
| `--clean` | false | 起動時に既存コメントと閲覧済みファイルをすべてクリア |
|
|
115
123
|
| `--include-untracked` | false | diffにuntrackedファイルを自動的に含める(`.`または`working`のみ有効) |
|
|
124
|
+
| `--keep-alive` | false | ブラウザ切断後もサーバーを終了せず起動したままにする(Ctrl+Cで手動停止) |
|
|
116
125
|
|
|
117
126
|
## 💬 コメントシステム
|
|
118
127
|
|
|
@@ -138,6 +147,14 @@ src/components/Button.tsx:L42-L48 # この行が自動的に追加されます
|
|
|
138
147
|
この部分は不要です
|
|
139
148
|
```
|
|
140
149
|
|
|
150
|
+
## 🤖 エージェントからの呼び出し
|
|
151
|
+
|
|
152
|
+
difitを利用してユーザーにレビューを依頼するSkillを以下でインストールできます
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
npx skills add yoshiko-pg/difit
|
|
156
|
+
```
|
|
157
|
+
|
|
141
158
|
## 🎨 シンタックスハイライト対応言語
|
|
142
159
|
|
|
143
160
|
- **JavaScript/TypeScript**:`.js`, `.jsx`, `.ts`, `.tsx`
|
|
@@ -193,10 +210,9 @@ pnpm run build
|
|
|
193
210
|
# テストの実行
|
|
194
211
|
pnpm test
|
|
195
212
|
|
|
196
|
-
#
|
|
197
|
-
pnpm run
|
|
213
|
+
# 型チェックとlintとフォーマット
|
|
214
|
+
pnpm run check
|
|
198
215
|
pnpm run format
|
|
199
|
-
pnpm run typecheck
|
|
200
216
|
```
|
|
201
217
|
|
|
202
218
|
### 開発ワークフロー
|
|
@@ -210,17 +226,18 @@ pnpm run typecheck
|
|
|
210
226
|
|
|
211
227
|
- **CLI**:包括的なバリデーションを備えたCommander.jsでの引数解析
|
|
212
228
|
- **バックエンド**:diff処理用のsimple-gitを備えたExpressサーバー
|
|
213
|
-
- **GitHub
|
|
229
|
+
- **GitHub統合**:GitHub CLI(`gh pr diff --patch`)によるPRパッチ取得
|
|
214
230
|
- **フロントエンド**:React 18 + TypeScript + Vite
|
|
215
231
|
- **スタイリング**:GitHubライクなダークテーマを備えたTailwind CSS v4
|
|
216
232
|
- **シンタックスハイライト**:動的言語ロードを備えたPrism.js
|
|
217
233
|
- **テスト**:同じ場所に配置されたテストファイルを使用したVitestユニットテスト
|
|
218
|
-
- **品質**:
|
|
234
|
+
- **品質**:Oxlint、Biome、lefthookプリコミットフック
|
|
219
235
|
|
|
220
236
|
## 📋 要件
|
|
221
237
|
|
|
222
238
|
- Node.js ≥ 21.0.0
|
|
223
239
|
- レビューするコミットを含むGitリポジトリ
|
|
240
|
+
- `--pr` モード利用時は GitHub CLI(`gh`)
|
|
224
241
|
|
|
225
242
|
## 📄 ライセンス
|
|
226
243
|
|
package/README.ko.md
CHANGED
|
@@ -32,7 +32,6 @@ difit # WebUI에서 최신 커밋 diff 보기
|
|
|
32
32
|
```bash
|
|
33
33
|
difit <target> # 단일 커밋 diff 보기
|
|
34
34
|
difit <target> [compare-with] # 두 커밋/브랜치 비교
|
|
35
|
-
difit --pr <github-pr-url> # GitHub 풀 리퀘스트 검토
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
### 단일 커밋 검토
|
|
@@ -67,19 +66,19 @@ difit working # 미스테이징 변경 사항만
|
|
|
67
66
|
difit --pr https://github.com/owner/repo/pull/123
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
`--pr` 모드는 내부적으로 `gh pr diff --patch`를 실행해 패치를 가져옵니다.
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
인증은 GitHub CLI가 처리합니다:
|
|
72
|
+
|
|
73
|
+
1. **한 번 로그인** (권장): `gh auth login`
|
|
74
|
+
2. **토큰 인증** (CI/비대화형 환경): `GH_TOKEN` 또는 `GITHUB_TOKEN` 설정
|
|
75
75
|
|
|
76
76
|
#### GitHub Enterprise Server
|
|
77
77
|
|
|
78
|
-
Enterprise Server PR의 경우
|
|
78
|
+
Enterprise Server PR의 경우 GitHub CLI를 Enterprise 호스트에 인증하세요:
|
|
79
79
|
|
|
80
|
-
1. `
|
|
81
|
-
2.
|
|
82
|
-
3. `GITHUB_TOKEN` 환경 변수로 설정
|
|
80
|
+
1. `gh auth login --hostname YOUR-ENTERPRISE-SERVER`
|
|
81
|
+
2. 또는 `GH_HOST=YOUR-ENTERPRISE-SERVER`와 `GH_TOKEN`/`GITHUB_TOKEN` 설정
|
|
83
82
|
|
|
84
83
|
### 표준 입력
|
|
85
84
|
|
|
@@ -97,8 +96,17 @@ git diff --merge-base main feature | difit
|
|
|
97
96
|
|
|
98
97
|
# 기존 파일 전체를 신규 추가처럼 검토
|
|
99
98
|
git diff -- /dev/null path/to/file | difit
|
|
99
|
+
|
|
100
|
+
# 명시적 표준 입력 모드
|
|
101
|
+
git diff --cached | difit -
|
|
100
102
|
```
|
|
101
103
|
|
|
104
|
+
표준 입력 모드는 의도 우선 규칙으로 선택됩니다:
|
|
105
|
+
|
|
106
|
+
- `-`를 지정하면 표준 입력 모드가 명시적으로 활성화됩니다
|
|
107
|
+
- positional 인수(`<target>` / `[compare-with]`), `--pr`, `--tui` 중 하나라도 지정되면 Git/PR/TUI 모드로 처리하고 stdin 자동 읽기를 하지 않습니다
|
|
108
|
+
- 명시적 모드 지정이 없고 stdin이 pipe/file/socket 인 경우에만 자동으로 표준 입력 모드가 됩니다
|
|
109
|
+
|
|
102
110
|
## ⚙️ CLI 옵션
|
|
103
111
|
|
|
104
112
|
| 플래그 | 기본값 | 설명 |
|
|
@@ -113,6 +121,7 @@ git diff -- /dev/null path/to/file | difit
|
|
|
113
121
|
| `--tui` | false | WebUI 대신 터미널 UI 모드 사용 |
|
|
114
122
|
| `--clean` | false | 시작 시 모든 기존 코멘트와 열람된 파일 표시 초기화 |
|
|
115
123
|
| `--include-untracked` | false | diff에 untracked 파일 자동 포함 (`.` 또는 `working`에서만 유효) |
|
|
124
|
+
| `--keep-alive` | false | 브라우저 연결이 끊겨도 서버 유지 (Ctrl+C로 수동 종료) |
|
|
116
125
|
|
|
117
126
|
## 💬 코멘트 시스템
|
|
118
127
|
|
|
@@ -138,6 +147,14 @@ src/components/Button.tsx:L42-L48 # 이 줄은 자동으로 추가됩니다
|
|
|
138
147
|
이 부분은 불필요합니다
|
|
139
148
|
```
|
|
140
149
|
|
|
150
|
+
## 🤖 에이전트에서 호출
|
|
151
|
+
|
|
152
|
+
difit을 사용해 사용자에게 리뷰를 요청하는 Skill은 아래 명령으로 설치할 수 있습니다:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
npx skills add yoshiko-pg/difit
|
|
156
|
+
```
|
|
157
|
+
|
|
141
158
|
## 🎨 구문 강조 언어
|
|
142
159
|
|
|
143
160
|
- **JavaScript/TypeScript**: `.js`, `.jsx`, `.ts`, `.tsx`
|
|
@@ -193,10 +210,9 @@ pnpm run build
|
|
|
193
210
|
# 테스트 실행
|
|
194
211
|
pnpm test
|
|
195
212
|
|
|
196
|
-
#
|
|
197
|
-
pnpm run
|
|
213
|
+
# 타입체크와 lint와 포맷
|
|
214
|
+
pnpm run check
|
|
198
215
|
pnpm run format
|
|
199
|
-
pnpm run typecheck
|
|
200
216
|
```
|
|
201
217
|
|
|
202
218
|
### 개발 워크플로우
|
|
@@ -210,17 +226,18 @@ pnpm run typecheck
|
|
|
210
226
|
|
|
211
227
|
- **CLI**: 포괄적인 검증을 갖춘 Commander.js로 인수 구문 분석
|
|
212
228
|
- **백엔드**: diff 처리를 위한 simple-git이 포함된 Express 서버
|
|
213
|
-
- **GitHub 통합**:
|
|
229
|
+
- **GitHub 통합**: GitHub CLI(`gh pr diff --patch`) 기반 PR 패치 조회
|
|
214
230
|
- **프론트엔드**: React 18 + TypeScript + Vite
|
|
215
231
|
- **스타일링**: GitHub과 유사한 다크 테마를 갖춘 Tailwind CSS v4
|
|
216
232
|
- **구문 강조**: 동적 언어 로딩을 갖춘 Prism.js
|
|
217
233
|
- **테스트**: 동일 위치에 배치된 테스트 파일을 사용하는 Vitest 단위 테스트
|
|
218
|
-
- **품질**:
|
|
234
|
+
- **품질**: Oxlint, Biome, lefthook 사전 커밋 훅
|
|
219
235
|
|
|
220
236
|
## 📋 요구 사항
|
|
221
237
|
|
|
222
238
|
- Node.js ≥ 21.0.0
|
|
223
239
|
- 검토할 커밋이 포함된 Git 저장소
|
|
240
|
+
- `--pr` 모드 사용 시 GitHub CLI(`gh`)
|
|
224
241
|
|
|
225
242
|
## 📄 라이선스
|
|
226
243
|
|
package/README.md
CHANGED
|
@@ -32,7 +32,6 @@ difit # View the latest commit diff in WebUI
|
|
|
32
32
|
```bash
|
|
33
33
|
difit <target> # View single commit diff
|
|
34
34
|
difit <target> [compare-with] # Compare two commits/branches
|
|
35
|
-
difit --pr <github-pr-url> # Review GitHub pull request
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
### Single commit review
|
|
@@ -67,19 +66,19 @@ difit working # Unstaged changes only
|
|
|
67
66
|
difit --pr https://github.com/owner/repo/pull/123
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
`--pr` mode fetches patches by running `gh pr diff --patch` under the hood.
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
Authentication is handled by GitHub CLI:
|
|
72
|
+
|
|
73
|
+
1. **Login once** (recommended): `gh auth login`
|
|
74
|
+
2. **Token-based auth** (CI/non-interactive): set `GH_TOKEN` or `GITHUB_TOKEN`
|
|
75
75
|
|
|
76
76
|
#### GitHub Enterprise Server
|
|
77
77
|
|
|
78
|
-
For Enterprise Server PRs,
|
|
78
|
+
For Enterprise Server PRs, authenticate GitHub CLI against your Enterprise host:
|
|
79
79
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
82
|
-
3. Set it as `GITHUB_TOKEN` environment variable
|
|
80
|
+
1. `gh auth login --hostname YOUR-ENTERPRISE-SERVER`
|
|
81
|
+
2. Or set `GH_HOST=YOUR-ENTERPRISE-SERVER` with `GH_TOKEN`/`GITHUB_TOKEN`
|
|
83
82
|
|
|
84
83
|
### Stdin
|
|
85
84
|
|
|
@@ -97,8 +96,17 @@ git diff --merge-base main feature | difit
|
|
|
97
96
|
|
|
98
97
|
# Review an entire existing file as newly added
|
|
99
98
|
git diff -- /dev/null path/to/file | difit
|
|
99
|
+
|
|
100
|
+
# Explicit stdin mode
|
|
101
|
+
git diff --cached | difit -
|
|
100
102
|
```
|
|
101
103
|
|
|
104
|
+
Stdin mode is selected with intent-first rules:
|
|
105
|
+
|
|
106
|
+
- `-` explicitly enables stdin mode
|
|
107
|
+
- If positional arguments (`<target>` / `[compare-with]`), `--pr`, or `--tui` are provided, difit treats the command as Git/PR/TUI mode and does not auto-read stdin
|
|
108
|
+
- Auto stdin detection applies only when no explicit mode is selected and stdin is a pipe/file/socket
|
|
109
|
+
|
|
102
110
|
## ⚙️ CLI Options
|
|
103
111
|
|
|
104
112
|
| Flag | Default | Description |
|
|
@@ -113,6 +121,7 @@ git diff -- /dev/null path/to/file | difit
|
|
|
113
121
|
| `--tui` | false | Use terminal UI mode instead of WebUI |
|
|
114
122
|
| `--clean` | false | Clear all existing comments and viewed files on startup |
|
|
115
123
|
| `--include-untracked` | false | Automatically include untracked files in diff (only with `.` or `working`) |
|
|
124
|
+
| `--keep-alive` | false | Keep server running after browser disconnects (stop manually with Ctrl+C) |
|
|
116
125
|
|
|
117
126
|
## 💬 Comment System
|
|
118
127
|
|
|
@@ -138,6 +147,14 @@ src/components/Button.tsx:L42-L48 # This line is automatically added
|
|
|
138
147
|
This section is unnecessary
|
|
139
148
|
```
|
|
140
149
|
|
|
150
|
+
## 🤖 Calling from Agents
|
|
151
|
+
|
|
152
|
+
You can install the following Skill to request reviews from users with difit:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
npx skills add yoshiko-pg/difit
|
|
156
|
+
```
|
|
157
|
+
|
|
141
158
|
## 🎨 Syntax Highlighting Languages
|
|
142
159
|
|
|
143
160
|
- **JavaScript/TypeScript**: `.js`, `.jsx`, `.ts`, `.tsx`
|
|
@@ -193,10 +210,9 @@ pnpm run build
|
|
|
193
210
|
# Run tests
|
|
194
211
|
pnpm test
|
|
195
212
|
|
|
196
|
-
#
|
|
197
|
-
pnpm run
|
|
213
|
+
# Run typecheck, lint, and format
|
|
214
|
+
pnpm run check
|
|
198
215
|
pnpm run format
|
|
199
|
-
pnpm run typecheck
|
|
200
216
|
```
|
|
201
217
|
|
|
202
218
|
### Development Workflow
|
|
@@ -210,17 +226,18 @@ pnpm run typecheck
|
|
|
210
226
|
|
|
211
227
|
- **CLI**: Commander.js for argument parsing with comprehensive validation
|
|
212
228
|
- **Backend**: Express server with simple-git for diff processing
|
|
213
|
-
- **GitHub Integration**:
|
|
229
|
+
- **GitHub Integration**: GitHub CLI (`gh pr diff --patch`) for PR patch retrieval
|
|
214
230
|
- **Frontend**: React 18 + TypeScript + Vite
|
|
215
231
|
- **Styling**: Tailwind CSS v4 with GitHub-like dark theme
|
|
216
232
|
- **Syntax Highlighting**: Prism.js with dynamic language loading
|
|
217
233
|
- **Testing**: Vitest for unit tests with co-located test files
|
|
218
|
-
- **Quality**:
|
|
234
|
+
- **Quality**: Oxlint, Biome, lefthook pre-commit hooks
|
|
219
235
|
|
|
220
236
|
## 📋 Requirements
|
|
221
237
|
|
|
222
238
|
- Node.js ≥ 21.0.0
|
|
223
239
|
- Git repository with commits to review
|
|
240
|
+
- GitHub CLI (`gh`) for `--pr` mode
|
|
224
241
|
|
|
225
242
|
## 📄 License
|
|
226
243
|
|
package/README.zh.md
CHANGED
|
@@ -32,7 +32,6 @@ difit # 在 WebUI 中查看最新提交的差异
|
|
|
32
32
|
```bash
|
|
33
33
|
difit <target> # 查看单个提交差异
|
|
34
34
|
difit <target> [compare-with] # 比较两个提交/分支
|
|
35
|
-
difit --pr <github-pr-url> # 审查 GitHub 拉取请求
|
|
36
35
|
```
|
|
37
36
|
|
|
38
37
|
### 单个提交审查
|
|
@@ -67,19 +66,19 @@ difit working # 仅未暂存的更改
|
|
|
67
66
|
difit --pr https://github.com/owner/repo/pull/123
|
|
68
67
|
```
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
`--pr` 模式会在内部执行 `gh pr diff --patch` 来获取补丁。
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
认证由 GitHub CLI 处理:
|
|
72
|
+
|
|
73
|
+
1. **先登录一次**(推荐):`gh auth login`
|
|
74
|
+
2. **令牌认证**(CI/非交互环境):设置 `GH_TOKEN` 或 `GITHUB_TOKEN`
|
|
75
75
|
|
|
76
76
|
#### GitHub Enterprise Server
|
|
77
77
|
|
|
78
|
-
对于 Enterprise Server PR
|
|
78
|
+
对于 Enterprise Server PR,请先让 GitHub CLI 认证到 Enterprise 主机:
|
|
79
79
|
|
|
80
|
-
1.
|
|
81
|
-
2.
|
|
82
|
-
3. 将其设置为 `GITHUB_TOKEN` 环境变量
|
|
80
|
+
1. `gh auth login --hostname YOUR-ENTERPRISE-SERVER`
|
|
81
|
+
2. 或设置 `GH_HOST=YOUR-ENTERPRISE-SERVER`,并配置 `GH_TOKEN` / `GITHUB_TOKEN`
|
|
83
82
|
|
|
84
83
|
### 标准输入
|
|
85
84
|
|
|
@@ -97,8 +96,17 @@ git diff --merge-base main feature | difit
|
|
|
97
96
|
|
|
98
97
|
# 将整个现有文件视为新添加进行审查
|
|
99
98
|
git diff -- /dev/null path/to/file | difit
|
|
99
|
+
|
|
100
|
+
# 显式标准输入模式
|
|
101
|
+
git diff --cached | difit -
|
|
100
102
|
```
|
|
101
103
|
|
|
104
|
+
标准输入模式按“意图优先”规则选择:
|
|
105
|
+
|
|
106
|
+
- `-` 会显式启用标准输入模式
|
|
107
|
+
- 当提供 positional 参数(`<target>` / `[compare-with]`)、`--pr` 或 `--tui` 时,difit 会按 Git/PR/TUI 模式处理,不会自动读取 stdin
|
|
108
|
+
- 只有在未显式选择模式且 stdin 为 pipe/file/socket 时,才会自动进入标准输入模式
|
|
109
|
+
|
|
102
110
|
## ⚙️ CLI 选项
|
|
103
111
|
|
|
104
112
|
| 标志 | 默认值 | 描述 |
|
|
@@ -113,6 +121,7 @@ git diff -- /dev/null path/to/file | difit
|
|
|
113
121
|
| `--tui` | false | 使用终端 UI 模式而不是 WebUI |
|
|
114
122
|
| `--clean` | false | 启动时清除所有现有评论和已查看的文件 |
|
|
115
123
|
| `--include-untracked` | false | 自动将 untracked 文件包含在 diff 中(仅在 `.` 或 `working` 时有效) |
|
|
124
|
+
| `--keep-alive` | false | 浏览器断开后保持服务器运行(使用 Ctrl+C 手动停止) |
|
|
116
125
|
|
|
117
126
|
## 💬 评论系统
|
|
118
127
|
|
|
@@ -138,6 +147,14 @@ src/components/Button.tsx:L42-L48 # 此行自动添加
|
|
|
138
147
|
此部分是不必要的
|
|
139
148
|
```
|
|
140
149
|
|
|
150
|
+
## 🤖 从代理调用
|
|
151
|
+
|
|
152
|
+
你可以通过以下命令安装 Skill,以便使用 difit 向用户请求审查:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
npx skills add yoshiko-pg/difit
|
|
156
|
+
```
|
|
157
|
+
|
|
141
158
|
## 🎨 语法高亮语言
|
|
142
159
|
|
|
143
160
|
- **JavaScript/TypeScript**:`.js`, `.jsx`, `.ts`, `.tsx`
|
|
@@ -193,10 +210,9 @@ pnpm run build
|
|
|
193
210
|
# 运行测试
|
|
194
211
|
pnpm test
|
|
195
212
|
|
|
196
|
-
#
|
|
197
|
-
pnpm run
|
|
213
|
+
# 运行 typecheck、lint 和格式化
|
|
214
|
+
pnpm run check
|
|
198
215
|
pnpm run format
|
|
199
|
-
pnpm run typecheck
|
|
200
216
|
```
|
|
201
217
|
|
|
202
218
|
### 开发工作流程
|
|
@@ -210,17 +226,18 @@ pnpm run typecheck
|
|
|
210
226
|
|
|
211
227
|
- **CLI**:使用 Commander.js 进行参数解析,具有全面的验证
|
|
212
228
|
- **后端**:Express 服务器配合 simple-git 进行差异处理
|
|
213
|
-
- **GitHub
|
|
229
|
+
- **GitHub 集成**:使用 GitHub CLI(`gh pr diff --patch`)获取 PR 补丁
|
|
214
230
|
- **前端**:React 18 + TypeScript + Vite
|
|
215
231
|
- **样式**:Tailwind CSS v4,带有类似 GitHub 的深色主题
|
|
216
232
|
- **语法高亮**:Prism.js 带动态语言加载
|
|
217
233
|
- **测试**:Vitest 用于单元测试,测试文件与源代码放在一起
|
|
218
|
-
- **质量**:
|
|
234
|
+
- **质量**:Oxlint、Biome、lefthook 预提交钩子
|
|
219
235
|
|
|
220
236
|
## 📋 要求
|
|
221
237
|
|
|
222
238
|
- Node.js ≥ 21.0.0
|
|
223
239
|
- 包含要审查的提交的 Git 仓库
|
|
240
|
+
- 使用 `--pr` 模式时需要 GitHub CLI(`gh`)
|
|
224
241
|
|
|
225
242
|
## 📄 许可证
|
|
226
243
|
|
package/dist/cli/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import pkg from '../../package.json' with { type: 'json' };
|
|
|
6
6
|
import { startServer } from '../server/server.js';
|
|
7
7
|
import { DiffMode } from '../types/watch.js';
|
|
8
8
|
import { DEFAULT_DIFF_VIEW_MODE, normalizeDiffViewMode } from '../utils/diffMode.js';
|
|
9
|
-
import { findUntrackedFiles, markFilesIntentToAdd, promptUser, validateDiffArguments,
|
|
9
|
+
import { shouldReadStdin, findUntrackedFiles, markFilesIntentToAdd, promptUser, validateDiffArguments, getPrPatch, getGitRoot, } from './utils.js';
|
|
10
10
|
function isSpecialArg(arg) {
|
|
11
11
|
return arg === 'working' || arg === 'staged' || arg === '.';
|
|
12
12
|
}
|
|
@@ -43,28 +43,62 @@ program
|
|
|
43
43
|
.option('--pr <url>', 'GitHub PR URL to review (e.g., https://github.com/owner/repo/pull/123)')
|
|
44
44
|
.option('--clean', 'start with a clean slate by clearing all existing comments')
|
|
45
45
|
.option('--include-untracked', 'automatically include untracked files in diff')
|
|
46
|
+
.option('--keep-alive', 'keep server running even after browser disconnects')
|
|
46
47
|
.action(async (commitish, compareWith, options) => {
|
|
47
48
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
let stdinDiff;
|
|
50
|
+
let stdinReviewLabel = 'diff from stdin';
|
|
51
|
+
if (options.pr) {
|
|
52
|
+
if (commitish !== 'HEAD' || compareWith) {
|
|
53
|
+
console.error('Error: --pr option cannot be used with positional arguments');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
if (options.tui) {
|
|
57
|
+
console.error('Error: --pr option cannot be used with --tui');
|
|
55
58
|
process.exit(1);
|
|
56
59
|
}
|
|
57
|
-
|
|
60
|
+
try {
|
|
61
|
+
stdinDiff = getPrPatch(options.pr);
|
|
62
|
+
stdinReviewLabel = options.pr;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error(`Error resolving PR: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Check if we should read from stdin
|
|
71
|
+
const readFromStdin = shouldReadStdin({
|
|
72
|
+
commitish,
|
|
73
|
+
hasPositionalArgs: program.args.length > 0,
|
|
74
|
+
hasPrOption: false,
|
|
75
|
+
hasTuiOption: Boolean(options.tui),
|
|
76
|
+
});
|
|
77
|
+
if (readFromStdin) {
|
|
78
|
+
// Read unified diff from stdin
|
|
79
|
+
stdinDiff = await readStdin();
|
|
80
|
+
if (!stdinDiff.trim()) {
|
|
81
|
+
console.error('Error: No diff content received from stdin');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (stdinDiff) {
|
|
87
|
+
// Start server with stdin diff (including --pr patch)
|
|
58
88
|
const { url } = await startServer({
|
|
59
|
-
stdinDiff
|
|
89
|
+
stdinDiff,
|
|
60
90
|
preferredPort: options.port,
|
|
61
91
|
host: options.host,
|
|
62
92
|
openBrowser: options.open,
|
|
63
93
|
mode: options.mode,
|
|
64
94
|
clearComments: options.clean,
|
|
95
|
+
keepAlive: options.keepAlive,
|
|
65
96
|
});
|
|
66
97
|
console.log(`\n🚀 difit server started on ${url}`);
|
|
67
|
-
console.log(`📋 Reviewing:
|
|
98
|
+
console.log(`📋 Reviewing: ${stdinReviewLabel}`);
|
|
99
|
+
if (options.keepAlive) {
|
|
100
|
+
console.log('🔒 Keep-alive mode: server will stay running after browser disconnects');
|
|
101
|
+
}
|
|
68
102
|
console.log('\nPress Ctrl+C to stop the server');
|
|
69
103
|
return;
|
|
70
104
|
}
|
|
@@ -80,26 +114,7 @@ program
|
|
|
80
114
|
// Determine target and base commitish
|
|
81
115
|
let targetCommitish = commitish;
|
|
82
116
|
let baseCommitish;
|
|
83
|
-
|
|
84
|
-
if (options.pr) {
|
|
85
|
-
if (commitish !== 'HEAD' || compareWith) {
|
|
86
|
-
console.error('Error: --pr option cannot be used with positional arguments');
|
|
87
|
-
process.exit(1);
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
const prCommits = await resolvePrCommits(options.pr);
|
|
91
|
-
targetCommitish = prCommits.targetCommitish;
|
|
92
|
-
baseCommitish = prCommits.baseCommitish;
|
|
93
|
-
console.log(`📋 Reviewing PR: ${options.pr}`);
|
|
94
|
-
console.log(`🎯 Target commit: ${targetCommitish.substring(0, 7)}`);
|
|
95
|
-
console.log(`📍 Base commit: ${baseCommitish.substring(0, 7)}`);
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
console.error(`Error resolving PR: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else if (compareWith) {
|
|
117
|
+
if (compareWith) {
|
|
103
118
|
// If compareWith is provided, use it as base
|
|
104
119
|
baseCommitish = compareWith;
|
|
105
120
|
}
|
|
@@ -138,15 +153,11 @@ program
|
|
|
138
153
|
}));
|
|
139
154
|
return;
|
|
140
155
|
}
|
|
141
|
-
|
|
142
|
-
if (!
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
console.error(`Error: ${validation.error}`);
|
|
146
|
-
process.exit(1);
|
|
147
|
-
}
|
|
156
|
+
const validation = validateDiffArguments(targetCommitish, compareWith);
|
|
157
|
+
if (!validation.valid) {
|
|
158
|
+
console.error(`Error: ${validation.error}`);
|
|
159
|
+
process.exit(1);
|
|
148
160
|
}
|
|
149
|
-
const diffMode = determineDiffMode(targetCommitish, compareWith);
|
|
150
161
|
const { url, port, isEmpty } = await startServer({
|
|
151
162
|
targetCommitish,
|
|
152
163
|
baseCommitish,
|
|
@@ -155,11 +166,15 @@ program
|
|
|
155
166
|
openBrowser: options.open,
|
|
156
167
|
mode: options.mode,
|
|
157
168
|
clearComments: options.clean,
|
|
158
|
-
|
|
169
|
+
keepAlive: options.keepAlive,
|
|
170
|
+
diffMode: determineDiffMode(targetCommitish, compareWith),
|
|
159
171
|
repoPath,
|
|
160
172
|
});
|
|
161
173
|
console.log(`\n🚀 difit server started on ${url}`);
|
|
162
174
|
console.log(`📋 Reviewing: ${targetCommitish}`);
|
|
175
|
+
if (options.keepAlive) {
|
|
176
|
+
console.log('🔒 Keep-alive mode: server will stay running after browser disconnects');
|
|
177
|
+
}
|
|
163
178
|
if (options.clean) {
|
|
164
179
|
console.log('🧹 Starting with a clean slate - all existing comments will be cleared');
|
|
165
180
|
}
|