difit 4.0.7 → 5.0.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.
Files changed (137) hide show
  1. package/README.ja.md +1 -3
  2. package/README.ko.md +1 -3
  3. package/README.md +6 -3
  4. package/README.zh.md +1 -3
  5. package/dist/cli/index.js +0 -39
  6. package/dist/cli/index.test.js +0 -374
  7. package/dist/cli/utils.d.ts +0 -2
  8. package/dist/cli/utils.js +1 -18
  9. package/dist/cli/utils.test.js +0 -16
  10. package/dist/client/assets/{arc-DX2p9X2Y.js → arc-47JvE2o4.js} +1 -1
  11. package/dist/client/assets/architecture-YZFGNWBL-CAofxL11.js +1 -0
  12. package/dist/client/assets/{architectureDiagram-Q4EWVU46-FixTWViB.js → architectureDiagram-Q4EWVU46-PEhI9x48.js} +1 -1
  13. package/dist/client/assets/{blockDiagram-DXYQGD6D-CUAMgGr9.js → blockDiagram-DXYQGD6D-SUrPMV8E.js} +1 -1
  14. package/dist/client/assets/{c4Diagram-AHTNJAMY-BM_HNNZe.js → c4Diagram-AHTNJAMY-BJ9pq9B3.js} +1 -1
  15. package/dist/client/assets/channel-DXpjokeU.js +1 -0
  16. package/dist/client/assets/{chunk-2KRD3SAO-DeT59g2K.js → chunk-2KRD3SAO-2O6hV_yw.js} +1 -1
  17. package/dist/client/assets/{chunk-336JU56O-CaGvJA86.js → chunk-336JU56O-C0NxME-U.js} +2 -2
  18. package/dist/client/assets/chunk-426QAEUC-DO73G5YJ.js +1 -0
  19. package/dist/client/assets/{chunk-4BX2VUAB-D9mNDl5f.js → chunk-4BX2VUAB-PjGa5t5G.js} +1 -1
  20. package/dist/client/assets/{chunk-4TB4RGXK-Df3b4HEG.js → chunk-4TB4RGXK-DKCtDLTf.js} +1 -1
  21. package/dist/client/assets/{chunk-55IACEB6-dCWLe_n4.js → chunk-55IACEB6-BUBhWZ5_.js} +1 -1
  22. package/dist/client/assets/{chunk-5FUZZQ4R-EScvXcSN.js → chunk-5FUZZQ4R-D52DoV-0.js} +1 -1
  23. package/dist/client/assets/{chunk-5PVQY5BW-ail-oj89.js → chunk-5PVQY5BW-Cpp0JjTq.js} +1 -1
  24. package/dist/client/assets/{chunk-67CJDMHE-CHeCIL1u.js → chunk-67CJDMHE-DFAAAXYj.js} +1 -1
  25. package/dist/client/assets/{chunk-7N4EOEYR-P0tNRVMZ.js → chunk-7N4EOEYR-DeLrWd_x.js} +1 -1
  26. package/dist/client/assets/{chunk-AA7GKIK3-DloBHWSo.js → chunk-AA7GKIK3-Pb9IU0o9.js} +1 -1
  27. package/dist/client/assets/{chunk-BSJP7CBP-CGLThsR8.js → chunk-BSJP7CBP-DvFe6BQg.js} +1 -1
  28. package/dist/client/assets/{chunk-CIAEETIT-rCt2IEMp.js → chunk-CIAEETIT-AytpwHlv.js} +1 -1
  29. package/dist/client/assets/{chunk-EDXVE4YY-DIJEIKIq.js → chunk-EDXVE4YY-DSprT5LQ.js} +1 -1
  30. package/dist/client/assets/{chunk-ENJZ2VHE-CdrdxFfV.js → chunk-ENJZ2VHE-DsQnPoSa.js} +1 -1
  31. package/dist/client/assets/{chunk-FMBD7UC4-BH_GgR9u.js → chunk-FMBD7UC4-CRzu5RUs.js} +1 -1
  32. package/dist/client/assets/{chunk-FOC6F5B3-D71VljSN.js → chunk-FOC6F5B3-GWMv90go.js} +1 -1
  33. package/dist/client/assets/{chunk-ICPOFSXX-2vcQKuhB.js → chunk-ICPOFSXX-LaB5P0SR.js} +1 -1
  34. package/dist/client/assets/{chunk-K5T4RW27-BWIFd7pZ.js → chunk-K5T4RW27-S036x5p5.js} +1 -1
  35. package/dist/client/assets/{chunk-KGLVRYIC-Ck8I8tdt.js → chunk-KGLVRYIC-DDzbiNrj.js} +1 -1
  36. package/dist/client/assets/{chunk-LIHQZDEY-Cc7TtI-w.js → chunk-LIHQZDEY-BoUwuY9Y.js} +1 -1
  37. package/dist/client/assets/{chunk-ORNJ4GCN-BMSqiphc.js → chunk-ORNJ4GCN-CopGHq93.js} +1 -1
  38. package/dist/client/assets/{chunk-OYMX7WX6-B5faFb53.js → chunk-OYMX7WX6-Do8-v0_P.js} +1 -1
  39. package/dist/client/assets/chunk-QZHKN3VN-BdzTLtlM.js +1 -0
  40. package/dist/client/assets/{chunk-U2HBQHQK-BILTfRyq.js → chunk-U2HBQHQK-CuugOH8t.js} +1 -1
  41. package/dist/client/assets/{chunk-X2U36JSP-D4-56gWx.js → chunk-X2U36JSP-ZX9AmJVa.js} +1 -1
  42. package/dist/client/assets/{chunk-XPW4576I-SxB401Zg.js → chunk-XPW4576I-DwqcIpF8.js} +1 -1
  43. package/dist/client/assets/{chunk-YZCP3GAM-CWXUVxFj.js → chunk-YZCP3GAM-w3hvGtGQ.js} +1 -1
  44. package/dist/client/assets/{chunk-ZZ45TVLE-CXjZua4f.js → chunk-ZZ45TVLE-CX35ksjr.js} +1 -1
  45. package/dist/client/assets/classDiagram-6PBFFD2Q-C9JPZQtl.js +1 -0
  46. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BgDR8rt-.js +1 -0
  47. package/dist/client/assets/clone-BygUtDF6.js +1 -0
  48. package/dist/client/assets/{cose-bilkent-S5V4N54A-YToNpueF.js → cose-bilkent-S5V4N54A-DXfb_bs_.js} +1 -1
  49. package/dist/client/assets/{dagre-tvaMpP4D.js → dagre-BYBAH6EF.js} +1 -1
  50. package/dist/client/assets/{dagre-KV5264BT-QFYoTa0z.js → dagre-KV5264BT-Bj9WMi27.js} +1 -1
  51. package/dist/client/assets/{diagram-5BDNPKRD-DM0NNmEN.js → diagram-5BDNPKRD-DHnS0s39.js} +1 -1
  52. package/dist/client/assets/{diagram-G4DWMVQ6-TiLkMmwt.js → diagram-G4DWMVQ6-DdKcPnFw.js} +1 -1
  53. package/dist/client/assets/{diagram-MMDJMWI5-DM1ykqrB.js → diagram-MMDJMWI5-DfdNeC0p.js} +1 -1
  54. package/dist/client/assets/{diagram-TYMM5635-BEOLX1wr.js → diagram-TYMM5635-DwieVXZu.js} +1 -1
  55. package/dist/client/assets/{dist-CCBhd9az.js → dist-COv0rtkK.js} +1 -1
  56. package/dist/client/assets/{erDiagram-SMLLAGMA-DZcjZq6z.js → erDiagram-SMLLAGMA--nNfIX9m.js} +1 -1
  57. package/dist/client/assets/{flowDiagram-DWJPFMVM-B1AVT9es.js → flowDiagram-DWJPFMVM-BFk7GDSn.js} +1 -1
  58. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BCEXws9V.js → ganttDiagram-T4ZO3ILL-DlVKHIi_.js} +1 -1
  59. package/dist/client/assets/gitGraph-7Q5UKJZL-4fOTOOzG.js +1 -0
  60. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CVznBDOl.js → gitGraphDiagram-UUTBAWPF-ww35jb2y.js} +1 -1
  61. package/dist/client/assets/{graphlib-C4fWcyt1.js → graphlib-cvGsNSEN.js} +1 -1
  62. package/dist/client/assets/index-CrvsDrrA.js +79 -0
  63. package/dist/client/assets/{index-C16wNcPQ.css → index-v-PY_jQI.css} +1 -1
  64. package/dist/client/assets/info-OMHHGYJF-BcwRhjJb.js +1 -0
  65. package/dist/client/assets/{infoDiagram-42DDH7IO-D8Oxr-KJ.js → infoDiagram-42DDH7IO-CbZg29-f.js} +1 -1
  66. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BE9KniVE.js → ishikawaDiagram-UXIWVN3A-DbmLYe6W.js} +1 -1
  67. package/dist/client/assets/{journeyDiagram-VCZTEJTY-B3lGcz06.js → journeyDiagram-VCZTEJTY-m6lofB3D.js} +1 -1
  68. package/dist/client/assets/{kanban-definition-6JOO6SKY-Bs1QdB0j.js → kanban-definition-6JOO6SKY-zNyvW0z9.js} +1 -1
  69. package/dist/client/assets/{line-CO4-KhEq.js → line-DYCPrtIt.js} +1 -1
  70. package/dist/client/assets/{linear-CnaJKs0I.js → linear-BAKLx75z.js} +1 -1
  71. package/dist/client/assets/{mermaid-parser.core-CravK6bS.js → mermaid-parser.core-BGGMv1j6.js} +2 -2
  72. package/dist/client/assets/{mermaid.core-DTh9KJvF.js → mermaid.core-CMGQEZKx.js} +3 -3
  73. package/dist/client/assets/{mindmap-definition-QFDTVHPH-D2xU2hfX.js → mindmap-definition-QFDTVHPH-4Qsf3Hkp.js} +1 -1
  74. package/dist/client/assets/packet-4T2RLAQJ-LdDEUu30.js +1 -0
  75. package/dist/client/assets/pie-ZZUOXDRM-B-ezG4xa.js +1 -0
  76. package/dist/client/assets/{pieDiagram-DEJITSTG-CRX6y4IQ.js → pieDiagram-DEJITSTG-Cnlop37j.js} +1 -1
  77. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-K2HFp8O8.js → quadrantDiagram-34T5L4WZ-CLFb7OC8.js} +1 -1
  78. package/dist/client/assets/radar-PYXPWWZC-D66LzHfH.js +1 -0
  79. package/dist/client/assets/{requirementDiagram-MS252O5E-C-8AW0uI.js → requirementDiagram-MS252O5E-CFMEftHL.js} +1 -1
  80. package/dist/client/assets/{sankeyDiagram-XADWPNL6-Bv-_ZFS5.js → sankeyDiagram-XADWPNL6-Bz_Rsg7k.js} +1 -1
  81. package/dist/client/assets/{sequenceDiagram-FGHM5R23-Bk4QYIPk.js → sequenceDiagram-FGHM5R23-C_UnEheO.js} +1 -1
  82. package/dist/client/assets/{src-XMuEuFcU.js → src-D4dXpp2L.js} +1 -1
  83. package/dist/client/assets/{stateDiagram-FHFEXIEX-CI1G7zGC.js → stateDiagram-FHFEXIEX-D5jyXLVB.js} +1 -1
  84. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CTyQGCYc.js +1 -0
  85. package/dist/client/assets/{timeline-definition-GMOUNBTQ-CnXv8xHg.js → timeline-definition-GMOUNBTQ-BtgnceD7.js} +1 -1
  86. package/dist/client/assets/treeView-SZITEDCU-BsI_6Qwy.js +1 -0
  87. package/dist/client/assets/treemap-W4RFUUIX-CzaM5y4Y.js +1 -0
  88. package/dist/client/assets/{vennDiagram-DHZGUBPP-M5x471Ar.js → vennDiagram-DHZGUBPP-DWtzk4wH.js} +1 -1
  89. package/dist/client/assets/wardley-RL74JXVD-C1IHEcDw.js +1 -0
  90. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-BG99uPNN.js → wardleyDiagram-NUSXRM2D-D88r6BkP.js} +1 -1
  91. package/dist/client/assets/{xychartDiagram-5P7HB3ND-DO7Upr9G.js → xychartDiagram-5P7HB3ND-DkXj8P_J.js} +1 -1
  92. package/dist/client/index.html +2 -2
  93. package/dist/server/server.d.ts +0 -1
  94. package/dist/server/server.js +0 -3
  95. package/dist/server/server.test.js +0 -37
  96. package/dist/types/diff.d.ts +0 -12
  97. package/dist/utils/commentFormatting.test.js +0 -52
  98. package/package.json +4 -5
  99. package/dist/cli/tuiDeprecation.d.ts +0 -3
  100. package/dist/cli/tuiDeprecation.js +0 -16
  101. package/dist/cli/tuiDeprecation.test.d.ts +0 -1
  102. package/dist/cli/tuiDeprecation.test.js +0 -16
  103. package/dist/client/assets/architecture-YZFGNWBL-2zVtKbnG.js +0 -1
  104. package/dist/client/assets/channel-B_ddQhpW.js +0 -1
  105. package/dist/client/assets/chunk-426QAEUC-CMTCMPn4.js +0 -1
  106. package/dist/client/assets/chunk-QZHKN3VN-B-G9G-FB.js +0 -1
  107. package/dist/client/assets/classDiagram-6PBFFD2Q-DnUQ2iGN.js +0 -1
  108. package/dist/client/assets/classDiagram-v2-HSJHXN6E-Dwp5vuOB.js +0 -1
  109. package/dist/client/assets/clone-aWrl-obY.js +0 -1
  110. package/dist/client/assets/gitGraph-7Q5UKJZL-BE3Mcr-v.js +0 -1
  111. package/dist/client/assets/index-6LShOAAb.js +0 -79
  112. package/dist/client/assets/info-OMHHGYJF-CBpXVhw-.js +0 -1
  113. package/dist/client/assets/packet-4T2RLAQJ-abaJ3V5T.js +0 -1
  114. package/dist/client/assets/pie-ZZUOXDRM-B12dpA7V.js +0 -1
  115. package/dist/client/assets/radar-PYXPWWZC-BbBaJJN8.js +0 -1
  116. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-DQ0U-oto.js +0 -1
  117. package/dist/client/assets/treeView-SZITEDCU-CM0rCBUc.js +0 -1
  118. package/dist/client/assets/treemap-W4RFUUIX-CXoNE_rL.js +0 -1
  119. package/dist/client/assets/wardley-RL74JXVD-B_EtnvOk.js +0 -1
  120. package/dist/server/git-diff-tui.d.ts +0 -2
  121. package/dist/server/git-diff-tui.js +0 -100
  122. package/dist/server/git-diff-tui.test.d.ts +0 -1
  123. package/dist/server/git-diff-tui.test.js +0 -76
  124. package/dist/tui/App.d.ts +0 -10
  125. package/dist/tui/App.js +0 -92
  126. package/dist/tui/components/DiffViewer.d.ts +0 -8
  127. package/dist/tui/components/DiffViewer.js +0 -88
  128. package/dist/tui/components/FileList.d.ts +0 -8
  129. package/dist/tui/components/FileList.js +0 -48
  130. package/dist/tui/components/SideBySideDiffViewer.d.ts +0 -9
  131. package/dist/tui/components/SideBySideDiffViewer.js +0 -240
  132. package/dist/tui/components/StatusBar.d.ts +0 -8
  133. package/dist/tui/components/StatusBar.js +0 -19
  134. package/dist/tui/utils/parseDiff.d.ts +0 -2
  135. package/dist/tui/utils/parseDiff.js +0 -67
  136. package/dist/utils/createId.test.d.ts +0 -1
  137. package/dist/utils/createId.test.js +0 -48
@@ -1,240 +0,0 @@
1
- import { Box, Text, useInput, useApp } from 'ink';
2
- import React, { useState } from 'react';
3
- import { parseDiff } from '../utils/parseDiff.js';
4
- const SideBySideDiffViewer = ({ files, initialFileIndex, onBack, }) => {
5
- const [currentFileIndex, setCurrentFileIndex] = useState(initialFileIndex);
6
- const [scrollOffset, setScrollOffset] = useState(0);
7
- const { exit } = useApp();
8
- const viewportHeight = Math.max(10, (process.stdout.rows || 24) - 10);
9
- const currentFile = files[currentFileIndex];
10
- useInput((input, key) => {
11
- if (input === 'q' || (key.ctrl && input === 'c')) {
12
- exit();
13
- return;
14
- }
15
- if (key.escape || input === 'b') {
16
- onBack();
17
- return;
18
- }
19
- if (!currentFile)
20
- return;
21
- // Scroll within file
22
- if (key.upArrow || input === 'k') {
23
- setScrollOffset((prev) => Math.max(0, prev - 1));
24
- }
25
- if (key.downArrow || input === 'j') {
26
- setScrollOffset((prev) => prev + 1);
27
- }
28
- if (key.pageUp) {
29
- setScrollOffset((prev) => Math.max(0, prev - viewportHeight));
30
- }
31
- if (key.pageDown) {
32
- setScrollOffset((prev) => prev + viewportHeight);
33
- }
34
- // Navigate between files
35
- if (key.tab && !key.shift) {
36
- // Next file (loop to first when at end)
37
- setCurrentFileIndex((currentFileIndex + 1) % files.length);
38
- setScrollOffset(0);
39
- }
40
- if (key.tab && key.shift) {
41
- // Previous file (loop to last when at start)
42
- setCurrentFileIndex((currentFileIndex - 1 + files.length) % files.length);
43
- setScrollOffset(0);
44
- }
45
- }, { isActive: true });
46
- if (!currentFile || files.length === 0) {
47
- return (React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
48
- React.createElement(Text, { color: "yellow" }, "No files to display"),
49
- React.createElement(Box, { marginTop: 1 },
50
- React.createElement(Text, { dimColor: true }, "Press ESC or 'b' to go back"))));
51
- }
52
- const parsedDiff = parseDiff(currentFile.diff);
53
- // Calculate total lines for current file
54
- const allLines = [];
55
- parsedDiff.chunks.forEach((chunk) => {
56
- // Add chunk header
57
- allLines.push({
58
- old: chunk.header,
59
- new: chunk.header,
60
- type: 'header',
61
- });
62
- let oldIdx = 0;
63
- let newIdx = 0;
64
- while (oldIdx < chunk.lines.length || newIdx < chunk.lines.length) {
65
- const oldLine = chunk.lines[oldIdx];
66
- const newLine = chunk.lines[newIdx];
67
- if (oldLine?.type === 'remove' && newLine?.type === 'add') {
68
- // Same line modified - show side by side
69
- allLines.push({
70
- old: oldLine.content,
71
- new: newLine.content,
72
- oldNum: oldLine.oldLineNumber,
73
- newNum: newLine.newLineNumber,
74
- type: 'modified',
75
- });
76
- oldIdx++;
77
- newIdx++;
78
- }
79
- else if (oldLine?.type === 'remove') {
80
- // Line removed
81
- allLines.push({
82
- old: oldLine.content,
83
- oldNum: oldLine.oldLineNumber,
84
- type: 'remove',
85
- });
86
- oldIdx++;
87
- }
88
- else if (newLine?.type === 'add') {
89
- // Line added
90
- allLines.push({
91
- new: newLine.content,
92
- newNum: newLine.newLineNumber,
93
- type: 'add',
94
- });
95
- newIdx++;
96
- }
97
- else if (oldLine?.type === 'context') {
98
- // Unchanged line
99
- allLines.push({
100
- old: oldLine.content,
101
- new: oldLine.content,
102
- oldNum: oldLine.oldLineNumber,
103
- newNum: oldLine.newLineNumber,
104
- type: 'context',
105
- });
106
- oldIdx++;
107
- newIdx++;
108
- }
109
- else {
110
- oldIdx++;
111
- newIdx++;
112
- }
113
- }
114
- });
115
- const actualMaxScroll = Math.max(0, allLines.length - viewportHeight);
116
- const clampedScrollOffset = Math.max(0, Math.min(actualMaxScroll, scrollOffset));
117
- const visibleLines = allLines.slice(clampedScrollOffset, clampedScrollOffset + viewportHeight);
118
- const terminalWidth = process.stdout.columns || 80;
119
- const columnWidth = Math.floor((terminalWidth - 6) / 2); // 6 for borders and separators
120
- const getLineColor = (type) => {
121
- switch (type) {
122
- case 'add':
123
- return 'green';
124
- case 'remove':
125
- return 'red';
126
- case 'modified':
127
- return undefined; // Will be handled separately for each side
128
- case 'header':
129
- return 'cyan';
130
- default:
131
- return undefined;
132
- }
133
- };
134
- const truncateLine = (line, width) => {
135
- if (line.length <= width)
136
- return line.padEnd(width);
137
- return line.substring(0, width - 1) + '…';
138
- };
139
- return (React.createElement(Box, { flexDirection: "column", flexGrow: 1 },
140
- React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
141
- React.createElement(Box, null,
142
- React.createElement(Text, { bold: true },
143
- currentFile.path,
144
- " (",
145
- currentFileIndex + 1,
146
- "/",
147
- files.length,
148
- ")"),
149
- React.createElement(Text, { dimColor: true },
150
- ' ',
151
- "- ",
152
- currentFile.additions,
153
- " additions, ",
154
- currentFile.deletions,
155
- " deletions")),
156
- React.createElement(Box, { height: 2, overflow: "hidden", flexDirection: "column" }, (() => {
157
- const terminalWidth = process.stdout.columns || 80;
158
- const maxWidth = terminalWidth - 4; // Leave some margin
159
- // Generate file list with current file highlighted
160
- const fileItems = [];
161
- // Add files before current
162
- for (let i = Math.max(0, currentFileIndex - 2); i < currentFileIndex; i++) {
163
- fileItems.push({
164
- text: files[i].path,
165
- isActive: false,
166
- });
167
- }
168
- // Add current file
169
- fileItems.push({
170
- text: `[${files[currentFileIndex].path}]`,
171
- isActive: true,
172
- });
173
- // Add files after current
174
- for (let i = currentFileIndex + 1; i < Math.min(files.length, currentFileIndex + 3); i++) {
175
- fileItems.push({
176
- text: files[i].path,
177
- isActive: false,
178
- });
179
- }
180
- // Build lines (max 2 lines)
181
- const lines = [[]];
182
- let currentLineWidth = 0;
183
- for (const item of fileItems) {
184
- const itemWidth = item.text.length + 3; // Include separator
185
- if (currentLineWidth + itemWidth > maxWidth && lines.length < 2) {
186
- lines.push([]);
187
- currentLineWidth = 0;
188
- }
189
- if (lines.length <= 2) {
190
- lines[lines.length - 1].push(item);
191
- currentLineWidth += itemWidth;
192
- }
193
- }
194
- return lines.map((line, lineIndex) => (React.createElement(Box, { key: lineIndex }, line.map((item, itemIndex) => (React.createElement(React.Fragment, { key: itemIndex },
195
- itemIndex > 0 && React.createElement(Text, { dimColor: true }, " | "),
196
- React.createElement(Text, { color: item.isActive ? 'cyan' : undefined, dimColor: !item.isActive }, item.text)))))));
197
- })())),
198
- React.createElement(Box, { borderStyle: "single", flexDirection: "column", flexGrow: 1 },
199
- React.createElement(Box, { borderStyle: "single", borderTop: false, borderLeft: false, borderRight: false },
200
- React.createElement(Box, { width: columnWidth },
201
- React.createElement(Text, { dimColor: true }, " \u2502 "),
202
- React.createElement(Text, { bold: true }, "Old")),
203
- React.createElement(Text, { dimColor: true }, " \u2503 "),
204
- React.createElement(Box, { width: columnWidth },
205
- React.createElement(Text, { dimColor: true }, " \u2502 "),
206
- React.createElement(Text, { bold: true }, "New"))),
207
- React.createElement(Box, { flexDirection: "column", flexGrow: 1 }, visibleLines.map((line, index) => (React.createElement(Box, { key: `line-${scrollOffset + index}` },
208
- React.createElement(Box, { width: columnWidth },
209
- React.createElement(Text, { dimColor: true }, line.oldNum ? String(line.oldNum).padStart(4) : ' '),
210
- React.createElement(Text, { dimColor: true }, " \u2502 "),
211
- React.createElement(Text, { color: line.type === 'remove' || line.type === 'modified' ? 'red' : undefined, dimColor: line.type === 'header' }, line.type === 'remove' || line.type === 'modified' ? '- ' : ' '),
212
- React.createElement(Text, { color: line.type === 'remove' || line.type === 'modified'
213
- ? 'red'
214
- : getLineColor(line.type) }, line.old
215
- ? truncateLine(line.old, columnWidth - 10)
216
- : ' '.repeat(columnWidth - 10))),
217
- React.createElement(Text, { dimColor: true }, " \u2503 "),
218
- React.createElement(Box, { width: columnWidth },
219
- React.createElement(Text, { dimColor: true }, line.newNum ? String(line.newNum).padStart(4) : ' '),
220
- React.createElement(Text, { dimColor: true }, " \u2502 "),
221
- React.createElement(Text, { color: line.type === 'add' || line.type === 'modified' ? 'green' : undefined, dimColor: line.type === 'header' }, line.type === 'add' || line.type === 'modified' ? '+ ' : ' '),
222
- React.createElement(Text, { color: line.type === 'add' || line.type === 'modified'
223
- ? 'green'
224
- : getLineColor(line.type) }, line.new
225
- ? truncateLine(line.new, columnWidth - 10)
226
- : ' '.repeat(columnWidth - 10)))))))),
227
- React.createElement(Box, { marginTop: 1, justifyContent: "space-between" },
228
- React.createElement(Text, { dimColor: true },
229
- "Lines ",
230
- scrollOffset + 1,
231
- "-",
232
- Math.min(scrollOffset + viewportHeight, allLines.length),
233
- " of",
234
- ' ',
235
- allLines.length,
236
- scrollOffset + viewportHeight < allLines.length &&
237
- ` (${allLines.length - scrollOffset - viewportHeight} more)`),
238
- React.createElement(Text, { dimColor: true }, "Tab: next file | Shift+Tab: prev file | \u2191\u2193/jk: scroll | ESC/b: back"))));
239
- };
240
- export default SideBySideDiffViewer;
@@ -1,8 +0,0 @@
1
- import React from 'react';
2
- interface StatusBarProps {
3
- commitish: string;
4
- totalFiles: number;
5
- currentMode: 'list' | 'split' | 'unified';
6
- }
7
- declare const StatusBar: React.FC<StatusBarProps>;
8
- export default StatusBar;
@@ -1,19 +0,0 @@
1
- import { Box, Text } from 'ink';
2
- import React from 'react';
3
- const StatusBar = ({ commitish, totalFiles, currentMode }) => {
4
- return (React.createElement(Box, { borderStyle: "round", paddingX: 1, marginBottom: 1 },
5
- React.createElement(Box, { flexGrow: 1 },
6
- React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDCCB difit TUI"),
7
- React.createElement(Text, null, " | "),
8
- React.createElement(Text, { color: "yellow" }, commitish),
9
- React.createElement(Text, null, " | "),
10
- React.createElement(Text, null,
11
- totalFiles,
12
- " files changed")),
13
- React.createElement(Box, null,
14
- React.createElement(Text, { dimColor: true },
15
- "[",
16
- currentMode === 'list' ? 'File List' : currentMode === 'split' ? 'Split' : 'Unified',
17
- "]"))));
18
- };
19
- export default StatusBar;
@@ -1,2 +0,0 @@
1
- import { type ParsedDiff } from '../../types/diff.js';
2
- export declare function parseDiff(diffText: string): ParsedDiff;
@@ -1,67 +0,0 @@
1
- export function parseDiff(diffText) {
2
- const lines = diffText.split('\n');
3
- const chunks = [];
4
- let currentChunk = null;
5
- let oldLineNumber = 0;
6
- let newLineNumber = 0;
7
- for (const line of lines) {
8
- // Skip file headers
9
- if (line.startsWith('diff --git') ||
10
- line.startsWith('index ') ||
11
- line.startsWith('---') ||
12
- line.startsWith('+++')) {
13
- continue;
14
- }
15
- // Chunk header
16
- if (line.startsWith('@@')) {
17
- const match = line.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);
18
- if (match) {
19
- const [, oldStart, oldLinesStr, newStart, newLinesStr] = match;
20
- currentChunk = {
21
- header: line,
22
- oldStart: parseInt(oldStart),
23
- oldLines: parseInt(oldLinesStr || '1'),
24
- newStart: parseInt(newStart),
25
- newLines: parseInt(newLinesStr || '1'),
26
- lines: [],
27
- };
28
- chunks.push(currentChunk);
29
- oldLineNumber = currentChunk.oldStart - 1;
30
- newLineNumber = currentChunk.newStart - 1;
31
- }
32
- continue;
33
- }
34
- // Skip if no current chunk
35
- if (!currentChunk)
36
- continue;
37
- // Parse diff lines
38
- if (line.startsWith('+')) {
39
- newLineNumber++;
40
- currentChunk.lines.push({
41
- type: 'add',
42
- content: line.substring(1),
43
- newLineNumber: newLineNumber,
44
- });
45
- }
46
- else if (line.startsWith('-')) {
47
- oldLineNumber++;
48
- currentChunk.lines.push({
49
- type: 'remove',
50
- content: line.substring(1),
51
- oldLineNumber: oldLineNumber,
52
- });
53
- }
54
- else {
55
- // Context line
56
- oldLineNumber++;
57
- newLineNumber++;
58
- currentChunk.lines.push({
59
- type: 'context',
60
- content: line.substring(1),
61
- oldLineNumber: oldLineNumber,
62
- newLineNumber: newLineNumber,
63
- });
64
- }
65
- }
66
- return { chunks };
67
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,48 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { createId } from './createId';
3
- describe('createId', () => {
4
- it('creates a 16-character lowercase alphanumeric id', () => {
5
- const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0);
6
- expect(createId()).toBe('aaaaaaaaaaaaaaaa');
7
- randomSpy.mockRestore();
8
- });
9
- it('creates different ids across successive calls', () => {
10
- const randomSpy = vi
11
- .spyOn(Math, 'random')
12
- .mockReturnValueOnce(0)
13
- .mockReturnValueOnce(1 / 36)
14
- .mockReturnValueOnce(2 / 36)
15
- .mockReturnValueOnce(3 / 36)
16
- .mockReturnValueOnce(4 / 36)
17
- .mockReturnValueOnce(5 / 36)
18
- .mockReturnValueOnce(6 / 36)
19
- .mockReturnValueOnce(7 / 36)
20
- .mockReturnValueOnce(8 / 36)
21
- .mockReturnValueOnce(9 / 36)
22
- .mockReturnValueOnce(10 / 36)
23
- .mockReturnValueOnce(11 / 36)
24
- .mockReturnValueOnce(12 / 36)
25
- .mockReturnValueOnce(13 / 36)
26
- .mockReturnValueOnce(14 / 36)
27
- .mockReturnValueOnce(15 / 36)
28
- .mockReturnValueOnce(16 / 36)
29
- .mockReturnValueOnce(17 / 36)
30
- .mockReturnValueOnce(18 / 36)
31
- .mockReturnValueOnce(19 / 36)
32
- .mockReturnValueOnce(20 / 36)
33
- .mockReturnValueOnce(21 / 36)
34
- .mockReturnValueOnce(22 / 36)
35
- .mockReturnValueOnce(23 / 36)
36
- .mockReturnValueOnce(24 / 36)
37
- .mockReturnValueOnce(25 / 36)
38
- .mockReturnValueOnce(26 / 36)
39
- .mockReturnValueOnce(27 / 36)
40
- .mockReturnValueOnce(28 / 36)
41
- .mockReturnValueOnce(29 / 36)
42
- .mockReturnValueOnce(30 / 36)
43
- .mockReturnValueOnce(31 / 36);
44
- expect(createId()).toBe('abcdefghijklmnop');
45
- expect(createId()).toBe('qrstuvwxyz012345');
46
- randomSpy.mockRestore();
47
- });
48
- });