dsh-loopx-plugin
loopx-project/loopxLoopX——面向长周期 Agent 的提供商中立、本地优先状态内核与控制平面:在 DeepSeek Harness 执行层之上持久化 Goal、Todo、门禁、证据、配额、恢复与交接状态;插件负责引导安装 CLI 与技能、准入有界的同会话续跑,并为精确绑定的工作循环提供本地 GoalBar。
English | 简体中文
Native, local project task management for DeepSeek Harness. SQLite is the sole task authority. Harness Agent Sessions, Goals, Workspaces, tools, permissions, and the Web Client remain the execution and conversation owners.
This README is written so a human or another coding agent can install the plugin into a live Harness profile, verify it, and start using it without guessing.
Package: @shengsheng/dsh-taskboard Repository: https://github.com/shengsheng90/DSH-taskboard License: Apache-2.0 Host version policy: DSH runtime peers use * (no version gate). Installation/loading is tested against 0.1.6-alpha.1, 0.1.7-rc.1/rc.2, and 0.2.0-rc.1/rc.2. This verifies installation and module loading; GUI operations and model execution still need checking after a Host upgrade.
If you are an installing agent, jump to Install into DeepSeek Harness and follow every step in order. Git, npm, and release tarballs carry prebuilt Host/Client artifacts. Installation requires neither a TypeScript build nor a Harness source checkout.
After a successful install, Harness gains:
DSH-42 plus opaque ids and optimistic versionsbacklog → todo → in_progress → in_review → done, plus blocked and canceledtaskboard_* (no accept / no generic status mutation)dsh-taskboardmanage-taskboardAgents can submit verified work to in_review. Only an authenticated human UI or CLI operation can accept it as done.
Further design docs: Architecture, Security and recovery, CLI reference, Acceptance audit. Attribution shipped to package consumers is in THIRD_PARTY_NOTICES.md.
Requirement · Value Node.js · ^22.19.0 or >=24.0.0 (24 recommended; built-in node:sqlite) pnpm · Use 11.15.1 for repository development (packageManager); profile installation uses Harness's pnpm DeepSeek Harness · checkout or installation, web profile; no DSH version constraint Network · only needed to clone this repo and install Node dependencies Permissions · write access to $DSH_HOME (default ~/.dsh) and the ability to restart the Harness process
Confirm the toolchain before installing:
node -v # v22.19+ or v24+
pnpm -v # 11.xUse these constants. Read live values from disk; do not invent a different package name.
Name · Value Package name · @shengsheng/dsh-taskboard Default profile · web Default Web port · 3080 (detect; do not assume) Profile directory · $DSH_HOME/profiles/ , usually ~/.dsh/profiles/web Packed tarball name · shengsheng-dsh-taskboard-.tgz
is whatever this repo's package.json currently declares — read it there rather than copying a number out of this document. After pnpm pack`, use the tarball that was actually written.
A longer copy-paste prompt for a Harness-side agent is in docs/install-plugin-prompt.zh.md. The steps below are the normative English procedure.
Find the Web listener and its working directory:
PORT=3080
lsof -iTCP:"$PORT" -sTCP:LISTEN
# then, with the listener PID:
lsof -p <PID> -a -d cwdIf nothing is listening on 3080, search other common ports or ask the operator for the URL they use (http://127.0.0.1:).
Set PORT to the actual listener port and keep using that value below. Use the running Host's DSH_HOME and profile; the examples use profile web.
Decide how to invoke the dsh CLI:
pnpm-workspace.yaml and package.json contains a "dsh" script), run every later command from that checkout root as pnpm dsh ....command -v dsh succeeds, use dsh ... directly.In the commands below, dsh means whichever of those two forms you just chose. First use of a profile may initialize it and install @deepseek-ai/dsh-base.
Use npm, Git (which includes lib/), or a GitHub release .tgz:
dsh plugin --profile web add -w @shengsheng/dsh-taskboard
# Alternatively:
dsh plugin --profile web add -w git+https://github.com/shengsheng90/DSH-taskboard.gitFor the local tarball path in step 3, download a release .tgz and record its absolute path. Developers changing source run pnpm install --frozen-lockfile && pnpm build && pnpm pack:release. Consumer installation does not run a build. Release checks and CI validate completeness, source freshness, and compatibility. See distribution and compatibility strategy for the verification boundaries.
The profile directory is a pnpm workspace root (packages: [.]). The -w / workspace-root flag is mandatory. Without it, pnpm fails with ERR_PNPM_ADDING_TO_ROOT.
dsh plugin --profile web add -w /absolute/path/to/shengsheng-dsh-taskboard-<version>.tgzIf you already installed through npm or Git in step 2, skip this step and continue to composition verification. Rebuild and run pnpm verify:package before installing a source checkout with local changes.
This command may rewrite the profile package.json, lockfile, and node_modules. That is expected.
Install succeeded only when all of the following are true:
$DSH_HOME/profiles/web/package.json dependencies contains @shengsheng/dsh-taskboard.dsh.profile.bundles lists @shengsheng/dsh-taskboard after @deepseek-ai/dsh-base.$DSH_HOME/profiles/web/node_modules/@shengsheng/dsh-taskboard/ exists and contains lib/ plus cordis.patch.yml.If the CLI warns declares no dsh.bundle, the package is missing "dsh": { "bundle": { "patch": "./cordis.patch.yml" } } in package.json. This repository already declares that; rebuild and reinstall rather than editing the installed copy by hand.
dsh --profile web --dump-configPass when the dump ends with a # == @shengsheng/dsh-taskboard layer and the taskboard plugin config (databasePath, attachmentRoot, worker limits, and the other keys listed in Configuration).
--dump-config idempotently rewrites the profile-root cordis.yml. If a sandbox returns EPERM while writing ~/.dsh, ask the operator for full filesystem permission and retry. That rewrite is expected, not a failure.
(cd "${DSH_HOME:-$HOME/.dsh}/profiles/web" && node --input-type=module -e \
"import('@shengsheng/dsh-taskboard').then(m=>console.log('OK', m.name, typeof m.apply)).catch(e=>{console.error(e.message);process.exit(1)})")Pass: OK taskboard function.
Fail is usually a missing peer (@deepseek-ai/* or react). Those resolve through the install-fallback links under $DSH_HOME/profiles/node_modules (usually ~/.dsh/profiles/node_modules), which Harness heals on boot. Re-run step 4, then retry this import.
Plugin composition and client-module scanning happen only at boot. Installing into the profile does not hot-load the UI.
After upgrading or reinstalling the package, restart Harness in step 7 even if both checks below pass. The manifest contains the package name, not proof that the running Host loaded the new build.
curl -s "http://127.0.0.1:$PORT/" | grep -c '@shengsheng/dsh-taskboard'
curl -s -o /dev/null -w '%{http_code}\n' "http://127.0.0.1:$PORT/plugins/@shengsheng/dsh-taskboard/client.js"> 0 and bundle HTTP 200, with no package changes since boot → client artifacts are served; skip the restart and go to Confirm activation.Restart stops the process that hosts the current session. Session data lives in $DSH_HOME/sessions and is not deleted; in-flight Agent turns are interrupted. Tell the operator before restarting.
From a Harness source checkout, a typical restart is:
# stop the current listener
OLD_PID=$(lsof -tiTCP:"$PORT" -sTCP:LISTEN | head -1)
if [ -n "$OLD_PID" ]; then kill -TERM "$OLD_PID"; fi
# wait until the port is free, then start again from the checkout root
cd /absolute/path/to/deepseek-harness
nohup pnpm dsh --profile web >> /tmp/dsh-harness-restart.log 2>&1 &Do not treat the first successful GET / as “plugin ready”. The Web server can accept connections before the boot manifest injects the plugin. Poll until the package name appears:
for _ in $(seq 1 30); do
if curl -s "http://127.0.0.1:$PORT/" | grep -q '@shengsheng/dsh-taskboard'; then echo ready; break; fi
sleep 2
done
curl -s -o /dev/null -w '%{http_code}\n' "http://127.0.0.1:$PORT/plugins/@shengsheng/dsh-taskboard/client.js"A detached restart script used in a real install is documented in docs/install-plugin-prompt.zh.md (step 6). Prefer that script when the installing agent would be killed with the old Harness process group.
All of these must pass:
Check · Expected GET / contains @shengsheng/dsh-taskboard · count ≥ 1 GET /plugins/@shengsheng/dsh-taskboard/client.js · HTTP 200 Harness boot log · no plugin import / apply error Browser · refresh http://127.0.0.1:; a Taskboard control appears in the sidebar footer UI write · create a test project and task; refresh and confirm both persist
Loading the page alone does not verify the write channel. In browser developer tools, UI actions should POST to /taskboard/ and return a server-response with result.ok: true. The channel uses Harness authentication and Origin checks. A 401 / 403 requires checking the browser login and Host access configuration; 404 indicates a missing route or an incorrect proxy path. HTTP 200 with result.ok: false is an application error, not a successful write. Custom RPC callers must send a client-request envelope with a string rpcId, a method matching the endpoint, and a payload.
Default data files (created on first use; the Host resolves these paths):
.dsh/taskboard.sqlite
.dsh/taskboard-attachmentsThose defaults are relative, and a Host inherits its working directory from whatever started it, so they are never resolved against a raw process cwd. They bind to the nearest git project above the startup directory; configuration directories are not projects, so a versioned ~/.claude or ~/.config/... is skipped rather than written into. With no project behind the startup directory the store goes to $DSH_HOME (default ~/.dsh) instead of dropping a .dsh/ folder where nobody asked for one. An existing cwd-relative database is kept, so stores created before this rule are not abandoned, and a project-local store gets a .dsh/.gitignore so it stays out of git status. The Host logs the resolved absolute paths on startup, plus taskboard database created at when it initializes a new one. Absolute values, including absolute DSH_TASKBOARD_DATABASE / DSH_TASKBOARD_ATTACHMENTS, are used as given. See Configuration, and Upgrading from a cwd-relative store if you ran an earlier version.
Symptom · Cause · Fix dsh: command not found · CLI not on PATH · From a Harness checkout root, use pnpm dsh ... ERR_PNPM_ADDING_TO_ROOT · profile is a pnpm workspace root · Add -w Old Git ref / package lacks lib/ · Old distribution omitted artifacts · Use a new prebuilt version; maintainers run pnpm build && pnpm pack:release incompatible with dsh · Old package still declares a bounded DSH range · Upgrade to the package with DSH peers set to *; actual API failures still need adaptation EPERM writing ~/.dsh · sandbox · Ask the operator for full permissions; the write is idempotent Manifest / client.js still 404 · no restart, or checked too early · Restart, then poll (step 7) Page loads, but create/edit fails · RPC route, authentication, proxy, or request error · Check /taskboard/ requests and result.ok as in step 8; upgrade an older plugin and restart Import / apply error · missing peers or missing bundle entry · Heal fallbacks with --dump-config; confirm dsh.profile.bundles declares no dsh.bundle · package missing bundle patch · Rebuild this repo; do not hand-edit the installed tree GUI down after restart · Harness failed to boot · Read /tmp/dsh-harness-restart.log or the process log; confirm checkout path and pnpm dsh
Install only packages you trust. pnpm runs package lifecycle scripts, and Harness then loads the plugin.
DSH-1), optional Harness Workspace id. Leave Workspace blank for a global project.backlog unless you create it already as todo.backlog → todo. Agents and automation may claim only eligible todo items.done) or Return for rework.todo / in_progress tasks and opens a native Session with an unsent task draft. It also binds a fresh claim to that Session, moving todo to in_progress; an existing claim must be released before a new Session can be bound. Binding increments the task version, so reread the task before writing. Send the draft when ready to start the Agent.For both manually bound and automation Sessions, a bound Goal reaching complete submits the task to in_review; blocked moves it to blocked. Human acceptance is still required for done.
Human-only actions (UI or CLI, never model tools): approve, accept, return, archive, restore, cancel, reopen, force takeover, permanent delete.
human creates backlog
-> human approves to todo
-> Agent or automation claims (dependency recheck + exclusive claim + Session)
-> Agent works in the bound Workspace / branch / worktree
-> Agent verifies and submits in_review
-> human accepts done, or returns to todo / in_progressRules every caller must keep:
TASK_STALE_VERSION means reread and reconcile; do not retry the stale version.DSH-42. Use the id the API returned.in_review.todo releases the claim. Direct in_progress rework must create a fresh explicit claim.