@ycniuqton/devlens 0.1.8 → 0.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.
- package/dist/services/git.js +1 -0
- package/dist/services/git.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
- package/public/css/style.css +145 -1
- package/public/js/history.js +66 -8
package/dist/services/git.js
CHANGED
package/dist/services/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/services/git.ts"],"names":[],"mappings":";;;;;AAeA,
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/services/git.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
package/public/css/style.css
CHANGED
|
@@ -1781,9 +1781,16 @@ body {
|
|
|
1781
1781
|
}
|
|
1782
1782
|
|
|
1783
1783
|
.commit-header-content {
|
|
1784
|
+
display: flex;
|
|
1785
|
+
flex-direction: column;
|
|
1786
|
+
gap: var(--sp-3);
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
.commit-header-top {
|
|
1784
1790
|
display: flex;
|
|
1785
1791
|
align-items: center;
|
|
1786
1792
|
gap: var(--sp-3);
|
|
1793
|
+
flex-wrap: wrap;
|
|
1787
1794
|
}
|
|
1788
1795
|
|
|
1789
1796
|
.commit-header-hash {
|
|
@@ -1796,15 +1803,112 @@ body {
|
|
|
1796
1803
|
border-radius: var(--radius-sm);
|
|
1797
1804
|
}
|
|
1798
1805
|
|
|
1806
|
+
.commit-header-meta {
|
|
1807
|
+
display: flex;
|
|
1808
|
+
align-items: center;
|
|
1809
|
+
gap: var(--sp-2);
|
|
1810
|
+
font-size: var(--text-xs);
|
|
1811
|
+
color: var(--color-text-muted);
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1799
1814
|
.commit-header-files {
|
|
1800
1815
|
font-size: var(--text-xs);
|
|
1801
1816
|
color: var(--color-text-muted);
|
|
1802
1817
|
}
|
|
1803
1818
|
|
|
1819
|
+
.commit-header-message {
|
|
1820
|
+
background: var(--color-bg);
|
|
1821
|
+
border: 1px solid var(--color-border-subtle);
|
|
1822
|
+
border-radius: var(--radius-md);
|
|
1823
|
+
padding: var(--sp-3) var(--sp-4);
|
|
1824
|
+
max-height: 240px;
|
|
1825
|
+
overflow-y: auto;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
.commit-header-subject {
|
|
1829
|
+
font-size: var(--text-base);
|
|
1830
|
+
font-weight: 600;
|
|
1831
|
+
color: var(--color-text);
|
|
1832
|
+
word-break: break-word;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
.commit-header-body {
|
|
1836
|
+
margin: var(--sp-2) 0 0;
|
|
1837
|
+
font-family: var(--font-mono);
|
|
1838
|
+
font-size: var(--text-xs);
|
|
1839
|
+
color: var(--color-text-secondary);
|
|
1840
|
+
white-space: pre-wrap;
|
|
1841
|
+
word-break: break-word;
|
|
1842
|
+
line-height: var(--leading-normal);
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1804
1845
|
.commit-header-actions {
|
|
1805
|
-
margin-left: auto;
|
|
1806
1846
|
display: flex;
|
|
1807
1847
|
gap: var(--sp-2);
|
|
1848
|
+
flex-wrap: wrap;
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
/* Hover tooltip on commit list items */
|
|
1852
|
+
.commit-item { position: relative; }
|
|
1853
|
+
|
|
1854
|
+
.commit-tooltip {
|
|
1855
|
+
position: absolute;
|
|
1856
|
+
left: calc(100% + 12px);
|
|
1857
|
+
top: 50%;
|
|
1858
|
+
transform: translateY(-50%);
|
|
1859
|
+
background: var(--color-surface-2);
|
|
1860
|
+
border: 1px solid var(--color-border);
|
|
1861
|
+
border-radius: var(--radius-md);
|
|
1862
|
+
padding: var(--sp-3) var(--sp-4);
|
|
1863
|
+
min-width: 320px;
|
|
1864
|
+
max-width: 480px;
|
|
1865
|
+
box-shadow: var(--shadow-lg);
|
|
1866
|
+
opacity: 0;
|
|
1867
|
+
pointer-events: none;
|
|
1868
|
+
transform-origin: left center;
|
|
1869
|
+
transform: translateY(-50%) scale(0.95);
|
|
1870
|
+
transition: opacity var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
|
|
1871
|
+
z-index: 50;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
.commit-item:hover .commit-tooltip {
|
|
1875
|
+
opacity: 1;
|
|
1876
|
+
transform: translateY(-50%) scale(1);
|
|
1877
|
+
transition-delay: 250ms;
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
.commit-tooltip::before {
|
|
1881
|
+
content: '';
|
|
1882
|
+
position: absolute;
|
|
1883
|
+
left: -6px;
|
|
1884
|
+
top: 50%;
|
|
1885
|
+
transform: translateY(-50%);
|
|
1886
|
+
width: 0;
|
|
1887
|
+
height: 0;
|
|
1888
|
+
border-top: 6px solid transparent;
|
|
1889
|
+
border-bottom: 6px solid transparent;
|
|
1890
|
+
border-right: 6px solid var(--color-border);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
.commit-tooltip-message {
|
|
1894
|
+
font-family: var(--font-mono);
|
|
1895
|
+
font-size: var(--text-xs);
|
|
1896
|
+
color: var(--color-text);
|
|
1897
|
+
white-space: pre-wrap;
|
|
1898
|
+
word-break: break-word;
|
|
1899
|
+
line-height: var(--leading-normal);
|
|
1900
|
+
max-height: 240px;
|
|
1901
|
+
overflow-y: auto;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
.commit-tooltip-meta {
|
|
1905
|
+
display: flex;
|
|
1906
|
+
gap: var(--sp-2);
|
|
1907
|
+
margin-top: var(--sp-2);
|
|
1908
|
+
padding-top: var(--sp-2);
|
|
1909
|
+
border-top: 1px solid var(--color-border-subtle);
|
|
1910
|
+
font-size: 10px;
|
|
1911
|
+
color: var(--color-text-muted);
|
|
1808
1912
|
}
|
|
1809
1913
|
|
|
1810
1914
|
.commit-detail-diff {
|
|
@@ -1849,7 +1953,47 @@ body {
|
|
|
1849
1953
|
overflow: hidden;
|
|
1850
1954
|
text-overflow: ellipsis;
|
|
1851
1955
|
white-space: nowrap;
|
|
1956
|
+
flex: 1;
|
|
1957
|
+
min-width: 0;
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
/* File status icon (left of filename) */
|
|
1961
|
+
.commit-file-status-icon {
|
|
1962
|
+
display: inline-flex;
|
|
1963
|
+
align-items: center;
|
|
1964
|
+
justify-content: center;
|
|
1965
|
+
width: 20px;
|
|
1966
|
+
height: 20px;
|
|
1967
|
+
border-radius: var(--radius-sm);
|
|
1968
|
+
flex-shrink: 0;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
.commit-file-status-icon.added { color: var(--color-success); background: var(--color-success-subtle); }
|
|
1972
|
+
.commit-file-status-icon.modified { color: var(--color-warning); background: var(--color-warning-subtle); }
|
|
1973
|
+
.commit-file-status-icon.deleted { color: var(--color-danger); background: var(--color-danger-subtle); }
|
|
1974
|
+
.commit-file-status-icon.renamed { color: var(--color-purple); background: var(--color-purple-subtle); }
|
|
1975
|
+
|
|
1976
|
+
/* File status text tag (right side) */
|
|
1977
|
+
.commit-file-status-tag {
|
|
1978
|
+
font-size: 10px;
|
|
1979
|
+
font-weight: 700;
|
|
1980
|
+
letter-spacing: 0.06em;
|
|
1981
|
+
padding: 2px 8px;
|
|
1982
|
+
border-radius: var(--radius-sm);
|
|
1983
|
+
flex-shrink: 0;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
.commit-file-status-tag.added { color: var(--color-success); background: var(--color-success-subtle); }
|
|
1987
|
+
.commit-file-status-tag.modified { color: var(--color-warning); background: var(--color-warning-subtle); }
|
|
1988
|
+
.commit-file-status-tag.deleted { color: var(--color-danger); background: var(--color-danger-subtle); }
|
|
1989
|
+
.commit-file-status-tag.renamed { color: var(--color-purple); background: var(--color-purple-subtle); }
|
|
1990
|
+
|
|
1991
|
+
/* Filename color hints based on status */
|
|
1992
|
+
.commit-file-header.file-status-deleted .commit-file-name {
|
|
1993
|
+
text-decoration: line-through;
|
|
1994
|
+
color: var(--color-text-muted);
|
|
1852
1995
|
}
|
|
1996
|
+
.commit-file-header.file-status-added .commit-file-name { color: var(--color-success); }
|
|
1853
1997
|
|
|
1854
1998
|
.commit-file-body {
|
|
1855
1999
|
display: none;
|
package/public/js/history.js
CHANGED
|
@@ -4,6 +4,7 @@ var historyLoaded = false;
|
|
|
4
4
|
var historySelectedHash = null;
|
|
5
5
|
var historyViewMode = localStorage.getItem('devlens-history-view') || 'side-by-side';
|
|
6
6
|
var historyCachedData = null; // last loaded commit { hash, files, diff }
|
|
7
|
+
var historyCommits = []; // last loaded commit list (for full message lookup)
|
|
7
8
|
|
|
8
9
|
async function loadBranchInfo() {
|
|
9
10
|
try {
|
|
@@ -20,6 +21,7 @@ async function loadCommits() {
|
|
|
20
21
|
try {
|
|
21
22
|
const res = await fetch('/api/browser/commits?limit=100');
|
|
22
23
|
const commits = await res.json();
|
|
24
|
+
historyCommits = commits;
|
|
23
25
|
document.getElementById('commit-count').textContent = commits.length;
|
|
24
26
|
|
|
25
27
|
if (!commits.length) {
|
|
@@ -27,7 +29,9 @@ async function loadCommits() {
|
|
|
27
29
|
return;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
list.innerHTML = commits.map(c =>
|
|
32
|
+
list.innerHTML = commits.map(c => {
|
|
33
|
+
const fullMessage = c.body ? `${c.message}\n\n${c.body}` : c.message;
|
|
34
|
+
return `
|
|
31
35
|
<li class="commit-item" data-hash="${c.hash}">
|
|
32
36
|
<div class="commit-marker"></div>
|
|
33
37
|
<div class="commit-content">
|
|
@@ -38,8 +42,16 @@ async function loadCommits() {
|
|
|
38
42
|
<span class="commit-date">${formatRelativeDate(c.date)}</span>
|
|
39
43
|
</div>
|
|
40
44
|
</div>
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
<div class="commit-tooltip">
|
|
46
|
+
<div class="commit-tooltip-message">${escapeHtmlHistory(fullMessage)}</div>
|
|
47
|
+
<div class="commit-tooltip-meta">
|
|
48
|
+
<span>${escapeHtmlHistory(c.author)}</span>
|
|
49
|
+
<span>·</span>
|
|
50
|
+
<span>${new Date(c.date).toLocaleString()}</span>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</li>`;
|
|
54
|
+
}).join('');
|
|
43
55
|
|
|
44
56
|
list.querySelectorAll('.commit-item').forEach(item => {
|
|
45
57
|
item.addEventListener('click', () => {
|
|
@@ -99,11 +111,26 @@ function renderCommitDetails(hash, data) {
|
|
|
99
111
|
if (!headerEl || !diffEl) return;
|
|
100
112
|
|
|
101
113
|
const isUnified = historyViewMode === 'line-by-line';
|
|
114
|
+
const commit = historyCommits.find(c => c.hash === hash) || {};
|
|
115
|
+
const subject = commit.message || '';
|
|
116
|
+
const body = commit.body || '';
|
|
117
|
+
const author = commit.author || '';
|
|
118
|
+
const date = commit.date ? new Date(commit.date).toLocaleString() : '';
|
|
102
119
|
|
|
103
120
|
headerEl.innerHTML = `
|
|
104
121
|
<div class="commit-header-content">
|
|
105
|
-
<div class="commit-header-
|
|
106
|
-
|
|
122
|
+
<div class="commit-header-top">
|
|
123
|
+
<div class="commit-header-hash">${hash}</div>
|
|
124
|
+
<div class="commit-header-meta">
|
|
125
|
+
${author ? `<span>${escapeHtmlHistory(author)}</span>` : ''}
|
|
126
|
+
${date ? `<span>·</span><span>${date}</span>` : ''}
|
|
127
|
+
<span>·</span><span>${data.files.length} file(s)</span>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="commit-header-message">
|
|
131
|
+
<div class="commit-header-subject">${escapeHtmlHistory(subject)}</div>
|
|
132
|
+
${body ? `<pre class="commit-header-body">${escapeHtmlHistory(body)}</pre>` : ''}
|
|
133
|
+
</div>
|
|
107
134
|
<div class="commit-header-actions">
|
|
108
135
|
<div class="btn-group">
|
|
109
136
|
<button class="btn btn-ghost btn-sm ${!isUnified ? 'active' : ''}" id="history-view-split" title="Side by side">
|
|
@@ -134,6 +161,10 @@ function renderCommitDetails(hash, data) {
|
|
|
134
161
|
|
|
135
162
|
const files = historySplitDiffByFile(data.diff);
|
|
136
163
|
|
|
164
|
+
// Build a path → status map from data.files (e.g. "added", "modified", "deleted", "renamed")
|
|
165
|
+
const statusByPath = {};
|
|
166
|
+
for (const f of (data.files || [])) statusByPath[f.path] = f.status;
|
|
167
|
+
|
|
137
168
|
// Stash raw diffs on a closure-accessible array indexed by data-idx
|
|
138
169
|
const renderCommitFileBody = (section) => {
|
|
139
170
|
const body = section.querySelector('.commit-file-body');
|
|
@@ -150,15 +181,20 @@ function renderCommitDetails(hash, data) {
|
|
|
150
181
|
body.dataset.rendered = 'true';
|
|
151
182
|
};
|
|
152
183
|
|
|
153
|
-
diffEl.innerHTML = files.map((file, i) =>
|
|
184
|
+
diffEl.innerHTML = files.map((file, i) => {
|
|
185
|
+
const status = statusByPath[file.name] || 'modified';
|
|
186
|
+
return `
|
|
154
187
|
<div class="commit-file-section" data-file="${escapeAttrHistory(file.name)}" data-idx="${i}">
|
|
155
|
-
<div class="commit-file-header">
|
|
188
|
+
<div class="commit-file-header file-status-${status}">
|
|
156
189
|
<svg class="commit-file-chevron" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
|
190
|
+
<span class="commit-file-status-icon ${status}" title="${status}">${commitFileStatusIcon(status)}</span>
|
|
157
191
|
<span class="commit-file-name">${escapeHtmlHistory(file.name)}</span>
|
|
192
|
+
<span class="commit-file-status-tag ${status}">${commitFileStatusLabel(status)}</span>
|
|
158
193
|
</div>
|
|
159
194
|
<div class="commit-file-body" data-rendered="false"></div>
|
|
160
195
|
</div>
|
|
161
|
-
|
|
196
|
+
`;
|
|
197
|
+
}).join('');
|
|
162
198
|
|
|
163
199
|
// Wire collapse/expand with lazy render on first expand
|
|
164
200
|
diffEl.querySelectorAll('.commit-file-header').forEach(h => {
|
|
@@ -198,6 +234,28 @@ function escapeAttrHistory(str) {
|
|
|
198
234
|
return String(str).replace(/"/g, '"');
|
|
199
235
|
}
|
|
200
236
|
|
|
237
|
+
function commitFileStatusIcon(status) {
|
|
238
|
+
// SVG icons for each git status
|
|
239
|
+
const svg = (path) => `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">${path}</svg>`;
|
|
240
|
+
switch (status) {
|
|
241
|
+
case 'added': return svg('<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>'); // +
|
|
242
|
+
case 'deleted': return svg('<line x1="5" y1="12" x2="19" y2="12"/>'); // —
|
|
243
|
+
case 'renamed': return svg('<polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>'); // ↻
|
|
244
|
+
case 'modified':
|
|
245
|
+
default: return svg('<circle cx="12" cy="12" r="3"/>'); // •
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function commitFileStatusLabel(status) {
|
|
250
|
+
switch (status) {
|
|
251
|
+
case 'added': return 'NEW';
|
|
252
|
+
case 'deleted': return 'DEL';
|
|
253
|
+
case 'renamed': return 'REN';
|
|
254
|
+
case 'modified': return 'MOD';
|
|
255
|
+
default: return status.toUpperCase();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
201
259
|
function escapeHtmlHistory(str) {
|
|
202
260
|
if (str == null) return '';
|
|
203
261
|
const div = document.createElement('div');
|