@linxin666/dsh-client-ui-task-board 0.4.3 → 0.4.4
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 +17 -10
- package/README.zh.md +17 -10
- package/lib/client.js +1350 -552
- package/lib/client.js.map +1 -1
- package/lib/index.js +655 -134
- package/lib/types/client/board/TaskForm.d.ts +19 -1
- package/lib/types/client/board/preset-label.d.ts +22 -0
- package/lib/types/client/host-api.d.ts +24 -1
- package/lib/types/client/locales.d.ts +38 -2
- package/lib/types/client/schedule-zone.d.ts +47 -0
- package/lib/types/core/controller.d.ts +1 -0
- package/lib/types/core/degraded-reason.d.ts +46 -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 +26 -2
- 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-update.d.ts +1 -1
- package/lib/types/host-ledger.d.ts +56 -4
- package/lib/types/host-runner.d.ts +76 -3
- package/lib/types/host-service.d.ts +26 -0
- package/lib/types/protocol.d.ts +9 -3
- package/package.json +25 -25
- package/src/client/board/LinkSubtaskModal.tsx +21 -11
- package/src/client/board/NewTaskModal.tsx +271 -150
- package/src/client/board/TaskCard.tsx +24 -5
- package/src/client/board/TaskDetail.tsx +83 -33
- package/src/client/board/TaskForm.tsx +48 -3
- package/src/client/board/preset-label.ts +44 -0
- package/src/client/board.module.css +114 -5
- package/src/client/host-api.ts +109 -6
- package/src/client/index.ts +5 -1
- package/src/client/locales.ts +82 -8
- package/src/client/schedule-zone.ts +135 -0
- package/src/core/controller.ts +7 -2
- package/src/core/degraded-reason.ts +81 -0
- package/src/core/package-name.ts +9 -0
- package/src/core/schedule.ts +211 -55
- package/src/core/store.ts +10 -1
- package/src/core/subtask.ts +77 -22
- package/src/core/tasks.ts +38 -4
- package/src/core/use-cases/task-create.ts +14 -2
- package/src/core/use-cases/task-schedule.ts +17 -6
- package/src/core/use-cases/task-update.ts +4 -1
- package/src/host/agent-tools.ts +40 -8
- package/src/host-ledger.ts +203 -23
- package/src/host-runner.ts +164 -14
- package/src/host-service.ts +94 -17
- package/src/protocol.ts +27 -8
- package/lib/types/host/run-guarded.d.ts +0 -39
- package/src/host/run-guarded.ts +0 -76
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# node scripts/verify-docs.mjs --write <dir>
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: ca2285edbe96040109e64f4b1c6c69aea4aea191
|
|
6
|
+
README.zh.md: bd038165d02318a0d11c876f487db58786ed76ce
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A hot-pluggable DeepSeek Harness (DSH) Web GUI plugin with a Host-authoritative
|
|
|
6
6
|
|
|
7
7
|
- The browser is an asynchronous view; closing the page does not stop Host scheduling or execution settlement.
|
|
8
8
|
- Every run applies the pinned workspace, agent preset, and permission before sending the task prompt; by default each run creates its own DSH session, and a task can opt into continuing in its previous session instead (issue #1419).
|
|
9
|
+
- dsh's built-in `/goal` is armed for every run by default, so the session keeps working automatic continuation rounds until the goal completes and the board settles the execution on that goal's end; each task can turn the option off.
|
|
9
10
|
- The display may turn off while optional power protection keeps the computer from entering idle system sleep.
|
|
10
11
|
|
|
11
12
|
## Features
|
|
@@ -16,20 +17,22 @@ A hot-pluggable DeepSeek Harness (DSH) Web GUI plugin with a Host-authoritative
|
|
|
16
17
|
- **Claim provenance wrap and source audit**: executing a continuation card (a card with a frozen snapshot) mandatorily wraps the task instruction in a source-declaration template — freeze instant, source session, and an unreviewed-content warning — composed after the handover preamble so the picking-up agent stays wary of stored prompt injection in card text. The session issuing a create/update action is stamped into the snapshot (frozenBy, re-stamped when the snapshot is replaced), and the session issuing a run/rerun lands on the execution record (initiatedBy) together with a captured copy of the freeze provenance; both are visible in the task detail. The initiator is client-asserted audit metadata, not a trust boundary.
|
|
17
18
|
- **Task tags (issue #1521)**: a task may carry up to eight labels. A label renders as a colour-toned badge on the card — the tone is hashed from the name, so one label always paints the same way and no colour is stored — the board header gains a multi-select tag filter built from every label in use (including archived tasks), and search also matches label names. A label with an "execution hint" is injected ahead of the execution prompt on every run as a `标签提示` block; a label without one is display and filter only, so an untagged task's prompt is byte-for-byte what it was before the feature. Labels stay editable after the first run: they classify the task and shape the next run, they are not the record of what already ran.
|
|
18
19
|
- **Subtasks and cascade runs**: a task can be given subtasks, either by creating one from its detail view (the form starts from the parent's workspace, preset, permission, and model, and each stays overridable) or by linking an existing task that has no parent yet; a subtask can be detached again once it is not running. The lineage gate lives in the Host: the parent must exist and be on board, a task can never be attached under one of its own descendants, and a tree may not exceed the configured `maxSubtaskDepth` (1 by default, 3 maximum). Running a task also runs its whole subtask tree concurrently — one DSH session per member, all under one run group — and the parent card stays in the running column until its own turn and every subtask have settled; its verdict fails if any member failed, and one failing subtask never stops the others. The board marks parent and subtask cards, the detail view lists the direct subtasks, and the header offers a one-click hide-subtasks filter.
|
|
19
|
-
- **Agent Team runs (opt-in per task)**: a task may opt into team execution in its detail view (or through `task_board_create`/`task_board_update`). Running such a task starts ONE session — the Team Lead — and the Host then asks the Agent Teams service to spawn one teammate per subtask inside it, attaching each teammate's session to that subtask's execution
|
|
20
|
+
- **Agent Team runs (opt-in per task)**: a task may opt into team execution in its detail view (or through `task_board_create`/`task_board_update`). Running such a task starts ONE session — the Team Lead — and the Host then asks the Agent Teams service to spawn one teammate per subtask inside it, attaching each teammate's session to that subtask's execution. The subtree is flattened into that one Team (only a Lead may spawn); the Lead's prompt lists every teammate by name and points at the team tools, and the Lead's verdict governs the run: a teammate's own completed turn settles its card even while the Team keeps that session alive, and once the Lead's own outcome lands, every member still open is settled with it. A plain cascade prompts the same way but names the independent sessions instead. The mode needs the optional `agentTeams` service: a deployment without it refuses the run by name instead of silently degrading, and a subtask that pins its own above-default permission is refused because a teammate cannot carry that pin. Team runs always mint a fresh Lead session (teammate names are immutable within a Team) and use `teamProvider`. An execution whose session history cannot be read at all is reported failed with the reason after two minutes of polling, so an unreadable session can never leave a card in the running column.
|
|
20
21
|
- **Project partition (issue #1536)**: the board header offers a project row built from the deployment's DSH workspaces — "all projects" plus one entry per registered project. Selecting a project narrows the columns to the tasks pinned to it, and tasks with no pinned workspace stay visible under "all projects". Opening the new-task form while a project is open preselects that project as the task's workspace, and "new project…" registers a host directory through the same runtime call the GUI's own add-project uses.
|
|
21
22
|
- **AI parse of pasted text (issue #1540)**: the new-task form takes text copied from anywhere and has a model turn it into the title, description, and run prompt. The model is one of the deployment's configured models (the same list the task's model pin uses, first entry preselected), and the call runs on the Host behind the board's usual loopback and same-origin fence, with a 45 s budget and a cancel affordance. The draft only fills the form: nothing is created until the task is submitted, and a failed parse leaves what you already typed untouched.
|
|
23
|
+
- **Collapsible task form**: the create/duplicate/subtask dialog groups its configuration into collapsible regions — task content open by default, then labels, execution settings, run mode, handover, and scheduled runs — and every collapsed region keeps a one-line summary of the values it holds, so the dialog fits without a scrollbar (its body keeps an overflow fallback for very short windows). The agent-preset field is named "Agent preset" and lists the deployment's built-in presets under localized names plus any user preset, with an inherit default that names the preset a run without a pin actually uses.
|
|
22
24
|
- **Host-authoritative ledger**: tasks, schedules, and execution records live in `$DSH_HOME/task-board/ledger-v2.json`; browser actions become confirmed Host transactions.
|
|
23
25
|
- **Bounded execution history**: each task keeps the most recent 20 execution records; the oldest runs are trimmed when a new run starts, so ledger size and write cost stay bounded regardless of how often a task has run.
|
|
24
26
|
- **Real execution**: manual and scheduled runs use the same Host runner, which by default creates a fresh session, renames it, applies the agent preset and `/permission <id>`, then queues the task prompt.
|
|
27
|
+
- **Goal-driven runs (on by default)**: unless a card opts out through its detail-view checkbox (the new-task dialog starts checked), the runner queues the task prompt and then arms dsh's built-in `/goal` with that same composed prompt as the objective. dsh's goal-round driver keeps starting continuation rounds in the session until the agent marks the goal complete, and the board keeps the execution in `running` until the goal leaves its active phase: a completed goal settles the run as succeeded, a blocked one fails it with the goal's own reason. The option is per task (`goalRun`, absent means on) and is available to `task_board_create`/`task_board_update` too.
|
|
25
28
|
- **Optional session reuse**: a task can opt into continuing in its previous execution's session (issue #1419). Reuse happens only when that session is idle and still present in the runtime roster — the Host then re-applies the pinned permission and model on it and queues the prompt, keeping the conversation title and history; otherwise the run mints a fresh session as before, so an unknown roster or a busy session never blocks a scheduled run.
|
|
26
29
|
- **Fail-closed pins**: a missing workspace, missing or broken preset, or rejected permission command fails before the task prompt is sent.
|
|
27
|
-
- **Host scheduler**: 5-field cron supports `*`, `*/n`, ranges, comma lists, Sunday `0/7
|
|
30
|
+
- **Host scheduler**: 5-field cron supports `*`, `*/n`, ranges, comma lists, and Sunday `0/7`. Each rule carries its own IANA time zone (the Host's zone by default), and day-of-month/day-of-week follow Vixie semantics: both fields restricted means OR, any other combination means AND. Wall-clock gaps at a daylight-saving transition are skipped, and an ambiguous repeated time fires once, at the earlier instant.
|
|
28
31
|
- **Deterministic recovery**: a running execution with a recorded session is observed after restart; an interrupted start without a session id is cancelled and is not resent.
|
|
29
32
|
- **Live synchronization**: mutations return a full revisioned snapshot; SSE announces revision, scheduler, and power changes, while reconnect and page visibility recovery fetch a full snapshot.
|
|
30
33
|
- **Optional idle-sleep protection**: off by default; when enabled it covers every running DSH session, enabled non-archived task-board schedules, and unknown session state.
|
|
31
34
|
- **System-prompt injection**: the Host registers a `plugin:task-board` section (order 200) through `SystemPrompt.section`, and the task-board settings can disable the announcement without disabling the board. The guidance also reminds agents to close any visible `todo_write` plan before the final answer.
|
|
32
|
-
- **Agent tools**: every session gets eight model-facing tools (`task_board_list`, `task_board_get`, `task_board_create`, `task_board_update`, `task_board_set_parent`, `task_board_run`, `task_board_manage`, `task_board_schedule`) that drive the same Host ledger the browser drives, so an agent can list the board, create subtasks, link or detach them, run a cascade, move/archive/restore/delete a card, and arm its cron schedule from the conversation.
|
|
35
|
+
- **Agent tools**: every session gets eight model-facing tools (`task_board_list`, `task_board_get`, `task_board_create`, `task_board_update`, `task_board_set_parent`, `task_board_run`, `task_board_manage`, `task_board_schedule`) that drive the same Host ledger the browser drives, so an agent can list the board, create subtasks, link or detach them, run a cascade, move/archive/restore/delete a card, settle a card the board can no longer observe, and arm its cron schedule from the conversation.
|
|
33
36
|
|
|
34
37
|
## Architecture and protocol
|
|
35
38
|
|
|
@@ -53,8 +56,8 @@ The board is operable from a conversation, not only from the GUI. Each tool driv
|
|
|
53
56
|
- `task_board_update` edits content, labels, and execution targets; an empty string clears a target and an empty label array clears the labels.
|
|
54
57
|
- `task_board_set_parent` links an existing card under a parent, or detaches it with an empty parent id.
|
|
55
58
|
- `task_board_run` runs a card now (optionally re-running a settled one), cascading over its whole subtask tree; it consumes real API quota and refuses an unconfirmed above-default permission with `confirmation-required`.
|
|
56
|
-
- `task_board_manage` moves a card between backlog and todo, archives or restores it,
|
|
57
|
-
- `task_board_schedule` arms, changes, or disarms a card's cron schedule.
|
|
59
|
+
- `task_board_manage` moves a card between backlog and todo, archives or restores it, deletes it, or settles a running card the board can no longer observe (recording a cancelled verdict with the caller as the reason and returning the card to todo), with the Host's running-task and subtask guards.
|
|
60
|
+
- `task_board_schedule` arms, changes, or disarms a card's cron schedule, including its IANA time zone (an empty `timeZone` clears it back to the Host zone).
|
|
58
61
|
|
|
59
62
|
There is deliberately no tool that confirms a permission binding: that gate exists so a human lifts an above-default permission, and an agent able to stamp it would make the gate decorative. An agent that hits `confirmation-required` asks the user to confirm the card in the board UI. Tool calls are attributed: a run records the calling session as its initiator, and a create/update stamps it into a continuation card's snapshot.
|
|
60
63
|
|
|
@@ -100,6 +103,7 @@ On macOS the backend starts `/usr/bin/caffeinate -i -w <host-pid>` and never req
|
|
|
100
103
|
- On the first upgraded page load for an origin, `dsh.taskBoard.v1` is imported by stable source and request ids. Tasks merge by id, strictly newer browser top-level fields win, equal timestamps keep Host fields, and execution records merge by execution id.
|
|
101
104
|
- The most recent 256 request ids and SHA-256 action fingerprints are stored with the ledger, so a retried mutation remains idempotent after a Host restart without duplicating full action payloads.
|
|
102
105
|
- Task labels are an optional `tags` field on the task row (`{ name, promptPrefix? }[]`) and needed no schema bump: a v3 document without it loads unchanged, and a malformed list is repaired entry by entry (blanks, repeats, and over-long names dropped, count capped) rather than dropping the task row.
|
|
106
|
+
- The goal opt-in is an optional `goalRun` field on the task row and needed no schema bump either: absent means on, an explicit `false` is the opt-out, and a stray `true` is repaired back to absent on load.
|
|
103
107
|
- The import marker `dsh.taskBoard.v2.hostImported` stores the confirmed Host ledger generation only after import succeeds. A new or recovered ledger generation is offered the retained v1 data again. The v1 localStorage value remains untouched as a read-only rollback copy.
|
|
104
108
|
- One Host process owns a task-board ledger directory at a time through `$DSH_HOME/task-board/ledger-v2.lock`; a second Host using the same DSH home fails closed instead of concurrently writing the ledger.
|
|
105
109
|
|
|
@@ -132,11 +136,12 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
132
136
|
1. Mount the package, restart `dsh web`, open the task board, and confirm the Host time zone and power status are visible.
|
|
133
137
|
2. Create and edit a task; refresh or open a second same-origin tab and confirm both show the same Host revision.
|
|
134
138
|
3. Run a task with pinned workspace, preset, and permission; confirm a new session appears and the task settles from its `turn/end` history.
|
|
135
|
-
4.
|
|
136
|
-
5.
|
|
137
|
-
6.
|
|
138
|
-
7.
|
|
139
|
-
8.
|
|
139
|
+
4. Run a task with the /goal option checked: confirm the session starts a goal and the card stays in `running` across continuation rounds until the goal completes, then settles as succeeded. Uncheck the option and confirm the next run is a single turn that settles from one `turn/end`.
|
|
140
|
+
5. Enable a near-future cron, close all browser pages, and confirm the Host still creates and settles exactly one execution.
|
|
141
|
+
6. Stop the Host past a cron occurrence, restart it, and confirm the missed occurrence is skipped and `nextRunAt` rolls forward from current Host time.
|
|
142
|
+
7. Enable `preventIdleSleep`, run a long session, and let the display turn off; after restoring the display, confirm the session continued and the execution settled.
|
|
143
|
+
8. Disable the setting and all schedules, stop DSH, and confirm the helper exits; on macOS, `pmset -g assertions` should show no display-sleep assertion from this plugin.
|
|
144
|
+
9. On Linux, use `systemd-inhibit --list` to confirm that only an `idle`/`block` entry exists; the display should still follow desktop settings, while manual sleep and lid close remain under system policy.
|
|
140
145
|
|
|
141
146
|
## Known limitations
|
|
142
147
|
|
|
@@ -151,6 +156,8 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
151
156
|
- Host execution consumes the same API quota as an ordinary DSH agent session.
|
|
152
157
|
- Running a task also runs its subtask tree: one DSH session per member starts at once, so a deep tree opens several concurrent sessions and each consumes API quota.
|
|
153
158
|
- Agent tool calls are model-driven: a run or a scheduled cascade started from a conversation consumes the same API quota, and an agent can arm a schedule that keeps firing until it is disarmed or the board is switched off.
|
|
159
|
+
- A goal run keeps working for as many rounds as the objective needs: every round consumes API quota, and the session stays busy until the goal completes or dsh blocks it (round limit, a rejected round, or a failed queue), which the board reports as a failed execution.
|
|
160
|
+
- Goal mode needs the runtime's `/goal` command and a command dispatcher. A deployment that serves neither still runs every card as a single turn; the host log reports that the goal was unavailable instead of failing the run.
|
|
154
161
|
|
|
155
162
|
## Telemetry
|
|
156
163
|
|
package/README.zh.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
- 浏览器只是异步视图;关闭页面不会停止 Host 调度或执行结算。
|
|
8
8
|
- 每次运行在发送任务 Prompt 前应用钉住的工作区、agent 预设与权限;默认每次新建独立 DSH 会话,任务也可选择改为在上一会话中继续(issue #1419)。
|
|
9
|
+
- 默认每次运行都会武装 dsh 内置的 `/goal`:会话自动续跑多轮直到目标完成,看板在该目标真正结束后才结算本次执行;每个任务都可以关闭该选项。
|
|
9
10
|
- 可选电源保护允许显示器熄灭,同时阻止整机因空闲进入系统睡眠。
|
|
10
11
|
|
|
11
12
|
## 功能
|
|
@@ -16,20 +17,22 @@
|
|
|
16
17
|
- **领卡来源声明包裹与来源审计**:执行续接卡片(带冻结快照的卡片)时,任务指令被来源声明模板强制包裹——冻结时间、来源会话与未经人工审查提示,组合在交接前言之后,使接手 Agent 对卡片文本中的存储型提示注入保持警惕。create/update 动作的发起方会话织入快照(frozenBy,快照被替换时重新盖章),run/rerun 的发起方会话连同冻结来源的捕获副本一起落在执行记录(initiatedBy)上,两者均可在任务详情查看。发起方为客户端断言的审计元数据,不构成信任边界。
|
|
17
18
|
- **任务标签(issue #1521)**:每个任务可带最多八个标签。标签在卡片上渲染为带色调的徽章——色调由标签名哈希得到,因此同一标签永远同色,也不需要存储颜色;看板顶栏据此提供多选标签筛选,候选项来自全账本在用的标签(含已归档任务),搜索也会匹配标签名。填了「执行提示」的标签会在每次执行前以 `标签提示` 段注入到执行 Prompt 之前;没填的标签只作展示与筛选,因此无标签任务的 Prompt 与加入该功能前逐字节一致。标签在首次执行后仍可编辑:它们给任务分类、塑造下一次运行,而不是「已经跑过什么」的凭证。
|
|
18
19
|
- **子任务与级联执行**:任务可以有子任务——在详情页新建子任务(表单以父任务的工作区、模式、权限和模型为起点,每一项都可覆盖),或把一个还没有父任务的现有任务关联为子任务;子任务不在运行中时也可以解除关联。父子关系的准入由 Host 判定:父任务必须存在且在看板上、任务不能挂到自己的后代之下、树的深度不得超过配置的 `maxSubtaskDepth`(默认 1 层,最大 3 层)。执行一个任务会并发执行它整棵子任务树——每个成员各开一个 DSH 会话,同属一个 run group——父任务卡片会一直留在「进行中」列,直到它自己的回合与全部子任务都结算;任一成员失败则父任务判为失败,而单个子任务失败不会阻塞其它子任务。看板会标注父任务与子任务卡片,详情页列出直接子任务,顶栏提供一键隐藏子任务。
|
|
19
|
-
- **Agent Team 执行(任务级 opt-in)**:任务可在详情页(或经 `task_board_create`/`task_board_update`)开启团队执行。执行这样的任务只启动一个会话——Team Lead——随后 Host 通过 Agent Teams 服务在它内部为每个子任务派生一个 teammate,并把 teammate 的会话挂到该子任务的 execution
|
|
20
|
+
- **Agent Team 执行(任务级 opt-in)**:任务可在详情页(或经 `task_board_create`/`task_board_update`)开启团队执行。执行这样的任务只启动一个会话——Team Lead——随后 Host 通过 Agent Teams 服务在它内部为每个子任务派生一个 teammate,并把 teammate 的会话挂到该子任务的 execution 上。整棵子树被压平成这一个 Team(只有 Lead 可以派生);Lead 的提示词按名字列出每个 teammate 并指向团队工具,团队执行由 Lead 判定统辖:teammate 自己已完成的回合即结算它的卡片(即使 Team 仍让该会话存活),Lead 自身结果落定后,仍未报结果的成员一并按该判定结算。普通级联的提示词结构相同,只是改为列出各独立会话。该模式依赖可选的 `agentTeams` 服务:未提供该服务的部署会明确拒绝执行而不是静默降级;子任务自己钉住的高于默认的权限也会被拒绝,因为 teammate 无法承载该钉住值。团队执行总是新建 Lead 会话(同一 Team 内 teammate 名字不可变),并使用 `teamProvider`。会话历史完全读不到的 execution 会在轮询满两分钟后带原因判为失败,因此读不到历史的会话不会把卡片永久留在运行列。
|
|
20
21
|
- **项目分区(issue #1536)**:看板头部新增项目下拉,选项来自当前部署的 DSH 工作区——「全部项目」加每个已注册项目。选定项目后各列只显示钉在该项目上的任务,未钉工作区的任务只在「全部项目」下可见;在某个项目下打开「新建任务」会把该项目预选为任务工作区,「新建项目…」则用与 GUI「添加项目」相同的运行时接口把宿主目录注册为项目。
|
|
21
22
|
- **粘贴文本 AI 解析(issue #1540)**:新建任务表单可以把从别处复制的一段话交给模型,整理成标题、描述和执行 Prompt。模型取当前部署已配置的模型(与任务「模型」下拉同一份列表,默认选中第一项),调用在宿主侧完成,走看板既有的回环与同源校验,预算 45 秒并支持取消。解析结果只填进表单:不提交就不会创建任务,解析失败也不会改动你已经输入的内容。
|
|
23
|
+
- **可折叠的任务表单**:新建/复制/子任务对话框把配置分成可折叠区域——任务内容默认展开,其后依次是标签、执行设置、运行方式、交接与续跑、定时运行——每个折叠区域都保留一行当前值摘要,因此对话框不需要滚动条(正文仍保留极矮窗口下的溢出兜底)。Agent 预设字段更名为「Agent 预设」,把部署内置预设以本地化名称列出,并附上任何用户预设;默认的「继承」选项会写明未钉住时真正使用的预设。
|
|
22
24
|
- **Host 权威账本**:任务、计划和执行记录存于 `$DSH_HOME/task-board/ledger-v2.json`;浏览器动作只有经 Host 确认后才成为 UI 状态。
|
|
23
25
|
- **有界执行历史**:每个任务只保留最近 20 条执行记录;新运行开始时截掉最旧的记录,使账本大小与每次写入成本不随任务历史无限增长。
|
|
24
26
|
- **真实执行**:手动运行和定时运行共用 Host runner,默认新建独立会话、重命名、应用 agent 预设和 `/permission <id>`,再以 queue 模式发送任务 Prompt。
|
|
27
|
+
- **目标驱动执行(默认开启)**:除非卡片在详情页取消勾选(新建任务对话框默认勾选),runner 会先入队任务 Prompt,再以同一份组合 Prompt 作为目标武装 dsh 内置的 `/goal`。dsh 的目标轮次驱动器会在同一会话中不断开启续跑轮次,直到 agent 标记目标完成;看板则让该执行一直保持 `running`,直到目标离开 active 阶段:目标正常完成判为成功,被阻塞则以目标自身的原因判为失败。该选项按任务设置(`goalRun`,缺席即开启),`task_board_create`/`task_board_update` 同样可用。
|
|
25
28
|
- **可选会话复用**:任务可选择在上一执行会话中继续(issue #1419)。仅当该会话空闲且仍在运行时会话名册中才复用——Host 会重新应用钉住的权限与模型再以 queue 模式发送 Prompt,会话标题与历史保持不变;否则照旧新建会话,因此名册未知或会话正忙都不会阻塞定时运行。
|
|
26
29
|
- **钉子失败即关闭**:工作区缺失、预设缺失或损坏、权限命令被拒绝时,任务 Prompt 不会发送。
|
|
27
|
-
- **Host 调度器**:5 段 cron 支持 `*`、`*/n
|
|
30
|
+
- **Host 调度器**:5 段 cron 支持 `*`、`*/n`、范围、逗号列表和周日 `0/7`。每条规则携带自己的 IANA 时区(默认跟随 Host 时区),日期/星期遵循 Vixie 语义:两个字段都受限时为 OR,其余组合为 AND。夏令时切换处的墙上时间空洞会被跳过,重复出现的歧义时刻只触发一次并取更早者。
|
|
28
31
|
- **确定性恢复**:已有 session id 的 running execution 在重启后继续观察;没有 session id 的启动中断会取消且不会重发。
|
|
29
32
|
- **实时同步**:变更返回完整 revision snapshot;SSE 只提示 revision、scheduler 与 power 变化,重连和页面恢复可见时重新拉完整 snapshot。
|
|
30
33
|
- **可选空闲睡眠保护**:默认关闭;开启后覆盖全部运行中的 DSH 会话、已启用且未归档的任务计划和未知会话状态。
|
|
31
34
|
- **系统提示词注入**:Host 通过 `SystemPrompt.section` 注册 order 200 的 `plugin:task-board` 段;任务看板设置可单独关闭声明而不关闭看板。该提示也会提醒 agent 在最终回复前收尾可见的 `todo_write` 计划列表。
|
|
32
|
-
- **Agent 工具**:每个会话都可使用八个面向模型的工具(`task_board_list`、`task_board_get`、`task_board_create`、`task_board_update`、`task_board_set_parent`、`task_board_run`、`task_board_manage`、`task_board_schedule`),它们驱动与浏览器完全相同的 Host 账本,因此 agent
|
|
35
|
+
- **Agent 工具**:每个会话都可使用八个面向模型的工具(`task_board_list`、`task_board_get`、`task_board_create`、`task_board_update`、`task_board_set_parent`、`task_board_run`、`task_board_manage`、`task_board_schedule`),它们驱动与浏览器完全相同的 Host 账本,因此 agent 可以在对话里列出看板、创建子任务、关联或解除关联、执行级联、移动/归档/恢复/删除卡片、对看板已无法观察的卡片强制结算,以及为卡片配置 cron 计划。
|
|
33
36
|
|
|
34
37
|
## 架构与协议
|
|
35
38
|
|
|
@@ -53,8 +56,8 @@
|
|
|
53
56
|
- `task_board_update`:修改内容、标签与执行目标;空字符串清除某个目标,空标签数组清除全部标签。
|
|
54
57
|
- `task_board_set_parent`:把现有卡片挂到某个父任务下,或用空 parentId 解除关联。
|
|
55
58
|
- `task_board_run`:立即执行一张卡片(可选择重跑已结算的卡片),并级联执行它整棵子任务树;会消耗真实 API 额度,且未确认的高于默认权限的绑定会以 `confirmation-required` 被拒绝。
|
|
56
|
-
- `task_board_manage
|
|
57
|
-
- `task_board_schedule`:启用、修改或关闭卡片的 cron
|
|
59
|
+
- `task_board_manage`:在待办与待规划之间移动卡片、归档或恢复、删除,或对看板已无法观察的运行中卡片强制结算(记为 cancelled 并记录调用者原因,卡片回到待办),同样受 Host 的运行中子任务与父子关系护栏约束。
|
|
60
|
+
- `task_board_schedule`:启用、修改或关闭卡片的 cron 计划,包括其 IANA 时区(`timeZone` 传空字符串即清除,回退到 Host 时区)。
|
|
58
61
|
|
|
59
62
|
这里刻意没有「确认权限」工具:该门禁存在的意义就是由人工放行高于默认值的权限,若 agent 能自行盖章,这道门就形同虚设。遇到 `confirmation-required` 的 agent 应当请用户在界面确认该卡片。工具调用带归属:执行会把发起会话记为 initiator,创建/更新则会把发起会话写进续接卡片快照。
|
|
60
63
|
|
|
@@ -100,6 +103,7 @@ macOS 后端启动 `/usr/bin/caffeinate -i -w <host-pid>`,绝不请求 `-d`。
|
|
|
100
103
|
- 每个 origin 首次加载新版页面时,按稳定 source id 和 request id 导入 `dsh.taskBoard.v1`。任务按 id 合并,浏览器端严格较新的顶层字段优先,时间戳相同时保留 Host 字段,执行记录按 execution id 合并。
|
|
101
104
|
- 最近 256 个 request id 与动作的 SHA-256 指纹会随账本持久化,因此 Host 重启后的变更重试仍保持幂等,且不会复制完整动作载荷。
|
|
102
105
|
- 任务标签是任务行上的可选 `tags` 字段(`{ name, promptPrefix? }[]`),无需 bump schema:不含该字段的 v3 文档原样加载,非法的标签列表逐条修复(丢弃空名、重复项与超长名,并封顶数量),而不是丢掉整行任务。
|
|
106
|
+
- /goal 选项是任务行上的可选 `goalRun` 字段,同样无需 bump schema:缺席即开启,显式 `false` 是退出选择,多写的 `true` 在加载时被修复回缺席。
|
|
103
107
|
- 只有导入成功并经 Host 确认后,`dsh.taskBoard.v2.hostImported` 才保存当前 Host 账本 generation;新建或损坏恢复出的新 generation 会再次接收保留的 v1 数据。v1 localStorage 原值保持不变,作为只读回退备份。
|
|
104
108
|
- 同一时间只有一个 Host 进程能通过 `$DSH_HOME/task-board/ledger-v2.lock` 持有任务看板账本目录;第二个使用同一 DSH home 的 Host 会失败关闭,不并发写账本。
|
|
105
109
|
|
|
@@ -132,11 +136,12 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
132
136
|
1. 挂载插件并重启 `dsh web`,打开任务看板,确认 Host 时区和电源状态可见。
|
|
133
137
|
2. 新建并编辑任务;刷新或打开第二个同源标签页,确认两者显示同一 Host revision。
|
|
134
138
|
3. 执行一个钉住工作区、预设和权限的任务;确认出现新会话,并由该会话的 `turn/end` 历史结算任务。
|
|
135
|
-
4.
|
|
136
|
-
5.
|
|
137
|
-
6.
|
|
138
|
-
7.
|
|
139
|
-
8.
|
|
139
|
+
4. 在勾选 /goal 选项的情况下执行一个任务:确认会话启动了目标,卡片在多轮续跑期间保持 `running`,直到目标完成后结算为成功。取消勾选后再执行一次,确认变回单回合、由一条 `turn/end` 结算。
|
|
140
|
+
5. 启用一个即将到期的 cron,关闭全部浏览器页面,确认 Host 仍只创建并结算一次 execution。
|
|
141
|
+
6. 让 Host 停止并错过一个 cron 触发点,重启后确认该次被跳过,`nextRunAt` 从当前 Host 时间向后滚动。
|
|
142
|
+
7. 开启 `preventIdleSleep` 并运行长任务,让显示器自动熄灭;恢复显示后确认会话继续且 execution 已结算。
|
|
143
|
+
8. 关闭设置并禁用所有计划,再停止 DSH,确认 helper 退出;macOS 可用 `pmset -g assertions` 辅助确认插件没有 display-sleep assertion。
|
|
144
|
+
9. Linux 可用 `systemd-inhibit --list` 确认只存在 `idle`/`block` 条目;显示器仍按桌面设置关闭,手动睡眠和合盖仍由系统策略处理。
|
|
140
145
|
|
|
141
146
|
## 已知限制
|
|
142
147
|
|
|
@@ -151,6 +156,8 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
151
156
|
- Host 执行消耗与普通 DSH agent 会话相同的 API 额度。
|
|
152
157
|
- 执行一个任务会同时执行它的子任务树:每个成员都会立刻开启一个 DSH 会话,树越深并发会话越多,每个会话都会消耗 API 额度。
|
|
153
158
|
- Agent 工具调用由模型驱动:从对话发起的执行或定时级联同样消耗 API 额度,且 agent 可以启用一个持续触发的计划,直到被关闭或看板被关掉。
|
|
159
|
+
- 目标执行会按目标需要不断续跑:每一轮都消耗 API 额度,会话会一直忙碌,直到目标完成或被 dsh 阻塞(轮次上限、回合被拒或入队失败),后者在看板上记为执行失败。
|
|
160
|
+
- 目标模式依赖运行时的 `/goal` 命令与命令派发器。两者都不提供的部署仍会把每张卡片当单回合执行,并在宿主日志中记录目标模式不可用,而不是让执行失败。
|
|
154
161
|
|
|
155
162
|
## 数据遥测
|
|
156
163
|
|