DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

oday0311 /

oday0311/open-dsh-market

Verified

a dsh-plugins-market

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@a580088e

CCTor Marketplace · DeepSeek Harness Bundle

English | 简体中文

cctor-dsh-marketplace is an installable DeepSeek Harness (DSH) bundle. It uses https://api.cctor.com as its dynamic catalog and ships both a native marketplace UI and model-facing Agent tools. The UI and tools share one Host service, one persistent cache, one installed-state reader, and one installation coordinator.

The current version is 0.1.0. v1 covers discovery, details, installed-state display, and installation that always requires an explicit user confirmation. It does not update, disable, or remove plugins, and it does not install into another profile.

What it provides

  • Master-detail workspace: a searchable result list on the left and the selected plugin's details on the right. On narrow screens the detail becomes a separate second screen with a Back control.
  • Search and filters: 300 ms search debounce with cancellation of superseded requests. Non-empty queries shorter than three characters are not sent (the API intentionally returns an empty page for them). Category, sort, refresh, pagination, and cache reset are supported.
  • Installed state: entries installed in the current profile show their local version and do not expose the normal Install action.
  • Bilingual UI: Chinese or English, following the active DSH locale. Dates, counts, empty states, errors, and install progress are localized. Plugin names, descriptions, README content, tags, and repository metadata are preserved as supplied by the API.
  • Three Agent tools over the same Host normalization and cache:
Tool Purpose Key constraints
cctor_search_plugins Search the catalog and return plugin summaries, pagination, and cache freshness Default 10 results, at most 20 per call; returns an opaque next_cursor; never returns README or install_command; never installs
cctor_get_plugin_details Read public details, verification state, and current-profile installed state by stable ID or exact slug Slug resolution must be unique; no match returns not_found, multiple matches return ambiguous_plugin; a stable ID goes directly to the detail endpoint
cctor_request_plugin_install Prepare a single-use installation confirmation for the current profile Returns only awaiting_confirmation, confirmation ID, expiry, target profile, route, and safe spec; the tool cannot approve or execute its own request

Tool outputs have per-field caps and a 64 KiB total budget. Cache internals, stacks, paths, and request headers never enter model context.

Architecture

Agent tools ─┐
             ├─ CctorMarketplaceService ── CCTor API (list / meta / detail)
Web Client ──┘        │
(via same-origin API) ├─ Storage Domain (plugin-owned persistent cache)
                      └─ Plugin Manager (installs only into the current profile)
  • The Host owns HTTP requests and response validation, caching, catalog normalization, profile inspection, confirmation state, and installation.
  • The Web Client is presentation only. It never calls CCTor directly and cannot execute an installation. It calls the Host through the same-origin /api/cctor-marketplace/rpc route registered with connection; Agent tools and the retained Typert Remote share the same Host service.
  • The bundle declares the official storageDomain, pluginManager, profileContext, typert, and tools services as required injections. If the runtime module cannot be imported or Host composition fails, the guarded entry logs one bounded compatibility diagnostic and stays inert rather than breaking the whole plugin tree.

Installation

Requirements: Node.js >= 22; DSH >= 0.2.1-rc.5 < 0.3.0 (see engines in package.json; peer dependencies are supplied by the DSH runtime).

Install from npm

dsh plugin --profile <name> add cctor-dsh-marketplace

Replace <name> with the target profile, then restart DSH when prompted.

Verify the installation

dsh plugin --profile <name> list cctor-dsh-marketplace --depth 0

The output should list cctor-dsh-marketplace and its installed version.

Upgrade

dsh plugin --profile <name> update cctor-dsh-marketplace --latest

Restart DSH after the upgrade.

Uninstall

dsh plugin --profile <name> remove cctor-dsh-marketplace

Restart DSH after removal.

These management commands operate on the marketplace bundle itself; the UI's v1 limitation applies to plugins discovered inside the marketplace.

Install from a local checkout

pnpm install
pnpm build
dsh plugin --profile <name> add /absolute/path/to/cctor-dsh-marketplace

The Plugin Manager validates the bundle metadata and compatibility and records the path as a link: dependency. Use an absolute path. Version 0.1.0 is published to the public npm registry. Post-publication validation installed the exact registry version, installed it into an owned cctor-release-validation profile through the DeepSeek Harness 0.2.2-rc.1 bundled CLI, composed its configuration, and moved that profile to Trash. Three existing profiles' direct manifest fingerprints stayed unchanged; this does not establish whole-profile filesystem equality.

Configuration

The bundle's config is defined with Schemastery and passed through DSH's plugin configuration. The fields are equivalent to:

{
  "apiBaseUrl": "https://api.cctor.com",
  "requestTimeoutMs": 15000
}
Field Default Meaning
apiBaseUrl https://api.cctor.com Must be a root origin. Production requires HTTPS; HTTP is allowed only for the literal hosts localhost and 127.0.0.1, for local development. URL userinfo, paths, query strings, and fragments are rejected.
requestTimeoutMs 15000 Per-request catalog timeout, as a positive integer number of milliseconds.

The toolbar's "Reset cache" control clears only this plugin's private cache domain. It does not touch other Storage Domains or installed state.

Cache and offline behavior

  • Cache first: when the marketplace opens and a matching persistent record exists, the Host returns it immediately and refreshes the list or metadata in the background. A successful, validated response atomically replaces the matching record; a failed or invalid response never overwrites the last successful one. Details are cache-first as well.
  • Freshness: lists and metadata for 5 minutes, details for 30 minutes. Records past their TTL are marked stale but still rendered immediately while a background refresh runs.
  • Seven-day fallback: the last successful record remains available as a fallback when refresh fails. After seven days it is marked possiblyOutdated, is never presented as live, and is eventually evicted by the LRU.
  • Bounded cache: up to 50 list scopes, 50 metadata records, and 200 details, evicted by LRU. Every record carries a cache schema version. Cache keys include the normalized API base URL, query, category, sort, and cursor.
  • Offline: with a cached record, the UI renders it with a localized "stale" or "possibly outdated" banner and a Retry action; a failed refresh is exposed as a bounded error code and never corrupts the cached response. Without a cache, a network failure shows a localized offline / timeout error with Retry.
  • Install confirmation bypasses the cache: preparing a confirmation always re-reads the plugin from the detail endpoint, so the confirmation binds the current network identity and safe spec.

Installation confirmation and safety boundary

  • Every installation needs a fresh, explicit confirmation. A confirmation is single-use, expires after five minutes, and binds the stable plugin ID, normalized install spec, target profile, verification state, and source-content digest. The source is rechecked before execution; if the spec or relevant source fields changed, the confirmation becomes invalid and the user must review the new values.
  • Unverified warning: unverified entries can be browsed and installed, but they are not silently trusted. The confirmation dialog explains that Host code may access conversations, files, and the network. Its primary button reads Install anyway (仍要安装 in Chinese). No extra checkbox or second confirmation step is required.
  • The safe spec is derived only from structured fields: a valid npm package name plus the API's exact version when present; otherwise a canonical GitHub repository rendered as github:owner/repo. For github+npm records, npm is preferred. Blank or missing package_name / version is treated exactly like null.
  • Unsafe targets are refused: invalid, unsupported, ambiguous, non-GitHub Git, tarball, local-path, or shell-like targets.
  • install_command is display data only and is never executed. Runtime source under src/ imports no child_process, builds no shell command, and never treats the API-provided command as executable input.
  • Serialized installs: only one installation may run at a time; a second request receives install_busy.
  • The target is always the current profile: v1 installs only through the official Plugin Manager's pluginManager.installBundle. It spawns no dsh process, writes no other profile, offers no profile picker, and has no defaultProfile setting. The route is always plugin-manager.
  • v1 does not update, disable, or remove: use DSH's own plugin management surface for those actions. Installed entries show their local version and hide the normal Install action.

Why v1 does not install across profiles

See design §15.1. The packaged Desktop runtime and the dsh on PATH can be different DSH generations. ProfileContext.packageManager exists precisely because packaged applications supply a bundled runtime instead of relying on a PATH executable. The current profile is also the only profile whose facts the Host can observe and whose mutation the Plugin Manager can validate end to end. The cross-profile CLI route, profile picker, and desktop exception path are deferred to v1.1.

Catalog reality and empty states

Observed against the production catalog on 2026-11-04 (7,567 public records; sample of 200):

  • verified was false for every sampled record, and featured was also always false. Unverified is the normal path, so the unverified warning is routine, not exceptional.
  • Only 1 of the 200 sampled list records had a non-empty readme; detail responses are frequently empty too.
  • package_name and version appear only on github+npm records (58 of 200); github records carry neither.
  • Stable IDs come in two namespaced forms: github:owner/repo and repo:owner/name. Both are accepted, and neither is re-derived from repository.

The UI therefore renders explicit empty states: a missing README shows the localized "This plugin provides no README." instead of an empty block, and a missing version or license shows "Unknown". These are expected catalog states, not load failures. API-supplied plugin names, descriptions, READMEs, and repository metadata remain unchanged.

API prerequisite

The bundle depends on the existing GET /market/plugins and GET /market/plugins/meta endpoints, plus the deployed exact-detail endpoint:

GET /market/plugins/detail?id=github%3Aowner%2Frepository

The endpoint was verified live on 2026-11-04 (200 with readme, verified, and featured; 400 for an empty id; 404 for an unknown id; CORS and Cache-Control: public, max-age=60, s-maxage=300 on the response). The separate read-only pnpm verify:live-api check passed again on 2026-11-06 for list, metadata, stable-ID detail, and an unknown ID; it does not recheck every historical HTTP/CORS/cache-header assertion above. The detail API implementation plan belongs to the external API repository; this repository validates only the deployed read-only contract.

Contract summary:

  • Exactly one non-empty id query parameter is accepted. Stable IDs can contain /, so the value must be URL-encoded.
  • Lookup is an exact primary-key lookup and returns only an active public record.
  • The success body contains the public list-item fields plus the complete readme, verified, and featured fields. It must not return moderation, synchronization, credential, or internal provenance fields.
  • Stable error responses:
    • 400 {"error":"invalid_plugin_id"}
    • 404 {"error":"plugin_not_found"} (unknown or inactive)
    • 405 {"error":"method_not_allowed"}
    • 502 {"error":"database_error"} (without leaking database details)
  • It uses the existing market CORS policy and public cache headers. The route must be matched before any generic /market/plugins/<segment> route.

The Host maps network, timeout, invalid-response, not-found, slug ambiguity, install-busy, confirmation-expired, source-changed, invalid-profile, incompatible, and install-failed failures to stable public codes with a recovery action where one exists.

Verification and known limits

Latest full automated gate results in this repository (2026-11-06):

Check Result
pnpm typecheck Passed (Host and Client tsconfigs)
pnpm build Passed; produced lib/index.js, lib/plugin.js, lib/client.js, declarations, and sourcemaps
pnpm test 348 Node tests passed, 0 failed, 0 skipped
pnpm test:e2e 16 tests passed (15 desktop + 1 @narrow), covering 1440×900, 1024×768, and 390×844; zero pixel differences across nine baselines
pnpm verify:package npm dry-run preview passed: 48 entries, both READMEs, the MIT license, the changelog, and required runtime artifacts; no tarball generated or published
pnpm verify:release Deterministic aggregate of type checks, build, Node tests, Playwright, and package preview passed
pnpm verify:live-api Separate networked read-only check passed: 1 list result, 7,567 total records, detail github:morluto/rea, unknown ID not_found
Forbidden-pattern scan No runtime execution of catalog commands; matches are only README safety text and the npm-preview script's child_process import

The 348 Node tests cover Client HTTP transport/store/locale/UI, Host routes and services, cache/install/catalog/profile behavior, entry/build contracts, real DSH Loader composition, package contents, the live verifier, and owned validation-profile lifecycle protections. They cover HTTP request validation, error envelopes, cache TTL/LRU/schema version/atomic replacement, slug resolution, install-spec allowlisting, confirmation expiry and source changes, revision refresh after loading more pages, tool output bounds, and the Client HTTP route contract.

What these results prove, and what they do not:

  • Catalog installation boundaries remain verified against a Plugin-Manager-compatible fake. Separate acceptance installed only this local marketplace bundle through the real bundled CLI, composed configuration, and cleaned up the owned validation profile. This does not prove third-party marketplace installation, application/restart behavior, or build approvals.
  • Cache durability is verified through the real Storage Domain with a test-owned file-backed backend. The deployed backend's media, per-record, compatibleVersions, and backup semantics are out of scope.
  • Playwright proves the built lib/client.js artifact, workflows, and layout with a fake shell and fake Host HTTP route. It does not prove the packaged shell's live seats, real module table, style variables, or the production Connection carrier round trip.
  • The integration fixture is an inert spec target: it is never installed and has no entry module, so it is not bootable. Do not treat it as a runnable example plugin.
  • pnpm build must run before pnpm test: test/integration/loader.test.ts has an mtime-based freshness guard that fails fast when artifacts are missing or older than the newest src/ file.
  • Unverified: the packaged Desktop shell's Connection route round trip, arbitrary third-party catalog installation, and cross-profile installation. Exact-version download from public npm and installation into a validation profile through the bundled CLI passed.
  • The Playwright screenshot baselines are Chromium/macOS/1×/UTC/light-specific. A different font stack or Chromium version may require --update-snapshots; that is a platform baseline change, not a UI change.
  • Desktop 0.2.1-rc.5 acceptance: App and bundled CLI versions matched; CLI local-bundle installation and configuration composition passed. open -na ... --args --profile cctor-release-validation returned 0 but started no validation Host; only the existing desktop Host remained. Read-only inspection found a fixed profiles/desktop path and a single-instance lock. Native automation returned no UI state, and no UI interaction occurred. The linked-peer warning remains unvalidated in the real Desktop runtime.
  • The user explicitly waived real Desktop UI acceptance for 0.1.0: the 2026-11-05 Typert mount issue was addressed by using the same-origin Connection HTTP route and passes automated tests. Real Desktop list, search, details, bilingual copy, confirmation, cancellation, and route diagnostics remain unexecuted. This is an accepted first-release risk and no longer blocks 0.1.0, but it does not establish that the real Desktop UI passed acceptance. See the acceptance record.
  • The owned validation profile was cleaned up; before/after fingerprints of three existing direct manifests matched. cctor-dsh-marketplace@0.1.0 was published and passed npm and bundled-CLI installation checks; no catalog plugin was installed and no API was deployed.

Screenshots

The nine screenshots below come from the Task 9 Playwright harness and were each inspected with the image reader. The harness bar is hidden, Date.now is frozen at 2026-11-04T12:05:00Z, and the data is a deterministic fixture rather than the production catalog. Dates, counts, and plugin names in these images demonstrate layout only.

List Detail Confirmation
1440×900 list 1440×900 detail 1440×900 dialog
1024×768 list 1024×768 detail 1024×768 dialog
390×844 list 390×844 detail 390×844 dialog

What I actually confirmed in these images:

  • 1440×900 list: the toolbar stays on one line, with the search field taking most of the width and category, sort, refresh, reset-cache, and the read-only current-profile label aligned to the right. Above the list are the catalog total and sync date; beside the list heading is "updated 5 minutes ago · from network". Multiple rows and right-aligned unverified/verified/installed badges are visible; a long plugin name wraps across several lines without clipping. No plugin is selected yet, so the detail pane shows "Select a plugin to view details." The viewport cuts off later rows at the bottom, with no horizontal overflow.
  • 1440×900 detail: the selected row is highlighted. "Alpha unverified plugin" shows its unverified state, a pink warning block, repository, author, version, license, tags, published/updated dates, stars/weekly downloads, and cache age. The long README extends past the viewport and is clipped by the detail column; the blue Install button begins at the bottom edge with its lower part clipped by the viewport — the detail column scrolls internally, so about 16 px of scrolling makes it fully visible and clickable.
  • 1440×900 confirmation: a centered dialog over the dimmed workspace, not covering the top toolbar. It contains the "Confirm install" title, the unverified badge and warning, plugin, repository, target profile web, route "Plugin Manager", package @cctor-lab/alpha-tool@1.2.3, command preview, the expiry date/time (12:10 on 2026-11-04), and Cancel / "Install anyway" actions. The command preview wraps to two lines.
  • 1024×768 list/detail: the toolbar is still one line; the list is narrower, long names wrap across more lines, and the last rows are cut off at the bottom. The detail column is narrower but fields and README wrap normally; the Install button sits below the fold (about 148 px of internal detail scrolling reveals it, and the button itself is clickable). The confirmation dialog fits within the 768 px height.
  • 390×844 list: the toolbar wraps to two rows (search and category on the first; sort, refresh, reset-cache, and the profile label on the second), and the profile label remains visible. The list is full width, long names wrap across several lines, and badges stay inside the right-hand column.
  • 390×844 detail: the list is hidden and a "← Back" control appears at the top, followed by the full unverified warning, fields, and wrapped README. There is no horizontal scrolling.
  • 390×844 confirmation: the narrow dialog fits the viewport width; the warning, fields, and three-line command preview wrap cleanly, the Cancel / "Install anyway" actions are visible at the bottom, and the underlying detail is dimmed.

These are pixel baselines (maxDiffPixels: 0, threshold: 0) that guard against layout regressions. They are not acceptance screenshots of the real DSH desktop shell.

Development and verification

pnpm install
pnpm verify:release   # type checks, build, 348 Node tests, 16 Playwright tests, package preview
pnpm verify:live-api  # explicit networked read-only check, outside the deterministic gate

Re-run Playwright after changing the Client; re-run pnpm build after changing src/. Playwright's webServer builds the harness assets itself and listens on 127.0.0.1:4517; it requires lib/client.js to exist.

Explicitly out of scope for this release

  • API deployment and arbitrary third-party catalog installation remain unverified; public npm publication, exact-version installation, and owned-profile CLI composition passed.
  • No update, disable, remove, cross-profile install, profile picker, or defaultProfile.
  • No execution of the API-provided install_command; no shell or dsh subprocess.
  • No cache writes to session history and no cache internals exposed to the model.
—/ 5

No ratings yet

Verified DSH bundle

Commit a580088ed8df

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout