jvcs 1.4.9 → 1.5.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.
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const blessed = require("blessed")
|
|
2
2
|
|
|
3
3
|
function startUI(state) {
|
|
4
|
-
|
|
5
4
|
const screen = blessed.screen({
|
|
6
5
|
smartCSR: true,
|
|
7
6
|
title: "JVCS Diff Viewer"
|
|
@@ -10,24 +9,23 @@ function startUI(state) {
|
|
|
10
9
|
// ---------------------------------------
|
|
11
10
|
// HEADER
|
|
12
11
|
// ---------------------------------------
|
|
13
|
-
|
|
14
12
|
const header = blessed.box({
|
|
15
13
|
top: 0,
|
|
16
14
|
height: 1,
|
|
17
15
|
width: "100%",
|
|
18
16
|
content: ` JVCS DIFF VIEW (${state.mode}) | ↑↓ Navigate | Enter Open | Esc Back | Tab Switch | Q Quit `,
|
|
19
17
|
style: {
|
|
20
|
-
fg: "
|
|
21
|
-
bg: "
|
|
18
|
+
fg: "white",
|
|
19
|
+
bg: "blue",
|
|
20
|
+
bold: true,
|
|
21
|
+
underline: true
|
|
22
22
|
}
|
|
23
23
|
})
|
|
24
|
-
|
|
25
24
|
screen.append(header)
|
|
26
25
|
|
|
27
26
|
// ---------------------------------------
|
|
28
27
|
// FILE LIST VIEW
|
|
29
28
|
// ---------------------------------------
|
|
30
|
-
|
|
31
29
|
const fileList = blessed.list({
|
|
32
30
|
top: 1,
|
|
33
31
|
left: 0,
|
|
@@ -38,19 +36,23 @@ function startUI(state) {
|
|
|
38
36
|
border: "line",
|
|
39
37
|
label: " Changed Files ",
|
|
40
38
|
style: {
|
|
41
|
-
selected: {
|
|
42
|
-
|
|
43
|
-
}
|
|
39
|
+
selected: { bg: "blue" },
|
|
40
|
+
item: { fg: "white" }
|
|
44
41
|
}
|
|
45
42
|
})
|
|
46
|
-
|
|
47
43
|
screen.append(fileList)
|
|
48
44
|
|
|
49
45
|
function renderFileList() {
|
|
50
|
-
const items = state.files.map(
|
|
51
|
-
|
|
46
|
+
const items = state.files.map(file => {
|
|
47
|
+
let statusColored
|
|
48
|
+
switch(file.status) {
|
|
49
|
+
case "added": statusColored = `{green-fg}${file.status.toUpperCase()}{/green-fg}`; break
|
|
50
|
+
case "deleted": statusColored = `{red-fg}${file.status.toUpperCase()}{/red-fg}`; break
|
|
51
|
+
case "modified": statusColored = `{yellow-fg}${file.status.toUpperCase()}{/yellow-fg}`; break
|
|
52
|
+
default: statusColored = file.status.toUpperCase()
|
|
53
|
+
}
|
|
54
|
+
return `${statusColored} ${file.path}`
|
|
52
55
|
})
|
|
53
|
-
|
|
54
56
|
fileList.setItems(items)
|
|
55
57
|
fileList.select(state.selectedIndex)
|
|
56
58
|
fileList.focus()
|
|
@@ -60,7 +62,6 @@ function startUI(state) {
|
|
|
60
62
|
// ---------------------------------------
|
|
61
63
|
// FILE VIEW (3 PANELS)
|
|
62
64
|
// ---------------------------------------
|
|
63
|
-
|
|
64
65
|
const leftBox = blessed.box({
|
|
65
66
|
top: 1,
|
|
66
67
|
left: 0,
|
|
@@ -71,7 +72,9 @@ function startUI(state) {
|
|
|
71
72
|
scrollable: true,
|
|
72
73
|
alwaysScroll: true,
|
|
73
74
|
keys: true,
|
|
74
|
-
vi: true
|
|
75
|
+
vi: true,
|
|
76
|
+
scrollbar: { ch: "│", track: { bg: "black" }, style: { bg: "yellow" } },
|
|
77
|
+
padding: { left: 1, right: 1 }
|
|
75
78
|
})
|
|
76
79
|
|
|
77
80
|
const rightBox = blessed.box({
|
|
@@ -84,7 +87,9 @@ function startUI(state) {
|
|
|
84
87
|
scrollable: true,
|
|
85
88
|
alwaysScroll: true,
|
|
86
89
|
keys: true,
|
|
87
|
-
vi: true
|
|
90
|
+
vi: true,
|
|
91
|
+
scrollbar: { ch: "│", track: { bg: "black" }, style: { bg: "yellow" } },
|
|
92
|
+
padding: { left: 1, right: 1 }
|
|
88
93
|
})
|
|
89
94
|
|
|
90
95
|
const aiBox = blessed.box({
|
|
@@ -97,25 +102,32 @@ function startUI(state) {
|
|
|
97
102
|
scrollable: true,
|
|
98
103
|
alwaysScroll: true,
|
|
99
104
|
keys: true,
|
|
100
|
-
vi: true
|
|
105
|
+
vi: true,
|
|
106
|
+
scrollbar: { ch: "│", track: { bg: "black" }, style: { bg: "yellow" } },
|
|
107
|
+
padding: { left: 1, right: 1 }
|
|
101
108
|
})
|
|
102
109
|
|
|
103
|
-
function
|
|
110
|
+
function colorDiffContent(content, type) {
|
|
111
|
+
return content.split("\n").map(line => {
|
|
112
|
+
if(type === "added") return `{green-fg}+ ${line}{/green-fg}`
|
|
113
|
+
if(type === "removed") return `{red-fg}- ${line}{/red-fg}`
|
|
114
|
+
return ` ${line}`
|
|
115
|
+
}).join("\n")
|
|
116
|
+
}
|
|
104
117
|
|
|
118
|
+
function renderFileView() {
|
|
105
119
|
const file = state.getCurrentFile()
|
|
106
120
|
if (!file) return
|
|
107
121
|
|
|
108
|
-
leftBox.setContent(file.leftContent
|
|
109
|
-
rightBox.setContent(file.rightContent
|
|
122
|
+
leftBox.setContent(colorDiffContent(file.leftContent, "removed"))
|
|
123
|
+
rightBox.setContent(colorDiffContent(file.rightContent, "added"))
|
|
110
124
|
|
|
111
125
|
aiBox.setContent(`
|
|
112
|
-
Summary:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Status: ${file.status}
|
|
126
|
+
{bold}Summary:{/bold}
|
|
127
|
+
Status: ${file.status.toUpperCase()}
|
|
116
128
|
|
|
117
|
-
Lines Added: ${file.stats.added}
|
|
118
|
-
Lines Removed: ${file.stats.removed}
|
|
129
|
+
{green-fg}Lines Added: ${file.stats.added}{/green-fg}
|
|
130
|
+
{red-fg}Lines Removed: ${file.stats.removed}{/red-fg}
|
|
119
131
|
|
|
120
132
|
(Real AI analysis will appear here later)
|
|
121
133
|
`)
|
|
@@ -125,7 +137,6 @@ Lines Removed: ${file.stats.removed}
|
|
|
125
137
|
screen.append(aiBox)
|
|
126
138
|
|
|
127
139
|
updateActiveTabHighlight()
|
|
128
|
-
|
|
129
140
|
screen.render()
|
|
130
141
|
}
|
|
131
142
|
|
|
@@ -137,23 +148,13 @@ Lines Removed: ${file.stats.removed}
|
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
function updateActiveTabHighlight() {
|
|
151
|
+
leftBox.style.border.fg = state.activeTab === 0 ? "yellow" : "grey"
|
|
152
|
+
rightBox.style.border.fg = state.activeTab === 1 ? "yellow" : "grey"
|
|
153
|
+
aiBox.style.border.fg = state.activeTab === 2 ? "yellow" : "grey"
|
|
140
154
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
aiBox.
|
|
144
|
-
|
|
145
|
-
if (state.activeTab === 0) {
|
|
146
|
-
leftBox.style.border.fg = "yellow"
|
|
147
|
-
leftBox.focus()
|
|
148
|
-
}
|
|
149
|
-
else if (state.activeTab === 1) {
|
|
150
|
-
rightBox.style.border.fg = "yellow"
|
|
151
|
-
rightBox.focus()
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
aiBox.style.border.fg = "yellow"
|
|
155
|
-
aiBox.focus()
|
|
156
|
-
}
|
|
155
|
+
if(state.activeTab === 0) leftBox.focus()
|
|
156
|
+
else if(state.activeTab === 1) rightBox.focus()
|
|
157
|
+
else aiBox.focus()
|
|
157
158
|
|
|
158
159
|
screen.render()
|
|
159
160
|
}
|
|
@@ -161,21 +162,17 @@ Lines Removed: ${file.stats.removed}
|
|
|
161
162
|
// ---------------------------------------
|
|
162
163
|
// KEYBOARD CONTROLS
|
|
163
164
|
// ---------------------------------------
|
|
164
|
-
|
|
165
|
-
screen.key(["q", "C-c"], () => {
|
|
166
|
-
return process.exit(0)
|
|
167
|
-
})
|
|
165
|
+
screen.key(["q", "C-c"], () => process.exit(0))
|
|
168
166
|
|
|
169
167
|
// Navigate list
|
|
170
168
|
fileList.key(["up"], () => {
|
|
171
|
-
if
|
|
169
|
+
if(state.selectedIndex > 0) {
|
|
172
170
|
state.selectFile(state.selectedIndex - 1)
|
|
173
171
|
renderFileList()
|
|
174
172
|
}
|
|
175
173
|
})
|
|
176
|
-
|
|
177
174
|
fileList.key(["down"], () => {
|
|
178
|
-
if
|
|
175
|
+
if(state.selectedIndex < state.files.length - 1) {
|
|
179
176
|
state.selectFile(state.selectedIndex + 1)
|
|
180
177
|
renderFileList()
|
|
181
178
|
}
|
|
@@ -190,7 +187,7 @@ Lines Removed: ${file.stats.removed}
|
|
|
190
187
|
|
|
191
188
|
// ESC → Back to list
|
|
192
189
|
screen.key(["escape"], () => {
|
|
193
|
-
if
|
|
190
|
+
if(state.screen === "FILE_VIEW") {
|
|
194
191
|
state.goToListView()
|
|
195
192
|
destroyFileView()
|
|
196
193
|
screen.append(fileList)
|
|
@@ -200,7 +197,7 @@ Lines Removed: ${file.stats.removed}
|
|
|
200
197
|
|
|
201
198
|
// TAB → switch active panel
|
|
202
199
|
screen.key(["tab"], () => {
|
|
203
|
-
if
|
|
200
|
+
if(state.screen === "FILE_VIEW") {
|
|
204
201
|
state.switchTab((state.activeTab + 1) % 3)
|
|
205
202
|
updateActiveTabHighlight()
|
|
206
203
|
}
|
|
@@ -209,7 +206,6 @@ Lines Removed: ${file.stats.removed}
|
|
|
209
206
|
// ---------------------------------------
|
|
210
207
|
// INITIAL RENDER
|
|
211
208
|
// ---------------------------------------
|
|
212
|
-
|
|
213
209
|
renderFileList()
|
|
214
210
|
}
|
|
215
211
|
|