@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
|
@@ -3,6 +3,9 @@ import { HostTaskLedger } from './host-ledger.ts';
|
|
|
3
3
|
import { HostExecutionRunner, type SessionCommandDispatcher, type TaskBoardWorkspaceRegistry } from './host-runner.ts';
|
|
4
4
|
import { PowerInhibitor } from './power-inhibitor.ts';
|
|
5
5
|
import { type TaskBoardAction, type TaskBoardEventPayload, type TaskBoardSnapshot } from './protocol.ts';
|
|
6
|
+
import { TaskBoardExtensionRegistry } from './host/extension-registry.ts';
|
|
7
|
+
import type { TaskBoardExtension } from './core/extension.ts';
|
|
8
|
+
import { type ModelCatalogView, type VerificationContract, type VerificationSettings } from './core/verification.ts';
|
|
6
9
|
import type { TaskPermission } from './core/handover.ts';
|
|
7
10
|
/** One teammate the Host asks the Agent Teams service to spawn for a team run. */
|
|
8
11
|
export interface TeamSpawnInput {
|
|
@@ -31,6 +34,16 @@ export interface TeamSpawnResult {
|
|
|
31
34
|
export interface TaskBoardTeamDispatcher {
|
|
32
35
|
spawn(input: TeamSpawnInput): Promise<TeamSpawnResult>;
|
|
33
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Provenance of one cron-triggered cascade: when the rule fired and the zone
|
|
39
|
+
* its wall clock was read in. Passed into every launched prompt of that run so
|
|
40
|
+
* a scheduled job knows its own clock rather than inferring one.
|
|
41
|
+
*/
|
|
42
|
+
export interface ScheduledRunContext {
|
|
43
|
+
triggeredAt: number;
|
|
44
|
+
timeZone: string;
|
|
45
|
+
cron: string;
|
|
46
|
+
}
|
|
34
47
|
/**
|
|
35
48
|
* The native timer face the Host arms through. The cordis `timer` service
|
|
36
49
|
* (dsh-base's own `cordis-plugin-timer` row) provides it: its handles are
|
|
@@ -63,29 +76,112 @@ export declare class TaskBoardHostService {
|
|
|
63
76
|
* conversation instead of prompting into a session it cannot see.
|
|
64
77
|
*/
|
|
65
78
|
private idleSessionIds;
|
|
79
|
+
/**
|
|
80
|
+
* Consecutive unreadable-history polls per open execution (see
|
|
81
|
+
* {@link noteUnreadableInspection}). Cleared as soon as an inspection
|
|
82
|
+
* resolves, so a transient reader failure never fails a card.
|
|
83
|
+
*/
|
|
84
|
+
private readonly unreadablePolls;
|
|
66
85
|
private preventIdleSleep;
|
|
86
|
+
private readonly verificationSettings;
|
|
87
|
+
private readonly verificationCatalog;
|
|
67
88
|
private readonly team;
|
|
68
89
|
private readonly timers;
|
|
69
90
|
private lastPowerJson;
|
|
70
91
|
private readonly now;
|
|
92
|
+
/** The deployment's workspaces, consulted to resolve a card that pins none. */
|
|
93
|
+
private readonly workspaceRegistry;
|
|
94
|
+
/**
|
|
95
|
+
* External provider extensions. The board owns task lifecycle and execution;
|
|
96
|
+
* a provider observes them through the registry's capability face and never
|
|
97
|
+
* reaches into the ledger itself.
|
|
98
|
+
*/
|
|
99
|
+
readonly extensions: TaskBoardExtensionRegistry;
|
|
71
100
|
constructor(gateway: TypertGateway, options?: {
|
|
72
101
|
ledger?: HostTaskLedger;
|
|
73
102
|
power?: PowerInhibitor;
|
|
74
103
|
now?: () => number;
|
|
75
104
|
commandDispatcher?: SessionCommandDispatcher;
|
|
76
105
|
workspaceRegistry?: TaskBoardWorkspaceRegistry;
|
|
77
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Permission baseline of the confirmation gate: a fixed value, or a live
|
|
108
|
+
* resolver the board re-reads so a Host Settings change needs no remount.
|
|
109
|
+
*/
|
|
110
|
+
sessionDefaultPermission?: TaskPermission | (() => TaskPermission);
|
|
78
111
|
maxSubtaskDepth?: number;
|
|
79
112
|
team?: TaskBoardTeamDispatcher;
|
|
80
113
|
timers?: HostTimerFace;
|
|
114
|
+
/**
|
|
115
|
+
* Live acceptance settings (volatile config reads). Absent keeps goal
|
|
116
|
+
* acceptance OFF for every execution this service opens, which is what a
|
|
117
|
+
* programmatic mount without the settings domain gets.
|
|
118
|
+
*/
|
|
119
|
+
verificationSettings?: () => VerificationSettings;
|
|
120
|
+
/** The host model catalog the acceptance contract resolves its route from. */
|
|
121
|
+
verificationCatalog?: () => Promise<ModelCatalogView | undefined>;
|
|
81
122
|
});
|
|
82
123
|
start(): void;
|
|
83
124
|
setConfiguration(active: boolean, preventIdleSleep: boolean): void;
|
|
84
125
|
snapshot(): TaskBoardSnapshot;
|
|
126
|
+
/**
|
|
127
|
+
* Admit one external provider. Idempotent by extension id; the returned
|
|
128
|
+
* disposer releases it (its stored data stays).
|
|
129
|
+
*/
|
|
130
|
+
registerExtension(extension: TaskBoardExtension): () => void;
|
|
131
|
+
/**
|
|
132
|
+
* The acceptance configuration the settings card displays: the live settings,
|
|
133
|
+
* the contract they resolve to, and the host catalog the choices come from.
|
|
134
|
+
*
|
|
135
|
+
* The card shows the RESOLVED route, not the raw configuration, so "inherit
|
|
136
|
+
* host" reads as the concrete model and reasoning level the next execution
|
|
137
|
+
* will actually freeze, including any recorded effort fallback.
|
|
138
|
+
* @returns the resolved acceptance options.
|
|
139
|
+
*/
|
|
140
|
+
verificationOptions(): Promise<{
|
|
141
|
+
settings: VerificationSettings;
|
|
142
|
+
contract: VerificationContract;
|
|
143
|
+
catalog: ModelCatalogView;
|
|
144
|
+
}>;
|
|
85
145
|
/** SSE frame payload; deliberately skips the tasks deep-clone of {@link snapshot}. */
|
|
86
146
|
eventPayload(): TaskBoardEventPayload;
|
|
87
147
|
subscribe(listener: () => void): () => void;
|
|
88
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Give a root card created without a workspace pin the workspace its creator
|
|
150
|
+
* is in.
|
|
151
|
+
*
|
|
152
|
+
* An agent's `task_board_create` arrives with the calling session, and the
|
|
153
|
+
* GUI submits the session the main view shows, so the card lands where the
|
|
154
|
+
* work was asked for instead of where the Host process happens to run. A card
|
|
155
|
+
* that names a workspace keeps it, and a subtask keeps inheriting its lineage
|
|
156
|
+
* (the runner walks the ancestor chain for that).
|
|
157
|
+
*
|
|
158
|
+
* The initiator is client-asserted, so it only chooses among workspaces the
|
|
159
|
+
* deployment already knows: it can neither register one nor reach outside the
|
|
160
|
+
* list the user sees.
|
|
161
|
+
* @param action - the action about to be applied.
|
|
162
|
+
* @param initiator - the session that issued the action, when one was asserted.
|
|
163
|
+
* @returns the action, with an inherited workspace on a root creation.
|
|
164
|
+
*/
|
|
165
|
+
private withInheritedWorkspace;
|
|
166
|
+
apply(requestId: string, action: Extract<TaskBoardAction, {
|
|
167
|
+
kind: 'extension-action';
|
|
168
|
+
}>, initiator?: string): Promise<TaskBoardSnapshot>;
|
|
169
|
+
apply(requestId: string, action: Exclude<TaskBoardAction, {
|
|
170
|
+
kind: 'extension-action';
|
|
171
|
+
}>, initiator?: string): TaskBoardSnapshot;
|
|
172
|
+
apply(requestId: string, action: TaskBoardAction, initiator?: string): TaskBoardSnapshot | Promise<TaskBoardSnapshot>;
|
|
173
|
+
/**
|
|
174
|
+
* Apply one board-owned action with every gate intact. Provider capability
|
|
175
|
+
* calls and the same-origin wire both land here, so the two surfaces can
|
|
176
|
+
* never disagree about a card.
|
|
177
|
+
*/
|
|
178
|
+
private applyBoardAction;
|
|
179
|
+
/** Route one provider action and answer the resulting board snapshot. */
|
|
180
|
+
private handleExtensionAction;
|
|
181
|
+
/** Current task id -> status map, for change detection around a mutation. */
|
|
182
|
+
private statusMap;
|
|
183
|
+
/** Emit a status change for every task whose column moved, isolated per callback. */
|
|
184
|
+
private emitStatusChanges;
|
|
89
185
|
dispose(): void;
|
|
90
186
|
private launch;
|
|
91
187
|
private scheduleTeammate;
|
|
@@ -100,6 +196,17 @@ export declare class TaskBoardHostService {
|
|
|
100
196
|
private pollSessions;
|
|
101
197
|
/** Reuse the session list this poll already fetched: one list RPC per tick, not 1 + E. */
|
|
102
198
|
private reconcileExecutions;
|
|
199
|
+
/**
|
|
200
|
+
* Count one poll whose session history could not be read. A reader failure is
|
|
201
|
+
* not progress: the session is not running (the runner only reads history for
|
|
202
|
+
* one that is idle), so nothing will ever change that verdict. After
|
|
203
|
+
* {@link UNREADABLE_SETTLE_POLLS} consecutive polls the execution is reported
|
|
204
|
+
* failed with the recorded reason, instead of holding its card — and every
|
|
205
|
+
* ancestor of it — in the running column with no way out. The first poll of
|
|
206
|
+
* each streak is logged, so the Host log names the session.
|
|
207
|
+
*/
|
|
208
|
+
private settleAndNotify;
|
|
209
|
+
private noteUnreadableInspection;
|
|
103
210
|
/** Drop the armed schedule timer and forget its target. */
|
|
104
211
|
private clearScheduleTimer;
|
|
105
212
|
/**
|
|
@@ -135,6 +242,11 @@ export declare class TaskBoardHostService {
|
|
|
135
242
|
* session instead, once that session exists.
|
|
136
243
|
*/
|
|
137
244
|
private dispatchRuns;
|
|
245
|
+
/**
|
|
246
|
+
* Move one execution's applicability without touching its frozen contract or
|
|
247
|
+
* its recorded attempts (used when the run's goal form becomes known).
|
|
248
|
+
*/
|
|
249
|
+
private setApplicability;
|
|
138
250
|
private scheduleLaunch;
|
|
139
251
|
private schedulePoll;
|
|
140
252
|
/**
|
package/lib/types/index.d.ts
CHANGED
|
@@ -47,9 +47,12 @@ export interface Config {
|
|
|
47
47
|
/** Environment variable whose value the authenticated proxy injects upstream. */
|
|
48
48
|
proxyTokenEnv?: string;
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* An explicit baseline for the permission confirmation gate. Left unset, the
|
|
51
|
+
* board follows the Host's own default permission preset — the value new DSH
|
|
52
|
+
* sessions start at — and falls back to `read-only` when the deployment
|
|
53
|
+
* serves no permission catalog. A card whose effective permission (handover
|
|
54
|
+
* bundle or pin) is above the baseline requires a human confirmation before
|
|
55
|
+
* it may run; cron refuses unconfirmed cards.
|
|
53
56
|
*/
|
|
54
57
|
sessionDefaultPermission?: TaskPermission;
|
|
55
58
|
/**
|
|
@@ -65,6 +68,31 @@ export interface Config {
|
|
|
65
68
|
* only team-mode runs use it.
|
|
66
69
|
*/
|
|
67
70
|
teamProvider?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Goal acceptance for executions this board starts (default ON). When on,
|
|
73
|
+
* update_goal(action: complete) inside a task execution is refused until an
|
|
74
|
+
* acceptance pass is recorded for that execution: the three coding criteria,
|
|
75
|
+
* a 0.65 threshold, two rounds per criterion with the A/B slots swapped, and
|
|
76
|
+
* at most two acceptances per execution — the first failure returns its
|
|
77
|
+
* findings to the fixing agent, the second ends the cycle. The switch only
|
|
78
|
+
* affects goal-form executions of the board; plain chat and a task pinned to
|
|
79
|
+
* goalRun: false are untouched. When a separate third-party verifier also
|
|
80
|
+
* runs its own automatic acceptance, both judges score independently: this
|
|
81
|
+
* one gates completion, the other only steers, and no public interface lets
|
|
82
|
+
* the two share a verdict.
|
|
83
|
+
*/
|
|
84
|
+
goalVerification?: Volatile<boolean>;
|
|
85
|
+
/**
|
|
86
|
+
* Judge model for goal acceptance as provider/model. Blank inherits the HOST's
|
|
87
|
+
* own model catalog default — never the card's pinned execution model.
|
|
88
|
+
*/
|
|
89
|
+
goalVerificationModel?: Volatile<string>;
|
|
90
|
+
/**
|
|
91
|
+
* Reasoning effort for the judge. Blank inherits the host default level; an
|
|
92
|
+
* effort the resolved model does not declare is dropped instead of being
|
|
93
|
+
* sent, and the fallback to the model's own default is reported.
|
|
94
|
+
*/
|
|
95
|
+
goalVerificationReasoningEffort?: Volatile<string>;
|
|
68
96
|
}
|
|
69
97
|
/**
|
|
70
98
|
* Continuable-subagent provider for fresh teammates, matching the Agent Teams
|
|
@@ -72,30 +100,42 @@ export interface Config {
|
|
|
72
100
|
*/
|
|
73
101
|
export declare const DEFAULT_TEAM_PROVIDER = "spawn";
|
|
74
102
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
103
|
+
* Profile-patch shape of {@link Config}: what the Host validates the row's
|
|
104
|
+
* config against, before the schema turns volatile fields into live references
|
|
105
|
+
* and applies defaults. Declared separately because the two sides no longer
|
|
106
|
+
* share one shape, so the schema is annotated `z<ConfigInput, Config>` — the
|
|
107
|
+
* same split `dsh-git-graph` uses. The annotation is also what keeps the
|
|
108
|
+
* emitted declaration portable: an unannotated schema holding a nested object
|
|
109
|
+
* array infers a type that cannot be named without reaching into a transitive
|
|
110
|
+
* dependency's own types.
|
|
79
111
|
*/
|
|
80
|
-
export
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
export interface ConfigInput {
|
|
113
|
+
/** Announce the board in the system prompt. */
|
|
114
|
+
announceToAgent?: boolean;
|
|
115
|
+
/** Master switch for the plugin. */
|
|
116
|
+
enabled?: boolean;
|
|
117
|
+
/** Prevent idle system sleep while sessions run or schedules are armed. */
|
|
118
|
+
preventIdleSleep?: boolean;
|
|
119
|
+
/** Canonical reverse-proxy Host authorities. */
|
|
120
|
+
trustedProxyHosts?: string[];
|
|
121
|
+
/** Environment variable whose value the authenticated proxy injects. */
|
|
122
|
+
proxyTokenEnv?: string;
|
|
123
|
+
/** Explicit baseline for the permission confirmation gate; unset follows the Host default. */
|
|
124
|
+
sessionDefaultPermission?: TaskPermission;
|
|
125
|
+
/** Subtask depth limit, 1..3. */
|
|
126
|
+
maxSubtaskDepth?: number;
|
|
127
|
+
/** Continuable-subagent provider the Agent Teams service composes a teammate from. */
|
|
128
|
+
teamProvider?: string;
|
|
129
|
+
/** Goal acceptance switch. */
|
|
130
|
+
goalVerification?: boolean;
|
|
131
|
+
/** Judge model route for goal acceptance; blank inherits the host default. */
|
|
132
|
+
goalVerificationModel?: string;
|
|
133
|
+
/** Judge reasoning effort; blank inherits the host default. */
|
|
134
|
+
goalVerificationReasoningEffort?: string;
|
|
135
|
+
}
|
|
136
|
+
export declare const Config: z<ConfigInput, Config>;
|
|
137
|
+
/** Schema default for the goal-acceptance switch, re-read for hand-built contexts. */
|
|
138
|
+
export declare const DEFAULT_GOAL_VERIFICATION = true;
|
|
99
139
|
declare module '@deepseek-ai/cordis' {
|
|
100
140
|
interface Events {
|
|
101
141
|
/**
|
|
@@ -129,6 +169,8 @@ export declare function resolveProxyAccess(config: Config | undefined, env?: Nod
|
|
|
129
169
|
/** The registry face the agent tools register into. */
|
|
130
170
|
interface AgentToolRegistry {
|
|
131
171
|
register(definition: ToolDefinition): () => void;
|
|
172
|
+
/** Scoped lookup; present on the real registry, absent on a stub that only registers. */
|
|
173
|
+
get?(name: string, scope?: unknown): unknown;
|
|
132
174
|
}
|
|
133
175
|
/**
|
|
134
176
|
* Resolve the optional agent-tool registry. The board deliberately does not
|
|
@@ -149,6 +191,18 @@ export declare function resolveToolRegistry(ctx: Context): AgentToolRegistry | u
|
|
|
149
191
|
* @returns the timer face, or undefined when this deployment serves none.
|
|
150
192
|
*/
|
|
151
193
|
export declare function resolveHostTimers(ctx: Context): HostTimerFace | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* The Host's own default permission preset, mapped into the board's vocabulary.
|
|
196
|
+
*
|
|
197
|
+
* This is the value new DSH sessions start at (the deployment's `permission`
|
|
198
|
+
* settings row), so a board that follows it treats an ordinary card exactly as
|
|
199
|
+
* the Host would. Absent when the deployment serves no permission catalog, or
|
|
200
|
+
* its default is a current-session identity (`auto`) that names no fixed
|
|
201
|
+
* sandbox mode; the caller then keeps the fail-safe baseline.
|
|
202
|
+
* @param ctx - the plugin context.
|
|
203
|
+
* @returns the Host default as a board permission, or undefined when unreadable.
|
|
204
|
+
*/
|
|
205
|
+
export declare function resolveHostDefaultPermission(ctx: Context): TaskPermission | undefined;
|
|
152
206
|
/** The subset of the Agent Teams service this plugin drives. */
|
|
153
207
|
interface AgentTeamsFace {
|
|
154
208
|
spawnTeammate(caller: unknown, request: {
|
package/lib/types/protocol.d.ts
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import type { TaskUpdatePatch } from './core/use-cases/task-update.ts';
|
|
2
2
|
import { type NewTaskInput, type TaskPermission, type TaskRecord, type TaskStatus } from './core/tasks.ts';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
3
|
+
import { type TaskBoardExtensionPayload } from './core/extension.ts';
|
|
4
|
+
import { type ModelCatalogView, type VerificationContract, type VerificationSettings } from './core/verification.ts';
|
|
5
|
+
export declare const TASK_BOARD_SCHEMA_VERSION: 5;
|
|
6
|
+
/** Ledger documents written before v5; loaded once and migrated on startup. */
|
|
7
|
+
export declare const TASK_BOARD_LEGACY_SCHEMA_VERSION: 4;
|
|
8
|
+
/** Ledger documents written before v4; migrated through the v4 normalization too. */
|
|
9
|
+
export declare const TASK_BOARD_OLDER_SCHEMA_VERSION: 3;
|
|
10
|
+
/** Ledger documents written before v3; migrated through every later normalization too. */
|
|
11
|
+
export declare const TASK_BOARD_OLDEST_SCHEMA_VERSION: 2;
|
|
12
|
+
/**
|
|
13
|
+
* Every older generation the loader migrates in place. v5 only ADDS the
|
|
14
|
+
* per-execution acceptance block, so the migration is the normalization pass
|
|
15
|
+
* that re-validates each row; a document from any listed generation upgrades
|
|
16
|
+
* losslessly.
|
|
17
|
+
*/
|
|
18
|
+
export declare const TASK_BOARD_MIGRATABLE_SCHEMA_VERSIONS: readonly number[];
|
|
6
19
|
export declare const TASK_BOARD_API_PREFIX = "/api/task-board";
|
|
7
20
|
export type PowerPhase = 'disabled' | 'idle' | 'acquiring' | 'active' | 'error' | 'unsupported';
|
|
8
21
|
export interface TaskBoardPowerSnapshot {
|
|
@@ -39,6 +52,24 @@ export interface TaskBoardSnapshot {
|
|
|
39
52
|
* into team execution (Team Lead session plus one teammate per subtask).
|
|
40
53
|
*/
|
|
41
54
|
teamRunAvailable?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Read-only summaries published by running extensions, keyed by extension id.
|
|
57
|
+
* The board forwards them verbatim; it never interprets their shape.
|
|
58
|
+
*/
|
|
59
|
+
extensions?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Body of `GET {TASK_BOARD_API_PREFIX}/verification`: the acceptance settings the
|
|
63
|
+
* card edits, the contract they resolve to right now, and the host model catalog
|
|
64
|
+
* the model and reasoning choices come from. Served through the same loopback /
|
|
65
|
+
* authenticated-proxy guard as the rest of the board API, and it carries no
|
|
66
|
+
* credential material — model routes and level ids only.
|
|
67
|
+
*/
|
|
68
|
+
export interface TaskBoardVerificationOptions {
|
|
69
|
+
settings: VerificationSettings;
|
|
70
|
+
/** The RESOLVED contract, so the card can show what the next execution freezes. */
|
|
71
|
+
contract: VerificationContract;
|
|
72
|
+
catalog: ModelCatalogView;
|
|
42
73
|
}
|
|
43
74
|
/** SSE event frame: revision/scheduler/power only, never the task list. */
|
|
44
75
|
export interface TaskBoardEventPayload {
|
|
@@ -90,12 +121,16 @@ export type TaskBoardAction = {
|
|
|
90
121
|
} | {
|
|
91
122
|
kind: 'restore';
|
|
92
123
|
taskId: string;
|
|
124
|
+
} | {
|
|
125
|
+
kind: 'settle';
|
|
126
|
+
taskId: string;
|
|
93
127
|
} | {
|
|
94
128
|
kind: 'set-schedule';
|
|
95
129
|
taskId: string;
|
|
96
130
|
patch: {
|
|
97
131
|
enabled?: boolean;
|
|
98
132
|
cron?: string;
|
|
133
|
+
timeZone?: string | null;
|
|
99
134
|
};
|
|
100
135
|
} | {
|
|
101
136
|
kind: 'run';
|
|
@@ -110,6 +145,21 @@ export type TaskBoardAction = {
|
|
|
110
145
|
kind: 'set-parent';
|
|
111
146
|
taskId: string;
|
|
112
147
|
parentId: string | null;
|
|
148
|
+
}
|
|
149
|
+
/** Ledger-wide label management; see core/use-cases/task-tag.ts. */
|
|
150
|
+
| {
|
|
151
|
+
kind: 'rename-tag';
|
|
152
|
+
from: string;
|
|
153
|
+
to: string;
|
|
154
|
+
} | {
|
|
155
|
+
kind: 'delete-tag';
|
|
156
|
+
name: string;
|
|
157
|
+
} | {
|
|
158
|
+
kind: 'extension-action';
|
|
159
|
+
extensionId: string;
|
|
160
|
+
action: string;
|
|
161
|
+
taskId?: string;
|
|
162
|
+
payload?: TaskBoardExtensionPayload;
|
|
113
163
|
};
|
|
114
164
|
export interface TaskBoardActionEnvelope {
|
|
115
165
|
requestId: string;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Family-shared tool-surface conventions for the packages that register
|
|
3
|
+
* model-facing tools.
|
|
4
|
+
*
|
|
5
|
+
* One home for the prompt-section placement and the visibility gate this
|
|
6
|
+
* family previously restated per package.
|
|
7
|
+
*
|
|
8
|
+
* Modelled on the official tool packages:
|
|
9
|
+
* - `@deepseek-ai/dsh-tool-subagent` renders its section through
|
|
10
|
+
* `tools.get(name, context.scope) === undefined ? '' : text`, so guidance
|
|
11
|
+
* disappears together with a restricted tool.
|
|
12
|
+
* - 21 of the 22 official tool packages register their tools GLOBALLY and gate
|
|
13
|
+
* them with a setting, not per agent. Only the Agent Teams tool package —
|
|
14
|
+
* whose tools belong to one membership — installs into each `agent.ctx`.
|
|
15
|
+
* This family follows the majority: registration stays global so the
|
|
16
|
+
* registry's per-scope `restrict()` mask (which filters inherited global
|
|
17
|
+
* tools and REJECTS scope-local names) can still withhold these tools.
|
|
18
|
+
*
|
|
19
|
+
* Structural types only: this copy lands in packages that do not all depend on
|
|
20
|
+
* the same SDK service packages.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Prompt-section order for each package's tool guidance.
|
|
24
|
+
*
|
|
25
|
+
* These sit in the family band between the deployment persona and the SDK's
|
|
26
|
+
* `PLAN_POLICY` (500). Values are owned here rather than written per package so
|
|
27
|
+
* the host plugins whose guidance shares one prompt cannot drift into an
|
|
28
|
+
* accidental tie.
|
|
29
|
+
*/
|
|
30
|
+
export declare const PLUGIN_TOOL_SECTION_ORDERS: {
|
|
31
|
+
readonly ssh: 150;
|
|
32
|
+
readonly 'task-board': 200;
|
|
33
|
+
};
|
|
34
|
+
/** One plugin id keyed by {@link PLUGIN_TOOL_SECTION_ORDERS}. */
|
|
35
|
+
export type PluginToolSectionId = keyof typeof PLUGIN_TOOL_SECTION_ORDERS;
|
|
36
|
+
/**
|
|
37
|
+
* Order of an external provider extension's own guidance section, right after
|
|
38
|
+
* the band of the plugin it extends.
|
|
39
|
+
*
|
|
40
|
+
* An extension names itself, not the plugin it plugs into, so its order stays
|
|
41
|
+
* out of {@link PLUGIN_TOOL_SECTION_ORDERS}: every package's copy of this module
|
|
42
|
+
* then carries no provider id. The slot still has one owner and cannot collide
|
|
43
|
+
* with a host plugin's band.
|
|
44
|
+
*/
|
|
45
|
+
export declare const EXTENSION_TOOL_SECTION_ORDER = 210;
|
|
46
|
+
/**
|
|
47
|
+
* The scoped tool lookup a section provider needs: the registry read for one
|
|
48
|
+
* assembly's scope. Matches `ctx.tools.get(name, scope)`.
|
|
49
|
+
*/
|
|
50
|
+
export interface ScopedToolLookup {
|
|
51
|
+
get(name: string, scope?: unknown): unknown;
|
|
52
|
+
}
|
|
53
|
+
/** One assembly context carrying the scope the section is rendered for. */
|
|
54
|
+
export interface SectionScopeContext {
|
|
55
|
+
scope?: unknown;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build a section provider that renders \`text\` only while at least one of
|
|
59
|
+
* \`toolNames\` is visible to the rendering scope.
|
|
60
|
+
*
|
|
61
|
+
* The native convention: a tool that a restriction, a preset, or a missing
|
|
62
|
+
* registry removed must not leave guidance behind telling the model to call it.
|
|
63
|
+
* An unreadable registry renders the text unchanged — guidance that outlives a
|
|
64
|
+
* momentary read failure is recoverable; guidance for a tool that is gone is
|
|
65
|
+
* not.
|
|
66
|
+
* @param tools - the scoped tool registry, when the deployment serves one.
|
|
67
|
+
* @param toolNames - registered names the guidance describes.
|
|
68
|
+
* @param text - the guidance rendered while they are reachable.
|
|
69
|
+
* @returns the section text provider.
|
|
70
|
+
*/
|
|
71
|
+
export declare function visibleToolText(tools: ScopedToolLookup | undefined, toolNames: readonly string[], text: string): (context: SectionScopeContext) => string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxin666/dsh-client-ui-task-board",
|
|
3
3
|
"description": "Host-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"icon": "icon.svg",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dsh": {
|
|
26
26
|
"engines": {
|
|
27
|
-
"dsh": ">=0.
|
|
27
|
+
"dsh": ">=0.2.0-rc.2"
|
|
28
28
|
},
|
|
29
29
|
"bundle": {
|
|
30
30
|
"patch": "./cordis.patch.yml"
|
|
@@ -44,36 +44,37 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@deepseek-ai/dsh": ">=0.
|
|
47
|
+
"@deepseek-ai/dsh": ">=0.2.0-rc.2",
|
|
48
48
|
"react": "^18.2.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@deepseek-ai/schemastery": "^3.18.4"
|
|
51
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
52
|
+
"marked": "^18.0.14"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
55
|
-
"@deepseek-ai/dsh-agent": "^0.
|
|
56
|
-
"@deepseek-ai/dsh-agent-preset-registry": "^0.
|
|
57
|
-
"@deepseek-ai/dsh-api-gateway": "^0.
|
|
58
|
-
"@deepseek-ai/dsh-api-remotes": "^0.
|
|
59
|
-
"@deepseek-ai/dsh-api-session-controller": "^0.
|
|
60
|
-
"@deepseek-ai/dsh-api-workspace-controller": "^0.
|
|
61
|
-
"@deepseek-ai/dsh-client-connection": "^0.
|
|
62
|
-
"@deepseek-ai/dsh-client-locale": "^0.
|
|
63
|
-
"@deepseek-ai/dsh-client-store": "^0.
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-layout": "^0.
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "^0.
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.
|
|
69
|
-
"@deepseek-ai/dsh-client-ui-workspace": "^0.
|
|
70
|
-
"@deepseek-ai/dsh-commands": "^0.
|
|
71
|
-
"@deepseek-ai/dsh-host-webserver": "^0.
|
|
72
|
-
"@deepseek-ai/dsh-llm": "^0.
|
|
73
|
-
"@deepseek-ai/dsh-settings": "^0.
|
|
74
|
-
"@deepseek-ai/dsh-system-prompt": "^0.
|
|
75
|
-
"@deepseek-ai/dsh-tools": "^0.
|
|
76
|
-
"@deepseek-ai/dsh-workspace": "^0.
|
|
56
|
+
"@deepseek-ai/dsh-agent": "^0.2.0-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-agent-preset-registry": "^0.2.0-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-api-gateway": "^0.2.0-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-api-remotes": "^0.2.0-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.2.0-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-api-workspace-controller": "^0.2.0-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-connection": "^0.2.0-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": "^0.2.0-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-store": "^0.2.0-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.2.0-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.2.0-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.2.0-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.2.0-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.2.0-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-workspace": "^0.2.0-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-commands": "^0.2.0-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-llm": "^0.2.0-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-settings": "^0.2.0-rc.2",
|
|
75
|
+
"@deepseek-ai/dsh-system-prompt": "^0.2.0-rc.2",
|
|
76
|
+
"@deepseek-ai/dsh-tools": "^0.2.0-rc.2",
|
|
77
|
+
"@deepseek-ai/dsh-workspace": "^0.2.0-rc.2",
|
|
77
78
|
"@types/node": "^22.20.0",
|
|
78
79
|
"@types/react": "~18.3.1",
|
|
79
80
|
"@types/react-dom": "^18.3.5",
|
|
@@ -41,6 +41,13 @@ export interface PluginSettingsCardProps<TKey extends string = string> {
|
|
|
41
41
|
descriptionKey: TKey
|
|
42
42
|
/** Optional rich header description rendered instead of the plain t(descriptionKey) text (the plain text stays as the tooltip). */
|
|
43
43
|
descriptionNode?: ReactNode
|
|
44
|
+
/**
|
|
45
|
+
* Optional leading mark identifying the plugin. A card without one keeps the
|
|
46
|
+
* plain official header shape, so the chrome stays a readable sibling of the
|
|
47
|
+
* built-in PluginCard wherever a family plugin lands in the official bundle
|
|
48
|
+
* seat.
|
|
49
|
+
*/
|
|
50
|
+
icon?: ReactNode
|
|
44
51
|
/** The card's form state: availability, writability, and what a save would do. */
|
|
45
52
|
state: CardShell
|
|
46
53
|
/** Write every staged edit. */
|
|
@@ -91,6 +98,7 @@ export function PluginSettingsCard<TKey extends string = string>(props: PluginSe
|
|
|
91
98
|
const header = alwaysOpen === true
|
|
92
99
|
? (
|
|
93
100
|
<div className={css.headerStatic}>
|
|
101
|
+
{props.icon !== undefined ? <span className={css.mark} aria-hidden="true">{props.icon}</span> : null}
|
|
94
102
|
<span className={css.headText}>
|
|
95
103
|
<span className={css.name} title={title}>{title}</span>
|
|
96
104
|
<span className={css.description} title={description}>{props.descriptionNode ?? description}</span>
|
|
@@ -106,6 +114,7 @@ export function PluginSettingsCard<TKey extends string = string>(props: PluginSe
|
|
|
106
114
|
aria-label={`${props.t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}
|
|
107
115
|
onClick={() => { setOpen(!open) }}
|
|
108
116
|
>
|
|
117
|
+
{props.icon !== undefined ? <span className={css.mark} aria-hidden="true">{props.icon}</span> : null}
|
|
109
118
|
<span className={css.headText}>
|
|
110
119
|
<span className={css.name} title={title}>{title}</span>
|
|
111
120
|
<span className={css.description} title={description}>{props.descriptionNode ?? description}</span>
|