deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
Jesse-njx/dsh-plugin-manager-registry
@dsh-pm/registry — discover dsh plugins by merging the awesome-dsh-plugin list, GitHub dsh-plugin-topic search, and npm keyword search into one deduped, offline-tolerant registry (the discovery engine of dsh pm)
PROJECT TOPICS
PROJECT README
The discovery engine of dsh pm — find dsh plugins by merging three
independent sources into one deduped, sorted, offline-tolerant registry:
awesomeUrl).dsh-plugin topic via the gh CLI,
with a plain api.github.com https fallback.npm search --json <keyword> (config npmKeyword,
default dsh), with a registry /-/v1/search https fallback.A GitHub hit and an npm hit for the same project collapse into one
RegistryEntry carrying both repoUrl and npmName; entries dedupe by
normalized repo URL first, then by bare name. Every source degrades
independently — a dead source contributes fewer (or cached) entries and a
warning, never a rejection. Offline, the client serves whatever the local
cache last recorded per source.
This package implements the frozen RegistryClient contract from
@dsh-pm/core (spec
§5.1) and exports exactly the §5.2 surface: createRegistryClient and a
one-shot search convenience.
Workspace package of the dsh-plugin-manager monorepo; consumed through
@dsh-pm/core (workspace dep). The product that wires it into DSH is the
plugin manager CLI:
dsh plugin add github:Jesse-njx/dsh-plugin-manager
import { createRegistryClient, search } from '@dsh-pm/registry'
import type { PmConfig } from '@dsh-pm/core'
const cfg: PmConfig['registry'] = {
awesomeUrl: 'https://raw.githubusercontent.com/awesome-dsh-plugin/awesome-dsh-plugin/main/README.md',
npmKeyword: 'dsh',
}
const client = createRegistryClient(cfg)
// Filtered, sorted: stars desc, then name.
const hits = await client.search('memory')
// Exact lookup by name, npmName, owner/repo, github:owner/repo or https URL.
const entry = await client.resolve('Jesse-njx/dsh-memory')
// Update-check version: npm dist-tag `latest`, else GitHub default-branch HEAD sha.
const version = await client.latestVersion(entry ?? hits[0]!)
// Warnings of the last run (documented extra beyond the frozen interface):
console.log(client.lastWarnings) // e.g. ["github: 'gh' CLI not found; results from https search"]
// One-shot convenience (spec §5.2):
const all = await search('', cfg)
search/resolve return RegistryEntry from @dsh-pm/core:
{
name: string // canonical bare name
repoUrl?: string // normalized https repo URL (dedupe key #1)
npmName?: string // npm package name when published
description: string
category: string // awesome-list heading, or ''
stars?: number // GitHub stars when known
updatedAt?: string // ISO 8601 of last repo push when known
source: ('github' | 'npm')[] // which discovery sources contributed
}
| Source | Primary | Fallback | Contributes |
|---|---|---|---|
| awesome | fetch(awesomeUrl) |
local cache | name, repoUrl, description, category |
| github | gh api search/repositories?q=topic:dsh-plugin |
https api.github.com search |
name, repoUrl, stars, updatedAt, description |
| npm | npm search --json --searchlimit=100 <keyword> |
https registry.npmjs.org/-/v1/search |
name→npmName, repoUrl, description |
git+https://…, git@github.com:…,
trailing .git all collapse to https://github.com/owner/repo), then bare
name. Distinct repos that merely share a bare name stay separate. Merged
metadata is unioned and source accumulates distinct contributors.stars ?? 0 descending, name ascending as tiebreak.awesome: …, github: …,
npm: …), e.g. github: 'gh api' failed (exit 1); results from https search.
An unparseable awesome row increments a single awesome: skipped N row(s)
warning — the parser never throws.Every source tries its primary path, then its https fallback, then its local cache, then degrades to zero entries with one warning. Caches are JSON files written atomically (temp + rename) under:
$DSH_PM_CACHE_DIR if set, else$XDG_CACHE_HOME/dsh-pm, else~/.cache/dsh-pmCache writes are best-effort: a failed write is swallowed, never fatal. The
default npm runner also gets its own writable cache (<cacheDir>/npm-cache)
so a broken global ~/.npm cache cannot take down the primary npm path.
pnpm install # from the monorepo root (requires packages/core to exist)
pnpm --filter @dsh-pm/registry test # node --test, 43 tests
pnpm --filter @dsh-pm/registry typecheck
pnpm --filter @dsh-pm/registry build # tsc → lib/
Tests never hit the network except test/live.test.ts, which skips when
offline (network guard, mirroring the suite convention). The merge/dedupe
matrix, parser goldens (fixture README committed in test/fixtures/) and
every degrade path run against injected fakes (test/helpers.ts).
dev/core/is a build-time-only stub.registryimports types from@dsh-pm/core(workspace dep) usingimport typeonly — erased at runtime. Because Session 1'scorehad not landed when this package was built, the frozen §5.1 contract is transcribed verbatim intodev/core/index.d.ts, referenced only through thepathsmapping intsconfig.json, never emitted intolib/, and never imported at runtime. Deletedev/the moment the realcorelinks — the coordinator can diff the stub against the landed types to catch any drift.
MIT — see LICENSE.
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: plugin-manager。