packages/dsh-web-all
zhu1090093659/dsh-webDSH Web UI 插件与皮肤合集:任务看板、git 图、右侧面板、远程移动端 UI、桌宠、实时 token 统计与皮肤中心。
侧边栏多列任务看板:卡片交给真实 DSH 智能体会话执行,支持 cron 定时(Host 侧到点执行,关浏览器也生效)。
English | 中文
Autonomous Kanban Task Board & Cron Scheduling for DeepSeek Harness (DSH) Host-Authoritative Ledger · Parent-Card Subtask Dispatch · Double-Blind Verification · Sleep Inhibition · GitHub Issue-to-PR
A hot-pluggable DeepSeek Harness (DSH) Web GUI and official desktop client task automation plugin with a Host-authoritative task ledger, real DSH agent session execution, cron background scheduling, cross-platform idle-sleep protection, parent-card subtask dispatch, and automated verification quality gates. It executes unattended background workflows including automated code reviews, routine health checks, and scheduled pipelines without requiring an open browser window. It mounts cleanly via cordis.patch.yml and profiles without modifying DSH core code.
task_board_get, dispatches them with subagent in dependency order, and writes their conclusions back with task_board_manage before it finishes. A card whose subtasks are still unfinished runs under the liangshen dispatcher preset.<<<FREEZE session context snapshots with handover packages; exposes 8 native model tools for autonomous planning and external execution registration.Cards keep multi-line title and description previews with visible metadata. Previews strip Markdown formatting; task details render description and prompt as safe Markdown without raw HTML or automatic remote images, and content taller than about eight rendered lines is clamped to a fixed height with a fade hint and a "Show more" toggle that expands and collapses it, while shorter content renders untouched with no toggle. Stored task text is unchanged. A bracketed title prefix such as [Bug]: renders as a type badge, and the description preview skips issue-form boilerplate (checkbox lists, section headings, empty-field placeholders), preferring a summary section when one exists. A left stripe shows the latest run (running, succeeded, failed, cancelled); a card whose column disagrees with that run is labelled as set by hand. Each column shows the time its cards differ by — created in Backlog/To Do, started while running, settled in Done/Failed — read in the Host time zone. The latest execution session opens straight from the card. Every column header toggles compact single-line cards (Done starts compact, the choice is stored in the browser); Done, Failed and the archive group cards into Today / Last 7 days / Earlier and fold the oldest group once a column holds more than 30 cards, unless a search is active.
ui-schedule page over the Host Schedule service) is hidden, so the sidebar offers one scheduling surface instead of two. The board's own master switch owns the state: switching the board off brings the official entry back, and the official page keeps working everywhere else it is still reachable — the entry is hidden, not uninstalled.>>FREEZE block from a session; it parses into a goal/progress/next snapshot persisted with the task (ledger v3). Cards carry a frozen badge, the detail view shows the full snapshot and freeze time, search covers snapshot text, and archive/restore matches plain tasks. The snapshot reuses the freeze security gate at the protocol layer: sensitive patterns become [REDACTED] with a marker, slash-prefixed command lines reject the whole snapshot, and each field is capped at 8 KiB.sessionDefaultPermission — is unconfirmed: manual run refuses, cron skips the card and rolls to the next occurrence, and the confirm button in the task detail resolves the binding; any later permission or bundle change re-arms the gate.标签提示 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. A Manage labels action on the filter row opens the label manager: every label in use with the number of tasks carrying it, a rename that rewrites the label on every card (merging into an existing label of that name and keeping that label's execution hint), and a delete that removes it from every task including archived ones. Both are ledger-wide Host transactions, so several windows looking at one board stay consistent.maxSubtaskDepth (1 by default, 3 maximum). Running a card opens one session for that card and none for its subtasks, and running a subtask directly is the same operation: that card is the root of the run even when it carries a parent and subtasks of its own, and nothing under it is expanded. A subtask already in the done column is outside the run's dispatch set, so finishing subtasks one by one and then running the parent costs one session instead of a repeat of the tree; move it back to the todo column to have it dispatched again. The board marks parent and subtask cards, the detail view lists the direct subtasks and says what one run will do, and the header offers a one-click hide-subtasks filter.liangshen dispatcher preset shipped by packages/dsh-liangshen, the card's stored agent preset is never rewritten, and session reuse is skipped so the run mints a fresh session; a deployment that registers no liangshen preset fails the run closed, with that missing preset as the reason on the card. The prompt names every unfinished subtask with its title, task id, and status, states that no session is opened for them, and asks the session to read each card with task_board_get, dispatch it with subagent in dependency order (independent ones may run together), and write each conclusion back with task_board_manage({action:'record-external-outcome'}) before it finishes. A conclusion the session never wrote back is supplied by the Host when the card's own run ends: every still-unrecorded unfinished subtask inherits that verdict as an external record whose initiator reads parent-run: and whose reason says the card ran no session of its own and inherited the parent run's conclusion. The backfill is idempotent, and a cancelled parent writes nothing. A card with no unfinished subtask is unaffected.$DSH_HOME/task-board/ledger-v2.json; browser actions become confirmed Host transactions./permission , then queues the task prompt./goal switch (below, off by default) is the master control; with it on, and only when a card opts in through its detail-view checkbox (the new-task dialog starts unchecked), 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 off, so a card that never touched it runs one plain turn) and is available to task_board_create/task_board_update too. The checkbox is always operable: the master switch decides whether the preference takes effect, never whether it can be stated, and it never rewrites the stored value.update_goal(action: complete) may take effect, because the board gates that call on the official tool pre-execute lifecycle instead of trusting the agent's own report. Acceptance runs the default final acceptance of the installed dsh-llm-verifier (MIT): the three coding criteria (Specification Adherence, Output Match, Error Signal Detection), a 0.65 threshold applied to the total AND to every criterion, two judge rounds per criterion with the A/B slots swapped and averaged, the task's real trajectory (tool calls, their output, assistant prose) judged against the empty-work baseline, the work must beat that baseline, and — when the deployment records workspace changes — the HOST's own record of what the run changed on disk (file list with added/deleted counts and bounded per-file comparisons) is attached as the prompt's reference context so a described-but-unapplied patch cannot pass. A veto is booked as a quality verdict only when it can be LOCATED: every criterion that makes the run fail must arrive with a structured finding naming the requirement it imposes, the observation that falls short, the difference, and a verbatim citation of the task, the work's own trajectory or the host's workspace record. A rejecting answer with no finding, a generic or empty finding, a citation that does not occur in the reviewed evidence, a citation of the empty-work baseline, and a criterion failed without its own evidence are recorded as an INVALID acceptance instead: they spend no quality budget, do not fail the card, and are bounded separately (two), after which the board stops calling the judge and holds the card for a human. A run whose only records are invalid ends for lack of a matching pass, but with its own terminal reason that states the acceptance was unusable and explicitly denies being an evidence-backed quality veto. A judge that could not see the output because the trace was truncated is treated the same way, because insufficient evidence is not a failure of the work. One execution may accept twice: the first failure returns the total, the per-criterion scores and the located findings to the fixing agent, the second failure ends that execution as failed. Once an execution PASSES and settles, the acceptance-only detail (its findings and structured citations) is removed automatically and only a lightweight audit credential remains — verdict, scores, time, judge route, evidence hash and a one-line problem summary. Nothing outside that execution's own acceptance record is touched, a failed or invalid execution keeps everything a repair or a review needs, the removal is idempotent, and a cleanup that fails is recorded and retried on the next Host start without ever revoking the pass. The budget lives on the execution record, so a repeated completion call, a new goal round, a plugin reload and a Host restart all reuse the same cycle, while a rerun or a scheduled occurrence is a new execution with its own budget. An anomaly (timeout, authentication failure, unparseable judge answer, unresolvable judge route) is recorded separately from a quality verdict and never consumes the quality budget. Exhausting the anomaly budget does NOT fail the card: a judge route that cannot answer is the environment failing, not the work, so the cycle is held open with no further judge call until a user clears the recorded anomalies through task_board_manage(action: reset-verification). An attempt that the acceptance time budget ends before any verdict is recorded as its own stage, spends no budget at all and also fails nothing. Both ceilings are settings (goalVerificationCallTimeoutSeconds, goalVerificationBudgetSeconds), read live, and a judge call is never opened when the time left cannot hold it. The running column shows executing / verifying / fixing, and each execution's row carries its verdict, judge model and level, count, scores with thresholds, findings, evidence scope and token usage. Forced acceptance also keeps the old fallback paths honest: a paused goal, an unreadable projection, a completed turn and a manual settle can no longer settle a goal execution as succeeded without a matching pass record. A failure carrying acceptance records means the judge answered and the work did not pass, while a failure with no acceptance record at all is reported as its own reason: the gate never opened because the session never called update_goal(action: complete) — often a session that narrated completion in prose — so nothing was ever judged and the delivery was never rejected. A single card can opt out of the gate: the new-task form and the task detail both carry a Skip acceptance checkbox (off by default, a card-level option like Continue in the same conversation and Start with /goal), and a checked card no longer intercepts its completion claim in goal form. The execution records applicability: skipped and the report says the CARD skipped acceptance, which is a different fact from the board-wide switch being off and is reported as such. It applies only to executions started afterwards, so flipping it mid-run never rewrites the rule judging a run already in flight.sessionPollSeconds setting, and a roster read that fails or stays unknown backs off on a doubling delay up to one minute, so a session tree that is down is not hammered at the poll interval.*, */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. A rule is either a recurring cron rule — optionally capped by a run limit (unlimited, 1, 2, or an