difit 3.1.7 → 3.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.ja.md +9 -1
  2. package/README.ko.md +9 -1
  3. package/README.md +9 -1
  4. package/README.zh.md +9 -1
  5. package/dist/cli/index.js +8 -3
  6. package/dist/cli/utils.d.ts +13 -11
  7. package/dist/cli/utils.js +25 -2
  8. package/dist/cli/utils.test.js +99 -1
  9. package/dist/client/assets/index-B1Ye1njT.js +92 -0
  10. package/dist/client/assets/index-D4vctQX_.css +1 -0
  11. package/dist/client/assets/{prism-csharp-CpJpO3Rp.js → prism-csharp-Dv4F6oYg.js} +1 -1
  12. package/dist/client/assets/{prism-hcl-D3OomFiZ.js → prism-hcl-BKiQPDt1.js} +1 -1
  13. package/dist/client/assets/{prism-java-DKu7Mdwl.js → prism-java-CsLA9BYF.js} +1 -1
  14. package/dist/client/assets/{prism-perl-BcSVuy7b.js → prism-perl-CjbksjRr.js} +1 -1
  15. package/dist/client/assets/{prism-php-BzFHnoKk.js → prism-php-Blls7Q4g.js} +1 -1
  16. package/dist/client/assets/{prism-ruby-_Fv626ts.js → prism-ruby-DVHs5uYA.js} +1 -1
  17. package/dist/client/assets/{prism-solidity-DNmqWy7k.js → prism-solidity-BxgmEX2j.js} +1 -1
  18. package/dist/client/index.html +2 -2
  19. package/dist/types/watch.d.ts +0 -14
  20. package/dist/utils/commentFormatting.d.ts +1 -1
  21. package/dist/utils/commentFormatting.js +32 -2
  22. package/dist/utils/commentFormatting.test.js +30 -0
  23. package/dist/utils/suggestionUtils.d.ts +18 -0
  24. package/dist/utils/suggestionUtils.js +31 -0
  25. package/dist/utils/suggestionUtils.test.d.ts +1 -0
  26. package/dist/utils/suggestionUtils.test.js +106 -0
  27. package/package.json +5 -7
  28. package/dist/client/assets/index-BVVFshvc.css +0 -1
  29. package/dist/client/assets/index-N61VWhYi.js +0 -67
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
  ### 単一コミットのレビュー
@@ -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
  | フラグ | デフォルト | 説明 |
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
  ### 단일 커밋 검토
@@ -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
  | 플래그 | 기본값 | 설명 |
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
@@ -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 |
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
  ### 单个提交审查
@@ -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
  | 标志 | 默认值 | 描述 |
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, resolvePrCommits, getGitRoot, } from './utils.js';
9
+ import { shouldReadStdin, findUntrackedFiles, markFilesIntentToAdd, promptUser, validateDiffArguments, resolvePrCommits, getGitRoot, } from './utils.js';
10
10
  function isSpecialArg(arg) {
11
11
  return arg === 'working' || arg === 'staged' || arg === '.';
12
12
  }
@@ -46,8 +46,13 @@ program
46
46
  .action(async (commitish, compareWith, options) => {
47
47
  try {
48
48
  // Check if we should read from stdin
49
- const shouldReadStdin = !process.stdin.isTTY || commitish === '-';
50
- if (shouldReadStdin) {
49
+ const readFromStdin = shouldReadStdin({
50
+ commitish,
51
+ hasPositionalArgs: program.args.length > 0,
52
+ hasPrOption: Boolean(options.pr),
53
+ hasTuiOption: Boolean(options.tui),
54
+ });
55
+ if (readFromStdin) {
51
56
  // Read unified diff from stdin
52
57
  const diffContent = await readStdin();
53
58
  if (!diffContent.trim()) {
@@ -1,4 +1,16 @@
1
+ import { type Stats } from 'node:fs';
1
2
  import type { SimpleGit } from 'simple-git';
3
+ type StdinStat = Pick<Stats, 'isFIFO' | 'isFile' | 'isSocket'>;
4
+ export type StdinSource = 'pipe' | 'file' | 'socket' | 'tty';
5
+ export declare function detectStdinSource(stdinStat?: StdinStat): StdinSource;
6
+ export interface ShouldReadStdinOptions {
7
+ commitish: string;
8
+ hasPositionalArgs: boolean;
9
+ hasPrOption: boolean;
10
+ hasTuiOption: boolean;
11
+ stdinSource?: StdinSource;
12
+ }
13
+ export declare function shouldReadStdin(options: ShouldReadStdinOptions): boolean;
2
14
  export declare function getGitRoot(): string;
3
15
  export declare function validateCommitish(commitish: string): boolean;
4
16
  export declare function shortHash(hash: string): string;
@@ -9,18 +21,7 @@ export interface PullRequestInfo {
9
21
  pullNumber: number;
10
22
  hostname: string;
11
23
  }
12
- export interface PullRequestDetails {
13
- baseSha: string;
14
- headSha: string;
15
- baseRef: string;
16
- headRef: string;
17
- }
18
24
  export declare function parseGitHubPrUrl(url: string): PullRequestInfo | null;
19
- export declare function fetchPrDetails(prInfo: PullRequestInfo): Promise<PullRequestDetails>;
20
- export declare function resolveCommitInLocalRepo(sha: string, context?: {
21
- owner: string;
22
- repo: string;
23
- }): string;
24
25
  export declare function resolvePrCommits(prUrl: string): Promise<{
25
26
  targetCommitish: string;
26
27
  baseCommitish: string;
@@ -32,3 +33,4 @@ export declare function validateDiffArguments(targetCommitish: string, baseCommi
32
33
  export declare function findUntrackedFiles(git: SimpleGit): Promise<string[]>;
33
34
  export declare function markFilesIntentToAdd(git: SimpleGit, files: string[]): Promise<void>;
34
35
  export declare function promptUser(message: string): Promise<boolean>;
36
+ export {};
package/dist/cli/utils.js CHANGED
@@ -1,6 +1,29 @@
1
1
  import { execSync } from 'child_process';
2
+ import { fstatSync } from 'node:fs';
2
3
  import { createInterface } from 'readline/promises';
3
4
  import { Octokit } from '@octokit/rest';
5
+ export function detectStdinSource(stdinStat = fstatSync(0)) {
6
+ if (stdinStat.isFIFO()) {
7
+ return 'pipe';
8
+ }
9
+ if (stdinStat.isFile()) {
10
+ return 'file';
11
+ }
12
+ if (stdinStat.isSocket()) {
13
+ return 'socket';
14
+ }
15
+ return 'tty';
16
+ }
17
+ export function shouldReadStdin(options) {
18
+ if (options.commitish === '-') {
19
+ return true;
20
+ }
21
+ if (options.hasPositionalArgs || options.hasPrOption || options.hasTuiOption) {
22
+ return false;
23
+ }
24
+ const stdinSource = options.stdinSource ?? detectStdinSource();
25
+ return stdinSource === 'pipe' || stdinSource === 'file' || stdinSource === 'socket';
26
+ }
4
27
  export function getGitRoot() {
5
28
  try {
6
29
  const result = execSync('git rev-parse --show-toplevel', { encoding: 'utf8', stdio: 'pipe' });
@@ -114,7 +137,7 @@ function getGitHubToken() {
114
137
  return undefined;
115
138
  }
116
139
  }
117
- export async function fetchPrDetails(prInfo) {
140
+ async function fetchPrDetails(prInfo) {
118
141
  const token = getGitHubToken();
119
142
  const octokitOptions = {
120
143
  auth: token,
@@ -160,7 +183,7 @@ export async function fetchPrDetails(prInfo) {
160
183
  throw new Error('Failed to fetch PR details: Unknown error');
161
184
  }
162
185
  }
163
- export function resolveCommitInLocalRepo(sha, context) {
186
+ function resolveCommitInLocalRepo(sha, context) {
164
187
  try {
165
188
  // Verify if the commit exists locally
166
189
  execSync(`git cat-file -e ${sha}`, { stdio: 'ignore' });
@@ -1,6 +1,104 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { validateCommitish, validateDiffArguments, shortHash, parseGitHubPrUrl } from './utils';
2
+ import { detectStdinSource, parseGitHubPrUrl, shortHash, shouldReadStdin, validateCommitish, validateDiffArguments, } from './utils';
3
3
  describe('CLI Utils', () => {
4
+ describe('stdin detection', () => {
5
+ it('detects pipe from stdin stat', () => {
6
+ expect(detectStdinSource({
7
+ isFIFO: () => true,
8
+ isFile: () => false,
9
+ isSocket: () => false,
10
+ })).toBe('pipe');
11
+ });
12
+ it('detects file from stdin stat', () => {
13
+ expect(detectStdinSource({
14
+ isFIFO: () => false,
15
+ isFile: () => true,
16
+ isSocket: () => false,
17
+ })).toBe('file');
18
+ });
19
+ it('detects socket from stdin stat', () => {
20
+ expect(detectStdinSource({
21
+ isFIFO: () => false,
22
+ isFile: () => false,
23
+ isSocket: () => true,
24
+ })).toBe('socket');
25
+ });
26
+ it('detects tty for character device stdin stat', () => {
27
+ expect(detectStdinSource({
28
+ isFIFO: () => false,
29
+ isFile: () => false,
30
+ isSocket: () => false,
31
+ })).toBe('tty');
32
+ });
33
+ it('reads stdin when commitish is explicit stdin marker', () => {
34
+ expect(shouldReadStdin({
35
+ commitish: '-',
36
+ hasPositionalArgs: true,
37
+ hasPrOption: true,
38
+ hasTuiOption: true,
39
+ stdinSource: 'tty',
40
+ })).toBe(true);
41
+ });
42
+ it('does not read stdin when positional args are explicitly passed', () => {
43
+ expect(shouldReadStdin({
44
+ commitish: '.',
45
+ hasPositionalArgs: true,
46
+ hasPrOption: false,
47
+ hasTuiOption: false,
48
+ stdinSource: 'pipe',
49
+ })).toBe(false);
50
+ });
51
+ it('does not read stdin when --pr is specified', () => {
52
+ expect(shouldReadStdin({
53
+ commitish: 'HEAD',
54
+ hasPositionalArgs: false,
55
+ hasPrOption: true,
56
+ hasTuiOption: false,
57
+ stdinSource: 'pipe',
58
+ })).toBe(false);
59
+ });
60
+ it('does not read stdin when --tui is specified', () => {
61
+ expect(shouldReadStdin({
62
+ commitish: 'HEAD',
63
+ hasPositionalArgs: false,
64
+ hasPrOption: false,
65
+ hasTuiOption: true,
66
+ stdinSource: 'pipe',
67
+ })).toBe(false);
68
+ });
69
+ it('auto-detects stdin for pipe/file/socket only when no explicit git mode is selected', () => {
70
+ expect(shouldReadStdin({
71
+ commitish: 'HEAD',
72
+ hasPositionalArgs: false,
73
+ hasPrOption: false,
74
+ hasTuiOption: false,
75
+ stdinSource: 'pipe',
76
+ })).toBe(true);
77
+ expect(shouldReadStdin({
78
+ commitish: 'HEAD',
79
+ hasPositionalArgs: false,
80
+ hasPrOption: false,
81
+ hasTuiOption: false,
82
+ stdinSource: 'file',
83
+ })).toBe(true);
84
+ expect(shouldReadStdin({
85
+ commitish: 'HEAD',
86
+ hasPositionalArgs: false,
87
+ hasPrOption: false,
88
+ hasTuiOption: false,
89
+ stdinSource: 'socket',
90
+ })).toBe(true);
91
+ });
92
+ it('does not auto-read stdin for tty source', () => {
93
+ expect(shouldReadStdin({
94
+ commitish: 'HEAD',
95
+ hasPositionalArgs: false,
96
+ hasPrOption: false,
97
+ hasTuiOption: false,
98
+ stdinSource: 'tty',
99
+ })).toBe(false);
100
+ });
101
+ });
4
102
  describe('validateCommitish', () => {
5
103
  it('should validate full SHA hashes', () => {
6
104
  expect(validateCommitish('a1b2c3d4e5f6789012345678901234567890abcd')).toBe(true);