feat(plugin-detail): show Markdown plugin details on bundle and market entry pages

Plugins bundle pages and Discover entry pages show the plugin's long
description first, as Markdown with images, in a height-limited region
without its own heading. The document is the file locale meta.detail
names, otherwise the package README, otherwise (market entries only)
the declared repository's README.

The new dsh-plugin-detail library selects documents and reads local
package directories and npm file CDNs without state. plugin-manager
reads installed and offered bundles through readBundleDetail; plugin-market
reads market entries through readEntryDetail, single-file APIs, and a
size-limited partial clone cache serialized across processes. Raw HTML is
omitted, relative links stay text, and relative images load from Host
routes with a sandbox CSP.
This commit is contained in:
turtle1999 committed 2026-10-19 19:13:22 +08:00
1 parent 82a5ae1744
commit 9c8522bb64
111 files changed
+5057 -141

No files matched your search

+1
View File
@@ -100,6 +100,7 @@ const PACKAGE_LIBRARIES: Readonly<Record<string, string>> = {
'packages/util/native-command': 'Host-side subprocess runner utility.',
'packages/util/output-retention': 'Zero-dependency retention utility.',
'packages/util/package-manifest': 'Shared package manifest declarations with type-only exports.',
'packages/util/plugin-detail': 'Plugin detail document library.',
'packages/util/plugin-market-index': 'Plugin market index validation library.',
'packages/util/time': 'Zero-dependency time-zone canonicalization utility.',
'packages/util/timeout': 'Zero-dependency timeout utility.',
+3
View File
@@ -309,6 +309,9 @@ export const LINK_MAP: Readonly<Record<string, string>> = {
MarketQuery: 'boot.md',
MarketSearchResult: 'boot.md',
MarketSort: 'boot.md',
PluginDetail: 'boot.md',
BundleDetail: 'boot.md',
NpmFileSource: 'boot.md',
ChangeResult: 'boot.md',
InstallBundleOptions: 'boot.md',
PluginEntryId: 'boot.md',
@@ -92,6 +92,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
'packages/util/chunked-list': { kind: 'none', reason: 'Immutable collection primitive; registers nothing model-facing.' },
'packages/util/package-manifest': { kind: 'none', reason: 'Type declarations only; registers nothing model-facing.' },
'packages/util/lazy-require': { kind: 'none', reason: 'Host module-loading primitive; registers nothing model-facing.' },
'packages/util/plugin-detail': { kind: 'none', reason: 'Pure document selection for plugin detail pages; registers nothing model-facing.' },
'packages/util/plugin-market-index': { kind: 'indirect', reason: 'Pure index validation; the plugin_market tool owns the entries it returns to the model.' },
'packages/util/time': { kind: 'indirect', reason: 'Pure zone validation; the consumer that records a canonical zone owns the model-visible line derived from it.' },
'packages/core/agent-default-model': { kind: 'indirect', reason: 'The service supplies a ModelSelection; request assembly and adapters own the model-visible request.' },