@goodandready/dsh-kanban 0.2.33 → 0.2.35
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/lib/client.js +170 -379
- package/lib/config.js +31 -1
- package/lib/index.js +120 -1205
- package/lib/remote-relay.js +149 -0
- package/lib/remote-runner.js +164 -0
- package/lib/routes/board.js +282 -0
- package/lib/routes/security.js +274 -0
- package/lib/routes/task-actions.js +345 -0
- package/lib/routes/task-worktree.js +107 -0
- package/lib/routes/task.js +211 -0
- package/lib/routes.js +71 -1206
- package/lib/server/route-handlers.js +367 -0
- package/lib/server/services.js +225 -0
- package/lib/server/task-handler.js +530 -0
- package/lib/server/timers.js +204 -0
- package/lib/store.js +9 -2
- package/lib/watchdog.js +169 -0
- package/lib/worktree.js +35 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
// Browser half of dsh-kanban: board screen and settings card.
|
|
2
|
-
//
|
|
3
|
-
// The identifier below must match `name` in package.json and `name:` in
|
|
4
|
-
// cordis.patch.yml. A mismatch produces NO log error: the loader silently fails
|
|
5
|
-
// to resolve the package, the server half works, and the UI never appears.
|
|
6
|
-
//
|
|
7
|
-
// This module is loaded by ModuleLoader and cannot import repository files;
|
|
8
|
-
// pure helpers live here and are exported as `helpers` for node:vm testing.
|
|
9
1
|
window.__ModuleLoader__.load({
|
|
10
2
|
id: '@goodandready/dsh-kanban',
|
|
11
3
|
factory: (require) => {
|
|
@@ -16,17 +8,11 @@ window.__ModuleLoader__.load({
|
|
|
16
8
|
const ReactDOM = require('react-dom/client')
|
|
17
9
|
|
|
18
10
|
const NS = 'dsh-kanban'
|
|
19
|
-
// Plugins page row seat (DSH 0.1.6-alpha.2): key = '<package name>#<row id>'.
|
|
20
11
|
const PKG = '@goodandready/dsh-kanban'
|
|
21
12
|
const ROW_ID = 'dsh-kanban'
|
|
22
13
|
const ROW_CONFIG_KEY = PKG + '#' + ROW_ID
|
|
23
14
|
const COLUMN_ORDER = ['backlog', 'in-progress', 'review', 'deploy', 'cleanup', 'done']
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Neighbours for card repositioning. The store operates on relative neighbours
|
|
28
|
-
* rather than numeric indexes: `afterId` above, `beforeId` below.
|
|
29
|
-
*/
|
|
30
16
|
function neighboursFor(columnTasks, dragId, index) {
|
|
31
17
|
const rest = (columnTasks || []).filter((t) => t.id !== dragId)
|
|
32
18
|
const clamped = Math.max(0, Math.min(index, rest.length))
|
|
@@ -40,13 +26,6 @@ window.__ModuleLoader__.load({
|
|
|
40
26
|
return (tasks || []).filter((t) => t.column === column)
|
|
41
27
|
}
|
|
42
28
|
|
|
43
|
-
/**
|
|
44
|
-
* Task ordering within a column.
|
|
45
|
-
*
|
|
46
|
-
* `manual` — server-provided order: manual order with active tasks on top.
|
|
47
|
-
* `old`/`new` sort by creation date while preserving project grouping
|
|
48
|
-
* and "active work first".
|
|
49
|
-
*/
|
|
50
29
|
function sortTasks(tasks, order) {
|
|
51
30
|
const list = tasks || []
|
|
52
31
|
if (order !== 'old' && order !== 'new') return list
|
|
@@ -67,22 +46,6 @@ window.__ModuleLoader__.load({
|
|
|
67
46
|
return out
|
|
68
47
|
}
|
|
69
48
|
|
|
70
|
-
/**
|
|
71
|
-
* Session task batch progress: sequence index and total count.
|
|
72
|
-
*
|
|
73
|
-
* Orders matching the agent execution order: active task first,
|
|
74
|
-
* followed by queue time.
|
|
75
|
-
*
|
|
76
|
-
* @returns {Object<string, {at: number, total: number}>} keyed by task id
|
|
77
|
-
*/
|
|
78
|
-
/**
|
|
79
|
-
* Apply a single batch action across all selected tasks.
|
|
80
|
-
*
|
|
81
|
-
* Failures on individual tasks do not abort remaining tasks;
|
|
82
|
-
* completed count is reported to the user.
|
|
83
|
-
*
|
|
84
|
-
* @returns {Promise<{done: number, failed: number}>}
|
|
85
|
-
*/
|
|
86
49
|
async function applyToEach(ids, act) {
|
|
87
50
|
let done = 0
|
|
88
51
|
let failed = 0
|
|
@@ -92,12 +55,6 @@ window.__ModuleLoader__.load({
|
|
|
92
55
|
return { done, failed }
|
|
93
56
|
}
|
|
94
57
|
|
|
95
|
-
/**
|
|
96
|
-
* Remembered launch settings in browser localStorage.
|
|
97
|
-
*
|
|
98
|
-
* Stored per user browser rather than plugin settings. Handles storage
|
|
99
|
-
* errors gracefully if localStorage is disabled or restricted.
|
|
100
|
-
*/
|
|
101
58
|
const RECALL_KEY = 'dsh-kanban:launch:'
|
|
102
59
|
|
|
103
60
|
function recallLaunch(board) {
|
|
@@ -111,16 +68,9 @@ window.__ModuleLoader__.load({
|
|
|
111
68
|
function rememberLaunch(board, choice) {
|
|
112
69
|
try {
|
|
113
70
|
window.localStorage.setItem(RECALL_KEY + (board || 'main'), JSON.stringify(choice))
|
|
114
|
-
} catch {
|
|
71
|
+
} catch { }
|
|
115
72
|
}
|
|
116
73
|
|
|
117
|
-
/**
|
|
118
|
-
* Re-apply remembered preset only if still available in active runtime.
|
|
119
|
-
*
|
|
120
|
-
* Avoids applying obsolete profiles or permission ranks removed from the build.
|
|
121
|
-
*
|
|
122
|
-
* @param {Array<string>} known valid choices
|
|
123
|
-
*/
|
|
124
74
|
function stillOffered(value, known, fallback) {
|
|
125
75
|
return typeof value === 'string' && (known || []).indexOf(value) >= 0 ? value : fallback
|
|
126
76
|
}
|
|
@@ -142,14 +92,6 @@ window.__ModuleLoader__.load({
|
|
|
142
92
|
return out
|
|
143
93
|
}
|
|
144
94
|
|
|
145
|
-
/**
|
|
146
|
-
* Group column tasks by assignee.
|
|
147
|
-
*
|
|
148
|
-
* Unassigned group ('Nobody') is placed first to highlight available work,
|
|
149
|
-
* followed alphabetically by assignee username.
|
|
150
|
-
*
|
|
151
|
-
* @returns {Array<{who: string, tasks: object[]}>}
|
|
152
|
-
*/
|
|
153
95
|
function groupByAssignee(tasks) {
|
|
154
96
|
const by = new Map()
|
|
155
97
|
for (const task of tasks || []) {
|
|
@@ -168,11 +110,6 @@ window.__ModuleLoader__.load({
|
|
|
168
110
|
return task.repo + '#' + task.issueNumber
|
|
169
111
|
}
|
|
170
112
|
|
|
171
|
-
/**
|
|
172
|
-
* Project repository and issue number rendered separately.
|
|
173
|
-
*
|
|
174
|
-
* Issue number links directly to the remote issue.
|
|
175
|
-
*/
|
|
176
113
|
function taskRef(task, t) {
|
|
177
114
|
if (!task || !task.repo) return null
|
|
178
115
|
const number = typeof task.issueNumber === 'number' ? '#' + task.issueNumber : ''
|
|
@@ -202,11 +139,6 @@ window.__ModuleLoader__.load({
|
|
|
202
139
|
return parts.join(' · ')
|
|
203
140
|
}
|
|
204
141
|
|
|
205
|
-
/**
|
|
206
|
-
* Compact plan summary line for card badge: "3 of 7 · writing tests".
|
|
207
|
-
*
|
|
208
|
-
* Only progress numbers and current item description are shown on cards.
|
|
209
|
-
*/
|
|
210
142
|
function planLine(task, t) {
|
|
211
143
|
const progress = task && task.plan && task.plan.progress
|
|
212
144
|
if (!progress || !progress.total) return ''
|
|
@@ -215,7 +147,6 @@ window.__ModuleLoader__.load({
|
|
|
215
147
|
return progress.text ? counter + ' · ' + progress.text : counter
|
|
216
148
|
}
|
|
217
149
|
|
|
218
|
-
/** Status badge text. Waiting indicator is rendered separately. */
|
|
219
150
|
function stateLabel(task, t) {
|
|
220
151
|
const state = task && task.state
|
|
221
152
|
if (state === 'running') return t('state.running')
|
|
@@ -223,26 +154,12 @@ window.__ModuleLoader__.load({
|
|
|
223
154
|
return ''
|
|
224
155
|
}
|
|
225
156
|
|
|
226
|
-
/**
|
|
227
|
-
* Determine whether column is collapsed.
|
|
228
|
-
*
|
|
229
|
-
* Empty columns collapse automatically to save horizontal space;
|
|
230
|
-
* explicit user toggle overrides automatic behavior.
|
|
231
|
-
*
|
|
232
|
-
* @param {object} column column data from board response
|
|
233
|
-
* @param {object} manual map of column id -> boolean user preference
|
|
234
|
-
*/
|
|
235
157
|
function isCollapsed(column, manual) {
|
|
236
158
|
const own = manual && manual[column.id]
|
|
237
159
|
if (own === true || own === false) return own
|
|
238
160
|
return (column.count || 0) === 0
|
|
239
161
|
}
|
|
240
162
|
|
|
241
|
-
/**
|
|
242
|
-
* Relative elapsed time string: "5m", "3h", "3d".
|
|
243
|
-
*
|
|
244
|
-
* Computed client-side with full ISO timestamp displayed on hover tooltip.
|
|
245
|
-
*/
|
|
246
163
|
function agoText(now, then, t) {
|
|
247
164
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
248
165
|
const delta = Math.max(0, now - then)
|
|
@@ -254,7 +171,6 @@ window.__ModuleLoader__.load({
|
|
|
254
171
|
return t('time.day', { n: Math.floor(hours / 24) })
|
|
255
172
|
}
|
|
256
173
|
|
|
257
|
-
/** Date formatted without time. Year is included only when not the current year. */
|
|
258
174
|
function shortDate(then) {
|
|
259
175
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
260
176
|
try {
|
|
@@ -266,19 +182,11 @@ window.__ModuleLoader__.load({
|
|
|
266
182
|
} catch { return '' }
|
|
267
183
|
}
|
|
268
184
|
|
|
269
|
-
/** Exact timestamp for tooltip. Empty tooltip if timestamp is invalid. */
|
|
270
185
|
function exactAt(then) {
|
|
271
186
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
272
187
|
try { return new Date(then).toLocaleString() } catch { return '' }
|
|
273
188
|
}
|
|
274
189
|
|
|
275
|
-
/**
|
|
276
|
-
* Sync telemetry status message.
|
|
277
|
-
*
|
|
278
|
-
* Alerts user when synchronization has halted or encountered errors.
|
|
279
|
-
*
|
|
280
|
-
* @returns {{tone: 'ok'|'bad'|'idle', text: string, title: string}}
|
|
281
|
-
*/
|
|
282
190
|
function syncLine(sync, now, t) {
|
|
283
191
|
const state = (sync && sync.state) || 'never'
|
|
284
192
|
if (state === 'running') return { tone: 'idle', text: t('sync.running'), title: '' }
|
|
@@ -303,13 +211,6 @@ window.__ModuleLoader__.load({
|
|
|
303
211
|
}
|
|
304
212
|
}
|
|
305
213
|
|
|
306
|
-
/**
|
|
307
|
-
* Accessible text color over label background color.
|
|
308
|
-
*
|
|
309
|
-
* Computes perceived brightness and picks black or white accordingly.
|
|
310
|
-
*
|
|
311
|
-
* @param {string} hex 6-character hex code without '#'
|
|
312
|
-
*/
|
|
313
214
|
function readableOn(hex) {
|
|
314
215
|
const n = parseInt(String(hex || ''), 16)
|
|
315
216
|
if (!isFinite(n)) return ''
|
|
@@ -319,11 +220,6 @@ window.__ModuleLoader__.load({
|
|
|
319
220
|
return (r * 299 + g * 587 + b * 114) / 1000 > 140 ? '#111' : '#fff'
|
|
320
221
|
}
|
|
321
222
|
|
|
322
|
-
/**
|
|
323
|
-
* Color accent stripe on left border of card for priority.
|
|
324
|
-
*
|
|
325
|
-
* Only applies to `priority/*` labels. Tasks without priority display no stripe.
|
|
326
|
-
*/
|
|
327
223
|
function priorityColor(task) {
|
|
328
224
|
const values = (task && task.facets && task.facets.priority) || []
|
|
329
225
|
for (const value of values) {
|
|
@@ -333,18 +229,12 @@ window.__ModuleLoader__.load({
|
|
|
333
229
|
return ''
|
|
334
230
|
}
|
|
335
231
|
|
|
336
|
-
/** Tag style helper. Neutral style when color is not defined. */
|
|
337
232
|
function tagStyle(task, name) {
|
|
338
233
|
const hex = task && task.labelColors ? task.labelColors[name] : undefined
|
|
339
234
|
if (!hex) return undefined
|
|
340
235
|
return { background: '#' + hex, color: readableOn(hex), borderColor: 'transparent' }
|
|
341
236
|
}
|
|
342
237
|
|
|
343
|
-
/**
|
|
344
|
-
* Render parsed task body tree safely using React elements.
|
|
345
|
-
*
|
|
346
|
-
* Constructs DOM elements rather than using dangerouslySetInnerHTML to prevent XSS.
|
|
347
|
-
*/
|
|
348
238
|
function renderSpans(spans, keyBase) {
|
|
349
239
|
return (spans || []).map((span, i) => {
|
|
350
240
|
const key = keyBase + '-' + i
|
|
@@ -385,14 +275,6 @@ window.__ModuleLoader__.load({
|
|
|
385
275
|
})
|
|
386
276
|
}
|
|
387
277
|
|
|
388
|
-
/**
|
|
389
|
-
* Label namespace display title.
|
|
390
|
-
*
|
|
391
|
-
* Falls back to raw namespace name when no translation key exists.
|
|
392
|
-
*/
|
|
393
|
-
/**
|
|
394
|
-
* Column title: custom override if configured, otherwise localized default.
|
|
395
|
-
*/
|
|
396
278
|
function columnTitle(col, t) {
|
|
397
279
|
const own = col && col.name
|
|
398
280
|
return own !== undefined && own !== '' ? own : t('column.' + (col && col.id))
|
|
@@ -404,11 +286,6 @@ window.__ModuleLoader__.load({
|
|
|
404
286
|
return text === key ? ns : text
|
|
405
287
|
}
|
|
406
288
|
|
|
407
|
-
/**
|
|
408
|
-
* Board title.
|
|
409
|
-
*
|
|
410
|
-
* Default 'main' and 'simple' boards use localized titles; custom board names are preserved verbatim.
|
|
411
|
-
*/
|
|
412
289
|
function boardTitle(board, t) {
|
|
413
290
|
const key = 'boardName.' + (board && board.id)
|
|
414
291
|
const text = t(key)
|
|
@@ -434,15 +311,8 @@ window.__ModuleLoader__.load({
|
|
|
434
311
|
}
|
|
435
312
|
}
|
|
436
313
|
|
|
437
|
-
/** Repository facet filter key matching backend dimension. */
|
|
438
314
|
const REPO_FACET = 'repo'
|
|
439
315
|
|
|
440
|
-
/**
|
|
441
|
-
* Check whether task matches active facet filters.
|
|
442
|
-
*
|
|
443
|
-
* AND across namespaces, OR within each namespace.
|
|
444
|
-
* Uses pre-parsed task.facets from server response.
|
|
445
|
-
*/
|
|
446
316
|
function matchesFilters(task, selected) {
|
|
447
317
|
const keys = Object.keys(selected || {})
|
|
448
318
|
for (const ns of keys) {
|
|
@@ -456,14 +326,12 @@ window.__ModuleLoader__.load({
|
|
|
456
326
|
return true
|
|
457
327
|
}
|
|
458
328
|
|
|
459
|
-
/** True if any filter is active. */
|
|
460
329
|
function anySelected(selected) {
|
|
461
330
|
const keys = Object.keys(selected || {})
|
|
462
331
|
for (const ns of keys) if ((selected[ns] || []).length > 0) return true
|
|
463
332
|
return false
|
|
464
333
|
}
|
|
465
334
|
|
|
466
|
-
/** Toggle filter value, returning a new map for React immutability. */
|
|
467
335
|
function toggleValue(selected, ns, value) {
|
|
468
336
|
const current = (selected || {})[ns] || []
|
|
469
337
|
const next = current.indexOf(value) >= 0
|
|
@@ -475,7 +343,6 @@ window.__ModuleLoader__.load({
|
|
|
475
343
|
return out
|
|
476
344
|
}
|
|
477
345
|
|
|
478
|
-
/** Human-readable explanation for empty state or error. */
|
|
479
346
|
function errorKey(error) {
|
|
480
347
|
switch (error) {
|
|
481
348
|
case 'gitea-absent': return 'error.giteaAbsent'
|
|
@@ -492,11 +359,6 @@ window.__ModuleLoader__.load({
|
|
|
492
359
|
}
|
|
493
360
|
}
|
|
494
361
|
|
|
495
|
-
/**
|
|
496
|
-
* Open session conversation in chat panel.
|
|
497
|
-
*
|
|
498
|
-
* @returns {boolean} true if session opened successfully
|
|
499
|
-
*/
|
|
500
362
|
function openSession(ctx, sessionId) {
|
|
501
363
|
if (!sessionId) return false
|
|
502
364
|
const sessions = ctx && typeof ctx.get === 'function' ? ctx.get('sessions') : undefined
|
|
@@ -509,7 +371,6 @@ window.__ModuleLoader__.load({
|
|
|
509
371
|
}
|
|
510
372
|
}
|
|
511
373
|
|
|
512
|
-
/** Repository option label with open issue count; marks archived repositories. */
|
|
513
374
|
function repoOption(r, t) {
|
|
514
375
|
const full = r.fullName || ((r.owner || '') + '/' + (r.repo || ''))
|
|
515
376
|
const parts = [full]
|
|
@@ -518,16 +379,12 @@ window.__ModuleLoader__.load({
|
|
|
518
379
|
return parts.join(' ')
|
|
519
380
|
}
|
|
520
381
|
|
|
521
|
-
/** Parse 'owner/repo' string into separate parts. */
|
|
522
382
|
function splitFullName(fullName) {
|
|
523
383
|
const parts = String(fullName || '').split('/')
|
|
524
384
|
if (parts.length !== 2 || parts[0] === '' || parts[1] === '') return undefined
|
|
525
385
|
return { owner: parts[0], repo: parts[1] }
|
|
526
386
|
}
|
|
527
387
|
|
|
528
|
-
/**
|
|
529
|
-
* Filter cards by client-side text search query: title, repo, issue number.
|
|
530
|
-
*/
|
|
531
388
|
function matchesQuery(task, query) {
|
|
532
389
|
const needle = String(query || '').trim().toLowerCase()
|
|
533
390
|
if (needle === '') return true
|
|
@@ -540,7 +397,6 @@ window.__ModuleLoader__.load({
|
|
|
540
397
|
return hay.indexOf(needle) >= 0
|
|
541
398
|
}
|
|
542
399
|
|
|
543
|
-
/** Retrieve session ID for header chip. */
|
|
544
400
|
function chipSessionId(props, session) {
|
|
545
401
|
return String((props && props.sessionId) || (session && (session.sessionId || session.id)) || '').trim()
|
|
546
402
|
}
|
|
@@ -554,7 +410,6 @@ window.__ModuleLoader__.load({
|
|
|
554
410
|
chipSessionId, matchesQuery, splitFullName, repoOption, openSession, COLUMN_ORDER,
|
|
555
411
|
}
|
|
556
412
|
|
|
557
|
-
|
|
558
413
|
function createTimeoutSignal(ms) {
|
|
559
414
|
const sig = typeof AbortSignal !== 'undefined' ? AbortSignal : (typeof globalThis !== 'undefined' ? globalThis.AbortSignal : undefined)
|
|
560
415
|
if (sig && typeof sig.timeout === 'function') {
|
|
@@ -684,188 +539,12 @@ window.__ModuleLoader__.load({
|
|
|
684
539
|
try {
|
|
685
540
|
const s = (ctx?.get && ctx.get('lanSettings')) || ctx?.configForms
|
|
686
541
|
s?.describe?.()?.load?.()
|
|
687
|
-
} catch (_) {
|
|
542
|
+
} catch (_) { }
|
|
688
543
|
}, 1000)
|
|
689
544
|
return () => clearTimer(timer)
|
|
690
545
|
}
|
|
691
546
|
|
|
692
|
-
|
|
693
|
-
const css =
|
|
694
|
-
'.dkb-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:14px 16px;display:flex;flex-direction:column;gap:8px;margin-bottom:12px}' +'.dkb-section-title{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px;padding-bottom:4px;border-bottom:1px solid var(--dsw-alias-border-l2)}' +'.dkb-section-badge{font-size:11px;font-weight:500;padding:2px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}' +'.dkb-section-badge-ok{border-color:var(--dsw-alias-state-success-secondary,#34d399);color:var(--dsw-alias-state-success-primary,#059669);background:var(--dsw-alias-state-success-secondary,rgba(16,185,129,0.1))}' +
|
|
695
|
-
'.dkb-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none}' +
|
|
696
|
-
'.dkb-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}' +
|
|
697
|
-
'.dkb-page{padding:0}' +
|
|
698
|
-
'.dkb-page .dkb-body{border-top:none;margin:0}' +
|
|
699
|
-
'.dkb-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px 16px}' +
|
|
700
|
-
'.dkb-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}' +
|
|
701
|
-
'.dkb-title{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}' +
|
|
702
|
-
'.dkb-sub{color:var(--dsw-alias-label-secondary);font-size:13px}' +
|
|
703
|
-
'.dkb-chevron{color:var(--dsw-alias-label-secondary);display:inline-flex;align-items:center;justify-content:center;flex:none;transition:transform .16s}' +
|
|
704
|
-
'.dkb-chevronOpen{transform:rotate(180deg)}' +
|
|
705
|
-
'.dkb-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}' +
|
|
706
|
-
'.dkb-group{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;padding:14px 0 2px}' +
|
|
707
|
-
'.dkb-field{display:flex;flex-direction:column;gap:6px;padding:10px 0}' +
|
|
708
|
-
'.dkb-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}' +
|
|
709
|
-
'.dkb-hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:1.5}' +
|
|
710
|
-
'.dkb-input{height:34px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;box-sizing:border-box;width:100%}' +
|
|
711
|
-
'.dkb-area{min-height:96px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;padding:8px 12px;font-size:13px;box-sizing:border-box;width:100%;resize:vertical;font:inherit}' +
|
|
712
|
-
'.dkb-input:disabled,.dkb-area:disabled{opacity:.55}' +
|
|
713
|
-
'.dkb-foot{border-top:1px solid var(--dsw-alias-border-l2);display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px}' +
|
|
714
|
-
'.dkb-footSplit{justify-content:space-between}' +
|
|
715
|
-
'.dkb-footLeft{display:flex;align-items:center;gap:8px}' +
|
|
716
|
-
'.dkb-note{min-width:0;flex:1;margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-secondary)}' +
|
|
717
|
-
'.dkb-failed{min-width:0;color:var(--dsw-alias-state-error-primary);flex:1;margin:0;font-size:12px;line-height:1.5}' +
|
|
718
|
-
'.dkb-save{appearance:none;font:inherit;cursor:pointer;border:1px solid transparent;border-radius:8px;padding:5px 14px;font-size:13px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}' +
|
|
719
|
-
'.dkb-discard{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 14px;font-size:13px;color:var(--dsw-alias-label-secondary);background:transparent}' +
|
|
720
|
-
'.dkb-discard:disabled,.dkb-save:disabled{opacity:.4;cursor:default}' +
|
|
721
|
-
'.dkb-entry-clone{align-items:center;gap:8px;display:flex}' +
|
|
722
|
-
'.dkb-entry-clone[data-active]{font-weight:600}' +
|
|
723
|
-
'.dkb-entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}' +
|
|
724
|
-
'.dkb-entryLabel{text-overflow:ellipsis;overflow:hidden}' +
|
|
725
|
-
'[data-dsh-frame][data-sidebar-collapsed] .dkb-entryLabel{display:none}' +
|
|
726
|
-
'[data-pane=conversation],[class*=centerCol]{position:relative}' +
|
|
727
|
-
'[data-dsh-kanban-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}' +
|
|
728
|
-
'html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [data-dsh-kanban-view]{display:block}' +
|
|
729
|
-
'html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-kanban-view]),' +
|
|
730
|
-
'html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-kanban-view]){display:none!important}' +
|
|
731
|
-
'.dkb-screen{box-sizing:border-box;background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 56px;display:flex}' +
|
|
732
|
-
'.dkb-bar{flex:none;align-items:center;gap:8px;display:flex;flex-wrap:wrap}' +
|
|
733
|
-
'.dkb-bar .dkb-input,.dkb-bar .dkb-search,.dkb-bar .dkb-save,.dkb-bar .dkb-discard,.dkb-bar .dkb-facetHead,.dkb-bar .dkb-back{height:30px;box-sizing:border-box;padding-top:0;padding-bottom:0;border-radius:8px;font-size:13px;line-height:28px;display:inline-flex;align-items:center}' +
|
|
734
|
-
'.dkb-bar .dkb-facet{display:inline-flex}' +
|
|
735
|
-
'.dkb-back{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;align-items:center;gap:6px;padding:4px 10px;font-size:13px;display:flex;flex:none}' +
|
|
736
|
-
'.dkb-back:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}' +
|
|
737
|
-
'.dkb-backIcon{align-items:center;display:flex}' +
|
|
738
|
-
'.dkb-archive{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:8px}' +
|
|
739
|
-
'.dkb-archiveList{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}' +
|
|
740
|
-
'.dkb-archiveRow{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;align-items:center;gap:12px;padding:8px 12px;display:flex}' +
|
|
741
|
-
'.dkb-start{display:contents}' +
|
|
742
|
-
'.dkb-pack{color:var(--dsw-alias-label-secondary)}' +
|
|
743
|
-
'.dkb-who{color:var(--dsw-alias-label-secondary)}' +
|
|
744
|
-
'.dkb-sameSession{outline:1px solid var(--dsw-alias-label-secondary);outline-offset:1px}' +
|
|
745
|
-
'.dkb-waitCount{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:0 10px;height:30px;cursor:pointer;color:var(--dsw-alias-label-primary)}' +
|
|
746
|
-
'.dkb-archiveOpen{background:none;border:0;padding:0;text-align:left;cursor:pointer;font:inherit}' +
|
|
747
|
-
'.dkb-archiveTitle{flex:1;font-size:13px;color:var(--dsw-alias-label-primary)}' +
|
|
748
|
-
'.dkb-urgent{border-left-width:3px;border-left-style:solid;padding-left:9px}' +
|
|
749
|
-
'.dkb-cardMenu{position:relative;align-self:flex-start;opacity:0;transition:opacity .12s}' +
|
|
750
|
-
'.dkb-taskCard:hover .dkb-cardMenu,.dkb-taskCard:focus-within .dkb-cardMenu,.dkb-taskCard:focus-visible .dkb-cardMenu{opacity:1}' +
|
|
751
|
-
'.dkb-groupHead{appearance:none;width:100%;font:inherit;color:var(--dsw-alias-label-secondary);text-align:left;cursor:pointer;background:0 0;border:0;border-top:1px solid var(--dsw-alias-border-l2);align-items:center;gap:6px;padding:8px 2px 4px;font-size:11px;font-weight:600;display:flex}' +
|
|
752
|
-
'.dkb-groupHead:first-child{border-top:0;padding-top:2px}' +
|
|
753
|
-
'.dkb-groupHead:hover{color:var(--dsw-alias-label-primary)}' +
|
|
754
|
-
'.dkb-groupCount{margin-left:auto;color:var(--dsw-alias-label-tertiary);font-weight:400}' +
|
|
755
|
-
'.dkb-shown{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;flex:none}' +
|
|
756
|
-
'.dkb-moveBtn{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-tertiary);background:0 0;border:0;padding:0;font-size:11px;text-decoration:underline dotted}' +
|
|
757
|
-
'.dkb-moveBtn:hover{color:var(--dsw-alias-label-primary)}' +
|
|
758
|
-
'.dkb-taskCard:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}' +
|
|
759
|
-
'.dkb-sync{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;flex:none}' +
|
|
760
|
-
'.dkb-syncBad{color:var(--dsw-alias-state-error-primary,#e5534b);cursor:help}' +
|
|
761
|
-
'.dkb-facet{position:relative;flex:none}' +
|
|
762
|
-
'.dkb-facetHead{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:4px 10px;font-size:13px;white-space:nowrap}' +
|
|
763
|
-
'.dkb-facetHead:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}' +
|
|
764
|
-
'.dkb-facetOn{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l3);background:var(--dsw-alias-interactive-bg-hover)}' +
|
|
765
|
-
'.dkb-facetList{position:absolute;top:calc(100% + 4px);left:0;z-index:60;min-width:180px;max-height:280px;overflow-y:auto;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;box-shadow:var(--dsw-shadow-lv2);padding:6px;display:flex;flex-direction:column;gap:2px}' +
|
|
766
|
-
'.dkb-facetRow{align-items:center;gap:8px;padding:4px 6px;border-radius:6px;font-size:13px;cursor:pointer;display:flex}' +
|
|
767
|
-
'.dkb-facetRow:hover{background:var(--dsw-alias-interactive-bg-hover)}' +
|
|
768
|
-
'.dkb-facetName{flex:1;color:var(--dsw-alias-label-primary)}' +
|
|
769
|
-
'.dkb-barTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700;margin-right:auto}' +
|
|
770
|
-
'.dkb-cols{overscroll-behavior-inline:contain;scrollbar-color:var(--dsw-alias-border-l3) var(--dsw-alias-interactive-bg-hover);scrollbar-width:thin;flex:1;gap:12px;min-height:0;padding-bottom:6px;display:flex;overflow:auto hidden}' +
|
|
771
|
-
'.dkb-cols::-webkit-scrollbar{height:10px}' +
|
|
772
|
-
'.dkb-cols::-webkit-scrollbar-track{background:var(--dsw-alias-interactive-bg-hover);border-radius:999px}' +
|
|
773
|
-
'.dkb-cols::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid transparent;border-radius:999px}' +
|
|
774
|
-
'.dkb-col{flex:1 1 220px;min-width:220px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}' +
|
|
775
|
-
'.dkb-colOver{border-color:var(--dsw-alias-border-l3)}' +
|
|
776
|
-
'.dkb-colHead{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}' +
|
|
777
|
-
'.dkb-colHead:hover{background:var(--dsw-alias-interactive-bg-hover)}' +
|
|
778
|
-
'.dkb-colShut{flex:0 0 auto;min-width:0;width:40px}' +
|
|
779
|
-
'.dkb-colShut .dkb-colHead{writing-mode:vertical-rl;height:100%;width:auto;padding:12px 10px;justify-content:flex-start;gap:10px}' +
|
|
780
|
-
'.dkb-colShut .dkb-colHead .dkb-dot{writing-mode:horizontal-tb}' +
|
|
781
|
-
'.dkb-colShut .dkb-count{writing-mode:horizontal-tb}' +
|
|
782
|
-
'.dkb-dot{border-radius:50%;flex:none;width:8px;height:8px}' +
|
|
783
|
-
'.dkb-dot[data-col=backlog]{background:var(--dsw-alias-label-tertiary)}' +
|
|
784
|
-
'.dkb-dot[data-col=in-progress]{background:var(--dsw-alias-state-warn-primary)}' +
|
|
785
|
-
'.dkb-dot[data-col=review]{background:var(--dsw-alias-state-business-primary)}' +
|
|
786
|
-
'.dkb-dot[data-col=deploy]{background:var(--dsw-alias-state-business-primary)}' +
|
|
787
|
-
'.dkb-dot[data-col=cleanup]{background:var(--dsw-alias-label-tertiary)}' +
|
|
788
|
-
'.dkb-dot[data-col=done]{background:var(--dsw-alias-state-success-primary)}' +
|
|
789
|
-
'.dkb-colName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}' +
|
|
790
|
-
'.dkb-count{min-width:20px;text-align:center;color:var(--dsw-alias-bg-base);background:var(--dsw-alias-label-tertiary);border-radius:999px;flex:none;padding:1px 8px;font-size:12px;font-weight:600}' +
|
|
791
|
-
'.dkb-count[data-col=in-progress]{background:var(--dsw-alias-state-warn-primary)}' +
|
|
792
|
-
'.dkb-count[data-col=review]{background:var(--dsw-alias-state-business-primary)}' +
|
|
793
|
-
'.dkb-count[data-col=deploy]{background:var(--dsw-alias-state-business-primary)}' +
|
|
794
|
-
'.dkb-count[data-col=done]{background:var(--dsw-alias-state-success-primary)}' +
|
|
795
|
-
'.dkb-countOver{background:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-label-primary-inverted,#fff)}' +
|
|
796
|
-
'.dkb-overdue{border-color:var(--dsw-alias-state-error-primary)}' +
|
|
797
|
-
'.dkb-dueOver{color:var(--dsw-alias-state-error-primary);font-weight:600}' +
|
|
798
|
-
'.dkb-list{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}' +
|
|
799
|
-
'.dkb-empty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}' +
|
|
800
|
-
'.dkb-taskCard{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}' +
|
|
801
|
-
'.dkb-taskCard:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}' +
|
|
802
|
-
'.dkb-taskTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}' +
|
|
803
|
-
'.dkb-mdBody{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.55;display:flex;flex-direction:column;gap:8px;max-height:46vh;overflow-y:auto}' +
|
|
804
|
-
'.dkb-mdPara{margin:0;overflow-wrap:anywhere}' +
|
|
805
|
-
'.dkb-mdHead{color:var(--dsw-alias-label-primary);font-weight:700;margin:6px 0 0;line-height:1.35}' +
|
|
806
|
-
'.dkb-mdHead1{font-size:15px}' +
|
|
807
|
-
'.dkb-mdHead2{font-size:14px}' +
|
|
808
|
-
'.dkb-mdHead3{font-size:13px;color:var(--dsw-alias-label-secondary)}' +
|
|
809
|
-
'.dkb-mdList{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:3px}' +
|
|
810
|
-
'.dkb-mdCode{margin:0;padding:8px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);font-size:12px;overflow-x:auto;white-space:pre}' +
|
|
811
|
-
'.dkb-mdQuote{margin:0;padding-left:10px;border-left:2px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary)}' +
|
|
812
|
-
'.dkb-mdRule{border:0;border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0;width:100%}' +
|
|
813
|
-
'.dkb-code{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:4px;padding:0 4px;font-size:12px}' +
|
|
814
|
-
'.dkb-issueLink{color:var(--dsw-alias-label-secondary)}' +
|
|
815
|
-
'.dkb-taskHead{align-items:center;gap:6px;flex-wrap:wrap;display:flex}' +
|
|
816
|
-
'.dkb-ref{align-items:baseline;gap:5px;min-width:0;display:inline-flex}' +
|
|
817
|
-
'.dkb-refRepo{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:1px 7px;font-size:11px;font-weight:600}' +
|
|
818
|
-
'.dkb-refNum{flex:none;color:var(--dsw-alias-label-tertiary);font-size:11px;font-family:var(--dsw-font-family-mono,ui-monospace,SFMono-Regular,Menlo,monospace);letter-spacing:.02em}' +
|
|
819
|
-
'.dkb-refLink{text-decoration:none}' +
|
|
820
|
-
'.dkb-refLink:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}' +
|
|
821
|
-
'.dkb-taskRef{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}' +
|
|
822
|
-
'.dkb-planLine{color:var(--dsw-alias-label-secondary);font-size:11px;line-height:1.35;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box}' +
|
|
823
|
-
'.dkb-state{border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:0 5px;font-size:10px;line-height:16px}' +
|
|
824
|
-
'.dkb-stateLive{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);font-weight:600}' +
|
|
825
|
-
'.dkb-batchList{list-style:none;margin:0;padding:0;max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}' +
|
|
826
|
-
'.dkb-batchRow{align-items:baseline;gap:8px;font-size:13px;color:var(--dsw-alias-label-primary);display:flex}' +
|
|
827
|
-
'.dkb-pick{margin:0;flex:none;opacity:0;transition:opacity .12s}' +
|
|
828
|
-
'.dkb-taskCard:hover .dkb-pick,.dkb-taskCard:focus-within .dkb-pick,.dkb-pickOn{opacity:1}' +
|
|
829
|
-
'.dkb-toChat{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:0;padding:0;font-size:11px;text-decoration:underline dotted}' +
|
|
830
|
-
'.dkb-toChat:hover{color:var(--dsw-alias-label-primary)}' +
|
|
831
|
-
'.dkb-planList{display:flex;flex-direction:column;gap:4px;margin:0;padding:0;list-style:none}' +
|
|
832
|
-
'.dkb-planItem{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.4;display:flex;gap:8px;align-items:baseline}' +
|
|
833
|
-
'.dkb-planItem.dkb-planDone{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}' +
|
|
834
|
-
'.dkb-planItem.dkb-planActive{color:var(--dsw-alias-label-primary);font-weight:600;text-decoration:none}' +
|
|
835
|
-
'.dkb-planMark{flex:none;width:14px;text-align:center}' +
|
|
836
|
-
'.dkb-tags{display:flex;flex-wrap:wrap;gap:4px}' +
|
|
837
|
-
'.dkb-waiting{color:var(--dsw-alias-state-warn-primary);font-weight:600}' +
|
|
838
|
-
'.dkb-waitDot{border-radius:50%;flex:none;width:8px;height:8px;background:var(--dsw-alias-state-warn-primary);display:inline-block}' +
|
|
839
|
-
'.dkb-tag{white-space:nowrap;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border:1px solid transparent;border-radius:999px;padding:1px 7px;font-size:11px;line-height:1.5;font-weight:500}' +
|
|
840
|
-
'.dkb-modal{position:absolute;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.4));display:flex;align-items:center;justify-content:center;padding:24px 24px 84px;box-sizing:border-box;z-index:70}' +
|
|
841
|
-
'.dkb-panel{width:min(720px,100%);max-height:100%;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:16px;box-sizing:border-box;overflow-y:auto;display:flex;flex-direction:column;gap:12px}' +
|
|
842
|
-
'@media (min-width: 960px){.dkb-panelWide{width:min(1100px,96%)}.dkb-drawerGrid{display:grid;grid-template-columns:300px 1fr;gap:20px;align-items:start}}' +
|
|
843
|
-
'.dkb-drawerSidebar{display:flex;flex-direction:column;gap:12px;border-right:1px solid var(--dsw-alias-border-l2);padding-right:16px}' +
|
|
844
|
-
'.dkb-drawerMain{display:flex;flex-direction:column;gap:12px;min-width:0}' +
|
|
845
|
-
'.dkb-panelBody{white-space:pre-wrap;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5;margin:0}' +
|
|
846
|
-
'.dkb-log{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}' +
|
|
847
|
-
'.dkb-logRow{color:var(--dsw-alias-label-secondary);font-size:12px}' +
|
|
848
|
-
'.dkb-dialog{position:absolute;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.4));display:flex;align-items:center;justify-content:center;z-index:80}' +
|
|
849
|
-
'.dkb-dialogBox{width:min(560px,94%);max-height:86%;overflow-y:auto;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:10px}' +
|
|
850
|
-
'.dkb-issue{appearance:none;font:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 10px;color:var(--dsw-alias-label-primary);font-size:13px}' +
|
|
851
|
-
'.dkb-issueUsed{opacity:.5}' +
|
|
852
|
-
'.dkb-row{display:flex;gap:8px;align-items:center}' +
|
|
853
|
-
'.dkb-search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 240px;padding:6px 10px;font-size:13px}' +
|
|
854
|
-
'.dkb-search::placeholder{color:var(--dsw-alias-label-tertiary)}' +
|
|
855
|
-
'.dkb-slot{height:2px;border-radius:2px;background:transparent;flex:none}' +
|
|
856
|
-
'.dkb-slotOn{background:var(--dsw-alias-state-business-primary)}' +
|
|
857
|
-
'.dkb-danger{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;padding:5px 14px;font-size:13px;color:var(--dsw-alias-state-error-primary);background:transparent}' +
|
|
858
|
-
'.dkb-danger:hover{background:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-bg-base)}' +
|
|
859
|
-
'.dkb-quickFilterBar{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:4px 0}' +
|
|
860
|
-
'.dkb-filterChip{appearance:none;font:inherit;cursor:pointer;background:var(--dsw-alias-interactive-bg-hover);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 10px;font-size:12px;color:var(--dsw-alias-label-secondary);transition:all .15s}' +
|
|
861
|
-
'.dkb-filterChip:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}' +
|
|
862
|
-
'.dkb-filterChipActive{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-inverted,#fff);border-color:transparent;font-weight:600}' +
|
|
863
|
-
'.dkb-epicTag{background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent);color:var(--dsw-alias-state-business-primary,#0969da);font-weight:600}' +
|
|
864
|
-
'.dkb-progressBar{height:4px;background:var(--dsw-alias-border-l2);border-radius:2px;overflow:hidden;margin:4px 0}' +
|
|
865
|
-
'.dkb-progressFill{height:100%;background:var(--dsw-alias-state-success-primary,#16a34a);transition:width .2s}' +
|
|
866
|
-
'.dkb-consolePre{background:var(--dsw-alias-bg-layer-1,#0d1117);color:var(--dsw-alias-state-business-primary,#58a6ff);border:1px solid var(--dsw-alias-border-l2);padding:12px;border-radius:8px;font-family:monospace;font-size:11px;max-height:260px;overflow-y:auto;white-space:pre-wrap}'
|
|
867
|
-
|
|
868
|
-
|
|
547
|
+
const css = '.dkb-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;padding:14px 16px;display:flex;flex-direction:column;gap:8px;margin-bottom:12px}.dkb-section-title{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px;padding-bottom:4px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dkb-section-badge{font-size:11px;font-weight:500;padding:2px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}.dkb-section-badge-ok{border-color:var(--dsw-alias-state-success-secondary,#34d399);color:var(--dsw-alias-state-success-primary,#059669);background:var(--dsw-alias-state-success-secondary,rgba(16,185,129,0.1))}.dkb-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none}.dkb-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.dkb-page{padding:0}.dkb-page .dkb-body{border-top:none;margin:0}.dkb-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px 16px}.dkb-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dkb-title{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dkb-sub{color:var(--dsw-alias-label-secondary);font-size:13px}.dkb-chevron{color:var(--dsw-alias-label-secondary);display:inline-flex;align-items:center;justify-content:center;flex:none;transition:transform .16s}.dkb-chevronOpen{transform:rotate(180deg)}.dkb-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.dkb-group{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;padding:14px 0 2px}.dkb-field{display:flex;flex-direction:column;gap:6px;padding:10px 0}.dkb-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.dkb-hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:1.5}.dkb-input{height:34px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;box-sizing:border-box;width:100%}.dkb-area{min-height:96px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;padding:8px 12px;font-size:13px;box-sizing:border-box;width:100%;resize:vertical;font:inherit}.dkb-input:disabled,.dkb-area:disabled{opacity:.55}.dkb-foot{border-top:1px solid var(--dsw-alias-border-l2);display:flex;justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px}.dkb-footSplit{justify-content:space-between}.dkb-footLeft{display:flex;align-items:center;gap:8px}.dkb-note{min-width:0;flex:1;margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-secondary)}.dkb-failed{min-width:0;color:var(--dsw-alias-state-error-primary);flex:1;margin:0;font-size:12px;line-height:1.5}.dkb-save{appearance:none;font:inherit;cursor:pointer;border:1px solid transparent;border-radius:8px;padding:5px 14px;font-size:13px;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.dkb-discard{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 14px;font-size:13px;color:var(--dsw-alias-label-secondary);background:transparent}.dkb-discard:disabled,.dkb-save:disabled{opacity:.4;cursor:default}.dkb-entry-clone{align-items:center;gap:8px;display:flex}.dkb-entry-clone[data-active]{font-weight:600}.dkb-entryIcon{flex:none;justify-content:center;align-items:center;display:inline-flex}.dkb-entryLabel{text-overflow:ellipsis;overflow:hidden}[data-dsh-frame][data-sidebar-collapsed] .dkb-entryLabel{display:none}[data-pane=conversation],[class*=centerCol]{position:relative}[data-dsh-kanban-view]{z-index:60;background:var(--dsw-alias-bg-base);display:none;position:absolute;inset:0}html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [data-dsh-kanban-view]{display:block}html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [data-pane=conversation]>:not([data-dsh-kanban-view]),html[data-dsh-kanban-active]:not([data-dsh-ssh-active]) [class*=centerCol]>:not([data-dsh-kanban-view]){display:none!important}.dkb-screen{box-sizing:border-box;background:var(--dsw-alias-bg-base);min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex-direction:column;gap:12px;padding:14px 16px 56px;display:flex}.dkb-bar{flex:none;align-items:center;gap:8px;display:flex;flex-wrap:wrap}.dkb-bar .dkb-input,.dkb-bar .dkb-search,.dkb-bar .dkb-save,.dkb-bar .dkb-discard,.dkb-bar .dkb-facetHead,.dkb-bar .dkb-back{height:30px;box-sizing:border-box;padding-top:0;padding-bottom:0;border-radius:8px;font-size:13px;line-height:28px;display:inline-flex;align-items:center}.dkb-bar .dkb-facet{display:inline-flex}.dkb-back{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;align-items:center;gap:6px;padding:4px 10px;font-size:13px;display:flex;flex:none}.dkb-back:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dkb-backIcon{align-items:center;display:flex}.dkb-archive{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:8px}.dkb-archiveList{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}.dkb-archiveRow{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;align-items:center;gap:12px;padding:8px 12px;display:flex}.dkb-start{display:contents}.dkb-pack{color:var(--dsw-alias-label-secondary)}.dkb-who{color:var(--dsw-alias-label-secondary)}.dkb-sameSession{outline:1px solid var(--dsw-alias-label-secondary);outline-offset:1px}.dkb-waitCount{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;padding:0 10px;height:30px;cursor:pointer;color:var(--dsw-alias-label-primary)}.dkb-archiveOpen{background:none;border:0;padding:0;text-align:left;cursor:pointer;font:inherit}.dkb-archiveTitle{flex:1;font-size:13px;color:var(--dsw-alias-label-primary)}.dkb-urgent{border-left-width:3px;border-left-style:solid;padding-left:9px}.dkb-cardMenu{position:relative;align-self:flex-start;opacity:0;transition:opacity .12s}.dkb-taskCard:hover .dkb-cardMenu,.dkb-taskCard:focus-within .dkb-cardMenu,.dkb-taskCard:focus-visible .dkb-cardMenu{opacity:1}.dkb-groupHead{appearance:none;width:100%;font:inherit;color:var(--dsw-alias-label-secondary);text-align:left;cursor:pointer;background:0 0;border:0;border-top:1px solid var(--dsw-alias-border-l2);align-items:center;gap:6px;padding:8px 2px 4px;font-size:11px;font-weight:600;display:flex}.dkb-groupHead:first-child{border-top:0;padding-top:2px}.dkb-groupHead:hover{color:var(--dsw-alias-label-primary)}.dkb-groupCount{margin-left:auto;color:var(--dsw-alias-label-tertiary);font-weight:400}.dkb-shown{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;flex:none}.dkb-moveBtn{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-tertiary);background:0 0;border:0;padding:0;font-size:11px;text-decoration:underline dotted}.dkb-moveBtn:hover{color:var(--dsw-alias-label-primary)}.dkb-taskCard:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.dkb-sync{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px;flex:none}.dkb-syncBad{color:var(--dsw-alias-state-error-primary,#e5534b);cursor:help}.dkb-facet{position:relative;flex:none}.dkb-facetHead{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:4px 10px;font-size:13px;white-space:nowrap}.dkb-facetHead:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dkb-facetOn{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l3);background:var(--dsw-alias-interactive-bg-hover)}.dkb-facetList{position:absolute;top:calc(100% + 4px);left:0;z-index:60;min-width:180px;max-height:280px;overflow-y:auto;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;box-shadow:var(--dsw-shadow-lv2);padding:6px;display:flex;flex-direction:column;gap:2px}.dkb-facetRow{align-items:center;gap:8px;padding:4px 6px;border-radius:6px;font-size:13px;cursor:pointer;display:flex}.dkb-facetRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.dkb-facetName{flex:1;color:var(--dsw-alias-label-primary)}.dkb-barTitle{color:var(--dsw-alias-label-primary);white-space:nowrap;margin:0;font-size:16px;font-weight:700;margin-right:auto}.dkb-cols{overscroll-behavior-inline:contain;scrollbar-color:var(--dsw-alias-border-l3) var(--dsw-alias-interactive-bg-hover);scrollbar-width:thin;flex:1;gap:12px;min-height:0;padding-bottom:6px;display:flex;overflow:auto hidden}.dkb-cols::-webkit-scrollbar{height:10px}.dkb-cols::-webkit-scrollbar-track{background:var(--dsw-alias-interactive-bg-hover);border-radius:999px}.dkb-cols::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid transparent;border-radius:999px}.dkb-col{flex:1 1 220px;min-width:220px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;min-height:0;display:flex;overflow:hidden}.dkb-colOver{border-color:var(--dsw-alias-border-l3)}.dkb-colHead{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex:none;align-items:center;gap:6px;padding:10px 12px;display:flex}.dkb-colHead:hover{background:var(--dsw-alias-interactive-bg-hover)}.dkb-colShut{flex:0 0 auto;min-width:0;width:40px}.dkb-colShut .dkb-colHead{writing-mode:vertical-rl;height:100%;width:auto;padding:12px 10px;justify-content:flex-start;gap:10px}.dkb-colShut .dkb-colHead .dkb-dot{writing-mode:horizontal-tb}.dkb-colShut .dkb-count{writing-mode:horizontal-tb}.dkb-dot{border-radius:50%;flex:none;width:8px;height:8px}.dkb-dot[data-col=backlog]{background:var(--dsw-alias-label-tertiary)}.dkb-dot[data-col=in-progress]{background:var(--dsw-alias-state-warn-primary)}.dkb-dot[data-col=review]{background:var(--dsw-alias-state-business-primary)}.dkb-dot[data-col=deploy]{background:var(--dsw-alias-state-business-primary)}.dkb-dot[data-col=cleanup]{background:var(--dsw-alias-label-tertiary)}.dkb-dot[data-col=done]{background:var(--dsw-alias-state-success-primary)}.dkb-colName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;margin:0;font-size:13px;font-weight:700;overflow:hidden}.dkb-count{min-width:20px;text-align:center;color:var(--dsw-alias-bg-base);background:var(--dsw-alias-label-tertiary);border-radius:999px;flex:none;padding:1px 8px;font-size:12px;font-weight:600}.dkb-count[data-col=in-progress]{background:var(--dsw-alias-state-warn-primary)}.dkb-count[data-col=review]{background:var(--dsw-alias-state-business-primary)}.dkb-count[data-col=deploy]{background:var(--dsw-alias-state-business-primary)}.dkb-count[data-col=done]{background:var(--dsw-alias-state-success-primary)}.dkb-countOver{background:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-label-primary-inverted,#fff)}.dkb-overdue{border-color:var(--dsw-alias-state-error-primary)}.dkb-dueOver{color:var(--dsw-alias-state-error-primary);font-weight:600}.dkb-list{flex-direction:column;flex:1;gap:8px;min-height:0;padding:2px 8px 10px;display:flex;overflow-y:auto}.dkb-empty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:24px 8px;font-size:12px}.dkb-taskCard{text-align:left;background:var(--dsw-alias-bg-base);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;color:var(--dsw-alias-label-primary);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-family:inherit;transition:box-shadow .12s,border-color .12s,transform .12s;display:flex}.dkb-taskCard:hover{box-shadow:var(--dsw-shadow-lv2);border-color:var(--dsw-alias-border-l3);transform:translateY(-1px)}.dkb-taskTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:13px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}.dkb-mdBody{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.55;display:flex;flex-direction:column;gap:8px;max-height:46vh;overflow-y:auto}.dkb-mdPara{margin:0;overflow-wrap:anywhere}.dkb-mdHead{color:var(--dsw-alias-label-primary);font-weight:700;margin:6px 0 0;line-height:1.35}.dkb-mdHead1{font-size:15px}.dkb-mdHead2{font-size:14px}.dkb-mdHead3{font-size:13px;color:var(--dsw-alias-label-secondary)}.dkb-mdList{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:3px}.dkb-mdCode{margin:0;padding:8px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);font-size:12px;overflow-x:auto;white-space:pre}.dkb-mdQuote{margin:0;padding-left:10px;border-left:2px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary)}.dkb-mdRule{border:0;border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0;width:100%}.dkb-code{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:4px;padding:0 4px;font-size:12px}.dkb-issueLink{color:var(--dsw-alias-label-secondary)}.dkb-taskHead{align-items:center;gap:6px;flex-wrap:wrap;display:flex}.dkb-ref{align-items:baseline;gap:5px;min-width:0;display:inline-flex}.dkb-refRepo{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:1px 7px;font-size:11px;font-weight:600}.dkb-refNum{flex:none;color:var(--dsw-alias-label-tertiary);font-size:11px;font-family:var(--dsw-font-family-mono,ui-monospace,SFMono-Regular,Menlo,monospace);letter-spacing:.02em}.dkb-refLink{text-decoration:none}.dkb-refLink:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.dkb-taskRef{color:var(--dsw-alias-label-tertiary);align-items:center;gap:8px;font-size:11px;display:flex}.dkb-planLine{color:var(--dsw-alias-label-secondary);font-size:11px;line-height:1.35;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box}.dkb-state{border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:0 5px;font-size:10px;line-height:16px}.dkb-stateLive{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);font-weight:600}.dkb-batchList{list-style:none;margin:0;padding:0;max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}.dkb-batchRow{align-items:baseline;gap:8px;font-size:13px;color:var(--dsw-alias-label-primary);display:flex}.dkb-pick{margin:0;flex:none;opacity:0;transition:opacity .12s}.dkb-taskCard:hover .dkb-pick,.dkb-taskCard:focus-within .dkb-pick,.dkb-pickOn{opacity:1}.dkb-toChat{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:0;padding:0;font-size:11px;text-decoration:underline dotted}.dkb-toChat:hover{color:var(--dsw-alias-label-primary)}.dkb-planList{display:flex;flex-direction:column;gap:4px;margin:0;padding:0;list-style:none}.dkb-planItem{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.4;display:flex;gap:8px;align-items:baseline}.dkb-planItem.dkb-planDone{color:var(--dsw-alias-label-tertiary);text-decoration:line-through}.dkb-planItem.dkb-planActive{color:var(--dsw-alias-label-primary);font-weight:600;text-decoration:none}.dkb-planMark{flex:none;width:14px;text-align:center}.dkb-tags{display:flex;flex-wrap:wrap;gap:4px}.dkb-waiting{color:var(--dsw-alias-state-warn-primary);font-weight:600}.dkb-waitDot{border-radius:50%;flex:none;width:8px;height:8px;background:var(--dsw-alias-state-warn-primary);display:inline-block}.dkb-tag{white-space:nowrap;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover);border:1px solid transparent;border-radius:999px;padding:1px 7px;font-size:11px;line-height:1.5;font-weight:500}.dkb-modal{position:absolute;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.4));display:flex;align-items:center;justify-content:center;padding:24px 24px 84px;box-sizing:border-box;z-index:70}.dkb-panel{width:min(720px,100%);max-height:100%;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:16px;box-sizing:border-box;overflow-y:auto;display:flex;flex-direction:column;gap:12px}@media (min-width:960px){.dkb-panelWide{width:min(1100px,96%)}.dkb-drawerGrid{display:grid;grid-template-columns:300px 1fr;gap:20px;align-items:start}}.dkb-drawerSidebar{display:flex;flex-direction:column;gap:12px;border-right:1px solid var(--dsw-alias-border-l2);padding-right:16px}.dkb-drawerMain{display:flex;flex-direction:column;gap:12px;min-width:0}.dkb-panelBody{white-space:pre-wrap;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.5;margin:0}.dkb-log{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.dkb-logRow{color:var(--dsw-alias-label-secondary);font-size:12px}.dkb-dialog{position:absolute;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.4));display:flex;align-items:center;justify-content:center;z-index:80}.dkb-dialogBox{width:min(560px,94%);max-height:86%;overflow-y:auto;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:10px}.dkb-issue{appearance:none;font:inherit;text-align:left;cursor:pointer;background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 10px;color:var(--dsw-alias-label-primary);font-size:13px}.dkb-issueUsed{opacity:.5}.dkb-row{display:flex;gap:8px;align-items:center}.dkb-search{min-width:120px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;outline:none;flex:0 240px;padding:6px 10px;font-size:13px}.dkb-search::placeholder{color:var(--dsw-alias-label-tertiary)}.dkb-slot{height:2px;border-radius:2px;background:transparent;flex:none}.dkb-slotOn{background:var(--dsw-alias-state-business-primary)}.dkb-danger{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;padding:5px 14px;font-size:13px;color:var(--dsw-alias-state-error-primary);background:transparent}.dkb-danger:hover{background:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-bg-base)}.dkb-quickFilterBar{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:4px 0}.dkb-filterChip{appearance:none;font:inherit;cursor:pointer;background:var(--dsw-alias-interactive-bg-hover);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:3px 10px;font-size:12px;color:var(--dsw-alias-label-secondary);transition:all .15s}.dkb-filterChip:hover{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.dkb-filterChipActive{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-inverted,#fff);border-color:transparent;font-weight:600}.dkb-epicTag{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary,#0969da);font-weight:600}.dkb-progressBar{height:4px;background:var(--dsw-alias-border-l2);border-radius:2px;overflow:hidden;margin:4px 0}.dkb-progressFill{height:100%;background:var(--dsw-alias-state-success-primary,#16a34a);transition:width .2s}.dkb-consolePre{background:var(--dsw-alias-bg-layer-1,#0d1117);color:var(--dsw-alias-state-business-primary,#58a6ff);border:1px solid var(--dsw-alias-border-l2);padding:12px;border-radius:8px;font-family:monospace;font-size:11px;max-height:260px;overflow-y:auto;white-space:pre-wrap}'
|
|
869
548
|
|
|
870
549
|
const en = {
|
|
871
550
|
'updater.title': 'Plugin Updates',
|
|
@@ -1288,6 +967,39 @@ window.__ModuleLoader__.load({
|
|
|
1288
967
|
'telemetry.output': 'Output',
|
|
1289
968
|
'telemetry.cache': 'Cached',
|
|
1290
969
|
'telemetry.cost': 'Estimated Cost',
|
|
970
|
+
'group.remote': 'Remote execution (Server 111)',
|
|
971
|
+
'field.remoteMode': 'Remote mode',
|
|
972
|
+
'hint.remoteMode': 'Execute tasks, worktrees, and git commands on remote server 111.',
|
|
973
|
+
'field.remoteHost': 'Remote host',
|
|
974
|
+
'hint.remoteHost': 'Hostname or IP address of the remote server.',
|
|
975
|
+
'field.remotePort': 'SSH port',
|
|
976
|
+
'hint.remotePort': 'SSH port on remote server (default 22).',
|
|
977
|
+
'field.remoteUser': 'SSH user',
|
|
978
|
+
'hint.remoteUser': 'SSH login username on remote host.',
|
|
979
|
+
'field.remoteAuthType': 'SSH auth type',
|
|
980
|
+
'hint.remoteAuthType': 'SSH authentication method: key, agent, or password.',
|
|
981
|
+
'field.remoteKeyPath': 'SSH private key',
|
|
982
|
+
'hint.remoteKeyPath': 'Path to SSH private key file on local PC.',
|
|
983
|
+
'field.remoteSudoUser': 'Sudo user',
|
|
984
|
+
'hint.remoteSudoUser': 'Run remote commands under this Linux user via sudo -u.',
|
|
985
|
+
'field.remoteRoot': 'Remote project root',
|
|
986
|
+
'hint.remoteRoot': 'Remote projects directory (/mnt/external/Project/DEV).',
|
|
987
|
+
'field.remoteServerUrl': 'DSH server URL',
|
|
988
|
+
'hint.remoteServerUrl': 'Remote DSH URL (http://192.168.1.111:3080) for unified board state.',
|
|
989
|
+
'field.remoteServerToken': 'Server auth token',
|
|
990
|
+
'hint.remoteServerToken': 'Optional authentication token for remote DSH server.',
|
|
991
|
+
'field.watchdogEnabled': 'Watchdog & circuit breaker',
|
|
992
|
+
'hint.watchdogEnabled': 'Pause stalled tasks and prevent runaway token consumption.',
|
|
993
|
+
'field.watchdogStallTimeoutMin': 'Watchdog stall timeout (min)',
|
|
994
|
+
'hint.watchdogStallTimeoutMin': 'Minutes of inactivity before active task is marked stalled.',
|
|
995
|
+
'field.watchdogMaxConsecutiveErrors': 'Watchdog max errors',
|
|
996
|
+
'hint.watchdogMaxConsecutiveErrors': 'Consecutive tool execution errors before circuit breaker trips.',
|
|
997
|
+
'watchdog.stalled': 'Stalled',
|
|
998
|
+
'remote.testBtn': 'Test Connection',
|
|
999
|
+
'remote.testing': 'Testing connection...',
|
|
1000
|
+
'remote.ok': 'Connected to server 111',
|
|
1001
|
+
'remote.failed': 'Connection failed',
|
|
1002
|
+
'remote.badge': 'Remote: 111',
|
|
1291
1003
|
'telemetry.limit': 'Budget Limit',
|
|
1292
1004
|
}
|
|
1293
1005
|
|
|
@@ -1712,6 +1424,39 @@ window.__ModuleLoader__.load({
|
|
|
1712
1424
|
'telemetry.output': '输出',
|
|
1713
1425
|
'telemetry.cache': '缓存命中',
|
|
1714
1426
|
'telemetry.cost': '预估成本',
|
|
1427
|
+
'group.remote': '远程执行 (111 服务器)',
|
|
1428
|
+
'field.remoteMode': '远程模式',
|
|
1429
|
+
'hint.remoteMode': '在远程 111 服务器上执行任务、工作树和 git 命令。',
|
|
1430
|
+
'field.remoteHost': '远程主机',
|
|
1431
|
+
'hint.remoteHost': '远程服务器的主机名或 IP 地址。',
|
|
1432
|
+
'field.remotePort': 'SSH 端口',
|
|
1433
|
+
'hint.remotePort': '远程服务器的 SSH 端口(默认 22)。',
|
|
1434
|
+
'field.remoteUser': 'SSH 用户',
|
|
1435
|
+
'hint.remoteUser': '远程主机上的 SSH 登录用户名。',
|
|
1436
|
+
'field.remoteAuthType': 'SSH 认证类型',
|
|
1437
|
+
'hint.remoteAuthType': 'SSH 认证方式:key、agent 或 password。',
|
|
1438
|
+
'field.remoteKeyPath': 'SSH 私钥路径',
|
|
1439
|
+
'hint.remoteKeyPath': '本地电脑上的 SSH 私钥文件路径。',
|
|
1440
|
+
'field.remoteSudoUser': 'Sudo 执行用户',
|
|
1441
|
+
'hint.remoteSudoUser': '在远程通过 sudo -u 以此 Linux 用户身份运行命令。',
|
|
1442
|
+
'field.remoteRoot': '远程项目根目录',
|
|
1443
|
+
'hint.remoteRoot': '远程项目仓库目录 (/mnt/external/Project/DEV)。',
|
|
1444
|
+
'field.remoteServerUrl': 'DSH 服务器地址',
|
|
1445
|
+
'hint.remoteServerUrl': '远程 DSH 服务器地址 (http://192.168.1.111:3080),用于共享看板状态。',
|
|
1446
|
+
'field.remoteServerToken': '服务器认证令牌',
|
|
1447
|
+
'hint.remoteServerToken': '远程 DSH 服务器的可选认证令牌。',
|
|
1448
|
+
'field.watchdogEnabled': '看门狗与熔断器',
|
|
1449
|
+
'hint.watchdogEnabled': '暂停卡住的任务并防止额度失控消耗。',
|
|
1450
|
+
'field.watchdogStallTimeoutMin': '看门狗超时时间 (分钟)',
|
|
1451
|
+
'hint.watchdogStallTimeoutMin': '在任务被标记为停滞之前的非活跃分钟数。',
|
|
1452
|
+
'field.watchdogMaxConsecutiveErrors': '看门狗最大连续错误数',
|
|
1453
|
+
'hint.watchdogMaxConsecutiveErrors': '熔断器跳闸前的连续工具执行错误次数。',
|
|
1454
|
+
'watchdog.stalled': '已停滞',
|
|
1455
|
+
'remote.testBtn': '测试连接',
|
|
1456
|
+
'remote.testing': '正在测试连接...',
|
|
1457
|
+
'remote.ok': '已连接到 111 服务器',
|
|
1458
|
+
'remote.failed': '连接失败',
|
|
1459
|
+
'remote.badge': '远程: 111',
|
|
1715
1460
|
'telemetry.limit': '预算限额',
|
|
1716
1461
|
}
|
|
1717
1462
|
|
|
@@ -1725,7 +1470,6 @@ window.__ModuleLoader__.load({
|
|
|
1725
1470
|
return text
|
|
1726
1471
|
}
|
|
1727
1472
|
|
|
1728
|
-
|
|
1729
1473
|
const FIELDS = [
|
|
1730
1474
|
{ field: 'gitProvider', kind: 'text', group: 'forge' },
|
|
1731
1475
|
{ field: 'giteaUrl', kind: 'text', group: 'gitea' },
|
|
@@ -1763,6 +1507,19 @@ window.__ModuleLoader__.load({
|
|
|
1763
1507
|
{ field: 'verificationTimeoutMs', kind: 'number', group: 'general' },
|
|
1764
1508
|
{ field: 'costMeterEnabled', kind: 'bool', group: 'sync' },
|
|
1765
1509
|
{ field: 'taskCostLimit', kind: 'number', group: 'limits' },
|
|
1510
|
+
{ field: 'remoteMode', kind: 'bool', group: 'remote' },
|
|
1511
|
+
{ field: 'remoteHost', kind: 'text', group: 'remote' },
|
|
1512
|
+
{ field: 'remotePort', kind: 'number', group: 'remote' },
|
|
1513
|
+
{ field: 'remoteUser', kind: 'text', group: 'remote' },
|
|
1514
|
+
{ field: 'remoteAuthType', kind: 'text', group: 'remote' },
|
|
1515
|
+
{ field: 'remoteKeyPath', kind: 'text', group: 'remote' },
|
|
1516
|
+
{ field: 'remoteSudoUser', kind: 'text', group: 'remote' },
|
|
1517
|
+
{ field: 'remoteRoot', kind: 'text', group: 'remote' },
|
|
1518
|
+
{ field: 'remoteServerUrl', kind: 'text', group: 'remote' },
|
|
1519
|
+
{ field: 'remoteServerToken', kind: 'text', group: 'remote' },
|
|
1520
|
+
{ field: 'watchdogEnabled', kind: 'bool', group: 'general' },
|
|
1521
|
+
{ field: 'watchdogStallTimeoutMin', kind: 'number', group: 'limits' },
|
|
1522
|
+
{ field: 'watchdogMaxConsecutiveErrors', kind: 'number', group: 'limits' },
|
|
1766
1523
|
]
|
|
1767
1524
|
|
|
1768
1525
|
function hintKey(spec) {
|
|
@@ -1770,6 +1527,7 @@ window.__ModuleLoader__.load({
|
|
|
1770
1527
|
if (spec.group === 'gitea') return 'hint.' + spec.field
|
|
1771
1528
|
if (spec.group === 'github') return 'hint.' + spec.field
|
|
1772
1529
|
if (spec.group === 'forge') return 'hint.' + spec.field
|
|
1530
|
+
if (spec.group === 'remote') return 'hint.' + spec.field
|
|
1773
1531
|
if (spec.group === 'labels') return 'hint.label'
|
|
1774
1532
|
if (spec.group === 'limits') return 'hint.limit'
|
|
1775
1533
|
return 'hint.' + spec.field
|
|
@@ -1807,6 +1565,63 @@ window.__ModuleLoader__.load({
|
|
|
1807
1565
|
}, h(Icon))
|
|
1808
1566
|
}
|
|
1809
1567
|
|
|
1568
|
+
function RemoteConnectionSection(props) {
|
|
1569
|
+
const t = props.t || fallbackT
|
|
1570
|
+
const [testing, setTesting] = React.useState(false)
|
|
1571
|
+
const [result, setResult] = React.useState(null)
|
|
1572
|
+
|
|
1573
|
+
const handleTest = React.useCallback(async () => {
|
|
1574
|
+
setTesting(true)
|
|
1575
|
+
setResult(null)
|
|
1576
|
+
try {
|
|
1577
|
+
const res = await fetch('/api/dsh-kanban/remote/test', {
|
|
1578
|
+
method: 'POST',
|
|
1579
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1580
|
+
})
|
|
1581
|
+
const data = await res.json()
|
|
1582
|
+
setResult(data)
|
|
1583
|
+
} catch (e) {
|
|
1584
|
+
setResult({ ok: false, error: e?.message || String(e) })
|
|
1585
|
+
} finally {
|
|
1586
|
+
setTesting(false)
|
|
1587
|
+
}
|
|
1588
|
+
}, [])
|
|
1589
|
+
|
|
1590
|
+
return h('div', {
|
|
1591
|
+
className: 'dkb-section-card',
|
|
1592
|
+
key: 'remote-test-card',
|
|
1593
|
+
style: { borderLeft: '3px solid var(--dsw-alias-state-business-primary, #0969da)', background: 'var(--dsw-alias-bg-layer-1, #f6f8fa)', padding: '12px 14px', marginBottom: '12px' },
|
|
1594
|
+
},
|
|
1595
|
+
h('div', {
|
|
1596
|
+
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: result ? '8px' : '0' },
|
|
1597
|
+
},
|
|
1598
|
+
h('span', { style: { fontWeight: '600', fontSize: '13px' } }, '🌐 ' + t('group.remote')),
|
|
1599
|
+
h('button', {
|
|
1600
|
+
type: 'button',
|
|
1601
|
+
className: 'dkb-save',
|
|
1602
|
+
style: { padding: '3px 10px', fontSize: '12px' },
|
|
1603
|
+
disabled: testing,
|
|
1604
|
+
onClick: handleTest,
|
|
1605
|
+
}, testing ? t('remote.testing') : t('remote.testBtn')),
|
|
1606
|
+
),
|
|
1607
|
+
result ? h('div', {
|
|
1608
|
+
style: {
|
|
1609
|
+
fontSize: '12px',
|
|
1610
|
+
padding: '6px 8px',
|
|
1611
|
+
borderRadius: '4px',
|
|
1612
|
+
background: (result.ssh?.ok || result.server?.ok)
|
|
1613
|
+
? 'var(--dsw-alias-state-success-secondary, #dafbe1)'
|
|
1614
|
+
: 'var(--dsw-alias-state-error-secondary, #ffebe9)',
|
|
1615
|
+
color: (result.ssh?.ok || result.server?.ok)
|
|
1616
|
+
? 'var(--dsw-alias-state-success-primary, #1a7f37)'
|
|
1617
|
+
: 'var(--dsw-alias-state-error-primary, #cf222e)',
|
|
1618
|
+
},
|
|
1619
|
+
},
|
|
1620
|
+
h('div', null, (result.ssh?.ok ? '✓ SSH: OK (' + result.ssh.latencyMs + 'ms)' : '✗ SSH: ' + (result.ssh?.error || 'unreachable'))),
|
|
1621
|
+
h('div', null, (result.server?.ok ? '✓ DSH Server: OK (' + result.server.latencyMs + 'ms)' : '✗ DSH Server: ' + (result.server?.error || 'unreachable'))),
|
|
1622
|
+
) : null,
|
|
1623
|
+
)
|
|
1624
|
+
}
|
|
1810
1625
|
|
|
1811
1626
|
function PluginUpdaterSection(props) {
|
|
1812
1627
|
const t = props.t || fallbackT
|
|
@@ -1899,8 +1714,6 @@ window.__ModuleLoader__.load({
|
|
|
1899
1714
|
const ctx = props && props.ctx
|
|
1900
1715
|
const t = (props && props.t) || fallbackT
|
|
1901
1716
|
ensureCss()
|
|
1902
|
-
|
|
1903
|
-
// Row seat (plugins.row.config): summary is a one-liner
|
|
1904
1717
|
if (props && props.view === 'summary') {
|
|
1905
1718
|
return h('span', { className: 'dkb-sub' }, t('settings.subtitle') || t('subtitle') || 'Kanban board for sessions and tasks')
|
|
1906
1719
|
}
|
|
@@ -2085,6 +1898,7 @@ window.__ModuleLoader__.load({
|
|
|
2085
1898
|
t('costMeter.notice'),
|
|
2086
1899
|
),
|
|
2087
1900
|
))
|
|
1901
|
+
rows.push(h(RemoteConnectionSection, { t, key: 'remote-test' }))
|
|
2088
1902
|
rows.push(h(PluginUpdaterSection, { t, key: 'updater' }))
|
|
2089
1903
|
rows.push(h('div', { className: 'dkb-foot', key: 'foot' },
|
|
2090
1904
|
note,
|
|
@@ -2100,12 +1914,10 @@ window.__ModuleLoader__.load({
|
|
|
2100
1914
|
return h('li', { className: 'dkb-card dkb-cardOpen' }, head, h('div', { className: 'dkb-body' }, body))
|
|
2101
1915
|
}
|
|
2102
1916
|
|
|
2103
|
-
/** Back button arrow icon: 14x14 stroke currentColor. */
|
|
2104
1917
|
const BACK_ICON = '<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor"'
|
|
2105
1918
|
+ ' stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
|
|
2106
1919
|
+ '<path d="M10 3.5 5.5 8l4.5 4.5"/></svg>'
|
|
2107
1920
|
|
|
2108
|
-
|
|
2109
1921
|
const TaskCard = React.memo(function TaskCard(props) {
|
|
2110
1922
|
const { task, t, now } = props
|
|
2111
1923
|
const ref = cardRef(task)
|
|
@@ -2124,6 +1936,7 @@ window.__ModuleLoader__.load({
|
|
|
2124
1936
|
return h('div', {
|
|
2125
1937
|
className: 'dkb-taskCard' + (urgent ? ' dkb-urgent' : '')
|
|
2126
1938
|
+ (overdue ? ' dkb-overdue' : '')
|
|
1939
|
+
+ (task.stalled ? ' dkb-stalled' : '')
|
|
2127
1940
|
+ (props.sameSession ? ' dkb-sameSession' : ''),
|
|
2128
1941
|
onMouseEnter: () => { if (props.onHover) props.onHover(task.sessionId || '') },
|
|
2129
1942
|
onMouseLeave: () => { if (props.onHover) props.onHover('') },
|
|
@@ -2132,7 +1945,7 @@ window.__ModuleLoader__.load({
|
|
|
2132
1945
|
tabIndex: 0,
|
|
2133
1946
|
draggable: true,
|
|
2134
1947
|
onDragStart: (e) => {
|
|
2135
|
-
try { e.dataTransfer.setData('text/plain', task.id) } catch {
|
|
1948
|
+
try { e.dataTransfer.setData('text/plain', task.id) } catch { }
|
|
2136
1949
|
props.onDragStart(task)
|
|
2137
1950
|
},
|
|
2138
1951
|
onClick: () => props.onOpen(task),
|
|
@@ -2148,6 +1961,7 @@ window.__ModuleLoader__.load({
|
|
|
2148
1961
|
}),
|
|
2149
1962
|
waiting ? h('span', { className: 'dkb-waitDot' }) : null,
|
|
2150
1963
|
waiting ? h('span', { className: 'dkb-waiting' }, t('board.waiting')) : null,
|
|
1964
|
+
task.stalled ? h('span', { className: 'dkb-tag', style: { background: 'var(--dsw-alias-state-warn-secondary, #fff8c5)', color: 'var(--dsw-alias-state-warn-primary, #9a6700)', borderColor: 'var(--dsw-alias-state-warn-secondary, #d4a72c)' }, title: task.stalledReason || 'Stalled' }, '⚠️ ' + (t('watchdog.stalled') || 'Stalled')) : null,
|
|
2151
1965
|
taskRef(task, t),
|
|
2152
1966
|
task.isEpic ? h('span', { className: 'dkb-tag dkb-epicTag', title: t('epic.badge') }, '👑 ' + t('epic.badge')) : null,
|
|
2153
1967
|
task.parentId ? h('span', { className: 'dkb-tag', style: { opacity: 0.75 } }, '↳') : null,
|
|
@@ -2304,10 +2118,6 @@ window.__ModuleLoader__.load({
|
|
|
2304
2118
|
)
|
|
2305
2119
|
})
|
|
2306
2120
|
|
|
2307
|
-
/**
|
|
2308
|
-
* Execution options: agent preset and permission rank.
|
|
2309
|
-
* Shared across single-task and batch launch modals.
|
|
2310
|
-
*/
|
|
2311
2121
|
function LaunchFields(props) {
|
|
2312
2122
|
const t = props.t
|
|
2313
2123
|
const rows = []
|
|
@@ -2491,7 +2301,7 @@ window.__ModuleLoader__.load({
|
|
|
2491
2301
|
es.addEventListener('task:change', scheduleReload)
|
|
2492
2302
|
es.onerror = () => {
|
|
2493
2303
|
if (es) {
|
|
2494
|
-
try { es.close() } catch {
|
|
2304
|
+
try { es.close() } catch { }
|
|
2495
2305
|
es = null
|
|
2496
2306
|
}
|
|
2497
2307
|
if (!reconnectTimer) {
|
|
@@ -2501,7 +2311,7 @@ window.__ModuleLoader__.load({
|
|
|
2501
2311
|
}, 5000)
|
|
2502
2312
|
}
|
|
2503
2313
|
}
|
|
2504
|
-
} catch {
|
|
2314
|
+
} catch { }
|
|
2505
2315
|
}
|
|
2506
2316
|
|
|
2507
2317
|
connect()
|
|
@@ -2509,7 +2319,7 @@ window.__ModuleLoader__.load({
|
|
|
2509
2319
|
return () => {
|
|
2510
2320
|
if (reconnectTimer) clearTimeout(reconnectTimer)
|
|
2511
2321
|
if (es) {
|
|
2512
|
-
try { es.close() } catch {
|
|
2322
|
+
try { es.close() } catch { }
|
|
2513
2323
|
es = null
|
|
2514
2324
|
}
|
|
2515
2325
|
}
|
|
@@ -2615,9 +2425,6 @@ window.__ModuleLoader__.load({
|
|
|
2615
2425
|
}
|
|
2616
2426
|
}, [load, t])
|
|
2617
2427
|
|
|
2618
|
-
/**
|
|
2619
|
-
* Confirm and execute card move transition.
|
|
2620
|
-
*/
|
|
2621
2428
|
const askMove = React.useCallback((task, column, where) => {
|
|
2622
2429
|
if (!task) return
|
|
2623
2430
|
const place = where ?? neighboursFor(tasksOf((state && state.tasks) || [], column), task.id, Infinity)
|
|
@@ -2688,6 +2495,19 @@ window.__ModuleLoader__.load({
|
|
|
2688
2495
|
h('span', null, t('board.back')),
|
|
2689
2496
|
),
|
|
2690
2497
|
h('span', { className: 'dkb-barTitle' }, t('section.label')),
|
|
2498
|
+
state && state.remoteMode
|
|
2499
|
+
? h('span', {
|
|
2500
|
+
className: 'dkb-tag',
|
|
2501
|
+
style: {
|
|
2502
|
+
background: 'var(--dsw-alias-state-business-tertiary, #ddf4ff)',
|
|
2503
|
+
color: 'var(--dsw-alias-state-business-primary, #0969da)',
|
|
2504
|
+
borderColor: 'var(--dsw-alias-state-business-tertiary, #54aeff)',
|
|
2505
|
+
fontWeight: '600',
|
|
2506
|
+
fontSize: '11px',
|
|
2507
|
+
},
|
|
2508
|
+
title: 'Operating in remote mode against server 111',
|
|
2509
|
+
}, '🌐 ' + t('remote.badge'))
|
|
2510
|
+
: null,
|
|
2691
2511
|
boards.length > 1
|
|
2692
2512
|
? h('select', {
|
|
2693
2513
|
className: 'dkb-input', style: { width: 'auto' }, value: board,
|
|
@@ -3055,6 +2875,11 @@ window.__ModuleLoader__.load({
|
|
|
3055
2875
|
} catch (e) { setError(t(e.key || 'error.unknown')) }
|
|
3056
2876
|
},
|
|
3057
2877
|
onOpenChat: (x) => {
|
|
2878
|
+
if (state && state.remoteMode && x.sessionId) {
|
|
2879
|
+
const url = 'http://192.168.1.111:3080/#/chat?sessionId=' + encodeURIComponent(x.sessionId)
|
|
2880
|
+
if (typeof window !== 'undefined') window.open(url, '_blank')
|
|
2881
|
+
return
|
|
2882
|
+
}
|
|
3058
2883
|
if (!openSession(props.ctx, x.sessionId)) {
|
|
3059
2884
|
setError(t('error.sessionNotOpened', { id: x.sessionId }))
|
|
3060
2885
|
return
|
|
@@ -3129,7 +2954,7 @@ window.__ModuleLoader__.load({
|
|
|
3129
2954
|
method: 'POST',
|
|
3130
2955
|
body: JSON.stringify({ reasoningEffort: val }),
|
|
3131
2956
|
})
|
|
3132
|
-
} catch {
|
|
2957
|
+
} catch { }
|
|
3133
2958
|
},
|
|
3134
2959
|
},
|
|
3135
2960
|
h('option', { value: '' }, t('reasoning.default')),
|
|
@@ -4080,7 +3905,7 @@ window.__ModuleLoader__.load({
|
|
|
4080
3905
|
}, t('panel.cleanupWorktree'))
|
|
4081
3906
|
: null,
|
|
4082
3907
|
),
|
|
4083
|
-
(openTask.worktree || openTask.rejectReason || (Array.isArray(openTask.runs) && openTask.runs.length > 0)) ? h('button', {
|
|
3908
|
+
(openTask.worktree || openTask.rejectReason || openTask.stalled || (Array.isArray(openTask.runs) && openTask.runs.length > 0)) ? h('button', {
|
|
4084
3909
|
type: 'button',
|
|
4085
3910
|
className: 'dkb-secondary',
|
|
4086
3911
|
style: { marginRight: '8px', border: '1px solid var(--dsw-alias-border-l2)' },
|
|
@@ -4640,9 +4465,6 @@ window.__ModuleLoader__.load({
|
|
|
4640
4465
|
)
|
|
4641
4466
|
}
|
|
4642
4467
|
|
|
4643
|
-
/**
|
|
4644
|
-
* Header task chip in chat conversation. Only rendered when session is linked to a task.
|
|
4645
|
-
*/
|
|
4646
4468
|
function TaskChip(props) {
|
|
4647
4469
|
const t = props.t || fallbackT
|
|
4648
4470
|
const [task, setTask] = React.useState(null)
|
|
@@ -4674,7 +4496,7 @@ window.__ModuleLoader__.load({
|
|
|
4674
4496
|
})
|
|
4675
4497
|
setTask(out.task)
|
|
4676
4498
|
setOpen(false)
|
|
4677
|
-
} catch {
|
|
4499
|
+
} catch { }
|
|
4678
4500
|
}, [task])
|
|
4679
4501
|
|
|
4680
4502
|
if (!task) return null
|
|
@@ -4717,7 +4539,7 @@ window.__ModuleLoader__.load({
|
|
|
4717
4539
|
setTask(out.task)
|
|
4718
4540
|
setNote('')
|
|
4719
4541
|
setOpen(false)
|
|
4720
|
-
} catch {
|
|
4542
|
+
} catch { } finally {
|
|
4721
4543
|
setSaving(false)
|
|
4722
4544
|
}
|
|
4723
4545
|
},
|
|
@@ -4726,8 +4548,6 @@ window.__ModuleLoader__.load({
|
|
|
4726
4548
|
)
|
|
4727
4549
|
}
|
|
4728
4550
|
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
4551
|
const PANEL = 'kanban'
|
|
4732
4552
|
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
4733
4553
|
const ACTIVE_ATTR = 'data-dsh-kanban-active'
|
|
@@ -4740,8 +4560,6 @@ window.__ModuleLoader__.load({
|
|
|
4740
4560
|
+ ' stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
|
|
4741
4561
|
+ '<rect x="2" y="2.5" width="12" height="11" rx="1.5"/><path d="M2 6.5h12M6.5 6.5v7"/></svg>'
|
|
4742
4562
|
|
|
4743
|
-
/** Board visibility state manager. */
|
|
4744
|
-
/** @see helpers.createToggle */
|
|
4745
4563
|
function createToggle() {
|
|
4746
4564
|
let open = false
|
|
4747
4565
|
let wanted = undefined
|
|
@@ -4754,12 +4572,10 @@ window.__ModuleLoader__.load({
|
|
|
4754
4572
|
for (const fn of listeners) fn()
|
|
4755
4573
|
},
|
|
4756
4574
|
toggle() { this.set(!open) },
|
|
4757
|
-
/** Open board focused on a specific task. */
|
|
4758
4575
|
show(taskId, boardId) {
|
|
4759
4576
|
wanted = { id: String(taskId || ''), board: String(boardId || 'main') }
|
|
4760
4577
|
if (open) { for (const fn of listeners) fn() } else this.set(true)
|
|
4761
4578
|
},
|
|
4762
|
-
/** Consume requested focus task ID (cleared after first read). */
|
|
4763
4579
|
takeWanted() {
|
|
4764
4580
|
const asked = wanted
|
|
4765
4581
|
wanted = undefined
|
|
@@ -4769,7 +4585,6 @@ window.__ModuleLoader__.load({
|
|
|
4769
4585
|
}
|
|
4770
4586
|
}
|
|
4771
4587
|
|
|
4772
|
-
/** Find native 'New Session' sidebar button. */
|
|
4773
4588
|
function nativeButton() {
|
|
4774
4589
|
const nodes = document.querySelectorAll('button[class*="newSession"]')
|
|
4775
4590
|
for (const node of nodes) {
|
|
@@ -4778,9 +4593,6 @@ window.__ModuleLoader__.load({
|
|
|
4778
4593
|
return undefined
|
|
4779
4594
|
}
|
|
4780
4595
|
|
|
4781
|
-
/**
|
|
4782
|
-
* Kanban entry button cloning native button styles to match host theme.
|
|
4783
|
-
*/
|
|
4784
4596
|
function createEntry(target, toggle, label) {
|
|
4785
4597
|
const entry = target.cloneNode(true)
|
|
4786
4598
|
entry.className = String(target.className) + ' dkb-entry-clone'
|
|
@@ -4809,7 +4621,6 @@ window.__ModuleLoader__.load({
|
|
|
4809
4621
|
return entry
|
|
4810
4622
|
}
|
|
4811
4623
|
|
|
4812
|
-
/** Place button at end of injected extension entries. */
|
|
4813
4624
|
function placeEntry(target, entry) {
|
|
4814
4625
|
let anchor = target
|
|
4815
4626
|
let next = target.nextElementSibling
|
|
@@ -4822,7 +4633,6 @@ window.__ModuleLoader__.load({
|
|
|
4822
4633
|
return true
|
|
4823
4634
|
}
|
|
4824
4635
|
|
|
4825
|
-
/** Sidebar entry button persistent across shell re-renders. */
|
|
4826
4636
|
function mountSidebarEntry(toggle, label) {
|
|
4827
4637
|
if (typeof document === 'undefined') return () => {}
|
|
4828
4638
|
|
|
@@ -4856,7 +4666,6 @@ window.__ModuleLoader__.load({
|
|
|
4856
4666
|
}
|
|
4857
4667
|
}
|
|
4858
4668
|
|
|
4859
|
-
/** Board overlay container mounted over conversation column. */
|
|
4860
4669
|
function mountBoard(ctx, toggle) {
|
|
4861
4670
|
if (typeof document === 'undefined') return () => {}
|
|
4862
4671
|
let root
|
|
@@ -4913,12 +4722,6 @@ window.__ModuleLoader__.load({
|
|
|
4913
4722
|
}
|
|
4914
4723
|
}
|
|
4915
4724
|
|
|
4916
|
-
|
|
4917
|
-
/**
|
|
4918
|
-
* Register component into first available UI slot.
|
|
4919
|
-
*
|
|
4920
|
-
* @returns {string|undefined} name of successfully resolved slot
|
|
4921
|
-
*/
|
|
4922
4725
|
function registerFirst(ctx, candidates, component) {
|
|
4923
4726
|
for (const entry of candidates) {
|
|
4924
4727
|
try {
|
|
@@ -4933,7 +4736,7 @@ window.__ModuleLoader__.load({
|
|
|
4933
4736
|
if (registeredInSlot || (res !== null && res !== false && res !== undefined)) {
|
|
4934
4737
|
return entry.name
|
|
4935
4738
|
}
|
|
4936
|
-
} catch {
|
|
4739
|
+
} catch { }
|
|
4937
4740
|
}
|
|
4938
4741
|
return undefined
|
|
4939
4742
|
}
|
|
@@ -4946,11 +4749,6 @@ window.__ModuleLoader__.load({
|
|
|
4946
4749
|
refreshMirrorUntilVisible(ctx)
|
|
4947
4750
|
const SettingsErrorBoundary = createErrorBoundary()
|
|
4948
4751
|
const SafeSettingsCard = (props) => h(SettingsErrorBoundary, null, h(KanbanSettingsCard, props))
|
|
4949
|
-
// List seat (plugins.item): the seat the Plugins page renders as the plugin's own
|
|
4950
|
-
// page with its configuration. Registered separately from the fallback chain
|
|
4951
|
-
// below — the seat is additive, not an either/or candidate. The label is a static
|
|
4952
|
-
// string on purpose: it is resolved while the page renders, and a locale lookup
|
|
4953
|
-
// there would take the whole client batch down with it.
|
|
4954
4752
|
const trySlot = (name, register) => {
|
|
4955
4753
|
try {
|
|
4956
4754
|
if (typeof ctx.slots?.inject === 'function') ctx.slots.inject(name, register)
|
|
@@ -4959,9 +4757,6 @@ window.__ModuleLoader__.load({
|
|
|
4959
4757
|
console.warn('[dsh-kanban] slot registration failed for ' + name + ':', e && e.message)
|
|
4960
4758
|
}
|
|
4961
4759
|
}
|
|
4962
|
-
|
|
4963
|
-
// #274: Newest slot first, older slots as fallbacks:
|
|
4964
|
-
// 1. plugins.row.config (Row seat on Plugins page, DSH 0.1.6-alpha.2)
|
|
4965
4760
|
let cardSlot = undefined
|
|
4966
4761
|
trySlot('plugins.row.config', () => {
|
|
4967
4762
|
ctx.slots.register(
|
|
@@ -4975,8 +4770,6 @@ window.__ModuleLoader__.load({
|
|
|
4975
4770
|
)
|
|
4976
4771
|
if (!cardSlot) cardSlot = 'plugins.row.config'
|
|
4977
4772
|
})
|
|
4978
|
-
|
|
4979
|
-
// 2. plugins.item (Official group on Plugins page)
|
|
4980
4773
|
trySlot('plugins.item', () => {
|
|
4981
4774
|
ctx.slots.register(
|
|
4982
4775
|
{
|
|
@@ -4990,8 +4783,6 @@ window.__ModuleLoader__.load({
|
|
|
4990
4783
|
SafeSettingsCard,
|
|
4991
4784
|
)
|
|
4992
4785
|
})
|
|
4993
|
-
|
|
4994
|
-
// 3. settings.plugin.item (legacy fallback for older cores)
|
|
4995
4786
|
trySlot('settings.plugin.item', () => {
|
|
4996
4787
|
ctx.slots.register(
|
|
4997
4788
|
{
|