DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

@jayyuen66/dsh-dir-prep-organize

Dir Prep Organize

dsh plugin: “Polish” button in the conversation input (main button to polish directly / ▾ to polish in a role’s style, using the current directory + session model to polish drafts) + “Templates” dropdown (built-in curated role set generated from the plugin’s agents/ role library, groupable by depart

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:JayYuen666/dsh-dir-prep-organize#0845f52f5eb5bb0bd32e9d39c63e757d2d6fdbeb
READMECompatibilityVersions

Description

dsh plugin: “Polish” button in the conversation input (main button to polish directly / ▾ to polish in a role’s style, using the current directory + session model to polish drafts) + “Templates” dropdown (built-in curated role set generated from the plugin’s agents/ role library, groupable by department; the settings card supports adding, editing, and deleting roles, one-click import of all built-ins, and importing local role .md files)

Compatibility and provenance

Dir Prep Organize is published as @jayyuen66/dsh-dir-prep-organize and currently resolves to version 0.1.8. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
11/4/2026

Versions

0.1.8stable
10/31/2026
0.1.7stable
10/29/2026
0.1.6stable
10/24/2026
Show 7 more versionsCollapse versions
0.1.5stable
10/22/2026
0.1.4stable
10/19/2026
0.1.3stable
10/18/2026
0.1.2stable
10/12/2026
0.1.2-rcprerelease
10/11/2026
0.1.1stable
10/5/2026
0.1.0stable
10/1/2026

Related plugins

Loading related plugins…

Latest
0.1.8
DSH
*
HMR
Process restart
Tree shaking
Declares side effects by file
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
343
Last push
10/31/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseExperimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundleOptional bundle that adds Schedule, its task page, and time context to the Web compositionClient Ui Task Board@linxin666/dsh-client-ui-task-boardHost-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.Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / pet / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。

README

dsh-dir-prep-organize logo

dsh-dir-prep-organize

Two buttons beside the dsh chat input: rewrite the draft with the current directory in view, and insert a role template at the caret.

tech stack

A dsh plugin: a split "Polish" button that hands your draft, the top level of the session directory and the recent real turns to the model selected for that conversation (falling back to the host default) for a rewrite, plus a "Template" dropdown of role templates. Zero model tools, zero HTTP routes of its own.

View image Contents

  • What it does
  • Install
  • Verify it is live
  • What it does not provide
  • Enabling it in dsh
  • The polish call
  • Templates
  • Settings
  • Public interface
  • Data and privacy
  • Known boundaries
  • FAQ
  • Development
  • License

View image What it does

  • Adds two controls to the right of the web chat input: a split "Polish" button (main key + caret) and a "Template" dropdown.
    • The main key polishes directly; the caret key offers "polish in a role's style".
    • The dropdown groups entries by their group field; an entry with an empty group lands in "General".
  • Polish sends the draft, the top level of the session cwd (file names, sizes, and the full text of key text files), and the session's real user/assistant turns to the model selected for that conversation (falling back to the host default), then replaces the draft with the rewrite. The result is written back only while the session, draft revision and input phase are unchanged.
    • On failure the draft is never touched: the button shows an error state for 4 seconds with the reason in its tooltip.
  • Templates insert text at the caret through the input box's insert face: quoted blocks and attachments stay intact, and a stale insertion is refused instead of replacing the draft. Both controls are disabled while the input box is submitting.
  • The built-in set is 85 curated role templates, generated by scripts/gen-defaults.mjs from this package's agents/ role library - a vendored collection of several hundred role .md files across more than twenty department directories. The curated 85 is the number that matters to a user; the library size is not pinned here because it changes whenever the upstream project is refreshed.
    • That table stays host-side: the client bundle no longer inlines it. The generated file is ~640 KB and used to push client.js to ~711 KB.
    • The browser calls the Remote defaults method once, lazily (first menu open or first settings-card visit) and reuses it in-process. Nothing is fetched at all when the user already has their own templates.
    • While it has not arrived the menu shows a loading row - not the "no templates" hint. A failure surfaces the host's own reason plus a Retry button.
  • The settings card's "Role library" section covers per-entry add/edit/delete, a two-step restore of the defaults, one-click import of the whole built-in library, import of a local .md or directory by path, and registration of extra allowed import directories. That section is one list feeding two places: the input-box "Template" dropdown and the "Polish" ▾ role menu.
  • Templates and allowed directories are read and written through the host settings with zero LLM calls, and .

View image Install

dsh plugin --profile web add @jayyuen66/dsh-dir-prep-organize

Remove with dsh plugin --profile web remove @jayyuen66/dsh-dir-prep-organize. The package is on the public npm registry, so installation needs no credentials and no scoped-registry line.

  • Requires Node.js >= 22.12. This is an ESM-only package. Use the named exports (import { apply } from "@jayyuen66/dsh-dir-prep-organize"); there is no default export, so import pkg from … fails with does not provide an export named 'default'. That Node floor is what makes require() of an ESM entry work at all, which is why engines.node is declared.
  • Requires host dsh in the 0.2.1-rc.3 → 0.2.2-alpha.2 window. The requirement the host actually reads is engines.dsh (^0.2.1-rc.3), and it decides alone: evaluatePluginCompatibility returns on the engines.dsh branch before it ever looks at peerDependencies. Measured against the real host code: 0.2.0-rc.2 is refused, 0.2.1-rc.3 and 0.2.2 pass, 0.3.0 is refused. A refused host needs the explicit risk grant dsh plugin --profile <p> allow-version <pkg>@<ver> --dsh-version <exact> --accept-risk. The support window rolls: this package is verified against the three most recently released host versions at publish time and re-verified once the window moves, so the version number in this bullet is not a standing promise.
  • The @deepseek-ai/dsh-* development pins are at 0.2.2-alpha.2 - the host line this package is built and tested against. engines.dsh and the optional peer ranges carry the separately checked support window (^0.2.1-rc.3); the pin is a fact about which host version it was compiled against, not a restatement of that window. Mixing the two is why the publish gate checks them separately.
  • No @deepseek-ai/* under dependencies, by contract (test/publish-manifest.test.ts enforces it). Consumer profiles install with nodeLinker: hoisted and autoInstallPeers: false, so a host package under dependencies is materialized as a real directory next to the copy the running host already loaded. @deepseek-ai/dsh-tools keys its tool-runtime scheduler with a plain Symbol (not Symbol.for), so symbol identity is per module instance: the host reads the scheduler off the profile copy, gets undefined, and every native tool call throws - while this package's build, typecheck and coverage gates stay green right up to that moment.

View image Shared version floor

If your profile pins @jayyuen66/dsh-plugin-shared with a pnpm overrides entry, that pin must be at least the version this package declares. A lower pin installs a copy without the names imported at runtime, and the host then reports N entries did not activate together with does not provide an export named ... at boot - the package installs fine and never loads, and no per-repository CI run can see it.

View image Verify it is live

  1. Two controls appear to the right of the chat input. If they do not, the bundle layer is not mounted - check dsh --profile web --dump-config for the dir-prep-organize layer.
    • --dump-config is the only accepted "it is in the layer stack" signal, and it is not read-only - it rewrites that profile's root assembly file. Read layer lines from stdout and check stderr separately: an unmatched patch target appears only on stderr, so the exit code alone proves nothing.
    • A layer line may read # == <layer> or # == <layer>, patched by <path>; accept both forms.
  2. The dropdown fills: open "Template" and the built-in list arrives through the Remote defaults method. A loading row means the call is in flight; a failure shows the host's reason plus Retry.
  3. Polish works: press the main key. The draft is replaced on success; on failure it is untouched and the button turns into an error state whose tooltip carries the reason.
  4. The settings card renders: the "Role library" section appears on the settings page, edits stage locally and take effect after Save.

View image What it does not provide

Worth knowing before you look for them:

  • It registers no model tools. The host half only injects settings; it never touches the tool registry. There is no organize_text tool to call.
  • It opens no HTTP route of its own. The data plane is the official Typert Remote namespace dirPrepOrganize, registered through an injected child fiber, reached through the host /api gateway. Authentication, Host/DNS-rebinding/Origin checks, the signed browser-session cookie and body limits are all the gateway's - this package keeps no CSRF token and no route table.
  • It adds no CLI subcommand.
  • It reads no environment variable and makes no outbound request of its own.
  • What it does consume: the host settings service (hard-injected, so the entry does not activate without it), llm.stream, agentDefaultModel, and the session/agent/filesystem services. When the settings form itself is not ready, the card renders disabled with a status hint while the dropdown falls back to the built-in curated set.

View image Enabling it in dsh

  • Installing contributes the bundle patch layer (dsh.bundle.patch → ./cordis.patch.yml), which inserts - id: dir-prep-organize with name set to the package name.
  • The client half registers two slots plus the settings card:
    • conversation.input.right - the polish button (id dir-prep-organize, order 99) and the templates dropdown (id dir-prep-organize-templates, order 100).
    • plugins.bundle.config - the settings card, keyed by the bundle package name @jayyuen66/dsh-dir-prep-organize. The host dispatches entryKey: pkg.name (source of truth: dsh.profile.bundles in the profile's package.json), so a bare entry id never matches and the card would render nowhere.
    • The settings namespace and configForms.get() stay the bare entry id dir-prep-organize - deliberately not the same identifier as that slot key.
  • The client half is dsh.client.platform = web with immediately.
  • The card follows the official locale plugin's preference for its own labels and copy; the host half reads the preference per request, so switching language needs no restart.
  • The plugin page reads its title, description and detail document from locale/<lang>.json (meta.title, meta.description, meta.detail). docs/DETAIL.md and docs/DETAIL.zh.md ship in the tarball; without meta.detail the host falls back to the README.

View image The polish call

AspectFact
TransportHost llm.stream: one request-only user text message (no id, no source) plus a system rule block
ModelThe live agent's current selection first - agent.model.current() on current hosts, agent.options on older ones - then agentDefaultModel.currentSelection(). Its absence reports "No model selection is available"
Draft guardThe rewrite is written back only if the session id, input action face, draft revision and input phase (plain) are unchanged. Otherwise the call reports "The input box changed; the polished text was not applied" and leaves the draft alone
Role styleAn optional roleText injected into the user message's <data> fence (never into the system block - see the trust-order note above buildOrganizeSystem). It borrows terminology and tone only; it never executes the role's tasks
Finish reasonAnything other than stop - including a missing finish chunk - fails and never writes back to the draft
TimeoutorganizeTimeoutMs, default 120000 ms, read per request via .get(). The client fetch timeout is that value + 5000 ms
Input capsmaxSnippetBytes (262144 = 256 KiB) per key file, a 2 MiB total snippet budget, and readConcurrency (8) for reads. A file over the per-file cap, or a snippet past the total budget, is skipped whole and counted in skipped.tooLarge. Directory listings, conversation text and role bodies are never truncated
No truncation, on purposeDirectory listings, conversation text and role bodies go in whole: a model context-overflow error is the feedback, and the user slims the input. A payload above the endpoint body cap gets a 413 instead

View image Templates

AspectFact
Entry shape{ id, name, description, text, group, emoji }, all strings. description / group / emoji default to empty strings
Validation on saveEntries with an empty name or text are dropped; emoji is cut to 12 characters; a missing or colliding id is deterministically replaced by tpl-<index>
Built-in set85 curated templates generated from the agents/ role library. The dropdown falls back to them when templates is unset
InsertionUses the input box's version-checked insert face (captureInsertion() + insertText()). Text goes in at the caret, quoted blocks and attachments stay intact, and a stale insertion inserts nothing
"Unset" is an empty arrayUnder implicit registration schemastery casts a missing array field to [], so an empty list always means "fall back to built-in". Only a non-empty array whose items are all invalid renders as an empty list
Restore defaultsUnsets templates back to the curated set and leaves importAllowRoots untouched. Two-step confirm; the second click must come within 4 seconds
ImportBy path: a local .md file or a directory. path exactly empty imports the whole built-in library. A role file whose code fence never closes is rejected instead of silently importing half its body

View image Settings

Namespace dir-prep-organize equals the settings entry id. Fields projected into the settings form are the .volatile() ones.

FieldTypeDefaultCard controlNotes
templates{id,name,description,text,group,emoji}[]unsetyesThe user's own templates. Unset falls back to the 85 built-in entries
importAllowRootsstring[][]yesExtra allowed roots for the import endpoint. Non-strings and whitespace-only items are dropped; duplicates removed. With nothing registered, only the session cwd and the built-in role library are allowed
organizeTimeoutMsnatural, volatile120000noThe LLM abort deadline in ms. Values are truncated and clamped to [1, 2147483647]; non-finite values fall back to 120000. 0 passes the schema and clamps to 1 ms, so it really does mean an immediate timeout. Past 2^31-1 Node's setTimeout prints a TimeoutOverflowWarning and silently uses 1 ms, which turns "raise the timeout" into "fail instantly". The card has no control, so changing it means settings.yaml or the row's config:
maxSnippetBytesnatural, non-volatile262144noPer-file cap for key-file snippets; a larger file, or one whose size is unknown, is skipped whole and counted in skipped.tooLarge. Import candidates use the same cap. Non-volatile means no form projection, hence no card row - deployment value only
readConcurrencynatural, non-volatile8noBounded read concurrency for snippets and directory imports. Clamped to [1, 64]: 0 or a negative value made the bounded map recurse forever until the host was killed by the OOM killer, and a huge value defeats the fd ceiling this field exists to hold

Settings are persisted in settings.yaml under the dsh data directory.

View image Public interface

Official Typert Remote namespace dirPrepOrganize, registered through an injected child fiber. The descriptors are hand-written, parameters go through strict shape validation, results go through src-json.

MethodInputSuccess payload
defaults-ok / templates[…] (the curated set)
context{ sessionId }ok / cwd / truncated / skipped / entries[{name,isDir,sizeBytes,snippet}]
model{ sessionId }ok / provider / model / reasoningEffort
organize{ sessionId, prompt, entriesSummary, roleText? }ok / content
importTemplates{ path, sessionId } (path exactly empty = whole built-in library)ok / count / truncated / skipped / entries
  • Business failures stay ok:false with error. The import path-policy branches are the exception: an out-of-bounds path or a malformed path field also carries status 403 or 400.
  • model is the preflight read of the default selection; organize prefers the live agent's selection as described under "The polish call".
  • Result parsing on the client keeps defensive defaults: a non-object payload or a missing ok:true becomes a visible error, never an empty list.

View image Data and privacy

AspectFact
NetworkNo outbound requests of its own: the data plane is the host gateway's RPC channel. No environment variable is read
On diskThe only data written is templates and importAllowRoots, in the host settings file
What one polish call sendsThe full draft, the session cwd path, top-level directory entries with the full text of key text files, the real user/assistant turns (framework-injected messages and tool results are filtered out), and the optional role body
Which files get a snippetOnly 20 code/document extensions (ts/tsx/js/jsx/mjs/cjs/py/rs/go/java/rb/json/toml/md/sql/graphql/proto/css/scss/less). yaml / env are not whitelisted
Sensitive file namesAny file whose name matches credentials / secret(s) / id_rsa / pem / p12 / pfx / keystore / env / key(s) / token(s) / auth / passwd / password / account(s) at a separator boundary never gets a snippet. The boundary is deliberate: a naive substring match would drop monkey.js and AUTHORS.md, while a miss would send credential text to a third-party model
Caps and concurrencyA single file over maxSnippetBytes, or with unknown size, is skipped whole - never half-summarized. Collected snippets share a 2 MiB budget; once it is exhausted the rest are skipped whole and counted in skipped.tooLarge. Reads run with readConcurrency
CountersToo-large / unreadable / deeper-level / non-role cases are counted in skipped, shown in the UI, and reflected honestly by truncated
Import endpointRead-only: no model call, no disk writes. Absolute paths are refused by default; only paths inside the session cwd, the package's agents/ and importAllowRoots pass. . / .. / hidden segments (such as .ssh) are always rejected, and an out-of-bounds path answers 403 echoing the resolved path

View image Known boundaries

Registered honestly, one entry per class.

  • Nothing is truncated for you. Directory listings, conversation text and role bodies go in whole. Snippets are omitted whole rather than shortened: one over the per-file cap or past the 2 MiB total budget is counted and left out. A context overflow is the model's error to report and yours to slim - this plugin will not silently drop half your draft.
  • The import card has no session context. Its POST sends sessionId as an empty string, so an import must live inside the built-in agents/ or a registered root, and must contain no . / .. / hidden segments. The rejection names the allowed zones and echoes the resolved path.
  • Directory import reaches two levels. The top level plus one sub-directory level; a third level is only counted as deeper, never imported.
  • A file whose name cannot be parsed from the first 20 frontmatter lines counts as unnamed and is skipped rather than guessed.
  • Machine translation does not exist here. The agents/ role library and template bodies are user data; they are never translated, whichever interface language is active.
  • The polish path is best-effort about the model's answer. A non-stop finish reason fails the whole call; a model that returns prose instead of a rewrite replaces your draft with that prose, unless the draft or input phase changed meanwhile and the write-back is refused.

View image FAQ

SymptomWhat happens
Nothing changed after pressing "Polish"Failures never touch the draft; the button shows an error state for a few seconds with the reason in its tooltip. Usual causes: no session cwd (sessionId missing or session unknown), no model selection, a finish reason other than stop, the organizeTimeoutMs deadline, or the draft/selection changing while the request was in flight (the result is discarded)
The model reports a context overflowWorking as designed: input is deliberately not truncated, so the model error is the feedback. A payload above the endpoint body cap gets 413 instead
Importing local roles was refusedAbsolute paths are refused by default and the card has no session context. The path must live inside the built-in agents/ or a registered directory and contain no . / .. / hidden segments
Fewer entries imported than expectedRead the four skipped counters: deeper (third level, counted only), tooLarge (over maxSnippetBytes), unnamed (no name in the first 20 frontmatter lines), unreadable (read failure)
Template edits not applied / wrong languageEdits stage locally and take effect for newly opened dropdowns after Save. Labels and copy follow the official locale preference; role and template bodies are user data and are never machine translated

View image Development

pnpm install
pnpm run check        # typecheck → lint → client build → host build → types → tests → format
pnpm run gen:defaults # regenerate the curated set from agents/ (dev-time only)
  • test/gen-defaults.test.ts is a drift lock. It compares the generated file field by field against the role library, checks both mirror tables' key order, and requires byte-level identity with what the generator produces. Editing the parsing or extraction logic means editing scripts/gen-defaults-lib.mjs and re-running pnpm run gen:defaults; anything else shows up as a red test rather than a silently stale dropdown.
  • The generator exits non-zero when a curated slug is missing or fails to parse, so a role can never disappear silently.
  • The rest of the suite splits the classes of defect a stub cannot see: the host half, the client half, the Remote contract (test/dir-prep-remote.test.ts), the two build artifacts (test/build-host.test.ts, test/build-client.test.ts), and an integration layer.
  • Coverage thresholds are 100% across four metrics, so a new branch needs a case that reaches it.

View image License

MIT. Source at github.com/JayYuen666/dsh-dir-prep-organize. Issues go to that repository's tracker.

agents/ is vendored from agency-agents-zh (MIT); see THIRD_PARTY_NOTICES.md.

no model tool is registered
  • The two host packages host.js imports as values are required peers: @deepseek-ai/schemastery (the host's fork - only it resolves the .volatile() fields) and @deepseek-ai/dsh-brand. build-host.mjs externalizes dependencies and peerDependencies, so the bare specifiers stay in the artifact; a devDependencies-only entry would let the bundler inline the official function body. test/build-host.test.ts pins both "specifier present" and "function body absent".
  • Every host package the emitted declarations name is declared under peerDependencies, and each one reached only there is optional (@deepseek-ai/cordis, cosmokit, and the dsh-agent-default-model / client-ui / fs / llm / session family). Declaring them is not ceremony: under pnpm's strict layout a bare specifier in types/host.d.ts that no manifest table names is unresolvable on the consumer's side, while this repository's own typecheck stays green. The test reads that roster off types/**/*.d.ts rather than off this paragraph, so the two cannot drift apart.
  • What ships: host.js, client.js, templates.data.mjs, types/, cordis.patch.yml, agents/, locale/, docs/ and THIRD_PARTY_NOTICES.md. package.json, README* and LICENSE are attached unconditionally by the registry client.
  • The built-in table ships as its own artifact and is loaded on first use, not at plugin load. It used to be bundled into host.js, so every user paid for the templates in memory even without opening the dropdown.
  • agents/ is not authored here: it comes from agency-agents-zh (MIT). The copyright and licence notice ship in THIRD_PARTY_NOTICES.md, because MIT requires it in every distributed copy. Do not hand-edit files under agents/.