@goodandready/dsh-kanban 0.2.22 → 0.2.23

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 CHANGED
@@ -487,6 +487,7 @@ window.__ModuleLoader__.load({
487
487
  case 'cross-site': return 'error.crossSite'
488
488
  case 'model-not-selected': return 'error.modelNotSelected'
489
489
  case 'start-failed': return 'error.startFailed'
490
+ case 'timeout': return 'error.timeout'
490
491
  default: return 'error.unknown'
491
492
  }
492
493
  }
@@ -549,15 +550,54 @@ window.__ModuleLoader__.load({
549
550
  neighboursFor, tasksOf, sortTasks, packInfo, groupByAssignee, applyToEach, recallLaunch, rememberLaunch, stillOffered,
550
551
  cardRef, taskRef, cardStatus, facetLabel, boardTitle,
551
552
  columnTitle, planLine, stateLabel, isCollapsed,
552
- agoText, exactAt, shortDate, syncLine, readableOn, tagStyle, priorityColor, renderBlocks, renderSpans, matchesFilters, anySelected, toggleValue, normalizeBoard, errorKey,
553
+ agoText, exactAt, shortDate, syncLine, readableOn, tagStyle, priorityColor, renderBlocks, renderSpans, matchesFilters, anySelected, toggleValue, normalizeBoard, errorKey, api, createTimeoutSignal,
553
554
  chipSessionId, matchesQuery, splitFullName, repoOption, openSession, COLUMN_ORDER,
554
555
  }
555
556
 
556
557
 
558
+ function createTimeoutSignal(ms) {
559
+ const sig = typeof AbortSignal !== 'undefined' ? AbortSignal : (typeof globalThis !== 'undefined' ? globalThis.AbortSignal : undefined)
560
+ if (sig && typeof sig.timeout === 'function') {
561
+ return sig.timeout(ms)
562
+ }
563
+ const ctrl = typeof AbortController !== 'undefined' ? AbortController : (typeof globalThis !== 'undefined' ? globalThis.AbortController : undefined)
564
+ if (ctrl) {
565
+ const c = new ctrl()
566
+ setTimeout(() => c.abort(new Error('TimeoutError')), ms)
567
+ return c.signal
568
+ }
569
+ return undefined
570
+ }
571
+
557
572
  async function api(path, options) {
558
- const res = await fetch('/dsh-kanban' + path, Object.assign({
573
+ const timeoutMs = (options && options.timeout) || 20000
574
+ let timeoutSignal
575
+ try {
576
+ if (!options?.signal) {
577
+ timeoutSignal = createTimeoutSignal(timeoutMs)
578
+ }
579
+ } catch (_) {}
580
+
581
+ const fetchOpts = Object.assign({
559
582
  headers: { 'Content-Type': 'application/json' },
560
- }, options))
583
+ }, options)
584
+ if (timeoutSignal && !fetchOpts.signal) {
585
+ fetchOpts.signal = timeoutSignal
586
+ }
587
+
588
+ let res
589
+ try {
590
+ res = await fetch('/dsh-kanban' + path, fetchOpts)
591
+ } catch (err) {
592
+ if (err && (err.name === 'TimeoutError' || (!options?.signal && err.name === 'AbortError'))) {
593
+ const timeoutErr = new Error('timeout')
594
+ timeoutErr.key = 'error.timeout'
595
+ timeoutErr.name = 'TimeoutError'
596
+ throw timeoutErr
597
+ }
598
+ throw err
599
+ }
600
+
561
601
  let payload = null
562
602
  try { payload = await res.json() } catch { payload = null }
563
603
  if (!res.ok) {
@@ -1220,6 +1260,7 @@ window.__ModuleLoader__.load({
1220
1260
  'error.issueNotFound': 'Issue not found.',
1221
1261
  'error.titleRequired': 'A title is required.',
1222
1262
  'error.crossSite': 'Request rejected as cross-site.',
1263
+ 'error.timeout': 'Request timed out. Please try again.',
1223
1264
  'error.unknown': 'Request failed.',
1224
1265
  }
1225
1266
 
@@ -1611,6 +1652,7 @@ window.__ModuleLoader__.load({
1611
1652
  'error.issueNotFound': '没有找到 issue。',
1612
1653
  'error.titleRequired': '标题不能为空。',
1613
1654
  'error.crossSite': '请求被判定为跨站而拒绝。',
1655
+ 'error.timeout': '请求超时,请重试。',
1614
1656
  'error.unknown': '请求失败。',
1615
1657
  }
1616
1658
 
package/lib/updater.js CHANGED
@@ -47,7 +47,7 @@ export function isTrustedUpdateRequest(request) {
47
47
  const remote = request.socket?.remoteAddress
48
48
  if (!isLoopback(remote) && !isPrivateLan(remote)) return false
49
49
  const site = header(request, 'sec-fetch-site')
50
- if (site !== undefined && site !== 'same-origin') return false
50
+ if (!site || (site !== 'same-origin' && site !== 'same-site' && site !== 'none')) return false
51
51
  const origin = header(request, 'origin')
52
52
  const host = header(request, 'host')
53
53
  if (origin === undefined || host === undefined) return false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-kanban",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "Visual Kanban board for DeepSeek Harness: Gitea and GitHub-backed tasks, workflow columns, and a dedicated agent session per task.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",