vg-coder-cli 2.0.15 → 2.0.17
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/package.json +14 -13
- package/src/server/api-server.js +131 -11
- package/src/server/views/css/git-view.css +241 -73
- package/src/server/views/css/iframe.css +188 -13
- package/src/server/views/dashboard.html +68 -66
- package/src/server/views/js/api.js +62 -66
- package/src/server/views/js/features/git-view.js +324 -70
- package/src/server/views/js/features/iframe-manager.js +48 -12
- package/src/server/views/js/main.js +36 -23
- package/vg-coder-cli-2.0.17.tgz +0 -0
- package/change.sh +0 -0
- package/vg-coder-cli-2.0.12.tgz +0 -0
- package/vg-coder-cli-2.0.14.tgz +0 -0
- package/vg-coder-cli-2.0.15.tgz +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vg-coder-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.17",
|
|
4
4
|
"description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting and copy functionality",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,26 +31,27 @@
|
|
|
31
31
|
"url": "https://github.com/tinhthanh/vg-coder-cli.git"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"body-parser": "^1.20.2",
|
|
35
|
+
"chalk": "^4.1.2",
|
|
34
36
|
"commander": "^11.1.0",
|
|
37
|
+
"cors": "^2.8.5",
|
|
35
38
|
"directory-tree": "^3.5.1",
|
|
36
|
-
"
|
|
39
|
+
"express": "^4.18.2",
|
|
40
|
+
"fs-extra": "^11.2.0",
|
|
37
41
|
"highlight.js": "^11.9.0",
|
|
38
42
|
"ignore": "^5.3.0",
|
|
39
|
-
"fs-extra": "^11.2.0",
|
|
40
|
-
"path": "^0.12.7",
|
|
41
|
-
"chalk": "^4.1.2",
|
|
42
|
-
"ora": "^5.4.1",
|
|
43
|
-
"express": "^4.18.2",
|
|
44
|
-
"cors": "^2.8.5",
|
|
45
|
-
"body-parser": "^1.20.2",
|
|
46
43
|
"node-pty": "^1.0.0",
|
|
47
|
-
"
|
|
44
|
+
"ora": "^5.4.1",
|
|
45
|
+
"path": "^0.12.7",
|
|
46
|
+
"socket.io": "^4.7.2",
|
|
47
|
+
"tiktoken": "^1.0.10",
|
|
48
|
+
"vg-coder-cli": "^2.0.15"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"jest": "^29.7.0",
|
|
51
|
-
"nodemon": "^3.0.2",
|
|
52
51
|
"@types/jest": "^29.5.8",
|
|
53
|
-
"adm-zip": "^0.5.10"
|
|
52
|
+
"adm-zip": "^0.5.10",
|
|
53
|
+
"jest": "^29.7.0",
|
|
54
|
+
"nodemon": "^3.0.2"
|
|
54
55
|
},
|
|
55
56
|
"engines": {
|
|
56
57
|
"node": ">=16.0.0"
|
package/src/server/api-server.js
CHANGED
|
@@ -51,13 +51,8 @@ class ApiServer {
|
|
|
51
51
|
|
|
52
52
|
setupSocketIO() {
|
|
53
53
|
this.io.on('connection', (socket) => {
|
|
54
|
-
// Nhận event init với termId
|
|
55
|
-
// FIX: Thêm default value = {} để tránh crash khi data undefined
|
|
56
54
|
socket.on('terminal:init', (data) => {
|
|
57
|
-
if (!data || !data.termId)
|
|
58
|
-
// console.warn('[Socket] Ignored invalid terminal:init', data);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
55
|
+
if (!data || !data.termId) return;
|
|
61
56
|
const { termId, cols, rows } = data;
|
|
62
57
|
terminalManager.createTerminal(socket, termId, cols, rows, this.workingDir);
|
|
63
58
|
});
|
|
@@ -99,19 +94,144 @@ class ApiServer {
|
|
|
99
94
|
}
|
|
100
95
|
});
|
|
101
96
|
|
|
97
|
+
// --- GIT API START ---
|
|
98
|
+
|
|
99
|
+
// Get Git Status
|
|
100
|
+
this.app.get('/api/git/status', async (req, res) => {
|
|
101
|
+
try {
|
|
102
|
+
const { stdout } = await execAsync('git status --porcelain', { cwd: this.workingDir });
|
|
103
|
+
|
|
104
|
+
const staged = [];
|
|
105
|
+
const unstaged = [];
|
|
106
|
+
const untracked = [];
|
|
107
|
+
|
|
108
|
+
const lines = stdout.split('\n').filter(l => l.trim());
|
|
109
|
+
|
|
110
|
+
lines.forEach(line => {
|
|
111
|
+
const x = line[0];
|
|
112
|
+
const y = line[1];
|
|
113
|
+
const path = line.substring(3);
|
|
114
|
+
|
|
115
|
+
if (x !== ' ' && x !== '?') {
|
|
116
|
+
staged.push({ path, status: x });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (y !== ' ') {
|
|
120
|
+
if (x === '?' && y === '?') {
|
|
121
|
+
untracked.push({ path, status: 'U' });
|
|
122
|
+
} else {
|
|
123
|
+
unstaged.push({ path, status: y });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const changes = [...unstaged, ...untracked];
|
|
129
|
+
res.json({ staged, changes });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(chalk.red('❌ [GIT STATUS] Error:'), error.message);
|
|
132
|
+
res.status(500).json({ error: error.message });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Git Stage
|
|
137
|
+
this.app.post('/api/git/stage', async (req, res) => {
|
|
138
|
+
try {
|
|
139
|
+
const { files } = req.body;
|
|
140
|
+
const target = files.includes('*') ? '.' : files.map(f => `"${f}"`).join(' ');
|
|
141
|
+
await execAsync(`git add ${target}`, { cwd: this.workingDir });
|
|
142
|
+
res.json({ success: true });
|
|
143
|
+
} catch (error) {
|
|
144
|
+
res.status(500).json({ error: error.message });
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Git Unstage
|
|
149
|
+
this.app.post('/api/git/unstage', async (req, res) => {
|
|
150
|
+
try {
|
|
151
|
+
const { files } = req.body;
|
|
152
|
+
const target = files.includes('*') ? '' : files.map(f => `"${f}"`).join(' ');
|
|
153
|
+
await execAsync(`git reset HEAD ${target}`, { cwd: this.workingDir });
|
|
154
|
+
res.json({ success: true });
|
|
155
|
+
} catch (error) {
|
|
156
|
+
res.status(500).json({ error: error.message });
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Git Discard (NEW)
|
|
161
|
+
this.app.post('/api/git/discard', async (req, res) => {
|
|
162
|
+
try {
|
|
163
|
+
const { files } = req.body; // array or '*'
|
|
164
|
+
|
|
165
|
+
// Discard All
|
|
166
|
+
if (files.includes('*')) {
|
|
167
|
+
// Restore tracked files
|
|
168
|
+
try { await execAsync('git restore .', { cwd: this.workingDir }); } catch (e) {}
|
|
169
|
+
// Clean untracked files
|
|
170
|
+
try { await execAsync('git clean -fd', { cwd: this.workingDir }); } catch (e) {}
|
|
171
|
+
} else {
|
|
172
|
+
// Discard specific files
|
|
173
|
+
for (const file of files) {
|
|
174
|
+
// Try restore (for tracked modified/deleted)
|
|
175
|
+
try { await execAsync(`git restore "${file}"`, { cwd: this.workingDir }); } catch (e) {}
|
|
176
|
+
// Try clean (for untracked)
|
|
177
|
+
try { await execAsync(`git clean -f "${file}"`, { cwd: this.workingDir }); } catch (e) {}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
res.json({ success: true });
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error('Discard error:', error);
|
|
183
|
+
res.status(500).json({ error: error.message });
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Git Commit
|
|
188
|
+
this.app.post('/api/git/commit', async (req, res) => {
|
|
189
|
+
try {
|
|
190
|
+
const { message } = req.body;
|
|
191
|
+
if (!message) throw new Error('Commit message is required');
|
|
192
|
+
const safeMessage = message.replace(/"/g, '\\"');
|
|
193
|
+
await execAsync(`git commit -m "${safeMessage}"`, { cwd: this.workingDir });
|
|
194
|
+
res.json({ success: true });
|
|
195
|
+
} catch (error) {
|
|
196
|
+
res.status(500).json({ error: error.message });
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Get Diff
|
|
102
201
|
this.app.get('/api/git/diff', async (req, res) => {
|
|
103
202
|
try {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
203
|
+
const file = req.query.file;
|
|
204
|
+
const type = req.query.type || 'working';
|
|
205
|
+
|
|
206
|
+
let cmd = '';
|
|
207
|
+
|
|
208
|
+
if (type === 'staged') {
|
|
209
|
+
cmd = file ? `git diff --cached -- "${file}"` : `git diff --cached`;
|
|
210
|
+
} else {
|
|
211
|
+
if (file) {
|
|
212
|
+
const { stdout: isUntracked } = await execAsync(`git ls-files --others --exclude-standard "${file}"`, { cwd: this.workingDir });
|
|
213
|
+
if (isUntracked.trim()) {
|
|
214
|
+
const content = await fs.readFile(path.join(this.workingDir, file), 'utf8');
|
|
215
|
+
let fakeDiff = `diff --git a/${file} b/${file}\nnew file mode 100644\n--- /dev/null\n+++ b/${file}\n@@ -0,0 +1,${content.split('\n').length} @@\n`;
|
|
216
|
+
content.split('\n').forEach(l => fakeDiff += `+${l}\n`);
|
|
217
|
+
return res.json({ diff: fakeDiff });
|
|
218
|
+
}
|
|
219
|
+
cmd = `git diff -- "${file}"`;
|
|
220
|
+
} else {
|
|
221
|
+
cmd = `git diff`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const { stdout } = await execAsync(cmd, { cwd: this.workingDir, maxBuffer: 20 * 1024 * 1024 });
|
|
108
226
|
res.json({ diff: stdout });
|
|
109
227
|
} catch (error) {
|
|
110
|
-
console.error(chalk.red('❌ [GIT] Error:'), error.message);
|
|
228
|
+
console.error(chalk.red('❌ [GIT DIFF] Error:'), error.message);
|
|
111
229
|
res.json({ diff: '', error: error.message });
|
|
112
230
|
}
|
|
113
231
|
});
|
|
114
232
|
|
|
233
|
+
// --- GIT API END ---
|
|
234
|
+
|
|
115
235
|
this.app.post('/api/analyze', async (req, res) => {
|
|
116
236
|
const { path: projectPath, options = {}, specificFiles } = req.body;
|
|
117
237
|
if (!projectPath) return res.status(400).json({ error: 'Missing path' });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* --- LAYOUT
|
|
1
|
+
/* --- CONTAINER & LAYOUT --- */
|
|
2
2
|
.git-toggle-group {
|
|
3
3
|
display: flex;
|
|
4
4
|
align-items: center;
|
|
@@ -42,24 +42,6 @@
|
|
|
42
42
|
justify-content: center;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/* --- CONTAINER CHÍNH --- */
|
|
46
|
-
.right-panel {
|
|
47
|
-
position: relative;
|
|
48
|
-
/* Quan trọng */
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.d2h-file-list {
|
|
52
|
-
position: fixed;
|
|
53
|
-
top: 0;
|
|
54
|
-
left: 0;
|
|
55
|
-
z-index: 99;
|
|
56
|
-
background-color: #0d1117;
|
|
57
|
-
overflow: scroll;
|
|
58
|
-
height: calc(100vh - 46px);
|
|
59
|
-
width: 446px;
|
|
60
|
-
top: 46px;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
45
|
.git-view-container {
|
|
64
46
|
position: absolute;
|
|
65
47
|
top: 50px;
|
|
@@ -67,89 +49,275 @@
|
|
|
67
49
|
right: 0;
|
|
68
50
|
bottom: 0;
|
|
69
51
|
z-index: 9999;
|
|
70
|
-
/* Z-index cao nhất */
|
|
71
52
|
background: #0d1117;
|
|
72
|
-
/* Nền đen GitHub */
|
|
73
53
|
display: none;
|
|
74
|
-
flex-direction:
|
|
75
|
-
overflow:
|
|
54
|
+
flex-direction: row;
|
|
55
|
+
overflow: hidden;
|
|
76
56
|
}
|
|
77
57
|
|
|
78
58
|
.git-view-container.active {
|
|
79
59
|
display: flex;
|
|
80
60
|
}
|
|
81
61
|
|
|
82
|
-
/* ---
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
62
|
+
/* --- SIDEBAR --- */
|
|
63
|
+
.git-sidebar {
|
|
64
|
+
width: 300px;
|
|
65
|
+
min-width: 250px;
|
|
66
|
+
background: #0d1117;
|
|
67
|
+
border-right: 1px solid #30363d;
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
overflow-y: auto;
|
|
71
|
+
color: #c9d1d9;
|
|
72
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
73
|
+
user-select: none;
|
|
86
74
|
}
|
|
87
75
|
|
|
88
|
-
/*
|
|
89
|
-
.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/* Trắng xám */
|
|
94
|
-
background: transparent !important;
|
|
76
|
+
/* --- COMMIT SECTION --- */
|
|
77
|
+
.git-commit-section {
|
|
78
|
+
padding: 10px;
|
|
79
|
+
border-bottom: 1px solid #30363d;
|
|
80
|
+
background: #0d1117;
|
|
95
81
|
}
|
|
96
82
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
83
|
+
.git-commit-input {
|
|
84
|
+
width: 100%;
|
|
85
|
+
background: #161b22;
|
|
86
|
+
border: 1px solid #30363d;
|
|
87
|
+
color: #c9d1d9;
|
|
88
|
+
padding: 6px 8px;
|
|
89
|
+
border-radius: 4px;
|
|
90
|
+
font-family: inherit;
|
|
91
|
+
font-size: 13px;
|
|
92
|
+
resize: vertical;
|
|
93
|
+
min-height: 32px;
|
|
94
|
+
margin-bottom: 8px;
|
|
102
95
|
}
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
.git-commit-input:focus {
|
|
98
|
+
outline: 1px solid #58a6ff;
|
|
99
|
+
border-color: #58a6ff;
|
|
107
100
|
}
|
|
108
101
|
|
|
109
|
-
.
|
|
110
|
-
|
|
102
|
+
.git-commit-btn {
|
|
103
|
+
width: 100%;
|
|
104
|
+
background: #0078d4;
|
|
105
|
+
color: white;
|
|
106
|
+
border: none;
|
|
107
|
+
padding: 6px 12px;
|
|
108
|
+
border-radius: 2px;
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
font-size: 13px;
|
|
111
|
+
font-weight: 500;
|
|
112
|
+
display: flex;
|
|
113
|
+
align-items: center;
|
|
114
|
+
justify-content: center;
|
|
115
|
+
gap: 6px;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
flex: 1;
|
|
116
|
-
overflow: auto;
|
|
117
|
-
background: #0d1117;
|
|
118
|
+
.git-commit-btn:hover {
|
|
119
|
+
background: #026ec1;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
border-right: 1px solid #30363d;
|
|
125
|
-
display: flex;
|
|
126
|
-
flex-direction: column;
|
|
122
|
+
.git-commit-btn:disabled {
|
|
123
|
+
background: #30363d;
|
|
124
|
+
color: #8b949e;
|
|
125
|
+
cursor: not-allowed;
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
|
|
130
|
-
.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
128
|
+
/* --- SECTIONS & TREE --- */
|
|
129
|
+
.git-section {
|
|
130
|
+
margin-bottom: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.git-section-header {
|
|
134
|
+
padding: 8px 16px;
|
|
135
|
+
font-size: 11px;
|
|
136
|
+
font-weight: bold;
|
|
137
|
+
text-transform: uppercase;
|
|
138
|
+
color: #8b949e;
|
|
139
|
+
background: #161b22;
|
|
140
|
+
display: flex;
|
|
141
|
+
justify-content: space-between;
|
|
142
|
+
align-items: center;
|
|
143
|
+
cursor: pointer;
|
|
134
144
|
position: sticky;
|
|
135
145
|
top: 0;
|
|
136
146
|
z-index: 10;
|
|
147
|
+
border-bottom: 1px solid #21262d;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.git-section-header:hover {
|
|
151
|
+
color: #c9d1d9;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.git-badge {
|
|
155
|
+
background: #30363d;
|
|
156
|
+
color: #c9d1d9;
|
|
157
|
+
padding: 2px 6px;
|
|
158
|
+
border-radius: 10px;
|
|
159
|
+
font-size: 10px;
|
|
160
|
+
min-width: 18px;
|
|
161
|
+
text-align: center;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.git-tree-root {
|
|
165
|
+
list-style: none;
|
|
166
|
+
padding: 0;
|
|
167
|
+
margin: 0;
|
|
137
168
|
}
|
|
138
169
|
|
|
139
|
-
.
|
|
140
|
-
|
|
141
|
-
text-decoration: none;
|
|
142
|
-
display: block;
|
|
143
|
-
padding: 5px 10px;
|
|
170
|
+
.git-tree-node {
|
|
171
|
+
list-style: none;
|
|
144
172
|
}
|
|
145
173
|
|
|
146
|
-
.
|
|
147
|
-
|
|
174
|
+
.git-tree-content {
|
|
175
|
+
display: flex;
|
|
176
|
+
align-items: center;
|
|
177
|
+
padding: 4px 8px;
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
font-size: 13px;
|
|
180
|
+
height: 24px;
|
|
181
|
+
color: #c9d1d9;
|
|
182
|
+
white-space: nowrap;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.git-tree-content:hover {
|
|
148
186
|
background: #161b22;
|
|
149
187
|
}
|
|
150
188
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
189
|
+
.git-tree-content.selected {
|
|
190
|
+
background: #30363d;
|
|
191
|
+
color: #fff;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.git-indent-guide {
|
|
195
|
+
display: inline-block;
|
|
196
|
+
width: 16px;
|
|
197
|
+
height: 100%;
|
|
198
|
+
flex-shrink: 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.git-arrow {
|
|
202
|
+
width: 16px;
|
|
203
|
+
text-align: center;
|
|
204
|
+
font-size: 10px;
|
|
205
|
+
color: #8b949e;
|
|
206
|
+
transition: transform 0.15s;
|
|
207
|
+
display: inline-block;
|
|
208
|
+
flex-shrink: 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.git-tree-node.collapsed > .git-tree-content > .git-arrow {
|
|
212
|
+
transform: rotate(-90deg);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.git-tree-node.collapsed > ul {
|
|
216
|
+
display: none;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.git-icon {
|
|
220
|
+
margin-right: 6px;
|
|
221
|
+
font-weight: bold;
|
|
222
|
+
width: 16px;
|
|
223
|
+
text-align: center;
|
|
224
|
+
flex-shrink: 0;
|
|
225
|
+
font-size: 14px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Status Colors */
|
|
229
|
+
.git-status-M { color: #d29922; }
|
|
230
|
+
.git-status-A, .git-status-U { color: #3fb950; }
|
|
231
|
+
.git-status-D { color: #f85149; text-decoration: line-through; }
|
|
232
|
+
.git-status-R { color: #d29922; }
|
|
233
|
+
|
|
234
|
+
.git-label {
|
|
235
|
+
flex: 1;
|
|
236
|
+
overflow: hidden;
|
|
237
|
+
text-overflow: ellipsis;
|
|
238
|
+
white-space: nowrap;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.git-dir-label {
|
|
242
|
+
color: #c9d1d9;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.git-file-label {
|
|
246
|
+
color: #8b949e;
|
|
247
|
+
}
|
|
248
|
+
.git-tree-content:hover .git-file-label,
|
|
249
|
+
.git-tree-content.selected .git-file-label {
|
|
250
|
+
color: #e6edf3;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* ACTIONS */
|
|
254
|
+
.git-actions {
|
|
255
|
+
display: none;
|
|
256
|
+
margin-left: 6px;
|
|
257
|
+
flex-shrink: 0;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.git-tree-content:hover .git-actions {
|
|
261
|
+
display: flex;
|
|
262
|
+
gap: 4px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.git-btn-action {
|
|
266
|
+
background: transparent;
|
|
267
|
+
border: none;
|
|
268
|
+
color: #c9d1d9;
|
|
269
|
+
cursor: pointer;
|
|
270
|
+
padding: 0 4px;
|
|
271
|
+
border-radius: 4px;
|
|
272
|
+
font-size: 14px;
|
|
273
|
+
line-height: 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.git-btn-action:hover {
|
|
277
|
+
background: #30363d;
|
|
278
|
+
color: #fff;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Destructive Action (Discard) */
|
|
282
|
+
.git-btn-action.destructive:hover {
|
|
283
|
+
background: #f85149;
|
|
284
|
+
color: #fff;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* --- DIFF AREA --- */
|
|
288
|
+
.git-diff-area {
|
|
289
|
+
flex: 1;
|
|
290
|
+
overflow: auto;
|
|
291
|
+
background: #0d1117;
|
|
292
|
+
position: relative;
|
|
293
|
+
display: flex;
|
|
294
|
+
flex-direction: column;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.git-empty-state {
|
|
298
|
+
display: flex;
|
|
299
|
+
flex-direction: column;
|
|
300
|
+
align-items: center;
|
|
301
|
+
justify-content: center;
|
|
302
|
+
height: 100%;
|
|
303
|
+
color: #8b949e;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* Diff2Html Overrides */
|
|
307
|
+
.d2h-wrapper * { box-sizing: border-box; }
|
|
308
|
+
.d2h-file-list-wrapper { display: none; }
|
|
309
|
+
.d2h-wrapper { margin: 0; }
|
|
310
|
+
.d2h-file-header { display: none; }
|
|
311
|
+
.d2h-code-line-ctn, .d2h-code-line, .hljs {
|
|
312
|
+
color: #e6edf3 !important;
|
|
313
|
+
background: transparent !important;
|
|
314
|
+
font-family: Menlo, Monaco, Consolas, monospace;
|
|
315
|
+
font-size: 12px;
|
|
316
|
+
}
|
|
317
|
+
.d2h-code-side-linenumber {
|
|
318
|
+
background: #0d1117 !important;
|
|
319
|
+
border-color: #30363d !important;
|
|
320
|
+
color: #6e7681 !important;
|
|
321
|
+
}
|
|
322
|
+
.d2h-ins { background-color: rgba(46, 160, 67, 0.15) !important; }
|
|
323
|
+
.d2h-del { background-color: rgba(248, 81, 73, 0.15) !important; }
|