jvcs 1.5.0 → 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: "black",
21
- bg: "cyan"
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
- bg: "blue"
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((file, index) => {
51
- return `${file.status.toUpperCase()} ${file.path}`
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 renderFileView() {
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
- Changes detected in file.
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
- leftBox.style.border.fg = "white"
142
- rightBox.style.border.fg = "white"
143
- aiBox.style.border.fg = "white"
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 (state.selectedIndex > 0) {
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 (state.selectedIndex < state.files.length - 1) {
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 (state.screen === "FILE_VIEW") {
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 (state.screen === "FILE_VIEW") {
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jvcs",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "bin": {
5
5
  "jvcs": "index.js"
6
6
  },