@linxin666/dsh-client-ui-task-board 0.4.3 → 0.4.5
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/README.i18n.yaml +2 -2
- package/README.md +56 -18
- package/README.zh.md +56 -18
- package/lib/client.js +6242 -958
- package/lib/client.js.map +1 -1
- package/lib/index.js +3475 -234
- package/lib/types/client/PluginSettingsCard.d.ts +7 -0
- package/lib/types/client/TaskBoardSettingsCard.d.ts +19 -3
- package/lib/types/client/board/ClampedMarkdown.d.ts +3 -0
- package/lib/types/client/board/ConfirmDialog.d.ts +4 -1
- package/lib/types/client/board/EditTaskModal.d.ts +5 -2
- package/lib/types/client/board/LinkSubtaskModal.d.ts +5 -2
- package/lib/types/client/board/NewTaskModal.d.ts +4 -1
- package/lib/types/client/board/TagManagerModal.d.ts +26 -0
- package/lib/types/client/board/TaskBoard.d.ts +10 -1
- package/lib/types/client/board/TaskCard.d.ts +14 -1
- package/lib/types/client/board/TaskDetail.d.ts +3 -1
- package/lib/types/client/board/TaskForm.d.ts +23 -2
- package/lib/types/client/board/VerificationReport.d.ts +23 -0
- package/lib/types/client/board/card-view.d.ts +113 -0
- package/lib/types/client/board/icons.d.ts +32 -0
- package/lib/types/client/board/overlay.d.ts +69 -0
- package/lib/types/client/board/preset-label.d.ts +22 -0
- package/lib/types/client/board/status-key.d.ts +15 -0
- package/lib/types/client/board/task-markdown.d.ts +19 -0
- package/lib/types/client/board-card-seat.d.ts +34 -0
- package/lib/types/client/host-api.d.ts +24 -1
- package/lib/types/client/index.d.ts +19 -0
- package/lib/types/client/locales.d.ts +141 -3
- package/lib/types/client/native-panel.d.ts +6 -20
- package/lib/types/client/schedule-zone.d.ts +47 -0
- package/lib/types/client/seats.d.ts +18 -0
- package/lib/types/client/service.d.ts +32 -0
- package/lib/types/client/settings-form.d.ts +16 -0
- package/lib/types/core/controller.d.ts +38 -1
- package/lib/types/core/degraded-reason.d.ts +46 -0
- package/lib/types/core/extension.d.ts +283 -0
- package/lib/types/core/handover.d.ts +13 -1
- package/lib/types/core/issue-form.d.ts +16 -0
- package/lib/types/core/package-name.d.ts +9 -0
- package/lib/types/core/schedule.d.ts +95 -20
- package/lib/types/core/subtask.d.ts +30 -11
- package/lib/types/core/tasks.d.ts +110 -5
- package/lib/types/core/use-cases/task-create.d.ts +2 -1
- package/lib/types/core/use-cases/task-schedule.d.ts +8 -4
- package/lib/types/core/use-cases/task-tag.d.ts +48 -0
- package/lib/types/core/use-cases/task-update.d.ts +5 -3
- package/lib/types/core/verification.d.ts +386 -0
- package/lib/types/core/workspace-target.d.ts +41 -0
- package/lib/types/host/agent-tools.d.ts +1 -1
- package/lib/types/host/extension-registry.d.ts +111 -0
- package/lib/types/host/llm-dispatch.d.ts +63 -0
- package/lib/types/host/verification-gate.d.ts +71 -0
- package/lib/types/host/verification-runner.d.ts +108 -0
- package/lib/types/host/workspace-evidence.d.ts +53 -0
- package/lib/types/host-ledger.d.ts +107 -11
- package/lib/types/host-runner.d.ts +99 -4
- package/lib/types/host-service.d.ts +114 -2
- package/lib/types/index.d.ts +80 -26
- package/lib/types/protocol.d.ts +53 -3
- package/lib/types/tool-surface.d.ts +71 -0
- package/package.json +27 -26
- package/src/client/PluginSettingsCard.tsx +9 -0
- package/src/client/TaskBoardSettingsCard.tsx +304 -65
- package/src/client/board/ClampedMarkdown.tsx +69 -0
- package/src/client/board/ConfirmDialog.tsx +7 -3
- package/src/client/board/EditTaskModal.tsx +5 -2
- package/src/client/board/LinkSubtaskModal.tsx +30 -15
- package/src/client/board/NewTaskModal.tsx +288 -151
- package/src/client/board/TagManagerModal.tsx +235 -0
- package/src/client/board/TaskBoard.tsx +259 -103
- package/src/client/board/TaskCard.tsx +238 -86
- package/src/client/board/TaskDetail.tsx +154 -59
- package/src/client/board/TaskForm.tsx +61 -6
- package/src/client/board/VerificationReport.tsx +203 -0
- package/src/client/board/card-view.ts +220 -0
- package/src/client/board/icons.tsx +89 -0
- package/src/client/board/overlay.tsx +189 -0
- package/src/client/board/preset-label.ts +44 -0
- package/src/client/board/status-key.ts +27 -0
- package/src/client/board/task-markdown.module.css +137 -0
- package/src/client/board/task-markdown.tsx +106 -0
- package/src/client/board-card-seat.ts +102 -0
- package/src/client/board-settings.module.css +66 -0
- package/src/client/board.module.css +602 -68
- package/src/client/host-api.ts +109 -6
- package/src/client/index.ts +48 -6
- package/src/client/locales.ts +290 -12
- package/src/client/native-panel.tsx +18 -2
- package/src/client/schedule-zone.ts +135 -0
- package/src/client/seats.tsx +58 -0
- package/src/client/service.ts +94 -0
- package/src/client/settings-card.module.css +31 -5
- package/src/client/settings-form.ts +27 -1
- package/src/core/controller.ts +101 -5
- package/src/core/degraded-reason.ts +81 -0
- package/src/core/extension.ts +376 -0
- package/src/core/freeze-snapshot.ts +2 -2
- package/src/core/handover.ts +16 -1
- package/src/core/issue-form.ts +19 -0
- package/src/core/package-name.ts +9 -0
- package/src/core/schedule.ts +211 -55
- package/src/core/store.ts +26 -1
- package/src/core/subtask.ts +77 -22
- package/src/core/tasks.ts +138 -10
- package/src/core/use-cases/task-create.ts +14 -2
- package/src/core/use-cases/task-parent.ts +3 -2
- package/src/core/use-cases/task-schedule.ts +17 -6
- package/src/core/use-cases/task-tag.ts +110 -0
- package/src/core/use-cases/task-update.ts +13 -4
- package/src/core/verification.ts +826 -0
- package/src/core/workspace-target.ts +59 -0
- package/src/host/agent-tools.ts +58 -24
- package/src/host/extension-registry.ts +509 -0
- package/src/host/llm-dispatch.ts +87 -0
- package/src/host/verification-gate.ts +331 -0
- package/src/host/verification-runner.ts +535 -0
- package/src/host/workspace-evidence.ts +176 -0
- package/src/host-ai.ts +15 -9
- package/src/host-ledger.ts +342 -51
- package/src/host-routes.ts +15 -2
- package/src/host-runner.ts +219 -20
- package/src/host-service.ts +346 -26
- package/src/index.ts +204 -16
- package/src/protocol.ts +122 -9
- package/src/tool-surface.ts +95 -0
- package/lib/types/host/run-guarded.d.ts +0 -39
- package/src/host/run-guarded.ts +0 -76
|
@@ -7,13 +7,36 @@ import { type TaskBoardAction, type TaskBoardEventPayload, type TaskBoardParseDr
|
|
|
7
7
|
* "Unexpected token 'o', \"not found\" is not valid JSON" is what a missing
|
|
8
8
|
* Host half looks like today.
|
|
9
9
|
*/
|
|
10
|
-
export type HostApiFailure =
|
|
10
|
+
export type HostApiFailure =
|
|
11
|
+
/** The board's own routes are not registered and nothing explains why. */
|
|
12
|
+
'not-mounted'
|
|
13
|
+
/** Another live DSH process owns the ledger, so this instance registered no board routes (#1730). */
|
|
14
|
+
| 'ledger-locked'
|
|
15
|
+
/** This row degraded during start for some other reason the family health route reports (#1730). */
|
|
16
|
+
| 'degraded' | 'unauthorized' | 'forbidden' | 'locked' | 'rejected' | 'timeout' | 'unreachable' | 'unexpected';
|
|
11
17
|
/** Transport failure carrying a stable class next to its user-facing message. */
|
|
12
18
|
export declare class HostApiError extends Error {
|
|
13
19
|
readonly failure: HostApiFailure;
|
|
14
20
|
readonly status?: number | undefined;
|
|
15
21
|
constructor(failure: HostApiFailure, message: string, status?: number | undefined);
|
|
16
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Name the real reason this board's routes are missing (issue #1730).
|
|
25
|
+
*
|
|
26
|
+
* The core webserver answers an unmounted route with a bare 404, which cannot
|
|
27
|
+
* distinguish "this deployment never loaded the plugin" from "this row
|
|
28
|
+
* degraded during start" — a second DSH process holding `ledger-v2.lock` is
|
|
29
|
+
* the case that matters, because the panel's advice ("restart the service")
|
|
30
|
+
* is then false: the lock belongs to the other process, and restarting cannot
|
|
31
|
+
* win it. The family health route knows the difference, so the 404 is
|
|
32
|
+
* disambiguated there before anything is shown.
|
|
33
|
+
* @param fallback - copy for the plain "routes are not there" failure, which
|
|
34
|
+
* is route-specific (the board's state route and the AI-parse route phrase
|
|
35
|
+
* their own absence); it is also what is shown when the ledger names nothing.
|
|
36
|
+
* @param fetchImpl - fetch implementation (injected for tests).
|
|
37
|
+
* @returns the HostApiError to throw for a missing board route.
|
|
38
|
+
*/
|
|
39
|
+
export declare function missingRouteFailure(fallback?: string, fetchImpl?: typeof fetch): Promise<HostApiError>;
|
|
17
40
|
export interface TaskBoardHostTransport {
|
|
18
41
|
bootstrap(legacy: readonly TaskRecord[]): Promise<TaskBoardSnapshot>;
|
|
19
42
|
state(): Promise<TaskBoardSnapshot>;
|
|
@@ -12,6 +12,7 @@ import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
|
12
12
|
import type { ConfigForm, ConfigForms } from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
13
13
|
import { type TaskBoardSettings } from './TaskBoardSettingsCard.tsx';
|
|
14
14
|
import { type TaskBoardKey } from './locales.ts';
|
|
15
|
+
import { type TaskBoardCardDecorationProps, type TaskBoardDetailSectionProps, type TaskBoardSettingsSectionProps } from '../core/extension.ts';
|
|
15
16
|
/** Domain-owned description of one settings namespace a family card binds. */
|
|
16
17
|
export interface SettingsFormSpec<T> {
|
|
17
18
|
/** Settings namespace the card edits. */
|
|
@@ -50,6 +51,24 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
|
50
51
|
scope: 'root';
|
|
51
52
|
owner: SettingsPluginItemOwnerProps;
|
|
52
53
|
};
|
|
54
|
+
/** Provider task-detail section; the board declares and renders it. */
|
|
55
|
+
'task-board.detail.section': {
|
|
56
|
+
kind: 'list';
|
|
57
|
+
scope: 'root';
|
|
58
|
+
owner: TaskBoardDetailSectionProps;
|
|
59
|
+
};
|
|
60
|
+
/** Provider settings section; the board declares and renders it. */
|
|
61
|
+
'task-board.settings.section': {
|
|
62
|
+
kind: 'list';
|
|
63
|
+
scope: 'root';
|
|
64
|
+
owner: TaskBoardSettingsSectionProps;
|
|
65
|
+
};
|
|
66
|
+
/** Provider card decoration; the board declares and renders it. */
|
|
67
|
+
'task-board.card.decoration': {
|
|
68
|
+
kind: 'list';
|
|
69
|
+
scope: 'root';
|
|
70
|
+
owner: TaskBoardCardDecorationProps;
|
|
71
|
+
};
|
|
53
72
|
}
|
|
54
73
|
}
|
|
55
74
|
/** Owner share of a plugin card (the section supplies nothing). */
|
|
@@ -25,11 +25,13 @@ export declare const zh: {
|
|
|
25
25
|
'board.status.failed': string;
|
|
26
26
|
'board.runs': string;
|
|
27
27
|
'board.pending': string;
|
|
28
|
-
'board.updated': string;
|
|
29
28
|
'board.created': string;
|
|
30
29
|
'board.hostError': string;
|
|
31
30
|
'board.hostError.notMounted': string;
|
|
31
|
+
'board.hostError.ledgerLocked': string;
|
|
32
|
+
'board.hostError.degraded': string;
|
|
32
33
|
'board.hostError.unauthorized': string;
|
|
34
|
+
'board.hostError.forbidden': string;
|
|
33
35
|
'board.hostError.locked': string;
|
|
34
36
|
'board.hostError.timeout': string;
|
|
35
37
|
'board.hostError.unreachable': string;
|
|
@@ -54,6 +56,19 @@ export declare const zh: {
|
|
|
54
56
|
'new.aiParseFailed': string;
|
|
55
57
|
'board.retryHost': string;
|
|
56
58
|
'board.hostMeta': string;
|
|
59
|
+
'new.section.parse': string;
|
|
60
|
+
'new.section.content': string;
|
|
61
|
+
'new.section.labels': string;
|
|
62
|
+
'new.section.execution': string;
|
|
63
|
+
'new.section.run': string;
|
|
64
|
+
'new.section.handover': string;
|
|
65
|
+
'new.section.schedule': string;
|
|
66
|
+
'new.summary.none': string;
|
|
67
|
+
'new.summary.labelCount': string;
|
|
68
|
+
'new.summary.filled': string;
|
|
69
|
+
'new.summary.scheduleOff': string;
|
|
70
|
+
'new.summary.multiRound': string;
|
|
71
|
+
'new.summary.singleRound': string;
|
|
57
72
|
'new.title': string;
|
|
58
73
|
'new.titlePlaceholder': string;
|
|
59
74
|
'new.description': string;
|
|
@@ -90,6 +105,22 @@ export declare const zh: {
|
|
|
90
105
|
'board.tagFilter': string;
|
|
91
106
|
'board.tagFilterClear': string;
|
|
92
107
|
'board.tagEmpty': string;
|
|
108
|
+
'board.tagManage': string;
|
|
109
|
+
'tags.title': string;
|
|
110
|
+
'tags.hint': string;
|
|
111
|
+
'tags.empty': string;
|
|
112
|
+
'tags.usage': string;
|
|
113
|
+
'tags.rename': string;
|
|
114
|
+
'tags.renameLabel': string;
|
|
115
|
+
'tags.delete': string;
|
|
116
|
+
'tags.deleteTitle': string;
|
|
117
|
+
'tags.deleteConfirm': string;
|
|
118
|
+
'tags.deleteOk': string;
|
|
119
|
+
'tags.save': string;
|
|
120
|
+
'tags.mergeHint': string;
|
|
121
|
+
'tags.renameFailed': string;
|
|
122
|
+
'tags.deleteFailed': string;
|
|
123
|
+
'tags.done': string;
|
|
93
124
|
'detail.permissionPending': string;
|
|
94
125
|
'detail.permissionConfirm': string;
|
|
95
126
|
'detail.permissionConfirmed': string;
|
|
@@ -105,6 +136,8 @@ export declare const zh: {
|
|
|
105
136
|
'new.archiveOriginal': string;
|
|
106
137
|
'detail.prompt': string;
|
|
107
138
|
'detail.description': string;
|
|
139
|
+
'detail.expand': string;
|
|
140
|
+
'detail.collapse': string;
|
|
108
141
|
'detail.execution': string;
|
|
109
142
|
'detail.noExecution': string;
|
|
110
143
|
'detail.run': string;
|
|
@@ -128,6 +161,9 @@ export declare const zh: {
|
|
|
128
161
|
'delete.cancel': string;
|
|
129
162
|
'status.move.backlog': string;
|
|
130
163
|
'status.move.todo': string;
|
|
164
|
+
'status.move.running': string;
|
|
165
|
+
'status.move.done': string;
|
|
166
|
+
'status.move.failed': string;
|
|
131
167
|
'exec.error.noWorkspace': string;
|
|
132
168
|
'exec.error.promptRejected': string;
|
|
133
169
|
'run.failed': string;
|
|
@@ -145,13 +181,31 @@ export declare const zh: {
|
|
|
145
181
|
'detail.schedule.invalid': string;
|
|
146
182
|
'detail.schedule.notScheduled': string;
|
|
147
183
|
'detail.schedule.dueSoon': string;
|
|
184
|
+
'detail.schedule.timeZone': string;
|
|
185
|
+
'detail.schedule.timeZoneHost': string;
|
|
186
|
+
'detail.schedule.timeZoneHostUnknown': string;
|
|
187
|
+
'detail.schedule.timeZoneHint': string;
|
|
188
|
+
'detail.schedule.timeZoneSearch': string;
|
|
189
|
+
'detail.schedule.timeZoneNone': string;
|
|
190
|
+
'detail.schedule.nextRunOverdue': string;
|
|
191
|
+
'detail.schedule.duration.days': string;
|
|
192
|
+
'detail.schedule.duration.hours': string;
|
|
193
|
+
'detail.schedule.duration.minutes': string;
|
|
194
|
+
'detail.schedule.duration.seconds': string;
|
|
148
195
|
'card.scheduled': string;
|
|
149
196
|
'new.workspace': string;
|
|
150
|
-
'new.
|
|
197
|
+
'new.agentPreset': string;
|
|
151
198
|
'new.permission': string;
|
|
152
199
|
'new.model': string;
|
|
153
200
|
'exec.workspace.recent': string;
|
|
154
|
-
'exec.mode.
|
|
201
|
+
'exec.mode.inherit': string;
|
|
202
|
+
'exec.mode.inheritWith': string;
|
|
203
|
+
'exec.mode.builtinGroup': string;
|
|
204
|
+
'exec.mode.customGroup': string;
|
|
205
|
+
'preset.builtin.standard': string;
|
|
206
|
+
'preset.builtin.ptc': string;
|
|
207
|
+
'preset.builtin.minimal': string;
|
|
208
|
+
'preset.builtin.cordis': string;
|
|
155
209
|
'exec.mode.defaultSuffix': string;
|
|
156
210
|
'exec.mode.brokenSuffix': string;
|
|
157
211
|
'exec.mode.removed': string;
|
|
@@ -167,11 +221,16 @@ export declare const zh: {
|
|
|
167
221
|
'exec.teamRunHint': string;
|
|
168
222
|
'exec.teamRunUnavailable': string;
|
|
169
223
|
'exec.reuseSessionHint': string;
|
|
224
|
+
'exec.goalRun': string;
|
|
225
|
+
'exec.goalRunHint': string;
|
|
226
|
+
'exec.skipVerification': string;
|
|
227
|
+
'exec.skipVerificationHint': string;
|
|
170
228
|
'detail.executionSettings': string;
|
|
171
229
|
'exec.hint': string;
|
|
172
230
|
'settings.title': string;
|
|
173
231
|
'settings.description': string;
|
|
174
232
|
'settings.enabled': string;
|
|
233
|
+
'settings.enabledCardHint': string;
|
|
175
234
|
'settings.enabledHint': string;
|
|
176
235
|
'settings.announceToAgent': string;
|
|
177
236
|
'settings.announceToAgentHint': string;
|
|
@@ -199,6 +258,65 @@ export declare const zh: {
|
|
|
199
258
|
'settings.maxSubtaskDepth': string;
|
|
200
259
|
'settings.maxSubtaskDepthHint': string;
|
|
201
260
|
'settings.maxSubtaskDepthOption': string;
|
|
261
|
+
'settings.goalVerificationTitle': string;
|
|
262
|
+
'settings.goalVerification': string;
|
|
263
|
+
'settings.goalVerificationCardHint': string;
|
|
264
|
+
'settings.goalVerificationHint': string;
|
|
265
|
+
'settings.goalVerificationModel': string;
|
|
266
|
+
'settings.goalVerificationModelHint': string;
|
|
267
|
+
'settings.goalVerificationModelInherit': string;
|
|
268
|
+
'settings.goalVerificationModelInheritUnknown': string;
|
|
269
|
+
'settings.goalVerificationEffort': string;
|
|
270
|
+
'settings.goalVerificationEffortHint': string;
|
|
271
|
+
'settings.goalVerificationEffortInherit': string;
|
|
272
|
+
'settings.goalVerificationEffortInheritUnknown': string;
|
|
273
|
+
'settings.goalVerificationResolved': string;
|
|
274
|
+
'settings.goalVerificationResolvedModel': string;
|
|
275
|
+
'settings.goalVerificationResolvedEffort': string;
|
|
276
|
+
'settings.goalVerificationResolvedNoEffort': string;
|
|
277
|
+
'settings.goalVerificationResolvedSource': string;
|
|
278
|
+
'settings.goalVerificationSourceInherit': string;
|
|
279
|
+
'settings.goalVerificationSourceExplicit': string;
|
|
280
|
+
'settings.goalVerificationResolvedPreset': string;
|
|
281
|
+
'settings.goalVerificationRouteMissing': string;
|
|
282
|
+
'settings.goalVerificationEffortFallback': string;
|
|
283
|
+
'settings.goalVerificationEffortFallbackNone': string;
|
|
284
|
+
'settings.goalVerificationModelInvalid': string;
|
|
285
|
+
'running.executing': string;
|
|
286
|
+
'running.verifying': string;
|
|
287
|
+
'running.repairing': string;
|
|
288
|
+
'running.verificationPassed': string;
|
|
289
|
+
'running.verificationFailed': string;
|
|
290
|
+
'verify.title': string;
|
|
291
|
+
'verify.status.passed': string;
|
|
292
|
+
'verify.status.failed': string;
|
|
293
|
+
'verify.status.exception': string;
|
|
294
|
+
'verify.status.verifying': string;
|
|
295
|
+
'verify.status.pending': string;
|
|
296
|
+
'verify.status.off': string;
|
|
297
|
+
'verify.summary': string;
|
|
298
|
+
'verify.criteria': string;
|
|
299
|
+
'verify.criterion': string;
|
|
300
|
+
'verify.rounds': string;
|
|
301
|
+
'verify.judge': string;
|
|
302
|
+
'verify.judgeNoEffort': string;
|
|
303
|
+
'verify.judgeInherited': string;
|
|
304
|
+
'verify.attempt': string;
|
|
305
|
+
'verify.attemptException': string;
|
|
306
|
+
'verify.counts': string;
|
|
307
|
+
'verify.findings': string;
|
|
308
|
+
'verify.noFindings': string;
|
|
309
|
+
'verify.evidence': string;
|
|
310
|
+
'verify.workspaceEvidence': string;
|
|
311
|
+
'verify.usage': string;
|
|
312
|
+
'verify.usageIncomplete': string;
|
|
313
|
+
'verify.finalFailure': string;
|
|
314
|
+
'verify.applicability.disabled': string;
|
|
315
|
+
'verify.applicability.goalUnavailable': string;
|
|
316
|
+
'verify.applicability.skipped': string;
|
|
317
|
+
'verify.applicability.teamMember': string;
|
|
318
|
+
'verify.effortFallback': string;
|
|
319
|
+
'verify.thresholdValue': string;
|
|
202
320
|
'detail.parent': string;
|
|
203
321
|
'detail.parent.open': string;
|
|
204
322
|
'detail.subtasks': string;
|
|
@@ -222,6 +340,25 @@ export declare const zh: {
|
|
|
222
340
|
'card.subtasksFailed': string;
|
|
223
341
|
'card.subtasksRunning': string;
|
|
224
342
|
'card.subtasksBreakdown': string;
|
|
343
|
+
'card.result.succeeded': string;
|
|
344
|
+
'card.result.failed': string;
|
|
345
|
+
'card.result.cancelled': string;
|
|
346
|
+
'card.declared': string;
|
|
347
|
+
'card.declaredHint': string;
|
|
348
|
+
'card.openSession': string;
|
|
349
|
+
'card.tagsLabel': string;
|
|
350
|
+
'card.time.created': string;
|
|
351
|
+
'card.time.started': string;
|
|
352
|
+
'card.time.settled': string;
|
|
353
|
+
'card.time.archived': string;
|
|
354
|
+
'card.time.updated': string;
|
|
355
|
+
'board.density.compact': string;
|
|
356
|
+
'board.density.comfortable': string;
|
|
357
|
+
'board.group.today': string;
|
|
358
|
+
'board.group.week': string;
|
|
359
|
+
'board.group.earlier': string;
|
|
360
|
+
'board.group.expand': string;
|
|
361
|
+
'board.group.collapse': string;
|
|
225
362
|
'board.hideSubtasks': string;
|
|
226
363
|
'board.showSubtasks': string;
|
|
227
364
|
'board.subtaskFilterHint': string;
|
|
@@ -229,6 +366,7 @@ export declare const zh: {
|
|
|
229
366
|
/** en dictionary, complete against the zh key set. */
|
|
230
367
|
export declare const en: Record<keyof typeof zh, string>;
|
|
231
368
|
/** The dictionary key union. */
|
|
369
|
+
/** The dictionary key union. */
|
|
232
370
|
export type TaskBoardKey = keyof typeof zh;
|
|
233
371
|
/** The settings-card slice of the task-board dictionary. */
|
|
234
372
|
export type SettingsCardKey = TaskBoardKey;
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
* Native panel registration for the task board.
|
|
3
|
-
*
|
|
4
|
-
* The board is an official-style center-column panel, not a DOM takeover: it
|
|
5
|
-
* contributes a row into the sidebar shell's own global panel list
|
|
6
|
-
* (`sidebar.panellist`) and its page into the layout's keyed `main` slot. The
|
|
7
|
-
* shell then owns the row box, the label, the active highlight, the collapsed
|
|
8
|
-
* rail, the panel switch and the window-chrome interplay exactly as it does for
|
|
9
|
-
* the shipped Plugins and Schedule pages, so the board renders through the same
|
|
10
|
-
* container the desktop application's Plugins page uses.
|
|
11
|
-
*
|
|
12
|
-
* Both registrations go through `ctx.slots.inject`, which fires only once the
|
|
13
|
-
* owning shell entry has declared the seat: load order between this plugin and
|
|
14
|
-
* ui-layout / ui-sidebar therefore does not matter, and neither does a shell
|
|
15
|
-
* that cannot serve the seats (the callback simply never runs).
|
|
16
|
-
*
|
|
17
|
-
* @module @linxin666/dsh-client-ui-task-board/client
|
|
18
|
-
*/
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
19
2
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
20
3
|
import { TASK_BOARD_PANEL_ID, type BoardController } from '../core/controller.ts';
|
|
4
|
+
import { type SlotRenderBinding } from './seats.tsx';
|
|
21
5
|
/** The panel id shared by the sidebar row and the main-slot occupant. */
|
|
22
6
|
export { TASK_BOARD_PANEL_ID };
|
|
23
7
|
/**
|
|
@@ -45,9 +29,11 @@ export declare function TaskBoardPanelIcon({ size }: {
|
|
|
45
29
|
* @param props - the framework main-slot share plus this entry's injected face.
|
|
46
30
|
* @returns the board page.
|
|
47
31
|
*/
|
|
48
|
-
export declare function TaskBoardPanel({ controller }: {
|
|
32
|
+
export declare function TaskBoardPanel({ controller, renderSlot }: {
|
|
49
33
|
controller: BoardController;
|
|
50
|
-
|
|
34
|
+
/** Child-slot renderer the registration declares (detail + card decoration). */
|
|
35
|
+
renderSlot?: SlotRenderBinding;
|
|
36
|
+
}): ReactNode;
|
|
51
37
|
/**
|
|
52
38
|
* Register the board's sidebar row and center-column page.
|
|
53
39
|
*
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** One selectable zone, in the order the picker shows it. */
|
|
2
|
+
export interface ZoneChoice {
|
|
3
|
+
/** Canonical IANA id, or `''` for the Host-zone entry. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Display label. */
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Zones offered by the picker: the Host zone first (the default, and the entry
|
|
10
|
+
* a rule with no stored zone follows), then the runtime's own inventory.
|
|
11
|
+
*
|
|
12
|
+
* The Host entry is always present, even before the Host snapshot reports a
|
|
13
|
+
* zone: it is the entry that stores no zone, so dropping it would leave a rule
|
|
14
|
+
* unable to express "follow the Host" and would let the control silently
|
|
15
|
+
* display an unrelated zone.
|
|
16
|
+
*
|
|
17
|
+
* A stored zone the inventory does not list (a rule written on another machine
|
|
18
|
+
* or under a different ICU build) is appended, so opening the editor can never
|
|
19
|
+
* silently rewrite the rule's zone.
|
|
20
|
+
* @param hostTimeZone - zone the Host reported for this deployment, when known.
|
|
21
|
+
* @param storedTimeZone - zone the edited rule already stores, when any.
|
|
22
|
+
* @returns the de-duplicated choice list.
|
|
23
|
+
*/
|
|
24
|
+
export declare function zoneChoices(hostTimeZone: string | undefined, storedTimeZone?: string): ZoneChoice[];
|
|
25
|
+
/**
|
|
26
|
+
* The relative half of a next-run label: how far away the instant is, or how
|
|
27
|
+
* far past it the board is running. `now` is passed in rather than sampled so
|
|
28
|
+
* callers can share one clock reading across a row, and tests stay
|
|
29
|
+
* deterministic.
|
|
30
|
+
* @param targetMs - the instant being described.
|
|
31
|
+
* @param now - the reference instant.
|
|
32
|
+
* @returns localized relative wording.
|
|
33
|
+
*/
|
|
34
|
+
export declare function relativeTimeLabel(targetMs: number, now: number): string;
|
|
35
|
+
/**
|
|
36
|
+
* The full next-run label: the absolute wall clock in the schedule's own zone,
|
|
37
|
+
* plus the relative distance in parentheses. Showing both matters because a
|
|
38
|
+
* rule's zone can differ from the reader's, so the wall clock alone is
|
|
39
|
+
* ambiguous and the distance alone loses the actual moment.
|
|
40
|
+
* @param targetMs - the instant being described.
|
|
41
|
+
* @param timeZone - zone to render the absolute half in.
|
|
42
|
+
* @param formatAbsolute - formatter for the absolute half (keeps Intl caching in the caller).
|
|
43
|
+
* @param now - the reference instant.
|
|
44
|
+
* @param translate - translate function, bound so this module stays dependency-light.
|
|
45
|
+
* @returns the combined label.
|
|
46
|
+
*/
|
|
47
|
+
export declare function nextRunLabel(targetMs: number, timeZone: string | undefined, formatAbsolute: (ms: number, timeZone?: string) => string, now: number): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type TaskBoardCardDecorationProps, type TaskBoardDetailSectionProps, type TaskBoardSettingsSectionProps } from '../core/extension.ts';
|
|
3
|
+
/** The three provider seats, adapted to plain render functions. */
|
|
4
|
+
export interface TaskBoardSeats {
|
|
5
|
+
detailSection: (props: TaskBoardDetailSectionProps) => ReactNode;
|
|
6
|
+
settingsSection: (props: TaskBoardSettingsSectionProps) => ReactNode;
|
|
7
|
+
cardDecoration: (props: TaskBoardCardDecorationProps) => ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/** Nothing registered: every seat renders empty. */
|
|
10
|
+
export declare const EMPTY_TASK_BOARD_SEATS: TaskBoardSeats;
|
|
11
|
+
/** The framework `renderSlot` binding shape (key + owner props share). */
|
|
12
|
+
export type SlotRenderBinding = (key: string, owner: Record<string, unknown>) => ReactNode;
|
|
13
|
+
/** Adapt one framework renderSlot binding to the board's seat interface. */
|
|
14
|
+
export declare function seatsFromRenderSlot(renderSlot: SlotRenderBinding | undefined): TaskBoardSeats;
|
|
15
|
+
/** Provider the board's registered components wrap their subtree in. */
|
|
16
|
+
export declare const TaskBoardSeatsProvider: import("react").Provider<TaskBoardSeats>;
|
|
17
|
+
/** Read the current seat set (empty when no board registration is above). */
|
|
18
|
+
export declare function useTaskBoardSeats(): TaskBoardSeats;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The board's browser-half extension service (`taskBoard`).
|
|
3
|
+
*
|
|
4
|
+
* It gives a provider's browser half the client capability face from the
|
|
5
|
+
* contract: dispatch over the board's same-origin action channel, card
|
|
6
|
+
* visibility predicates, and a subscription to the board mirror. The board
|
|
7
|
+
* controller is attached and detached as the master switch mounts and unmounts
|
|
8
|
+
* the UI, so the service can be provided before any controller exists.
|
|
9
|
+
*
|
|
10
|
+
* @module dsh-task-board/client/service
|
|
11
|
+
*/
|
|
12
|
+
import type { BoardController } from '../core/controller.ts';
|
|
13
|
+
import type { TaskBoardClientFace, TaskBoardClientMirror, TaskBoardExtensionActionRequest, TaskBoardVisibilityPredicate } from '../core/extension.ts';
|
|
14
|
+
export declare class TaskBoardClientService implements TaskBoardClientFace {
|
|
15
|
+
private controller;
|
|
16
|
+
private enabled;
|
|
17
|
+
private unsubscribeController;
|
|
18
|
+
/** Predicates registered before the controller exists, replayed on attach. */
|
|
19
|
+
private readonly pendingVisibility;
|
|
20
|
+
private readonly listeners;
|
|
21
|
+
/** Bind the live board controller (called when the UI mounts). */
|
|
22
|
+
attach(controller: BoardController): void;
|
|
23
|
+
/** Release the current controller (called when the UI unmounts). */
|
|
24
|
+
detach(): void;
|
|
25
|
+
/** Apply the board's master switch. */
|
|
26
|
+
setEnabled(enabled: boolean): void;
|
|
27
|
+
dispatch(request: TaskBoardExtensionActionRequest): Promise<boolean>;
|
|
28
|
+
registerVisibility(predicate: TaskBoardVisibilityPredicate): () => void;
|
|
29
|
+
subscribe(callback: (mirror: TaskBoardClientMirror) => void): () => void;
|
|
30
|
+
snapshot(): TaskBoardClientMirror;
|
|
31
|
+
private notify;
|
|
32
|
+
}
|
|
@@ -134,6 +134,8 @@ export declare class CardForm<T> {
|
|
|
134
134
|
private readonly disposeForm;
|
|
135
135
|
private disposed;
|
|
136
136
|
private saving;
|
|
137
|
+
/** A save asked for while one was in flight; it runs once the first settles (#1754). */
|
|
138
|
+
private saveQueued;
|
|
137
139
|
private failed;
|
|
138
140
|
private failedReason;
|
|
139
141
|
/** @param scope - the bound configuration form for this card's namespace. */
|
|
@@ -167,6 +169,20 @@ export declare class CardForm<T> {
|
|
|
167
169
|
* the user can correct them instead of retyping.
|
|
168
170
|
* @returns settlement after the mutation and the read-back.
|
|
169
171
|
*/
|
|
172
|
+
/**
|
|
173
|
+
* Run one save, and re-run it once if another was asked for while this one
|
|
174
|
+
* was still in flight.
|
|
175
|
+
*
|
|
176
|
+
* A save is a Host round trip that also drives the profile reconcile, and
|
|
177
|
+
* the Host runs that write inside one exclusive transaction. Answering a
|
|
178
|
+
* press that arrives mid-flight by returning immediately dropped the edit
|
|
179
|
+
* with no explanation, which is the "the save button stops working after a
|
|
180
|
+
* few rounds" report (#1754). Serializing instead means a save pressed while
|
|
181
|
+
* another is still settling runs against the settled state - which is what
|
|
182
|
+
* the operator meant by pressing it again.
|
|
183
|
+
* @returns settlement after the mutation and the read-back.
|
|
184
|
+
*/
|
|
185
|
+
requestSave(): Promise<void>;
|
|
170
186
|
save(): Promise<void>;
|
|
171
187
|
/**
|
|
172
188
|
* Every staged edit a save would write. An entry whose draft is not a value
|
|
@@ -15,6 +15,7 @@ import type { TaskStore } from './store.ts';
|
|
|
15
15
|
import { type NewTaskInput, type TaskRecord, type TaskStatus } from './tasks.ts';
|
|
16
16
|
import { type TaskUpdatePatch } from './use-cases/task-update.ts';
|
|
17
17
|
import type { TaskBoardAction, TaskBoardEventPayload, TaskBoardParseDraft, TaskBoardParseRequest, TaskBoardSnapshot } from '../protocol.ts';
|
|
18
|
+
import type { TaskBoardExtensionActionRequest, TaskBoardVisibilityPredicate } from './extension.ts';
|
|
18
19
|
export interface TaskBoardTransport {
|
|
19
20
|
bootstrap(legacy: readonly TaskRecord[]): Promise<TaskBoardSnapshot>;
|
|
20
21
|
state(): Promise<TaskBoardSnapshot>;
|
|
@@ -110,7 +111,7 @@ export interface ExecutionOptionsSnapshot {
|
|
|
110
111
|
* (revision/scheduler/power); a full snapshot also carries the deployment
|
|
111
112
|
* constants the UI reads (session default permission, subtask depth).
|
|
112
113
|
*/
|
|
113
|
-
export type HostMirror = Pick<TaskBoardSnapshot, 'revision' | 'scheduler' | 'power' | 'sessionDefaultPermission' | 'maxSubtaskDepth' | 'teamRunAvailable'>;
|
|
114
|
+
export type HostMirror = Pick<TaskBoardSnapshot, 'revision' | 'scheduler' | 'power' | 'sessionDefaultPermission' | 'maxSubtaskDepth' | 'teamRunAvailable' | 'extensions'>;
|
|
114
115
|
/** Immutable controller snapshot for UI subscriptions. */
|
|
115
116
|
export interface ControllerSnapshot {
|
|
116
117
|
tasks: readonly TaskRecord[];
|
|
@@ -127,6 +128,15 @@ export interface ControllerSnapshot {
|
|
|
127
128
|
canParseTask?: boolean;
|
|
128
129
|
transportError?: string;
|
|
129
130
|
host?: HostMirror;
|
|
131
|
+
/**
|
|
132
|
+
* Provider card-visibility predicates, in registration order. A task shows
|
|
133
|
+
* only while every predicate accepts it; providers hide their own off-board
|
|
134
|
+
* cards here instead of the board hard-coding a provider rule. Optional so a
|
|
135
|
+
* hand-built snapshot (tests, a shell-less composition) defaults to visible.
|
|
136
|
+
*/
|
|
137
|
+
visibility?: readonly TaskBoardVisibilityPredicate[];
|
|
138
|
+
/** Read-only summaries published by running extensions, keyed by extension id. */
|
|
139
|
+
extensions?: Readonly<Record<string, unknown>>;
|
|
130
140
|
}
|
|
131
141
|
/** The selected task (resolved from the ledger), or undefined. */
|
|
132
142
|
export declare function selectedTaskOf(snapshot: ControllerSnapshot): TaskRecord | undefined;
|
|
@@ -150,6 +160,8 @@ export declare class BoardController {
|
|
|
150
160
|
private readonly taskQueues;
|
|
151
161
|
private transportError;
|
|
152
162
|
private hostState;
|
|
163
|
+
/** Provider visibility predicates (immutable array; replaced on change). */
|
|
164
|
+
private visibility;
|
|
153
165
|
private remoteSubscribed;
|
|
154
166
|
private remoteInitialization;
|
|
155
167
|
/** @param deps - store and the sessions navigation face. */
|
|
@@ -159,6 +171,16 @@ export declare class BoardController {
|
|
|
159
171
|
/** Stop all subscriptions and drop retained state (idempotent). */
|
|
160
172
|
dispose(): void;
|
|
161
173
|
getSnapshot(): ControllerSnapshot;
|
|
174
|
+
/**
|
|
175
|
+
* Register one card-visibility predicate. The returned disposer removes it;
|
|
176
|
+
* both changes notify subscribers so the board re-renders.
|
|
177
|
+
*/
|
|
178
|
+
registerVisibility(predicate: TaskBoardVisibilityPredicate): () => void;
|
|
179
|
+
/**
|
|
180
|
+
* Deliver one provider action through the board's same-origin channel. A
|
|
181
|
+
* board without a Host transport (the legacy in-memory path) refuses it.
|
|
182
|
+
*/
|
|
183
|
+
dispatchExtension(request: TaskBoardExtensionActionRequest): Promise<boolean>;
|
|
162
184
|
subscribe(fn: () => void): () => void;
|
|
163
185
|
/** Whether production mutations are confirmed by the Host transport. */
|
|
164
186
|
isHostBacked(): boolean;
|
|
@@ -250,6 +272,20 @@ export declare class BoardController {
|
|
|
250
272
|
setParent(id: string, parentId: string | null): Promise<boolean>;
|
|
251
273
|
/** Restore an archived task back onto the board (same status column). */
|
|
252
274
|
restoreTask(id: string): boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Rename one label across the whole ledger; a name already in use merges the
|
|
277
|
+
* two labels. Host-backed: the ledger owns the transition and confirms it, so
|
|
278
|
+
* the board's label row reflects whether the Host accepted the edit.
|
|
279
|
+
* @returns true when the edit was accepted by the authority.
|
|
280
|
+
*/
|
|
281
|
+
renameTag(from: string, to: string): Promise<boolean>;
|
|
282
|
+
/**
|
|
283
|
+
* Remove one label from every task that carries it, board and archive alike —
|
|
284
|
+
* the board's label row is drawn from the whole ledger, so a label left on an
|
|
285
|
+
* archived card would come straight back.
|
|
286
|
+
* @returns true when the edit was accepted by the authority.
|
|
287
|
+
*/
|
|
288
|
+
deleteTag(name: string): Promise<boolean>;
|
|
253
289
|
/**
|
|
254
290
|
* Update a task's schedule rule. A blank or invalid cron expression is
|
|
255
291
|
* rejected (returns false, state untouched). When the rule ends up enabled
|
|
@@ -262,6 +298,7 @@ export declare class BoardController {
|
|
|
262
298
|
setSchedule(id: string, patch: {
|
|
263
299
|
enabled?: boolean;
|
|
264
300
|
cron?: string;
|
|
301
|
+
timeZone?: string | null;
|
|
265
302
|
}): boolean;
|
|
266
303
|
/**
|
|
267
304
|
* Legacy pure-controller seam retained for migration-focused tests. The
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The family health ledger's degraded-record contract (issues #1528, #1730).
|
|
3
|
+
*
|
|
4
|
+
* A family plugin row that fails during apply is recorded by the dsh-web-all
|
|
5
|
+
* shell as a degraded record; the shell serves the ledger through its
|
|
6
|
+
* loopback-only `GET /api/dsh-web-all/degraded` route because the failed
|
|
7
|
+
* plugin could not register any route of its own — the task board whose ledger
|
|
8
|
+
* lock is held by another DSH process is exactly that case, and without this
|
|
9
|
+
* the panel could only report "the Host API is not mounted".
|
|
10
|
+
*
|
|
11
|
+
* Both halves define this shape: the shell WRITES it (packages/dsh-web-all,
|
|
12
|
+
* src/degraded.ts — the two packages have no import edge, one is bundled into
|
|
13
|
+
* the other's profile) and a plugin's browser half PARSES it. The edits move
|
|
14
|
+
* together.
|
|
15
|
+
*/
|
|
16
|
+
/** Where a degraded row failed: module import, plugin shape, or fiber start. */
|
|
17
|
+
export type DegradedStage = 'import' | 'shape' | 'start';
|
|
18
|
+
/** One degraded family row as the shell's health route serves it. */
|
|
19
|
+
export interface DegradedRow {
|
|
20
|
+
/** Real plugin package name from the shell row config. */
|
|
21
|
+
plugin: string;
|
|
22
|
+
/** Where the failure happened. */
|
|
23
|
+
stage: DegradedStage;
|
|
24
|
+
/** The shell's one-line reason, for display. */
|
|
25
|
+
reason: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The one degraded record naming `plugin`, or undefined when that row is not
|
|
29
|
+
* degraded (or the payload does not come from the shell's own shape). A
|
|
30
|
+
* plugin may appear once: the shell keys the ledger by package name and
|
|
31
|
+
* refreshes the record on every new failure.
|
|
32
|
+
* @param body - parsed JSON body of the health route.
|
|
33
|
+
* @param plugin - the real plugin package name to look for.
|
|
34
|
+
* @returns the degraded row, or undefined when the ledger does not name it.
|
|
35
|
+
*/
|
|
36
|
+
export declare function degradedRowOf(body: unknown, plugin: string): DegradedRow | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Extract the pid of the LIVE process a ledger-lock failure blames, when the
|
|
39
|
+
* reason identifies one. The task board's lock refusal is the one degraded
|
|
40
|
+
* reason that carries an owner the user can act on, so the panel renders the
|
|
41
|
+
* pid in its own sentence and adds the guidance that actually applies.
|
|
42
|
+
* @param reason - the shell's one-line failure reason.
|
|
43
|
+
* @returns the confirmed owner pid, or undefined when the reason names none or
|
|
44
|
+
* warns that the PID may have been reused (its own text owns the recovery).
|
|
45
|
+
*/
|
|
46
|
+
export declare function ledgerOwnerPid(reason: string): number | undefined;
|