@goodandready/dsh-kanban 0.2.32 → 0.2.34
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 +401 -346
- package/lib/config.js +29 -1
- package/lib/cost-telemetry.js +146 -0
- package/lib/index.js +94 -6
- package/lib/remote-relay.js +149 -0
- package/lib/remote-runner.js +164 -0
- package/lib/routes.js +97 -9
- package/lib/store.js +22 -0
- package/lib/worktree.js +35 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -22,11 +22,6 @@ window.__ModuleLoader__.load({
|
|
|
22
22
|
const ROW_CONFIG_KEY = PKG + '#' + ROW_ID
|
|
23
23
|
const COLUMN_ORDER = ['backlog', 'in-progress', 'review', 'deploy', 'cleanup', 'done']
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Neighbours for card repositioning. The store operates on relative neighbours
|
|
28
|
-
* rather than numeric indexes: `afterId` above, `beforeId` below.
|
|
29
|
-
*/
|
|
30
25
|
function neighboursFor(columnTasks, dragId, index) {
|
|
31
26
|
const rest = (columnTasks || []).filter((t) => t.id !== dragId)
|
|
32
27
|
const clamped = Math.max(0, Math.min(index, rest.length))
|
|
@@ -40,13 +35,6 @@ window.__ModuleLoader__.load({
|
|
|
40
35
|
return (tasks || []).filter((t) => t.column === column)
|
|
41
36
|
}
|
|
42
37
|
|
|
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
38
|
function sortTasks(tasks, order) {
|
|
51
39
|
const list = tasks || []
|
|
52
40
|
if (order !== 'old' && order !== 'new') return list
|
|
@@ -67,22 +55,6 @@ window.__ModuleLoader__.load({
|
|
|
67
55
|
return out
|
|
68
56
|
}
|
|
69
57
|
|
|
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
58
|
async function applyToEach(ids, act) {
|
|
87
59
|
let done = 0
|
|
88
60
|
let failed = 0
|
|
@@ -92,12 +64,6 @@ window.__ModuleLoader__.load({
|
|
|
92
64
|
return { done, failed }
|
|
93
65
|
}
|
|
94
66
|
|
|
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
67
|
const RECALL_KEY = 'dsh-kanban:launch:'
|
|
102
68
|
|
|
103
69
|
function recallLaunch(board) {
|
|
@@ -114,13 +80,6 @@ window.__ModuleLoader__.load({
|
|
|
114
80
|
} catch { /* storage unavailable */ }
|
|
115
81
|
}
|
|
116
82
|
|
|
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
83
|
function stillOffered(value, known, fallback) {
|
|
125
84
|
return typeof value === 'string' && (known || []).indexOf(value) >= 0 ? value : fallback
|
|
126
85
|
}
|
|
@@ -142,14 +101,6 @@ window.__ModuleLoader__.load({
|
|
|
142
101
|
return out
|
|
143
102
|
}
|
|
144
103
|
|
|
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
104
|
function groupByAssignee(tasks) {
|
|
154
105
|
const by = new Map()
|
|
155
106
|
for (const task of tasks || []) {
|
|
@@ -168,11 +119,6 @@ window.__ModuleLoader__.load({
|
|
|
168
119
|
return task.repo + '#' + task.issueNumber
|
|
169
120
|
}
|
|
170
121
|
|
|
171
|
-
/**
|
|
172
|
-
* Project repository and issue number rendered separately.
|
|
173
|
-
*
|
|
174
|
-
* Issue number links directly to the remote issue.
|
|
175
|
-
*/
|
|
176
122
|
function taskRef(task, t) {
|
|
177
123
|
if (!task || !task.repo) return null
|
|
178
124
|
const number = typeof task.issueNumber === 'number' ? '#' + task.issueNumber : ''
|
|
@@ -202,11 +148,6 @@ window.__ModuleLoader__.load({
|
|
|
202
148
|
return parts.join(' · ')
|
|
203
149
|
}
|
|
204
150
|
|
|
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
151
|
function planLine(task, t) {
|
|
211
152
|
const progress = task && task.plan && task.plan.progress
|
|
212
153
|
if (!progress || !progress.total) return ''
|
|
@@ -215,7 +156,6 @@ window.__ModuleLoader__.load({
|
|
|
215
156
|
return progress.text ? counter + ' · ' + progress.text : counter
|
|
216
157
|
}
|
|
217
158
|
|
|
218
|
-
/** Status badge text. Waiting indicator is rendered separately. */
|
|
219
159
|
function stateLabel(task, t) {
|
|
220
160
|
const state = task && task.state
|
|
221
161
|
if (state === 'running') return t('state.running')
|
|
@@ -223,26 +163,12 @@ window.__ModuleLoader__.load({
|
|
|
223
163
|
return ''
|
|
224
164
|
}
|
|
225
165
|
|
|
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
166
|
function isCollapsed(column, manual) {
|
|
236
167
|
const own = manual && manual[column.id]
|
|
237
168
|
if (own === true || own === false) return own
|
|
238
169
|
return (column.count || 0) === 0
|
|
239
170
|
}
|
|
240
171
|
|
|
241
|
-
/**
|
|
242
|
-
* Relative elapsed time string: "5m", "3h", "3d".
|
|
243
|
-
*
|
|
244
|
-
* Computed client-side with full ISO timestamp displayed on hover tooltip.
|
|
245
|
-
*/
|
|
246
172
|
function agoText(now, then, t) {
|
|
247
173
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
248
174
|
const delta = Math.max(0, now - then)
|
|
@@ -254,7 +180,6 @@ window.__ModuleLoader__.load({
|
|
|
254
180
|
return t('time.day', { n: Math.floor(hours / 24) })
|
|
255
181
|
}
|
|
256
182
|
|
|
257
|
-
/** Date formatted without time. Year is included only when not the current year. */
|
|
258
183
|
function shortDate(then) {
|
|
259
184
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
260
185
|
try {
|
|
@@ -266,19 +191,11 @@ window.__ModuleLoader__.load({
|
|
|
266
191
|
} catch { return '' }
|
|
267
192
|
}
|
|
268
193
|
|
|
269
|
-
/** Exact timestamp for tooltip. Empty tooltip if timestamp is invalid. */
|
|
270
194
|
function exactAt(then) {
|
|
271
195
|
if (typeof then !== 'number' || then <= 0) return ''
|
|
272
196
|
try { return new Date(then).toLocaleString() } catch { return '' }
|
|
273
197
|
}
|
|
274
198
|
|
|
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
199
|
function syncLine(sync, now, t) {
|
|
283
200
|
const state = (sync && sync.state) || 'never'
|
|
284
201
|
if (state === 'running') return { tone: 'idle', text: t('sync.running'), title: '' }
|
|
@@ -303,13 +220,6 @@ window.__ModuleLoader__.load({
|
|
|
303
220
|
}
|
|
304
221
|
}
|
|
305
222
|
|
|
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
223
|
function readableOn(hex) {
|
|
314
224
|
const n = parseInt(String(hex || ''), 16)
|
|
315
225
|
if (!isFinite(n)) return ''
|
|
@@ -319,11 +229,6 @@ window.__ModuleLoader__.load({
|
|
|
319
229
|
return (r * 299 + g * 587 + b * 114) / 1000 > 140 ? '#111' : '#fff'
|
|
320
230
|
}
|
|
321
231
|
|
|
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
232
|
function priorityColor(task) {
|
|
328
233
|
const values = (task && task.facets && task.facets.priority) || []
|
|
329
234
|
for (const value of values) {
|
|
@@ -333,18 +238,12 @@ window.__ModuleLoader__.load({
|
|
|
333
238
|
return ''
|
|
334
239
|
}
|
|
335
240
|
|
|
336
|
-
/** Tag style helper. Neutral style when color is not defined. */
|
|
337
241
|
function tagStyle(task, name) {
|
|
338
242
|
const hex = task && task.labelColors ? task.labelColors[name] : undefined
|
|
339
243
|
if (!hex) return undefined
|
|
340
244
|
return { background: '#' + hex, color: readableOn(hex), borderColor: 'transparent' }
|
|
341
245
|
}
|
|
342
246
|
|
|
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
247
|
function renderSpans(spans, keyBase) {
|
|
349
248
|
return (spans || []).map((span, i) => {
|
|
350
249
|
const key = keyBase + '-' + i
|
|
@@ -385,14 +284,6 @@ window.__ModuleLoader__.load({
|
|
|
385
284
|
})
|
|
386
285
|
}
|
|
387
286
|
|
|
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
287
|
function columnTitle(col, t) {
|
|
397
288
|
const own = col && col.name
|
|
398
289
|
return own !== undefined && own !== '' ? own : t('column.' + (col && col.id))
|
|
@@ -404,11 +295,6 @@ window.__ModuleLoader__.load({
|
|
|
404
295
|
return text === key ? ns : text
|
|
405
296
|
}
|
|
406
297
|
|
|
407
|
-
/**
|
|
408
|
-
* Board title.
|
|
409
|
-
*
|
|
410
|
-
* Default 'main' and 'simple' boards use localized titles; custom board names are preserved verbatim.
|
|
411
|
-
*/
|
|
412
298
|
function boardTitle(board, t) {
|
|
413
299
|
const key = 'boardName.' + (board && board.id)
|
|
414
300
|
const text = t(key)
|
|
@@ -434,15 +320,8 @@ window.__ModuleLoader__.load({
|
|
|
434
320
|
}
|
|
435
321
|
}
|
|
436
322
|
|
|
437
|
-
/** Repository facet filter key matching backend dimension. */
|
|
438
323
|
const REPO_FACET = 'repo'
|
|
439
324
|
|
|
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
325
|
function matchesFilters(task, selected) {
|
|
447
326
|
const keys = Object.keys(selected || {})
|
|
448
327
|
for (const ns of keys) {
|
|
@@ -456,14 +335,12 @@ window.__ModuleLoader__.load({
|
|
|
456
335
|
return true
|
|
457
336
|
}
|
|
458
337
|
|
|
459
|
-
/** True if any filter is active. */
|
|
460
338
|
function anySelected(selected) {
|
|
461
339
|
const keys = Object.keys(selected || {})
|
|
462
340
|
for (const ns of keys) if ((selected[ns] || []).length > 0) return true
|
|
463
341
|
return false
|
|
464
342
|
}
|
|
465
343
|
|
|
466
|
-
/** Toggle filter value, returning a new map for React immutability. */
|
|
467
344
|
function toggleValue(selected, ns, value) {
|
|
468
345
|
const current = (selected || {})[ns] || []
|
|
469
346
|
const next = current.indexOf(value) >= 0
|
|
@@ -475,7 +352,6 @@ window.__ModuleLoader__.load({
|
|
|
475
352
|
return out
|
|
476
353
|
}
|
|
477
354
|
|
|
478
|
-
/** Human-readable explanation for empty state or error. */
|
|
479
355
|
function errorKey(error) {
|
|
480
356
|
switch (error) {
|
|
481
357
|
case 'gitea-absent': return 'error.giteaAbsent'
|
|
@@ -492,11 +368,6 @@ window.__ModuleLoader__.load({
|
|
|
492
368
|
}
|
|
493
369
|
}
|
|
494
370
|
|
|
495
|
-
/**
|
|
496
|
-
* Open session conversation in chat panel.
|
|
497
|
-
*
|
|
498
|
-
* @returns {boolean} true if session opened successfully
|
|
499
|
-
*/
|
|
500
371
|
function openSession(ctx, sessionId) {
|
|
501
372
|
if (!sessionId) return false
|
|
502
373
|
const sessions = ctx && typeof ctx.get === 'function' ? ctx.get('sessions') : undefined
|
|
@@ -509,7 +380,6 @@ window.__ModuleLoader__.load({
|
|
|
509
380
|
}
|
|
510
381
|
}
|
|
511
382
|
|
|
512
|
-
/** Repository option label with open issue count; marks archived repositories. */
|
|
513
383
|
function repoOption(r, t) {
|
|
514
384
|
const full = r.fullName || ((r.owner || '') + '/' + (r.repo || ''))
|
|
515
385
|
const parts = [full]
|
|
@@ -518,16 +388,12 @@ window.__ModuleLoader__.load({
|
|
|
518
388
|
return parts.join(' ')
|
|
519
389
|
}
|
|
520
390
|
|
|
521
|
-
/** Parse 'owner/repo' string into separate parts. */
|
|
522
391
|
function splitFullName(fullName) {
|
|
523
392
|
const parts = String(fullName || '').split('/')
|
|
524
393
|
if (parts.length !== 2 || parts[0] === '' || parts[1] === '') return undefined
|
|
525
394
|
return { owner: parts[0], repo: parts[1] }
|
|
526
395
|
}
|
|
527
396
|
|
|
528
|
-
/**
|
|
529
|
-
* Filter cards by client-side text search query: title, repo, issue number.
|
|
530
|
-
*/
|
|
531
397
|
function matchesQuery(task, query) {
|
|
532
398
|
const needle = String(query || '').trim().toLowerCase()
|
|
533
399
|
if (needle === '') return true
|
|
@@ -540,7 +406,6 @@ window.__ModuleLoader__.load({
|
|
|
540
406
|
return hay.indexOf(needle) >= 0
|
|
541
407
|
}
|
|
542
408
|
|
|
543
|
-
/** Retrieve session ID for header chip. */
|
|
544
409
|
function chipSessionId(props, session) {
|
|
545
410
|
return String((props && props.sessionId) || (session && (session.sessionId || session.id)) || '').trim()
|
|
546
411
|
}
|
|
@@ -554,7 +419,6 @@ window.__ModuleLoader__.load({
|
|
|
554
419
|
chipSessionId, matchesQuery, splitFullName, repoOption, openSession, COLUMN_ORDER,
|
|
555
420
|
}
|
|
556
421
|
|
|
557
|
-
|
|
558
422
|
function createTimeoutSignal(ms) {
|
|
559
423
|
const sig = typeof AbortSignal !== 'undefined' ? AbortSignal : (typeof globalThis !== 'undefined' ? globalThis.AbortSignal : undefined)
|
|
560
424
|
if (sig && typeof sig.timeout === 'function') {
|
|
@@ -689,183 +553,7 @@ window.__ModuleLoader__.load({
|
|
|
689
553
|
return () => clearTimer(timer)
|
|
690
554
|
}
|
|
691
555
|
|
|
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
|
-
|
|
556
|
+
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
557
|
|
|
870
558
|
const en = {
|
|
871
559
|
'updater.title': 'Plugin Updates',
|
|
@@ -1266,6 +954,55 @@ window.__ModuleLoader__.load({
|
|
|
1266
954
|
'error.crossSite': 'Request rejected as cross-site.',
|
|
1267
955
|
'error.timeout': 'Request timed out. Please try again.',
|
|
1268
956
|
'error.unknown': 'Request failed.',
|
|
957
|
+
'field.costMeterEnabled': 'Cost Meter Telemetry',
|
|
958
|
+
'hint.costMeterEnabled': 'Enable token and cost telemetry integration via @goodandready/dsh-cost-meter.',
|
|
959
|
+
'field.taskCostLimit': 'Task Cost Limit (USD)',
|
|
960
|
+
'hint.taskCostLimit': 'Cost threshold per task in USD; 0 disables threshold warnings.',
|
|
961
|
+
'card.costLimitExceeded': 'Cost limit exceeded',
|
|
962
|
+
'card.nudge': 'Nudge',
|
|
963
|
+
'card.nudgeHint': 'Send live instruction to running agent',
|
|
964
|
+
'nudge.title': 'Live Steering',
|
|
965
|
+
'nudge.placeholder': 'Enter immediate instruction or correction for the agent...',
|
|
966
|
+
'nudge.send': 'Send',
|
|
967
|
+
'nudge.sending': 'Sending...',
|
|
968
|
+
'nudge.success': 'Instruction delivered to agent',
|
|
969
|
+
'nudge.failed': 'Failed to deliver instruction',
|
|
970
|
+
'costMeter.notice': 'Cost and token tracking requires @goodandready/dsh-cost-meter to be installed and active in DSH profile.',
|
|
971
|
+
'costMeter.active': 'Plugin @goodandready/dsh-cost-meter is active',
|
|
972
|
+
'costMeter.inactive': 'Plugin @goodandready/dsh-cost-meter not detected',
|
|
973
|
+
'telemetry.title': 'Resource Telemetry',
|
|
974
|
+
'telemetry.tokens': 'Tokens',
|
|
975
|
+
'telemetry.input': 'Input',
|
|
976
|
+
'telemetry.output': 'Output',
|
|
977
|
+
'telemetry.cache': 'Cached',
|
|
978
|
+
'telemetry.cost': 'Estimated Cost',
|
|
979
|
+
'group.remote': 'Remote execution (Server 111)',
|
|
980
|
+
'field.remoteMode': 'Remote mode',
|
|
981
|
+
'hint.remoteMode': 'Execute tasks, worktrees, and git commands on remote server 111.',
|
|
982
|
+
'field.remoteHost': 'Remote host',
|
|
983
|
+
'hint.remoteHost': 'Hostname or IP address of the remote server.',
|
|
984
|
+
'field.remotePort': 'SSH port',
|
|
985
|
+
'hint.remotePort': 'SSH port on remote server (default 22).',
|
|
986
|
+
'field.remoteUser': 'SSH user',
|
|
987
|
+
'hint.remoteUser': 'SSH login username on remote host.',
|
|
988
|
+
'field.remoteAuthType': 'SSH auth type',
|
|
989
|
+
'hint.remoteAuthType': 'SSH authentication method: key, agent, or password.',
|
|
990
|
+
'field.remoteKeyPath': 'SSH private key',
|
|
991
|
+
'hint.remoteKeyPath': 'Path to SSH private key file on local PC.',
|
|
992
|
+
'field.remoteSudoUser': 'Sudo user',
|
|
993
|
+
'hint.remoteSudoUser': 'Run remote commands under this Linux user via sudo -u.',
|
|
994
|
+
'field.remoteRoot': 'Remote project root',
|
|
995
|
+
'hint.remoteRoot': 'Remote projects directory (/mnt/external/Project/DEV).',
|
|
996
|
+
'field.remoteServerUrl': 'DSH server URL',
|
|
997
|
+
'hint.remoteServerUrl': 'Remote DSH URL (http://192.168.1.111:3080) for unified board state.',
|
|
998
|
+
'field.remoteServerToken': 'Server auth token',
|
|
999
|
+
'hint.remoteServerToken': 'Optional authentication token for remote DSH server.',
|
|
1000
|
+
'remote.testBtn': 'Test Connection',
|
|
1001
|
+
'remote.testing': 'Testing connection...',
|
|
1002
|
+
'remote.ok': 'Connected to server 111',
|
|
1003
|
+
'remote.failed': 'Connection failed',
|
|
1004
|
+
'remote.badge': 'Remote: 111',
|
|
1005
|
+
'telemetry.limit': 'Budget Limit',
|
|
1269
1006
|
}
|
|
1270
1007
|
|
|
1271
1008
|
const zh = {
|
|
@@ -1667,6 +1404,55 @@ window.__ModuleLoader__.load({
|
|
|
1667
1404
|
'error.crossSite': '请求被判定为跨站而拒绝。',
|
|
1668
1405
|
'error.timeout': '请求超时,请重试。',
|
|
1669
1406
|
'error.unknown': '请求失败。',
|
|
1407
|
+
'field.costMeterEnabled': '成本计量遥测',
|
|
1408
|
+
'hint.costMeterEnabled': '通过 @goodandready/dsh-cost-meter 启用 Token 和成本遥测集成。',
|
|
1409
|
+
'field.taskCostLimit': '任务成本限额 (USD)',
|
|
1410
|
+
'hint.taskCostLimit': '每个任务的成本阈值(美元);0 表示禁用超额警告。',
|
|
1411
|
+
'card.costLimitExceeded': '超出成本限额',
|
|
1412
|
+
'card.nudge': '引导',
|
|
1413
|
+
'card.nudgeHint': '向正在运行的 Agent 发送实时引导指令',
|
|
1414
|
+
'nudge.title': '实时引导',
|
|
1415
|
+
'nudge.placeholder': '输入对 Agent 的即时指令或修正建议...',
|
|
1416
|
+
'nudge.send': '发送',
|
|
1417
|
+
'nudge.sending': '正在发送...',
|
|
1418
|
+
'nudge.success': '指令已发送给 Agent',
|
|
1419
|
+
'nudge.failed': '发送指令失败',
|
|
1420
|
+
'costMeter.notice': 'Token 及成本追踪功能需要 DSH Profile 中安装并激活 @goodandready/dsh-cost-meter 插件。',
|
|
1421
|
+
'costMeter.active': '已激活 @goodandready/dsh-cost-meter 插件',
|
|
1422
|
+
'costMeter.inactive': '未检测到 @goodandready/dsh-cost-meter 插件',
|
|
1423
|
+
'telemetry.title': '资源遥测',
|
|
1424
|
+
'telemetry.tokens': 'Token 统计',
|
|
1425
|
+
'telemetry.input': '输入',
|
|
1426
|
+
'telemetry.output': '输出',
|
|
1427
|
+
'telemetry.cache': '缓存命中',
|
|
1428
|
+
'telemetry.cost': '预估成本',
|
|
1429
|
+
'group.remote': '远程执行 (111 服务器)',
|
|
1430
|
+
'field.remoteMode': '远程模式',
|
|
1431
|
+
'hint.remoteMode': '在远程 111 服务器上执行任务、工作树和 git 命令。',
|
|
1432
|
+
'field.remoteHost': '远程主机',
|
|
1433
|
+
'hint.remoteHost': '远程服务器的主机名或 IP 地址。',
|
|
1434
|
+
'field.remotePort': 'SSH 端口',
|
|
1435
|
+
'hint.remotePort': '远程服务器的 SSH 端口(默认 22)。',
|
|
1436
|
+
'field.remoteUser': 'SSH 用户',
|
|
1437
|
+
'hint.remoteUser': '远程主机上的 SSH 登录用户名。',
|
|
1438
|
+
'field.remoteAuthType': 'SSH 认证类型',
|
|
1439
|
+
'hint.remoteAuthType': 'SSH 认证方式:key、agent 或 password。',
|
|
1440
|
+
'field.remoteKeyPath': 'SSH 私钥路径',
|
|
1441
|
+
'hint.remoteKeyPath': '本地电脑上的 SSH 私钥文件路径。',
|
|
1442
|
+
'field.remoteSudoUser': 'Sudo 执行用户',
|
|
1443
|
+
'hint.remoteSudoUser': '在远程通过 sudo -u 以此 Linux 用户身份运行命令。',
|
|
1444
|
+
'field.remoteRoot': '远程项目根目录',
|
|
1445
|
+
'hint.remoteRoot': '远程项目仓库目录 (/mnt/external/Project/DEV)。',
|
|
1446
|
+
'field.remoteServerUrl': 'DSH 服务器地址',
|
|
1447
|
+
'hint.remoteServerUrl': '远程 DSH 服务器地址 (http://192.168.1.111:3080),用于共享看板状态。',
|
|
1448
|
+
'field.remoteServerToken': '服务器认证令牌',
|
|
1449
|
+
'hint.remoteServerToken': '远程 DSH 服务器的可选认证令牌。',
|
|
1450
|
+
'remote.testBtn': '测试连接',
|
|
1451
|
+
'remote.testing': '正在测试连接...',
|
|
1452
|
+
'remote.ok': '已连接到 111 服务器',
|
|
1453
|
+
'remote.failed': '连接失败',
|
|
1454
|
+
'remote.badge': '远程: 111',
|
|
1455
|
+
'telemetry.limit': '预算限额',
|
|
1670
1456
|
}
|
|
1671
1457
|
|
|
1672
1458
|
function fallbackT(key, vars) {
|
|
@@ -1679,7 +1465,6 @@ window.__ModuleLoader__.load({
|
|
|
1679
1465
|
return text
|
|
1680
1466
|
}
|
|
1681
1467
|
|
|
1682
|
-
|
|
1683
1468
|
const FIELDS = [
|
|
1684
1469
|
{ field: 'gitProvider', kind: 'text', group: 'forge' },
|
|
1685
1470
|
{ field: 'giteaUrl', kind: 'text', group: 'gitea' },
|
|
@@ -1715,6 +1500,18 @@ window.__ModuleLoader__.load({
|
|
|
1715
1500
|
{ field: 'verificationGateEnabled', kind: 'bool', group: 'general' },
|
|
1716
1501
|
{ field: 'verificationCommand', kind: 'text', group: 'general' },
|
|
1717
1502
|
{ field: 'verificationTimeoutMs', kind: 'number', group: 'general' },
|
|
1503
|
+
{ field: 'costMeterEnabled', kind: 'bool', group: 'sync' },
|
|
1504
|
+
{ field: 'taskCostLimit', kind: 'number', group: 'limits' },
|
|
1505
|
+
{ field: 'remoteMode', kind: 'bool', group: 'remote' },
|
|
1506
|
+
{ field: 'remoteHost', kind: 'text', group: 'remote' },
|
|
1507
|
+
{ field: 'remotePort', kind: 'number', group: 'remote' },
|
|
1508
|
+
{ field: 'remoteUser', kind: 'text', group: 'remote' },
|
|
1509
|
+
{ field: 'remoteAuthType', kind: 'text', group: 'remote' },
|
|
1510
|
+
{ field: 'remoteKeyPath', kind: 'text', group: 'remote' },
|
|
1511
|
+
{ field: 'remoteSudoUser', kind: 'text', group: 'remote' },
|
|
1512
|
+
{ field: 'remoteRoot', kind: 'text', group: 'remote' },
|
|
1513
|
+
{ field: 'remoteServerUrl', kind: 'text', group: 'remote' },
|
|
1514
|
+
{ field: 'remoteServerToken', kind: 'text', group: 'remote' },
|
|
1718
1515
|
]
|
|
1719
1516
|
|
|
1720
1517
|
function hintKey(spec) {
|
|
@@ -1722,6 +1519,7 @@ window.__ModuleLoader__.load({
|
|
|
1722
1519
|
if (spec.group === 'gitea') return 'hint.' + spec.field
|
|
1723
1520
|
if (spec.group === 'github') return 'hint.' + spec.field
|
|
1724
1521
|
if (spec.group === 'forge') return 'hint.' + spec.field
|
|
1522
|
+
if (spec.group === 'remote') return 'hint.' + spec.field
|
|
1725
1523
|
if (spec.group === 'labels') return 'hint.label'
|
|
1726
1524
|
if (spec.group === 'limits') return 'hint.limit'
|
|
1727
1525
|
return 'hint.' + spec.field
|
|
@@ -1759,6 +1557,63 @@ window.__ModuleLoader__.load({
|
|
|
1759
1557
|
}, h(Icon))
|
|
1760
1558
|
}
|
|
1761
1559
|
|
|
1560
|
+
function RemoteConnectionSection(props) {
|
|
1561
|
+
const t = props.t || fallbackT
|
|
1562
|
+
const [testing, setTesting] = React.useState(false)
|
|
1563
|
+
const [result, setResult] = React.useState(null)
|
|
1564
|
+
|
|
1565
|
+
const handleTest = React.useCallback(async () => {
|
|
1566
|
+
setTesting(true)
|
|
1567
|
+
setResult(null)
|
|
1568
|
+
try {
|
|
1569
|
+
const res = await fetch('/api/dsh-kanban/remote/test', {
|
|
1570
|
+
method: 'POST',
|
|
1571
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1572
|
+
})
|
|
1573
|
+
const data = await res.json()
|
|
1574
|
+
setResult(data)
|
|
1575
|
+
} catch (e) {
|
|
1576
|
+
setResult({ ok: false, error: e?.message || String(e) })
|
|
1577
|
+
} finally {
|
|
1578
|
+
setTesting(false)
|
|
1579
|
+
}
|
|
1580
|
+
}, [])
|
|
1581
|
+
|
|
1582
|
+
return h('div', {
|
|
1583
|
+
className: 'dkb-section-card',
|
|
1584
|
+
key: 'remote-test-card',
|
|
1585
|
+
style: { borderLeft: '3px solid var(--dsw-alias-state-business-primary, #0969da)', background: 'var(--dsw-alias-bg-layer-1, #f6f8fa)', padding: '12px 14px', marginBottom: '12px' },
|
|
1586
|
+
},
|
|
1587
|
+
h('div', {
|
|
1588
|
+
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: result ? '8px' : '0' },
|
|
1589
|
+
},
|
|
1590
|
+
h('span', { style: { fontWeight: '600', fontSize: '13px' } }, '🌐 ' + t('group.remote')),
|
|
1591
|
+
h('button', {
|
|
1592
|
+
type: 'button',
|
|
1593
|
+
className: 'dkb-save',
|
|
1594
|
+
style: { padding: '3px 10px', fontSize: '12px' },
|
|
1595
|
+
disabled: testing,
|
|
1596
|
+
onClick: handleTest,
|
|
1597
|
+
}, testing ? t('remote.testing') : t('remote.testBtn')),
|
|
1598
|
+
),
|
|
1599
|
+
result ? h('div', {
|
|
1600
|
+
style: {
|
|
1601
|
+
fontSize: '12px',
|
|
1602
|
+
padding: '6px 8px',
|
|
1603
|
+
borderRadius: '4px',
|
|
1604
|
+
background: (result.ssh?.ok || result.server?.ok)
|
|
1605
|
+
? 'var(--dsw-alias-state-success-secondary, #dafbe1)'
|
|
1606
|
+
: 'var(--dsw-alias-state-error-secondary, #ffebe9)',
|
|
1607
|
+
color: (result.ssh?.ok || result.server?.ok)
|
|
1608
|
+
? 'var(--dsw-alias-state-success-primary, #1a7f37)'
|
|
1609
|
+
: 'var(--dsw-alias-state-error-primary, #cf222e)',
|
|
1610
|
+
},
|
|
1611
|
+
},
|
|
1612
|
+
h('div', null, (result.ssh?.ok ? '✓ SSH: OK (' + result.ssh.latencyMs + 'ms)' : '✗ SSH: ' + (result.ssh?.error || 'unreachable'))),
|
|
1613
|
+
h('div', null, (result.server?.ok ? '✓ DSH Server: OK (' + result.server.latencyMs + 'ms)' : '✗ DSH Server: ' + (result.server?.error || 'unreachable'))),
|
|
1614
|
+
) : null,
|
|
1615
|
+
)
|
|
1616
|
+
}
|
|
1762
1617
|
|
|
1763
1618
|
function PluginUpdaterSection(props) {
|
|
1764
1619
|
const t = props.t || fallbackT
|
|
@@ -2014,6 +1869,30 @@ window.__ModuleLoader__.load({
|
|
|
2014
1869
|
else if (!writable) note = h('p', { className: 'dkb-note', role: 'status' }, t('settings.readOnly'))
|
|
2015
1870
|
else if (saved) note = h('p', { className: 'dkb-note', role: 'status' }, t('settings.saved'))
|
|
2016
1871
|
else note = h('p', { className: 'dkb-note' })
|
|
1872
|
+
const costMeterDetected = Boolean(ctx?.costMeter || (ctx?.registry && Array.from(ctx.registry.keys()).some((k) => k === '@goodandready/dsh-cost-meter' || k?.name === '@goodandready/dsh-cost-meter')))
|
|
1873
|
+
rows.push(h('div', {
|
|
1874
|
+
className: 'dkb-section-card',
|
|
1875
|
+
key: 'cost-meter-notice',
|
|
1876
|
+
style: {
|
|
1877
|
+
borderLeft: '3px solid var(--dsw-alias-state-business-primary, #0969da)',
|
|
1878
|
+
background: 'var(--dsw-alias-bg-layer-1, #f6f8fa)',
|
|
1879
|
+
padding: '12px 14px',
|
|
1880
|
+
marginBottom: '12px',
|
|
1881
|
+
},
|
|
1882
|
+
},
|
|
1883
|
+
h('div', {
|
|
1884
|
+
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' },
|
|
1885
|
+
},
|
|
1886
|
+
h('span', { style: { fontWeight: '600', fontSize: '13px' } }, '🪙 ' + t('telemetry.title')),
|
|
1887
|
+
h('span', {
|
|
1888
|
+
className: 'dkb-section-badge' + (costMeterDetected ? ' dkb-section-badge-ok' : ''),
|
|
1889
|
+
}, costMeterDetected ? t('costMeter.active') : t('costMeter.inactive')),
|
|
1890
|
+
),
|
|
1891
|
+
h('p', { className: 'dkb-hint', style: { margin: 0, fontSize: '12px', lineHeight: '1.4' } },
|
|
1892
|
+
t('costMeter.notice'),
|
|
1893
|
+
),
|
|
1894
|
+
))
|
|
1895
|
+
rows.push(h(RemoteConnectionSection, { t, key: 'remote-test' }))
|
|
2017
1896
|
rows.push(h(PluginUpdaterSection, { t, key: 'updater' }))
|
|
2018
1897
|
rows.push(h('div', { className: 'dkb-foot', key: 'foot' },
|
|
2019
1898
|
note,
|
|
@@ -2029,12 +1908,10 @@ window.__ModuleLoader__.load({
|
|
|
2029
1908
|
return h('li', { className: 'dkb-card dkb-cardOpen' }, head, h('div', { className: 'dkb-body' }, body))
|
|
2030
1909
|
}
|
|
2031
1910
|
|
|
2032
|
-
/** Back button arrow icon: 14x14 stroke currentColor. */
|
|
2033
1911
|
const BACK_ICON = '<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor"'
|
|
2034
1912
|
+ ' stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
|
|
2035
1913
|
+ '<path d="M10 3.5 5.5 8l4.5 4.5"/></svg>'
|
|
2036
1914
|
|
|
2037
|
-
|
|
2038
1915
|
const TaskCard = React.memo(function TaskCard(props) {
|
|
2039
1916
|
const { task, t, now } = props
|
|
2040
1917
|
const ref = cardRef(task)
|
|
@@ -2094,6 +1971,20 @@ window.__ModuleLoader__.load({
|
|
|
2094
1971
|
: (task.report?.verification?.status === 'failed'
|
|
2095
1972
|
? h('span', { className: 'dkb-tag', style: { background: 'var(--dsw-alias-state-error-secondary, #ffebe9)', color: 'var(--dsw-alias-state-error-primary, #cf222e)', borderColor: 'var(--dsw-alias-state-error-secondary, #ffc1c0)' }, title: task.report.verification.command || 'Tests failed' }, '✗ FAIL')
|
|
2096
1973
|
: null),
|
|
1974
|
+
task.costMetrics && task.costMetrics.totalTokens > 0
|
|
1975
|
+
? h('span', {
|
|
1976
|
+
className: 'dkb-tag',
|
|
1977
|
+
style: { background: 'var(--dsw-alias-state-business-tertiary, #ddf4ff)', color: 'var(--dsw-alias-state-business-primary, #0969da)', borderColor: 'var(--dsw-alias-state-business-tertiary, #54aeff)' },
|
|
1978
|
+
title: 'Tokens: ' + task.costMetrics.totalTokens.toLocaleString()
|
|
1979
|
+
}, '🪙 ' + (task.costMetrics.totalTokens / 1000).toFixed(1) + 'k' + (task.costMetrics.costFormatted ? ' · ' + task.costMetrics.costFormatted : ''))
|
|
1980
|
+
: null,
|
|
1981
|
+
task.costLimitExceeded
|
|
1982
|
+
? h('span', {
|
|
1983
|
+
className: 'dkb-tag',
|
|
1984
|
+
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)' },
|
|
1985
|
+
title: 'Budget limit exceeded'
|
|
1986
|
+
}, '⚠️ ' + t('card.costLimitExceeded'))
|
|
1987
|
+
: null,
|
|
2097
1988
|
task.report && task.report.summary
|
|
2098
1989
|
? h('span', { className: 'dkb-tag', title: 'Execution Report' }, '📄 report')
|
|
2099
1990
|
: null,
|
|
@@ -2104,6 +1995,16 @@ window.__ModuleLoader__.load({
|
|
|
2104
1995
|
className: 'dkb-tag', key: l, style: tagStyle(task, l),
|
|
2105
1996
|
}, l))),
|
|
2106
1997
|
h('div', { className: 'dkb-taskTitle' }, task.title),
|
|
1998
|
+
task.state === 'running' && task.liveStep
|
|
1999
|
+
? h('div', {
|
|
2000
|
+
className: 'dkb-liveStep',
|
|
2001
|
+
style: { fontSize: '11px', color: 'var(--dsw-alias-state-business-primary, #0969da)', display: 'flex', alignItems: 'center', gap: '4px', margin: '3px 0' },
|
|
2002
|
+
title: task.liveStep
|
|
2003
|
+
},
|
|
2004
|
+
h('span', { style: { display: 'inline-block' } }, '⟳'),
|
|
2005
|
+
h('span', { style: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, task.liveStep)
|
|
2006
|
+
)
|
|
2007
|
+
: null,
|
|
2107
2008
|
task.subtasksCount && task.subtasksCount.total > 0
|
|
2108
2009
|
? h('div', { className: 'dkb-progressBar', title: `${task.subtasksCount.completed}/${task.subtasksCount.total}` },
|
|
2109
2010
|
h('div', {
|
|
@@ -2160,6 +2061,26 @@ window.__ModuleLoader__.load({
|
|
|
2160
2061
|
onClick: (e) => { e.stopPropagation(); props.onOpenChat(task) },
|
|
2161
2062
|
}, t('card.toChat'))
|
|
2162
2063
|
: null,
|
|
2064
|
+
(task.column === 'in-progress' || task.col === 'in-progress') && task.sessionId && (task.state === 'running' || task.state === 'idle')
|
|
2065
|
+
? h('button', {
|
|
2066
|
+
type: 'button',
|
|
2067
|
+
className: 'dkb-nudgeBtn',
|
|
2068
|
+
title: t('card.nudgeHint'),
|
|
2069
|
+
style: {
|
|
2070
|
+
fontSize: '11px',
|
|
2071
|
+
padding: '1px 6px',
|
|
2072
|
+
borderRadius: '4px',
|
|
2073
|
+
cursor: 'pointer',
|
|
2074
|
+
border: '1px solid var(--dsw-alias-state-business-tertiary, #54aeff)',
|
|
2075
|
+
background: 'var(--dsw-alias-state-business-tertiary, #ddf4ff)',
|
|
2076
|
+
color: 'var(--dsw-alias-state-business-primary, #0969da)',
|
|
2077
|
+
},
|
|
2078
|
+
onClick: (e) => {
|
|
2079
|
+
e.stopPropagation();
|
|
2080
|
+
if (props.onNudge) props.onNudge(task);
|
|
2081
|
+
}
|
|
2082
|
+
}, '💬 ' + t('card.nudge'))
|
|
2083
|
+
: null,
|
|
2163
2084
|
touched
|
|
2164
2085
|
? h('span', {
|
|
2165
2086
|
className: task.stale ? 'dkb-countOver' : '',
|
|
@@ -2189,10 +2110,6 @@ window.__ModuleLoader__.load({
|
|
|
2189
2110
|
)
|
|
2190
2111
|
})
|
|
2191
2112
|
|
|
2192
|
-
/**
|
|
2193
|
-
* Execution options: agent preset and permission rank.
|
|
2194
|
-
* Shared across single-task and batch launch modals.
|
|
2195
|
-
*/
|
|
2196
2113
|
function LaunchFields(props) {
|
|
2197
2114
|
const t = props.t
|
|
2198
2115
|
const rows = []
|
|
@@ -2317,6 +2234,32 @@ window.__ModuleLoader__.load({
|
|
|
2317
2234
|
const [agentPreset, setAgentPreset] = React.useState('')
|
|
2318
2235
|
const [permission, setPermission] = React.useState('')
|
|
2319
2236
|
const dragged = React.useRef(null)
|
|
2237
|
+
const [nudgeTask, setNudgeTask] = React.useState(null)
|
|
2238
|
+
const [nudgePrompt, setNudgePrompt] = React.useState('')
|
|
2239
|
+
const [nudgeSending, setNudgeSending] = React.useState(false)
|
|
2240
|
+
const [nudgeSuccess, setNudgeSuccess] = React.useState(false)
|
|
2241
|
+
|
|
2242
|
+
const handleNudgeSubmit = React.useCallback(async () => {
|
|
2243
|
+
if (!nudgeTask || !nudgePrompt.trim() || nudgeSending) return
|
|
2244
|
+
setNudgeSending(true)
|
|
2245
|
+
try {
|
|
2246
|
+
await api('/task/' + encodeURIComponent(nudgeTask.id) + '/nudge', {
|
|
2247
|
+
method: 'POST',
|
|
2248
|
+
body: JSON.stringify({ prompt: nudgePrompt.trim() }),
|
|
2249
|
+
})
|
|
2250
|
+
setNudgeSuccess(true)
|
|
2251
|
+
setTimeout(() => {
|
|
2252
|
+
setNudgeTask(null)
|
|
2253
|
+
setNudgePrompt('')
|
|
2254
|
+
setNudgeSuccess(false)
|
|
2255
|
+
}, 1200)
|
|
2256
|
+
load(board)
|
|
2257
|
+
} catch (e) {
|
|
2258
|
+
setError(t(e.key || e.error || 'nudge.failed'))
|
|
2259
|
+
} finally {
|
|
2260
|
+
setNudgeSending(false)
|
|
2261
|
+
}
|
|
2262
|
+
}, [nudgeTask, nudgePrompt, nudgeSending, load, board, t])
|
|
2320
2263
|
|
|
2321
2264
|
const load = React.useCallback(async (nextBoard) => {
|
|
2322
2265
|
try {
|
|
@@ -2474,9 +2417,6 @@ window.__ModuleLoader__.load({
|
|
|
2474
2417
|
}
|
|
2475
2418
|
}, [load, t])
|
|
2476
2419
|
|
|
2477
|
-
/**
|
|
2478
|
-
* Confirm and execute card move transition.
|
|
2479
|
-
*/
|
|
2480
2420
|
const askMove = React.useCallback((task, column, where) => {
|
|
2481
2421
|
if (!task) return
|
|
2482
2422
|
const place = where ?? neighboursFor(tasksOf((state && state.tasks) || [], column), task.id, Infinity)
|
|
@@ -2547,6 +2487,19 @@ window.__ModuleLoader__.load({
|
|
|
2547
2487
|
h('span', null, t('board.back')),
|
|
2548
2488
|
),
|
|
2549
2489
|
h('span', { className: 'dkb-barTitle' }, t('section.label')),
|
|
2490
|
+
state && state.remoteMode
|
|
2491
|
+
? h('span', {
|
|
2492
|
+
className: 'dkb-tag',
|
|
2493
|
+
style: {
|
|
2494
|
+
background: 'var(--dsw-alias-state-business-tertiary, #ddf4ff)',
|
|
2495
|
+
color: 'var(--dsw-alias-state-business-primary, #0969da)',
|
|
2496
|
+
borderColor: 'var(--dsw-alias-state-business-tertiary, #54aeff)',
|
|
2497
|
+
fontWeight: '600',
|
|
2498
|
+
fontSize: '11px',
|
|
2499
|
+
},
|
|
2500
|
+
title: 'Operating in remote mode against server 111',
|
|
2501
|
+
}, '🌐 ' + t('remote.badge'))
|
|
2502
|
+
: null,
|
|
2550
2503
|
boards.length > 1
|
|
2551
2504
|
? h('select', {
|
|
2552
2505
|
className: 'dkb-input', style: { width: 'auto' }, value: board,
|
|
@@ -2868,6 +2821,7 @@ window.__ModuleLoader__.load({
|
|
|
2868
2821
|
if (manyGroups && groups[col.id + '/' + (task.repo || '')] === true) return
|
|
2869
2822
|
rows.push(h(TaskCard, {
|
|
2870
2823
|
key: task.id, task, t, now: state.now,
|
|
2824
|
+
onNudge: (t) => { setNudgeTask(t); setNudgePrompt(''); setNudgeSuccess(false) },
|
|
2871
2825
|
columns: (state.columns || []).map((c) => c.id),
|
|
2872
2826
|
menuOpen: cardMenu,
|
|
2873
2827
|
onMenu: setCardMenu,
|
|
@@ -2913,6 +2867,11 @@ window.__ModuleLoader__.load({
|
|
|
2913
2867
|
} catch (e) { setError(t(e.key || 'error.unknown')) }
|
|
2914
2868
|
},
|
|
2915
2869
|
onOpenChat: (x) => {
|
|
2870
|
+
if (state && state.remoteMode && x.sessionId) {
|
|
2871
|
+
const url = 'http://192.168.1.111:3080/#/chat?sessionId=' + encodeURIComponent(x.sessionId)
|
|
2872
|
+
if (typeof window !== 'undefined') window.open(url, '_blank')
|
|
2873
|
+
return
|
|
2874
|
+
}
|
|
2916
2875
|
if (!openSession(props.ctx, x.sessionId)) {
|
|
2917
2876
|
setError(t('error.sessionNotOpened', { id: x.sessionId }))
|
|
2918
2877
|
return
|
|
@@ -3328,6 +3287,59 @@ window.__ModuleLoader__.load({
|
|
|
3328
3287
|
},
|
|
3329
3288
|
}, t('panel.openChat'))
|
|
3330
3289
|
: null,
|
|
3290
|
+
openTask.sessionId && (openTask.column === 'in-progress' || openTask.col === 'in-progress')
|
|
3291
|
+
? h('button', {
|
|
3292
|
+
type: 'button', className: 'dkb-discard', style: { alignSelf: 'flex-start' },
|
|
3293
|
+
onClick: () => { setNudgeTask(openTask); setNudgePrompt(''); setNudgeSuccess(false) },
|
|
3294
|
+
}, '💬 ' + t('card.nudge'))
|
|
3295
|
+
: null,
|
|
3296
|
+
openTask.costMetrics && openTask.costMetrics.totalTokens > 0
|
|
3297
|
+
? h('div', {
|
|
3298
|
+
className: 'dkb-section-card',
|
|
3299
|
+
style: {
|
|
3300
|
+
margin: '8px 0', padding: 12, border: '1px solid var(--dsw-alias-border-l2)',
|
|
3301
|
+
borderRadius: 8, display: 'flex', flexDirection: 'column', gap: 6,
|
|
3302
|
+
},
|
|
3303
|
+
},
|
|
3304
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
3305
|
+
h('div', { className: 'dkb-group', style: { margin: 0, fontWeight: 600 } },
|
|
3306
|
+
'🪙 ' + t('telemetry.title')
|
|
3307
|
+
),
|
|
3308
|
+
h('span', {
|
|
3309
|
+
className: 'dkb-tag',
|
|
3310
|
+
style: { background: 'var(--dsw-alias-state-business-tertiary, #ddf4ff)', color: 'var(--dsw-alias-state-business-primary, #0969da)', borderColor: 'var(--dsw-alias-state-business-tertiary, #54aeff)' }
|
|
3311
|
+
}, openTask.costMetrics.costFormatted || '$0.00'),
|
|
3312
|
+
),
|
|
3313
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8, fontSize: '11px', textAlign: 'center' } },
|
|
3314
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-1)', padding: '6px', borderRadius: '4px' } },
|
|
3315
|
+
h('div', { style: { opacity: 0.7 } }, t('telemetry.tokens')),
|
|
3316
|
+
h('div', { style: { fontWeight: 600 } }, openTask.costMetrics.totalTokens.toLocaleString()),
|
|
3317
|
+
),
|
|
3318
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-1)', padding: '6px', borderRadius: '4px' } },
|
|
3319
|
+
h('div', { style: { opacity: 0.7 } }, t('telemetry.input')),
|
|
3320
|
+
h('div', { style: { fontWeight: 600 } }, (openTask.costMetrics.uncachedInputTokens || 0).toLocaleString()),
|
|
3321
|
+
),
|
|
3322
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-1)', padding: '6px', borderRadius: '4px' } },
|
|
3323
|
+
h('div', { style: { opacity: 0.7 } }, t('telemetry.output')),
|
|
3324
|
+
h('div', { style: { fontWeight: 600 } }, (openTask.costMetrics.outputTokens || 0).toLocaleString()),
|
|
3325
|
+
),
|
|
3326
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-1)', padding: '6px', borderRadius: '4px' } },
|
|
3327
|
+
h('div', { style: { opacity: 0.7 } }, t('telemetry.cache')),
|
|
3328
|
+
h('div', { style: { fontWeight: 600 } }, (openTask.costMetrics.cacheReadTokens || 0).toLocaleString()),
|
|
3329
|
+
),
|
|
3330
|
+
),
|
|
3331
|
+
openTask.costLimitExceeded
|
|
3332
|
+
? h('div', {
|
|
3333
|
+
style: {
|
|
3334
|
+
fontSize: '11px',
|
|
3335
|
+
color: 'var(--dsw-alias-state-warn-primary, #9a6700)',
|
|
3336
|
+
background: 'var(--dsw-alias-state-warn-secondary, #fff8c5)',
|
|
3337
|
+
padding: '4px 8px', borderRadius: '4px', marginTop: '4px'
|
|
3338
|
+
}
|
|
3339
|
+
}, '⚠️ ' + t('card.costLimitExceeded'))
|
|
3340
|
+
: null
|
|
3341
|
+
)
|
|
3342
|
+
: null,
|
|
3331
3343
|
log.length
|
|
3332
3344
|
? h('div', null,
|
|
3333
3345
|
h('div', { className: 'dkb-group' }, t('panel.log')),
|
|
@@ -4372,17 +4384,79 @@ window.__ModuleLoader__.load({
|
|
|
4372
4384
|
)
|
|
4373
4385
|
: null
|
|
4374
4386
|
|
|
4387
|
+
const nudgeDialogEl = nudgeTask
|
|
4388
|
+
? h('div', {
|
|
4389
|
+
className: 'dkb-modal',
|
|
4390
|
+
onClick: () => { setNudgeTask(null); setNudgePrompt(''); setNudgeSuccess(false) },
|
|
4391
|
+
},
|
|
4392
|
+
h('div', {
|
|
4393
|
+
className: 'dkb-dialog',
|
|
4394
|
+
style: { maxWidth: '440px', width: '90%', padding: '16px' },
|
|
4395
|
+
onClick: (e) => e.stopPropagation(),
|
|
4396
|
+
},
|
|
4397
|
+
h('div', { className: 'dkb-dialogHead', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '12px' } },
|
|
4398
|
+
h('h3', { style: { margin: 0, fontSize: '15px' } }, t('nudge.title') + ': ' + (nudgeTask.title || '')),
|
|
4399
|
+
h('button', {
|
|
4400
|
+
type: 'button',
|
|
4401
|
+
className: 'dkb-discard',
|
|
4402
|
+
style: { border: 'none', background: 'transparent', cursor: 'pointer', fontSize: '16px', padding: '0 4px' },
|
|
4403
|
+
onClick: () => { setNudgeTask(null); setNudgePrompt(''); setNudgeSuccess(false) },
|
|
4404
|
+
}, '✕'),
|
|
4405
|
+
),
|
|
4406
|
+
nudgeSuccess
|
|
4407
|
+
? h('div', {
|
|
4408
|
+
style: {
|
|
4409
|
+
padding: '12px',
|
|
4410
|
+
borderRadius: '6px',
|
|
4411
|
+
background: 'var(--dsw-alias-state-success-secondary, #dafbe1)',
|
|
4412
|
+
color: 'var(--dsw-alias-state-success-primary, #1a7f37)',
|
|
4413
|
+
marginBottom: '12px',
|
|
4414
|
+
textAlign: 'center',
|
|
4415
|
+
fontWeight: '600',
|
|
4416
|
+
},
|
|
4417
|
+
}, '✓ ' + t('nudge.success'))
|
|
4418
|
+
: h('div', null,
|
|
4419
|
+
h('textarea', {
|
|
4420
|
+
className: 'dkb-area',
|
|
4421
|
+
style: { width: '100%', minHeight: '90px', marginBottom: '12px', boxSizing: 'border-box' },
|
|
4422
|
+
placeholder: t('nudge.placeholder'),
|
|
4423
|
+
value: nudgePrompt,
|
|
4424
|
+
autoFocus: true,
|
|
4425
|
+
onChange: (e) => setNudgePrompt(e.target.value),
|
|
4426
|
+
onKeyDown: (e) => {
|
|
4427
|
+
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
|
|
4428
|
+
e.preventDefault();
|
|
4429
|
+
handleNudgeSubmit();
|
|
4430
|
+
}
|
|
4431
|
+
},
|
|
4432
|
+
}),
|
|
4433
|
+
h('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: '8px' } },
|
|
4434
|
+
h('button', {
|
|
4435
|
+
type: 'button',
|
|
4436
|
+
className: 'dkb-discard',
|
|
4437
|
+
disabled: nudgeSending,
|
|
4438
|
+
onClick: () => { setNudgeTask(null); setNudgePrompt(''); setNudgeSuccess(false) },
|
|
4439
|
+
}, t('panel.close')),
|
|
4440
|
+
h('button', {
|
|
4441
|
+
type: 'button',
|
|
4442
|
+
className: 'dkb-save',
|
|
4443
|
+
disabled: !nudgePrompt.trim() || nudgeSending,
|
|
4444
|
+
onClick: handleNudgeSubmit,
|
|
4445
|
+
}, nudgeSending ? t('nudge.sending') : t('nudge.send')),
|
|
4446
|
+
),
|
|
4447
|
+
),
|
|
4448
|
+
),
|
|
4449
|
+
)
|
|
4450
|
+
: null;
|
|
4451
|
+
|
|
4375
4452
|
return h('div', { className: 'dkb-screen' },
|
|
4376
4453
|
style, bar,
|
|
4377
4454
|
error ? h('p', { className: 'dkb-failed' }, error) : null,
|
|
4378
4455
|
metrics ? metricsEl : archive ? archiveEl : columns,
|
|
4379
|
-
panel, dialogEl, moveDialogEl, batchEl, queueEl,
|
|
4456
|
+
panel, dialogEl, moveDialogEl, batchEl, queueEl, nudgeDialogEl,
|
|
4380
4457
|
)
|
|
4381
4458
|
}
|
|
4382
4459
|
|
|
4383
|
-
/**
|
|
4384
|
-
* Header task chip in chat conversation. Only rendered when session is linked to a task.
|
|
4385
|
-
*/
|
|
4386
4460
|
function TaskChip(props) {
|
|
4387
4461
|
const t = props.t || fallbackT
|
|
4388
4462
|
const [task, setTask] = React.useState(null)
|
|
@@ -4466,8 +4540,6 @@ window.__ModuleLoader__.load({
|
|
|
4466
4540
|
)
|
|
4467
4541
|
}
|
|
4468
4542
|
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
4543
|
const PANEL = 'kanban'
|
|
4472
4544
|
const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
4473
4545
|
const ACTIVE_ATTR = 'data-dsh-kanban-active'
|
|
@@ -4480,8 +4552,6 @@ window.__ModuleLoader__.load({
|
|
|
4480
4552
|
+ ' stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
|
|
4481
4553
|
+ '<rect x="2" y="2.5" width="12" height="11" rx="1.5"/><path d="M2 6.5h12M6.5 6.5v7"/></svg>'
|
|
4482
4554
|
|
|
4483
|
-
/** Board visibility state manager. */
|
|
4484
|
-
/** @see helpers.createToggle */
|
|
4485
4555
|
function createToggle() {
|
|
4486
4556
|
let open = false
|
|
4487
4557
|
let wanted = undefined
|
|
@@ -4494,12 +4564,10 @@ window.__ModuleLoader__.load({
|
|
|
4494
4564
|
for (const fn of listeners) fn()
|
|
4495
4565
|
},
|
|
4496
4566
|
toggle() { this.set(!open) },
|
|
4497
|
-
/** Open board focused on a specific task. */
|
|
4498
4567
|
show(taskId, boardId) {
|
|
4499
4568
|
wanted = { id: String(taskId || ''), board: String(boardId || 'main') }
|
|
4500
4569
|
if (open) { for (const fn of listeners) fn() } else this.set(true)
|
|
4501
4570
|
},
|
|
4502
|
-
/** Consume requested focus task ID (cleared after first read). */
|
|
4503
4571
|
takeWanted() {
|
|
4504
4572
|
const asked = wanted
|
|
4505
4573
|
wanted = undefined
|
|
@@ -4509,7 +4577,6 @@ window.__ModuleLoader__.load({
|
|
|
4509
4577
|
}
|
|
4510
4578
|
}
|
|
4511
4579
|
|
|
4512
|
-
/** Find native 'New Session' sidebar button. */
|
|
4513
4580
|
function nativeButton() {
|
|
4514
4581
|
const nodes = document.querySelectorAll('button[class*="newSession"]')
|
|
4515
4582
|
for (const node of nodes) {
|
|
@@ -4518,9 +4585,6 @@ window.__ModuleLoader__.load({
|
|
|
4518
4585
|
return undefined
|
|
4519
4586
|
}
|
|
4520
4587
|
|
|
4521
|
-
/**
|
|
4522
|
-
* Kanban entry button cloning native button styles to match host theme.
|
|
4523
|
-
*/
|
|
4524
4588
|
function createEntry(target, toggle, label) {
|
|
4525
4589
|
const entry = target.cloneNode(true)
|
|
4526
4590
|
entry.className = String(target.className) + ' dkb-entry-clone'
|
|
@@ -4549,7 +4613,6 @@ window.__ModuleLoader__.load({
|
|
|
4549
4613
|
return entry
|
|
4550
4614
|
}
|
|
4551
4615
|
|
|
4552
|
-
/** Place button at end of injected extension entries. */
|
|
4553
4616
|
function placeEntry(target, entry) {
|
|
4554
4617
|
let anchor = target
|
|
4555
4618
|
let next = target.nextElementSibling
|
|
@@ -4562,7 +4625,6 @@ window.__ModuleLoader__.load({
|
|
|
4562
4625
|
return true
|
|
4563
4626
|
}
|
|
4564
4627
|
|
|
4565
|
-
/** Sidebar entry button persistent across shell re-renders. */
|
|
4566
4628
|
function mountSidebarEntry(toggle, label) {
|
|
4567
4629
|
if (typeof document === 'undefined') return () => {}
|
|
4568
4630
|
|
|
@@ -4596,7 +4658,6 @@ window.__ModuleLoader__.load({
|
|
|
4596
4658
|
}
|
|
4597
4659
|
}
|
|
4598
4660
|
|
|
4599
|
-
/** Board overlay container mounted over conversation column. */
|
|
4600
4661
|
function mountBoard(ctx, toggle) {
|
|
4601
4662
|
if (typeof document === 'undefined') return () => {}
|
|
4602
4663
|
let root
|
|
@@ -4653,12 +4714,6 @@ window.__ModuleLoader__.load({
|
|
|
4653
4714
|
}
|
|
4654
4715
|
}
|
|
4655
4716
|
|
|
4656
|
-
|
|
4657
|
-
/**
|
|
4658
|
-
* Register component into first available UI slot.
|
|
4659
|
-
*
|
|
4660
|
-
* @returns {string|undefined} name of successfully resolved slot
|
|
4661
|
-
*/
|
|
4662
4717
|
function registerFirst(ctx, candidates, component) {
|
|
4663
4718
|
for (const entry of candidates) {
|
|
4664
4719
|
try {
|