@ai-setting/roy-plugin-task-show 1.2.0 → 2.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.
- package/dist/file-tree.d.ts +184 -0
- package/dist/file-tree.d.ts.map +1 -0
- package/dist/file-tree.js +371 -0
- package/dist/file-tree.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +148 -53
- package/dist/server.js.map +1 -1
- package/dist/tool-call-detail.d.ts +123 -0
- package/dist/tool-call-detail.d.ts.map +1 -0
- package/dist/tool-call-detail.js +423 -0
- package/dist/tool-call-detail.js.map +1 -0
- package/package.json +1 -1
- package/plugin.json +2 -2
- package/public/file-tree.js +210 -0
- package/public/style.css +502 -0
- package/public/tool-call-detail.js +311 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/* v2.0.0: file-tree sidebar hydrator.
|
|
2
|
+
*
|
|
3
|
+
* Loads the project file list from the data-files JSON attribute on the
|
|
4
|
+
* SSR-rendered `<ul id="file-tree">` and wires up:
|
|
5
|
+
* - chevron toggle (▶ / ▼) for directories
|
|
6
|
+
* - "expand all / collapse all" controls
|
|
7
|
+
* - click-to-highlight a file node (calls window.setActiveToolCallFile)
|
|
8
|
+
* - scrolling a node into view when window.__toolClick is fired
|
|
9
|
+
*
|
|
10
|
+
* Designed to be loaded AFTER app.js (so it can hook __toolClick) but
|
|
11
|
+
* BEFORE tool-call-detail.js (so that hydrator can call our
|
|
12
|
+
* setActiveToolCallFile when a Mermaid node is clicked).
|
|
13
|
+
*
|
|
14
|
+
* No dependencies — pure vanilla JS, no module loader, no JSX.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
(function attachFileTreeHydrator() {
|
|
18
|
+
const SIDEBAR_SELECTOR = "#file-tree";
|
|
19
|
+
|
|
20
|
+
// -----------------------------------------------------------------------
|
|
21
|
+
// State
|
|
22
|
+
// -----------------------------------------------------------------------
|
|
23
|
+
/** @type {HTMLElement|null} */
|
|
24
|
+
let root = null;
|
|
25
|
+
/** @type {Set<string>} */
|
|
26
|
+
let affectedSet = new Set();
|
|
27
|
+
/** @type {string|null} */
|
|
28
|
+
let activePath = null;
|
|
29
|
+
|
|
30
|
+
// -----------------------------------------------------------------------
|
|
31
|
+
// Helpers
|
|
32
|
+
// -----------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Toggle visibility of a directory's children.
|
|
36
|
+
* @param {HTMLElement} li
|
|
37
|
+
*/
|
|
38
|
+
function toggleDir(li) {
|
|
39
|
+
const isOpen = li.getAttribute("aria-expanded") === "true";
|
|
40
|
+
const next = !isOpen;
|
|
41
|
+
li.setAttribute("aria-expanded", String(next));
|
|
42
|
+
const chev = li.querySelector(".file-tree-chevron");
|
|
43
|
+
if (chev) chev.textContent = next ? "▼" : "▶";
|
|
44
|
+
// Update descendant visibility by toggling the `data-collapsed` flag on
|
|
45
|
+
// every sibling immediately under this directory.
|
|
46
|
+
const depth = Number(li.getAttribute("data-depth") || "0");
|
|
47
|
+
let sibling = li.nextElementSibling;
|
|
48
|
+
while (sibling) {
|
|
49
|
+
const sDepth = Number(sibling.getAttribute("data-depth") || "0");
|
|
50
|
+
if (sDepth <= depth) break;
|
|
51
|
+
if (!next) {
|
|
52
|
+
sibling.setAttribute("data-collapsed", "true");
|
|
53
|
+
} else {
|
|
54
|
+
sibling.removeAttribute("data-collapsed");
|
|
55
|
+
}
|
|
56
|
+
sibling = sibling.nextElementSibling;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set the active (highlighted) file path. Called by the tool-call
|
|
62
|
+
* detail hydrator when the user clicks a Mermaid tool node.
|
|
63
|
+
* @param {string|null} path
|
|
64
|
+
*/
|
|
65
|
+
function setActive(path) {
|
|
66
|
+
if (!root) return;
|
|
67
|
+
if (activePath) {
|
|
68
|
+
const prev = root.querySelector(`[data-path="${cssEscape(activePath)}"]`);
|
|
69
|
+
if (prev) prev.classList.remove("is-active");
|
|
70
|
+
}
|
|
71
|
+
activePath = path;
|
|
72
|
+
if (path) {
|
|
73
|
+
const next = root.querySelector(`[data-path="${cssEscape(path)}"]`);
|
|
74
|
+
if (next) {
|
|
75
|
+
next.classList.add("is-active");
|
|
76
|
+
// Expand parent directories so the active node is visible.
|
|
77
|
+
expandAncestors(next);
|
|
78
|
+
// Scroll into view (block: 'center') — but only if it's not
|
|
79
|
+
// already on-screen so we don't fight the user mid-scroll.
|
|
80
|
+
try {
|
|
81
|
+
next.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
82
|
+
} catch {
|
|
83
|
+
try {
|
|
84
|
+
next.scrollIntoView();
|
|
85
|
+
} catch (_) {
|
|
86
|
+
/* noop */
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Walk up the DOM expanding every ancestor directory so the given
|
|
95
|
+
* node becomes visible. Cheap because the tree is at most ~10 levels
|
|
96
|
+
* deep in practice.
|
|
97
|
+
* @param {HTMLElement} leaf
|
|
98
|
+
*/
|
|
99
|
+
function expandAncestors(leaf) {
|
|
100
|
+
let cur = leaf.previousElementSibling;
|
|
101
|
+
let targetDepth = Number(leaf.getAttribute("data-depth") || "0");
|
|
102
|
+
while (cur) {
|
|
103
|
+
const d = Number(cur.getAttribute("data-depth") || "0");
|
|
104
|
+
if (d < targetDepth) {
|
|
105
|
+
if (cur.getAttribute("aria-expanded") === "false") {
|
|
106
|
+
toggleDir(cur);
|
|
107
|
+
}
|
|
108
|
+
targetDepth = d; // keep walking
|
|
109
|
+
}
|
|
110
|
+
cur = cur.previousElementSibling;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* CSS.escape polyfill — older browsers / jsdom may lack it.
|
|
116
|
+
* @param {string} s
|
|
117
|
+
*/
|
|
118
|
+
function cssEscape(s) {
|
|
119
|
+
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
120
|
+
return CSS.escape(s);
|
|
121
|
+
}
|
|
122
|
+
return String(s).replace(/([^a-zA-Z0-9_-])/g, "\\$1");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// -----------------------------------------------------------------------
|
|
126
|
+
// Wiring
|
|
127
|
+
// -----------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Build the affected set from `[data-affected="true"]` nodes the SSR
|
|
131
|
+
* already flagged. Re-runs on each hydration so SSE-inserted nodes
|
|
132
|
+
* stay highlighted.
|
|
133
|
+
*/
|
|
134
|
+
function rebuildAffectedSet() {
|
|
135
|
+
if (!root) return;
|
|
136
|
+
affectedSet = new Set();
|
|
137
|
+
root.querySelectorAll('[data-affected="true"]').forEach((el) => {
|
|
138
|
+
const p = el.getAttribute("data-path");
|
|
139
|
+
if (p) affectedSet.add(p);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Initial hydration: bind click handlers + collect the affected set.
|
|
145
|
+
* Idempotent — safe to call multiple times.
|
|
146
|
+
*/
|
|
147
|
+
function hydrate() {
|
|
148
|
+
root = document.querySelector(SIDEBAR_SELECTOR);
|
|
149
|
+
if (!root) return;
|
|
150
|
+
rebuildAffectedSet();
|
|
151
|
+
root.addEventListener("click", (ev) => {
|
|
152
|
+
const target = ev.target;
|
|
153
|
+
// jsdom's eval'd scripts don't have `Element` in scope; use a
|
|
154
|
+
// duck-type check instead of `instanceof Element`.
|
|
155
|
+
if (!target || typeof target.getAttribute !== "function") return;
|
|
156
|
+
const li = target.closest && target.closest(".file-tree-node");
|
|
157
|
+
if (!li || typeof li.getAttribute !== "function") return;
|
|
158
|
+
const path = li.getAttribute("data-path") || null;
|
|
159
|
+
const type = li.getAttribute("data-type");
|
|
160
|
+
if (type === "directory") {
|
|
161
|
+
toggleDir(li);
|
|
162
|
+
// Suppress the subsequent active-path switch — directories
|
|
163
|
+
// aren't files, just containers.
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (path) setActive(path);
|
|
167
|
+
});
|
|
168
|
+
// Auto-hydrate on DOMContentLoaded if the DOM is already ready.
|
|
169
|
+
if (document.readyState === "loading") {
|
|
170
|
+
document.addEventListener("DOMContentLoaded", hydrate, { once: true });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
hydrate();
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Expand every directory in the tree (used by the "expand all" button).
|
|
177
|
+
*/
|
|
178
|
+
function expandAll() {
|
|
179
|
+
if (!root) return;
|
|
180
|
+
root.querySelectorAll('.file-tree-node[data-type="directory"]').forEach((li) => {
|
|
181
|
+
if (li.getAttribute("aria-expanded") === "false") toggleDir(li);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Collapse every directory (used by "collapse all").
|
|
187
|
+
*/
|
|
188
|
+
function collapseAll() {
|
|
189
|
+
if (!root) return;
|
|
190
|
+
root.querySelectorAll('.file-tree-node[data-type="directory"]').forEach((li) => {
|
|
191
|
+
if (li.getAttribute("aria-expanded") === "true") toggleDir(li);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Expose a tiny global API so other scripts (app.js, tool-call-detail.js)
|
|
196
|
+
// can drive the sidebar.
|
|
197
|
+
/** @type {any} */
|
|
198
|
+
const w = window;
|
|
199
|
+
w.__fileTree = {
|
|
200
|
+
setActive,
|
|
201
|
+
expandAll,
|
|
202
|
+
collapseAll,
|
|
203
|
+
/** Refresh affected-set from the current DOM (called by SSE handlers). */
|
|
204
|
+
refreshAffected: rebuildAffectedSet,
|
|
205
|
+
/** Return the currently-highlighted file path, or null. */
|
|
206
|
+
getActive() {
|
|
207
|
+
return activePath;
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
})();
|
package/public/style.css
CHANGED
|
@@ -1154,3 +1154,505 @@ details summary {
|
|
|
1154
1154
|
margin-bottom: 8px;
|
|
1155
1155
|
}
|
|
1156
1156
|
}
|
|
1157
|
+
|
|
1158
|
+
/* ============================================================================
|
|
1159
|
+
* v2.0.0: Monaco Editor + File Tree + Diff + Mermaid jump
|
|
1160
|
+
*
|
|
1161
|
+
* Sections (search for the header to navigate):
|
|
1162
|
+
* - .task-v2-layout — sidebar + main grid
|
|
1163
|
+
* - .file-tree-panel — left sidebar
|
|
1164
|
+
* - .file-tree — collapsible nested list
|
|
1165
|
+
* - .file-tree-node — individual rows
|
|
1166
|
+
* - .file-tree-chevron — directory expand/collapse
|
|
1167
|
+
* - .tool-call-detail — right-hand detail panel
|
|
1168
|
+
* - .monaco-editor — Monaco container
|
|
1169
|
+
* - .diff-body / .diff-line — LCS diff rendering
|
|
1170
|
+
* - .v2-hint — small inline hints
|
|
1171
|
+
* ========================================================================== */
|
|
1172
|
+
|
|
1173
|
+
/* ---------- v2.0.0 layout (sidebar + main) ---------- */
|
|
1174
|
+
.task-v2-layout {
|
|
1175
|
+
display: grid;
|
|
1176
|
+
grid-template-columns: minmax(220px, 280px) 1fr;
|
|
1177
|
+
gap: 16px;
|
|
1178
|
+
margin: 0 auto;
|
|
1179
|
+
max-width: 1400px;
|
|
1180
|
+
padding: 0 16px;
|
|
1181
|
+
}
|
|
1182
|
+
.task-v2-layout > .task-v2-main {
|
|
1183
|
+
min-width: 0; /* allow grid item to shrink */
|
|
1184
|
+
}
|
|
1185
|
+
.file-tree-panel {
|
|
1186
|
+
position: sticky;
|
|
1187
|
+
top: 12px;
|
|
1188
|
+
align-self: start;
|
|
1189
|
+
max-height: calc(100vh - 24px);
|
|
1190
|
+
overflow: auto;
|
|
1191
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1192
|
+
border-radius: 6px;
|
|
1193
|
+
padding: 12px 14px;
|
|
1194
|
+
background: var(--bg-panel, #fafafa);
|
|
1195
|
+
}
|
|
1196
|
+
.file-tree-panel h2 {
|
|
1197
|
+
font-size: 14px;
|
|
1198
|
+
margin: 0 0 6px;
|
|
1199
|
+
letter-spacing: 0.02em;
|
|
1200
|
+
}
|
|
1201
|
+
.file-tree-summary {
|
|
1202
|
+
font-size: 11px;
|
|
1203
|
+
color: var(--fg-muted, #6b7280);
|
|
1204
|
+
margin: 0 0 8px;
|
|
1205
|
+
}
|
|
1206
|
+
@media (max-width: 900px) {
|
|
1207
|
+
.task-v2-layout {
|
|
1208
|
+
grid-template-columns: 1fr;
|
|
1209
|
+
}
|
|
1210
|
+
.file-tree-panel {
|
|
1211
|
+
position: static;
|
|
1212
|
+
max-height: none;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/* ---------- file tree sidebar ---------- */
|
|
1217
|
+
.file-tree {
|
|
1218
|
+
list-style: none;
|
|
1219
|
+
margin: 0;
|
|
1220
|
+
padding: 0;
|
|
1221
|
+
font-family: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, monospace;
|
|
1222
|
+
font-size: 12px;
|
|
1223
|
+
line-height: 1.5;
|
|
1224
|
+
}
|
|
1225
|
+
.file-tree-node {
|
|
1226
|
+
display: flex;
|
|
1227
|
+
align-items: center;
|
|
1228
|
+
gap: 4px;
|
|
1229
|
+
padding: 1px 4px 1px calc(4px + var(--depth, 0) * 12px);
|
|
1230
|
+
border-radius: 3px;
|
|
1231
|
+
cursor: pointer;
|
|
1232
|
+
user-select: none;
|
|
1233
|
+
}
|
|
1234
|
+
.file-tree-node[data-collapsed="true"] {
|
|
1235
|
+
display: none;
|
|
1236
|
+
}
|
|
1237
|
+
.file-tree-node:hover {
|
|
1238
|
+
background: rgba(99, 102, 241, 0.08);
|
|
1239
|
+
}
|
|
1240
|
+
.file-tree-node.is-active {
|
|
1241
|
+
background: rgba(99, 102, 241, 0.18);
|
|
1242
|
+
outline: 1px solid rgba(99, 102, 241, 0.45);
|
|
1243
|
+
font-weight: 600;
|
|
1244
|
+
}
|
|
1245
|
+
.file-tree-node.is-affected .file-tree-name::after {
|
|
1246
|
+
content: " ●";
|
|
1247
|
+
color: rgba(220, 38, 38, 0.8);
|
|
1248
|
+
font-size: 10px;
|
|
1249
|
+
}
|
|
1250
|
+
.file-tree-chevron {
|
|
1251
|
+
display: inline-block;
|
|
1252
|
+
width: 12px;
|
|
1253
|
+
text-align: center;
|
|
1254
|
+
font-size: 9px;
|
|
1255
|
+
color: var(--fg-muted, #6b7280);
|
|
1256
|
+
flex: 0 0 12px;
|
|
1257
|
+
}
|
|
1258
|
+
.file-tree-spacer {
|
|
1259
|
+
display: inline-block;
|
|
1260
|
+
width: 12px;
|
|
1261
|
+
flex: 0 0 12px;
|
|
1262
|
+
}
|
|
1263
|
+
.file-tree-name {
|
|
1264
|
+
flex: 1 1 auto;
|
|
1265
|
+
white-space: nowrap;
|
|
1266
|
+
overflow: hidden;
|
|
1267
|
+
text-overflow: ellipsis;
|
|
1268
|
+
}
|
|
1269
|
+
.file-tree-empty {
|
|
1270
|
+
list-style: none;
|
|
1271
|
+
color: var(--fg-muted, #6b7280);
|
|
1272
|
+
font-style: italic;
|
|
1273
|
+
padding: 4px;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/* ---------- tool-call detail panel ---------- */
|
|
1277
|
+
.tool-call-detail-panel {
|
|
1278
|
+
border-left: 4px solid rgba(99, 102, 241, 0.55);
|
|
1279
|
+
padding-left: 14px;
|
|
1280
|
+
margin-top: 18px;
|
|
1281
|
+
}
|
|
1282
|
+
.tool-call-detail-panel .v2-hint {
|
|
1283
|
+
font-size: 12px;
|
|
1284
|
+
font-weight: 400;
|
|
1285
|
+
color: var(--fg-muted, #6b7280);
|
|
1286
|
+
margin-left: 8px;
|
|
1287
|
+
}
|
|
1288
|
+
.tool-call-detail {
|
|
1289
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1290
|
+
border-radius: 6px;
|
|
1291
|
+
padding: 10px 12px;
|
|
1292
|
+
margin-top: 8px;
|
|
1293
|
+
background: #ffffff;
|
|
1294
|
+
}
|
|
1295
|
+
.tool-call-header {
|
|
1296
|
+
display: flex;
|
|
1297
|
+
align-items: center;
|
|
1298
|
+
gap: 10px;
|
|
1299
|
+
font-size: 13px;
|
|
1300
|
+
margin-bottom: 6px;
|
|
1301
|
+
}
|
|
1302
|
+
.tool-call-header .tool-name code {
|
|
1303
|
+
background: rgba(99, 102, 241, 0.08);
|
|
1304
|
+
padding: 1px 6px;
|
|
1305
|
+
border-radius: 3px;
|
|
1306
|
+
}
|
|
1307
|
+
.tool-call-header .tool-path {
|
|
1308
|
+
color: var(--fg-muted, #6b7280);
|
|
1309
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
1310
|
+
font-size: 11px;
|
|
1311
|
+
margin-left: auto;
|
|
1312
|
+
overflow: hidden;
|
|
1313
|
+
text-overflow: ellipsis;
|
|
1314
|
+
white-space: nowrap;
|
|
1315
|
+
flex: 1 1 auto;
|
|
1316
|
+
}
|
|
1317
|
+
.tool-call-detail-empty {
|
|
1318
|
+
color: var(--fg-muted, #6b7280);
|
|
1319
|
+
font-style: italic;
|
|
1320
|
+
padding: 8px 0;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
/* ---------- Monaco container ---------- */
|
|
1324
|
+
.monaco-editor {
|
|
1325
|
+
width: 100%;
|
|
1326
|
+
height: 280px;
|
|
1327
|
+
border: 1px solid var(--border, #d1d5db);
|
|
1328
|
+
border-radius: 4px;
|
|
1329
|
+
margin: 6px 0 0;
|
|
1330
|
+
position: relative;
|
|
1331
|
+
background: #fafafa;
|
|
1332
|
+
overflow: hidden;
|
|
1333
|
+
}
|
|
1334
|
+
.monaco-editor .monaco-placeholder {
|
|
1335
|
+
display: flex;
|
|
1336
|
+
align-items: center;
|
|
1337
|
+
justify-content: center;
|
|
1338
|
+
height: 100%;
|
|
1339
|
+
color: var(--fg-muted, #6b7280);
|
|
1340
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
1341
|
+
font-size: 12px;
|
|
1342
|
+
}
|
|
1343
|
+
.monaco-editor .monaco-error {
|
|
1344
|
+
color: rgba(220, 38, 38, 0.9);
|
|
1345
|
+
background: rgba(254, 226, 226, 0.5);
|
|
1346
|
+
}
|
|
1347
|
+
.monaco-editor .monaco-truncation-note {
|
|
1348
|
+
position: absolute;
|
|
1349
|
+
bottom: 4px;
|
|
1350
|
+
right: 8px;
|
|
1351
|
+
font-size: 10px;
|
|
1352
|
+
color: var(--fg-muted, #6b7280);
|
|
1353
|
+
background: rgba(255, 255, 255, 0.85);
|
|
1354
|
+
padding: 1px 6px;
|
|
1355
|
+
border-radius: 3px;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
/* ---------- LCS diff body ---------- */
|
|
1359
|
+
.diff-body {
|
|
1360
|
+
list-style: none;
|
|
1361
|
+
margin: 6px 0 0;
|
|
1362
|
+
padding: 6px 8px;
|
|
1363
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1364
|
+
border-radius: 4px;
|
|
1365
|
+
background: #fafafa;
|
|
1366
|
+
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
1367
|
+
font-size: 12px;
|
|
1368
|
+
line-height: 1.5;
|
|
1369
|
+
max-height: 320px;
|
|
1370
|
+
overflow: auto;
|
|
1371
|
+
}
|
|
1372
|
+
.diff-line {
|
|
1373
|
+
display: flex;
|
|
1374
|
+
gap: 8px;
|
|
1375
|
+
padding: 0 4px;
|
|
1376
|
+
white-space: pre;
|
|
1377
|
+
}
|
|
1378
|
+
.diff-line .diff-gutter {
|
|
1379
|
+
flex: 0 0 14px;
|
|
1380
|
+
text-align: center;
|
|
1381
|
+
font-weight: 600;
|
|
1382
|
+
}
|
|
1383
|
+
.diff-line.diff-line-added {
|
|
1384
|
+
background: rgba(220, 252, 231, 0.6);
|
|
1385
|
+
}
|
|
1386
|
+
.diff-line.diff-line-added .diff-gutter {
|
|
1387
|
+
color: #15803d;
|
|
1388
|
+
}
|
|
1389
|
+
.diff-line.diff-line-removed {
|
|
1390
|
+
background: rgba(254, 226, 226, 0.6);
|
|
1391
|
+
}
|
|
1392
|
+
.diff-line.diff-line-removed .diff-gutter {
|
|
1393
|
+
color: #b91c1c;
|
|
1394
|
+
}
|
|
1395
|
+
.diff-line.diff-line-context .diff-gutter {
|
|
1396
|
+
color: var(--fg-muted, #9ca3af);
|
|
1397
|
+
}
|
|
1398
|
+
.diff-line .diff-text {
|
|
1399
|
+
flex: 1 1 auto;
|
|
1400
|
+
white-space: pre;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
/* ---------- v2 small inline hint ---------- */
|
|
1404
|
+
.v2-hint {
|
|
1405
|
+
font-size: 11px;
|
|
1406
|
+
color: var(--fg-muted, #6b7280);
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
/* ============================================================================
|
|
1410
|
+
* v2.0.0: Monaco Editor + File Tree + Diff + Mermaid jump
|
|
1411
|
+
*
|
|
1412
|
+
* Sections (search for the header to navigate):
|
|
1413
|
+
* - .task-v2-layout — sidebar + main grid
|
|
1414
|
+
* - .file-tree-panel — left sidebar
|
|
1415
|
+
* - .file-tree — collapsible nested list
|
|
1416
|
+
* - .file-tree-node — individual rows
|
|
1417
|
+
* - .file-tree-chevron — directory expand/collapse
|
|
1418
|
+
* - .tool-call-detail — right-hand detail panel
|
|
1419
|
+
* - .monaco-editor — Monaco container
|
|
1420
|
+
* - .diff-body / .diff-line — LCS diff rendering
|
|
1421
|
+
* - .v2-hint — small inline hints
|
|
1422
|
+
* ========================================================================== */
|
|
1423
|
+
|
|
1424
|
+
/* ---------- v2.0.0 layout (sidebar + main) ---------- */
|
|
1425
|
+
.task-v2-layout {
|
|
1426
|
+
display: grid;
|
|
1427
|
+
grid-template-columns: minmax(220px, 280px) 1fr;
|
|
1428
|
+
gap: 16px;
|
|
1429
|
+
margin: 0 auto;
|
|
1430
|
+
max-width: 1400px;
|
|
1431
|
+
padding: 0 16px;
|
|
1432
|
+
}
|
|
1433
|
+
.task-v2-layout > .task-v2-main {
|
|
1434
|
+
min-width: 0; /* allow grid item to shrink */
|
|
1435
|
+
}
|
|
1436
|
+
.file-tree-panel {
|
|
1437
|
+
position: sticky;
|
|
1438
|
+
top: 12px;
|
|
1439
|
+
align-self: start;
|
|
1440
|
+
max-height: calc(100vh - 24px);
|
|
1441
|
+
overflow: auto;
|
|
1442
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1443
|
+
border-radius: 6px;
|
|
1444
|
+
padding: 12px 14px;
|
|
1445
|
+
background: var(--bg-panel, #fafafa);
|
|
1446
|
+
}
|
|
1447
|
+
.file-tree-panel h2 {
|
|
1448
|
+
font-size: 14px;
|
|
1449
|
+
margin: 0 0 6px;
|
|
1450
|
+
letter-spacing: 0.02em;
|
|
1451
|
+
}
|
|
1452
|
+
.file-tree-summary {
|
|
1453
|
+
font-size: 11px;
|
|
1454
|
+
color: var(--fg-muted, #6b7280);
|
|
1455
|
+
margin: 0 0 8px;
|
|
1456
|
+
}
|
|
1457
|
+
@media (max-width: 900px) {
|
|
1458
|
+
.task-v2-layout {
|
|
1459
|
+
grid-template-columns: 1fr;
|
|
1460
|
+
}
|
|
1461
|
+
.file-tree-panel {
|
|
1462
|
+
position: static;
|
|
1463
|
+
max-height: none;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
/* ---------- file tree sidebar ---------- */
|
|
1468
|
+
.file-tree {
|
|
1469
|
+
list-style: none;
|
|
1470
|
+
margin: 0;
|
|
1471
|
+
padding: 0;
|
|
1472
|
+
font-family: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, monospace;
|
|
1473
|
+
font-size: 12px;
|
|
1474
|
+
line-height: 1.5;
|
|
1475
|
+
}
|
|
1476
|
+
.file-tree-node {
|
|
1477
|
+
display: flex;
|
|
1478
|
+
align-items: center;
|
|
1479
|
+
gap: 4px;
|
|
1480
|
+
padding: 1px 4px 1px calc(4px + var(--depth, 0) * 12px);
|
|
1481
|
+
border-radius: 3px;
|
|
1482
|
+
cursor: pointer;
|
|
1483
|
+
user-select: none;
|
|
1484
|
+
}
|
|
1485
|
+
.file-tree-node[data-collapsed="true"] {
|
|
1486
|
+
display: none;
|
|
1487
|
+
}
|
|
1488
|
+
.file-tree-node:hover {
|
|
1489
|
+
background: rgba(99, 102, 241, 0.08);
|
|
1490
|
+
}
|
|
1491
|
+
.file-tree-node.is-active {
|
|
1492
|
+
background: rgba(99, 102, 241, 0.18);
|
|
1493
|
+
outline: 1px solid rgba(99, 102, 241, 0.45);
|
|
1494
|
+
font-weight: 600;
|
|
1495
|
+
}
|
|
1496
|
+
.file-tree-node.is-affected .file-tree-name::after {
|
|
1497
|
+
content: " ●";
|
|
1498
|
+
color: rgba(220, 38, 38, 0.8);
|
|
1499
|
+
font-size: 10px;
|
|
1500
|
+
}
|
|
1501
|
+
.file-tree-chevron {
|
|
1502
|
+
display: inline-block;
|
|
1503
|
+
width: 12px;
|
|
1504
|
+
text-align: center;
|
|
1505
|
+
font-size: 9px;
|
|
1506
|
+
color: var(--fg-muted, #6b7280);
|
|
1507
|
+
flex: 0 0 12px;
|
|
1508
|
+
}
|
|
1509
|
+
.file-tree-spacer {
|
|
1510
|
+
display: inline-block;
|
|
1511
|
+
width: 12px;
|
|
1512
|
+
flex: 0 0 12px;
|
|
1513
|
+
}
|
|
1514
|
+
.file-tree-name {
|
|
1515
|
+
flex: 1 1 auto;
|
|
1516
|
+
white-space: nowrap;
|
|
1517
|
+
overflow: hidden;
|
|
1518
|
+
text-overflow: ellipsis;
|
|
1519
|
+
}
|
|
1520
|
+
.file-tree-empty {
|
|
1521
|
+
list-style: none;
|
|
1522
|
+
color: var(--fg-muted, #6b7280);
|
|
1523
|
+
font-style: italic;
|
|
1524
|
+
padding: 4px;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
/* ---------- tool-call detail panel ---------- */
|
|
1528
|
+
.tool-call-detail-panel {
|
|
1529
|
+
border-left: 4px solid rgba(99, 102, 241, 0.55);
|
|
1530
|
+
padding-left: 14px;
|
|
1531
|
+
margin-top: 18px;
|
|
1532
|
+
}
|
|
1533
|
+
.tool-call-detail-panel .v2-hint {
|
|
1534
|
+
font-size: 12px;
|
|
1535
|
+
font-weight: 400;
|
|
1536
|
+
color: var(--fg-muted, #6b7280);
|
|
1537
|
+
margin-left: 8px;
|
|
1538
|
+
}
|
|
1539
|
+
.tool-call-detail {
|
|
1540
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1541
|
+
border-radius: 6px;
|
|
1542
|
+
padding: 10px 12px;
|
|
1543
|
+
margin-top: 8px;
|
|
1544
|
+
background: #ffffff;
|
|
1545
|
+
}
|
|
1546
|
+
.tool-call-header {
|
|
1547
|
+
display: flex;
|
|
1548
|
+
align-items: center;
|
|
1549
|
+
gap: 10px;
|
|
1550
|
+
font-size: 13px;
|
|
1551
|
+
margin-bottom: 6px;
|
|
1552
|
+
}
|
|
1553
|
+
.tool-call-header .tool-name code {
|
|
1554
|
+
background: rgba(99, 102, 241, 0.08);
|
|
1555
|
+
padding: 1px 6px;
|
|
1556
|
+
border-radius: 3px;
|
|
1557
|
+
}
|
|
1558
|
+
.tool-call-header .tool-path {
|
|
1559
|
+
color: var(--fg-muted, #6b7280);
|
|
1560
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
1561
|
+
font-size: 11px;
|
|
1562
|
+
margin-left: auto;
|
|
1563
|
+
overflow: hidden;
|
|
1564
|
+
text-overflow: ellipsis;
|
|
1565
|
+
white-space: nowrap;
|
|
1566
|
+
flex: 1 1 auto;
|
|
1567
|
+
}
|
|
1568
|
+
.tool-call-detail-empty {
|
|
1569
|
+
color: var(--fg-muted, #6b7280);
|
|
1570
|
+
font-style: italic;
|
|
1571
|
+
padding: 8px 0;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/* ---------- Monaco container ---------- */
|
|
1575
|
+
.monaco-editor {
|
|
1576
|
+
width: 100%;
|
|
1577
|
+
height: 280px;
|
|
1578
|
+
border: 1px solid var(--border, #d1d5db);
|
|
1579
|
+
border-radius: 4px;
|
|
1580
|
+
margin: 6px 0 0;
|
|
1581
|
+
position: relative;
|
|
1582
|
+
background: #fafafa;
|
|
1583
|
+
overflow: hidden;
|
|
1584
|
+
}
|
|
1585
|
+
.monaco-editor .monaco-placeholder {
|
|
1586
|
+
display: flex;
|
|
1587
|
+
align-items: center;
|
|
1588
|
+
justify-content: center;
|
|
1589
|
+
height: 100%;
|
|
1590
|
+
color: var(--fg-muted, #6b7280);
|
|
1591
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
1592
|
+
font-size: 12px;
|
|
1593
|
+
}
|
|
1594
|
+
.monaco-editor .monaco-error {
|
|
1595
|
+
color: rgba(220, 38, 38, 0.9);
|
|
1596
|
+
background: rgba(254, 226, 226, 0.5);
|
|
1597
|
+
}
|
|
1598
|
+
.monaco-editor .monaco-truncation-note {
|
|
1599
|
+
position: absolute;
|
|
1600
|
+
bottom: 4px;
|
|
1601
|
+
right: 8px;
|
|
1602
|
+
font-size: 10px;
|
|
1603
|
+
color: var(--fg-muted, #6b7280);
|
|
1604
|
+
background: rgba(255, 255, 255, 0.85);
|
|
1605
|
+
padding: 1px 6px;
|
|
1606
|
+
border-radius: 3px;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
/* ---------- LCS diff body ---------- */
|
|
1610
|
+
.diff-body {
|
|
1611
|
+
list-style: none;
|
|
1612
|
+
margin: 6px 0 0;
|
|
1613
|
+
padding: 6px 8px;
|
|
1614
|
+
border: 1px solid var(--border, #e5e7eb);
|
|
1615
|
+
border-radius: 4px;
|
|
1616
|
+
background: #fafafa;
|
|
1617
|
+
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
1618
|
+
font-size: 12px;
|
|
1619
|
+
line-height: 1.5;
|
|
1620
|
+
max-height: 320px;
|
|
1621
|
+
overflow: auto;
|
|
1622
|
+
}
|
|
1623
|
+
.diff-line {
|
|
1624
|
+
display: flex;
|
|
1625
|
+
gap: 8px;
|
|
1626
|
+
padding: 0 4px;
|
|
1627
|
+
white-space: pre;
|
|
1628
|
+
}
|
|
1629
|
+
.diff-line .diff-gutter {
|
|
1630
|
+
flex: 0 0 14px;
|
|
1631
|
+
text-align: center;
|
|
1632
|
+
font-weight: 600;
|
|
1633
|
+
}
|
|
1634
|
+
.diff-line.diff-line-added {
|
|
1635
|
+
background: rgba(220, 252, 231, 0.6);
|
|
1636
|
+
}
|
|
1637
|
+
.diff-line.diff-line-added .diff-gutter {
|
|
1638
|
+
color: #15803d;
|
|
1639
|
+
}
|
|
1640
|
+
.diff-line.diff-line-removed {
|
|
1641
|
+
background: rgba(254, 226, 226, 0.6);
|
|
1642
|
+
}
|
|
1643
|
+
.diff-line.diff-line-removed .diff-gutter {
|
|
1644
|
+
color: #b91c1c;
|
|
1645
|
+
}
|
|
1646
|
+
.diff-line.diff-line-context .diff-gutter {
|
|
1647
|
+
color: var(--fg-muted, #9ca3af);
|
|
1648
|
+
}
|
|
1649
|
+
.diff-line .diff-text {
|
|
1650
|
+
flex: 1 1 auto;
|
|
1651
|
+
white-space: pre;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
/* ---------- v2 small inline hint ---------- */
|
|
1655
|
+
.v2-hint {
|
|
1656
|
+
font-size: 11px;
|
|
1657
|
+
color: var(--fg-muted, #6b7280);
|
|
1658
|
+
}
|