dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Structured form questions for the DeepSeek Harness agent: 14 typed field types, conditions, validation, targeted re-asks, and typed JSON answers.
A community plugin for DeepSeek Harness that lets the model ask structured questions as one form — typed fields, conditions, validation and targeted re-asks — and receive typed JSON answers.
The built-in ask_user_question tool is a flat option list shown one question per page. ask_form adds field types, cross-field constraints and a single submission, and it degrades to the built-in flow on any surface that cannot render it.
English | 中文
confirm, single, multi, text, longtext, number, integer, date, tags, scale, slider, ranking, matrix, budgetvisible_if, validate (a whitelisted expression language, never eval), pattern, max_length, min/max, sum_tomax_roundsscale/slider/number → number, ranking → ordered array, matrix → {row: choice}, budget → {option: number}, tags → string arrayrequirement-intake, design-choice, release-gate, incident-intake, tunable through pack_argssingle, multi and tags (allow_other: false closes the list)mode: "script" renders a custom React element in the Web UI; declare script.fallback for other surfacesrenderer: "generic". Script mode fails loud instead of degrading silently.Prerequisites: a Harness profile with the plugin_manager tool (the web profile has it).
Install the bundle — ask the agent in the Harness, or run the plugin_manager tool with:
action: install_bundle
target: github:Zekilou/dsh-ask-form
From a local clone, pass its absolute path instead: /absolute/path/to/dsh-ask-form.
Reload the Harness Web page once, so the client bundle registers (client.js owns the form surface).
The ask_form tool is now available next to ask_user_question.
A form is one tool call. Fields are ordered; the first option of a list is the recommended one by convention.
{
"title": "Runtime decision",
"intro": "Pick the runtime and weight the criteria.",
"fields": [
{ "name": "runtime", "type": "single", "label": "Runtime",
"options": ["Node 22 (Recommended)", "Bun", "Deno"] },
{ "name": "needs_wasm", "type": "confirm", "label": "Do you need WASM?",
"visible_if": "runtime == 'Bun'" },
{ "name": "weights", "type": "budget", "label": "Criteria weights (sum 100)",
"options": ["Performance", "Ecosystem", "Footprint"], "sum_to": 100 },
{ "name": "priority", "type": "ranking", "label": "Priority order",
"options": ["Ship fast", "Stay small", "Be portable"] },
{ "name": "scores", "type": "matrix", "label": "Score each dimension",
"rows": ["Performance", "Cost"], "options": ["High", "Medium", "Low"] }
],
"notes": true
}
A ready-made interview:
{ "pack": "requirement-intake", "pack_args": { "topic": "cache layer" }, "notes": true }
The result carries typed values plus provenance:
{ "status": "answered", "rounds": 1, "renderer": "form",
"values": { "runtime": "Bun", "needs_wasm": true,
"weights": { "Performance": 50, "Ecosystem": 30, "Footprint": 20 },
"priority": ["Be portable", "Ship fast", "Stay small"],
"scores": { "Performance": "High", "Cost": "Low" } },
"notes": "…" }
status is one of answered, incomplete, cancelled, aborted, no_answerer, unavailable, script_error.
The bundle has two halves and no build step.
Host half (index.js) registers the ask_form tool over the existing ctx.userQuestions seam. It compiles the typed form into ordinary AskUserQuestionItem[] — so any answerer can still answer it — and carries the rich spec to its own renderer through the marker item's intent. Afterwards it decodes either the renderer's JSON envelope or plain option/label answers, validates on the Host, and re-asks only the failures.
Client half (client.js) registers one low-priority entry in the conversation.composer chain. It claims a pending request only when a question carries this plugin's intent.kind, renders the whole form as a centered floating layer (react-dom portal, native modal geometry), and answers with the JSON envelope. Every other pending request — including plan reviews — returns null and stays with the shipped composer, so installing this bundle cannot change the built-in flow.
Notable behaviours:
undefined property makes the Remote event gateway reject the whole request.DSH_ASK_FORM_PROBE is answered automatically with a DOM report (card rect, computed styles, elementFromPoint hit tests). It is how this plugin was debugged without browser automation, and it stays useful for diagnosing a broken surface.Two standalone suites, no monorepo install and no browser needed:
node tests/host.test.mjs # compile -> decode -> validate -> rounds -> cancellation
node tests/client.test.mjs # render tree, marker selector, submit envelope
They stub React (the page provides the real one) and drive the real component tree, so they assert structure and protocol, not pixels. tests/client.test.mjs reads the bundle id from package.json, so a rename cannot desynchronise them.
ctx.tools and ctx.userQuestions.conversation.composer chain and react-dom as a shell seed word (both present in the Web app).@deepseek-ai/dsh-* packages of the 0.2.0-rc.2 era; those APIs may move.The client-side styles are adapted from MIT-licensed Harness client packages, with class names renamed under this plugin's prefix:
@deepseek-ai/dsh-client-ui-primitives — Button, Input, Tag, SegmentedControl, Modal geometry@deepseek-ai/dsh-client-ui-user-questions — the question card structure, option rows, recommendation badgeMIT — see LICENSE.