@klarkxy/dsh-dev-index 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # DSH Docs
2
2
 
3
+ <!-- release-state-note -->
4
+
3
5
  [简体中文](README.zh-CN.md) | [English](README.md)
4
6
 
5
- Runtime: Node `^22.19.0 || >=24.0.0` and DSH `>=0.1.7-rc.2`. The documentation reader is a DSH Web client; the four read-only tools and the Creator-mode guidance run in the host.
7
+ Runtime: Node `^22.19.0 || >=24.0.0` (26 verified) and DSH `>=0.1.7-rc.2`. The documentation reader is a DSH Web client; the four read-only tools and the Creator-mode guidance run in the host.
6
8
 
7
9
  Read the official DSH documentation without leaving DSH. The Plugins page embeds the official docs, and Creator mode also gets four native read-only tools: `dsh_docs_search` and `dsh_docs_fetch` to look up documentation, `dsh_plugins_search` and `dsh_plugins_fetch` to check a plugin's npm metadata. Installing and removing plugins stays with the official plugin manager; this plugin never installs anything.
8
10
 
@@ -23,7 +25,7 @@ The host half adds one system-prompt section when the session uses the `cordis`
23
25
  - `dsh_docs_search({ query: "plugin", language: "en" })` searches the live official `llms.txt` directory: titles, categories and paths. This is a directory search, not full-text search; an empty result does not establish that a topic is absent from the document bodies, so try broader Chinese or English keywords.
24
26
  - `dsh_docs_fetch({ id: "en/develop/basic/tool.md" })` reads a document ID returned by search. Results include the source URL, fetch time, content revision and `nextOffset`. Continue with that offset and the same `revision`; if the document changes, restart from offset zero. The default page size is 12,000 characters, at most 16,000.
25
27
  - `dsh_plugins_search({ query: "memory" })` finds candidate plugins. The default `catalog` source searches the curated klarkxy Chinese/English plugin catalog; `source: "npm"` searches npm's `dsh-plugin` keyword more broadly. Neither source is exhaustive, and a hit is a candidate rather than verified compatibility.
26
- - `dsh_plugins_fetch({ package: "@klarkxy/dsh-mood", version: "latest" })` reads npm registry metadata for an exact package name: dist-tags, published versions in publication-time order, and the selected version's bundle declaration, DSH/Node engine ranges, dependencies and deprecation. `version` accepts an exact release or a dist-tag; ranges are rejected.
28
+ - `dsh_plugins_fetch({ package: "@klarkxy/dsh-current-title", version: "latest" })` reads npm registry metadata for an exact package name: dist-tags, published versions in publication-time order, and the selected version's bundle declaration, DSH/Node engine ranges, dependencies and deprecation. `version` accepts an exact release or a dist-tag; ranges are rejected.
27
29
 
28
30
  The plugin-registry tools are read-only metadata lookups: nothing is downloaded, installed or executed, and a declared engines range is not runtime compatibility proof. GitHub-installed plugins have no registry metadata; install those directly with the official plugin manager as `github:owner/repo#commit`, and review their `package.json` yourself.
29
31
 
@@ -51,7 +53,7 @@ The published npm package includes the built `lib/` files.
51
53
  dsh plugin --profile web add "github:klarkxy/dsh-plugins#path:/plugins/dsh-dev-index"
52
54
  ```
53
55
 
54
- A Git install runs `prepare`, which builds `lib/`. pnpm blocks that script until the profile allowlists it, and the DSH 0.1.7-rc.2 CLI prints the exact key to add under `allowBuilds` in `$DSH_HOME/profiles/web/pnpm-workspace.yaml`:
56
+ A Git install runs `prepare`, which builds `lib/`. pnpm blocks that script until the profile allowlists it; the DSH CLI prints the exact key to add under `allowBuilds` in `$DSH_HOME/profiles/web/pnpm-workspace.yaml`:
55
57
 
56
58
  ```yaml
57
59
  allowBuilds:
@@ -60,25 +62,7 @@ allowBuilds:
60
62
 
61
63
  Run the add command again: that allowance executes this package's build on your machine. Pin a commit when the plugin source must not move.
62
64
 
63
- Peer ranges on `@deepseek-ai/dsh-system-prompt` and `@deepseek-ai/dsh-agent-preset-registry` are checked against the running `dsh` version. This package requires DSH `>=0.1.7-rc.2`, and the loader does not enforce `engines.dsh`.
64
-
65
- ## Install from this checkout
66
-
67
- ```bash
68
- pnpm install
69
- pnpm --filter @klarkxy/dsh-dev-index build
70
- dsh plugin --profile web add ./plugins/dsh-dev-index
71
- ```
72
-
73
- Restart the profile, or let HMR apply the new bundle. Then:
74
-
75
- ```bash
76
- dsh --profile web --dump-config
77
- ```
78
-
79
- The composition should contain a `dsh-dev-index` row. Start a new Creator-mode session to pick up the documentation guidance automatically.
80
-
81
- There is no configuration: the patch inserts the plugin and sets no keys.
65
+ Peer ranges on `@deepseek-ai/dsh-system-prompt` and `@deepseek-ai/dsh-agent-preset-registry` are checked against the running `dsh` version. The loader does not enforce `engines.dsh`.
82
66
 
83
67
  ## License
84
68
 
package/README.zh-CN.md CHANGED
@@ -1,8 +1,10 @@
1
- # DSH 文档
1
+ # DSH 文档
2
+
3
+ <!-- release-state-note -->
2
4
 
3
5
  [简体中文](README.zh-CN.md) | [English](README.md)
4
6
 
5
- **运行环境**:Node `^22.19.0 || >=24.0.0`、DSH `>=0.1.7-rc.2`。文档阅读器是 DSH Web 客户端;四个只读工具和创造模式指引运行在宿主里。
7
+ **运行环境**:Node `^22.19.0 || >=24.0.0`(已验证 26)、DSH `>=0.1.7-rc.2`。文档阅读器是 DSH Web 客户端;四个只读工具和创造模式指引运行在宿主里。
6
8
 
7
9
  不离开 DSH 就能读到官方文档:插件页内嵌官方文档站,创造模式另外拿到四个原生只读工具——`dsh_docs_search` 和 `dsh_docs_fetch` 检索文档,`dsh_plugins_search` 和 `dsh_plugins_fetch` 查核插件的 npm 元数据。安装和卸载插件始终由官方插件管理器负责,本插件不安装任何东西。
8
10
 
@@ -23,7 +25,7 @@
23
25
  - `dsh_docs_search({ query: "插件", language: "zh" })` 在线读取官方 `llms.txt`,搜索标题、分类和路径。这是目录搜索,不是全文搜索;没有命中不代表正文不含相关内容,可以改用更宽泛的中文或英文关键词。
24
26
  - `dsh_docs_fetch({ id: "develop/basic/tool.md" })` 读取搜索结果中的文档 ID。结果包含来源、获取时间、内容修订值和 `nextOffset`。长文用该偏移量和相同的 `revision` 继续读取;正文更新时需要从头重读。默认每次返回 12,000 字符,上限 16,000。
25
27
  - `dsh_plugins_search({ query: "记忆" })` 查找候选插件。默认 `catalog` 数据源搜索 klarkxy 维护的中英文插件目录;`source: "npm"` 用 npm 的 `dsh-plugin` 关键词做更宽的发现。两个源都不是全量目录,命中结果只是候选,不代表兼容性已验证。
26
- - `dsh_plugins_fetch({ package: "@klarkxy/dsh-mood", version: "latest" })` 按确切包名读取 npm 注册表元数据:dist-tags、按发布时间排序的版本列表,以及选定版本的组合包声明、DSH/Node 版本要求、依赖和弃用说明。`version` 可填精确版本或标签,不接受范围。
28
+ - `dsh_plugins_fetch({ package: "@klarkxy/dsh-current-title", version: "latest" })` 按确切包名读取 npm 注册表元数据:dist-tags、按发布时间排序的版本列表,以及选定版本的组合包声明、DSH/Node 版本要求、依赖和弃用说明。`version` 可填精确版本或标签,不接受范围。
27
29
 
28
30
  插件注册表工具是只读元数据查询:不下载、不安装、不执行任何代码,声明的 engines 范围也不是运行时兼容性证明。从 GitHub 安装的插件没有注册表元数据,直接用官方插件管理器以 `github:owner/repo#commit` 安装,并自行审阅其 `package.json`。
29
31
 
@@ -51,7 +53,7 @@ npm 包包含已构建的 `lib/`。
51
53
  dsh plugin --profile web add "github:klarkxy/dsh-plugins#path:/plugins/dsh-dev-index"
52
54
  ```
53
55
 
54
- Git 安装会运行 `prepare` 来构建 `lib/`。pnpm 在允许之前会拦住这个脚本,DSH 0.1.7-rc.2 的 CLI 会打印出要写进 `$DSH_HOME/profiles/web/pnpm-workspace.yaml` 里 `allowBuilds` 的确切包名:
56
+ Git 安装会运行 `prepare` 来构建 `lib/`。pnpm 在允许之前会拦住这个脚本,DSH CLI 会打印出要写进 `$DSH_HOME/profiles/web/pnpm-workspace.yaml` 里 `allowBuilds` 的确切包名:
55
57
 
56
58
  ```yaml
57
59
  allowBuilds:
@@ -60,25 +62,7 @@ allowBuilds:
60
62
 
61
63
  然后再执行一次 add:该许可会在本机执行这个包的构建。需要固定插件来源时请钉住 commit。
62
64
 
63
- `@deepseek-ai/dsh-system-prompt` 和 `@deepseek-ai/dsh-agent-preset-registry` 的 peer 范围会对照正在运行的 `dsh` 版本检查。本包要求 DSH `>=0.1.7-rc.2`;加载器不强制 `engines.dsh`。
64
-
65
- ## 从本仓库安装
66
-
67
- ```bash
68
- pnpm install
69
- pnpm --filter @klarkxy/dsh-dev-index build
70
- dsh plugin --profile web add ./plugins/dsh-dev-index
71
- ```
72
-
73
- 安装后重启该 profile,或让 HMR 应用新 bundle。然后:
74
-
75
- ```bash
76
- dsh --profile web --dump-config
77
- ```
78
-
79
- 组合结果里应有 `dsh-dev-index` 这一行。新建创造模式会话即可自动收到文档指引。
80
-
81
- 没有配置项:补丁只插入插件,不设置任何键。
65
+ `@deepseek-ai/dsh-system-prompt` 和 `@deepseek-ai/dsh-agent-preset-registry` 的 peer 范围会对照正在运行的 `dsh` 版本检查。加载器不强制 `engines.dsh`。
82
66
 
83
67
  ## 许可证
84
68
 
package/client.js CHANGED
@@ -85,18 +85,17 @@ const css = `
85
85
  const hostLanguage = locale => locale.getSnapshot().active.startsWith('zh') ? 'zh' : 'en';
86
86
 
87
87
  function DocumentationBrowser({ hostLocale }) {
88
- const [language, setLanguage] = React.useState(() => hostLanguage(hostLocale));
88
+ const subscribe = React.useCallback(listener => hostLocale.subscribe(listener), [hostLocale]);
89
+ const snapshot = React.useCallback(() => hostLanguage(hostLocale), [hostLocale]);
90
+ const uiLanguage = React.useSyncExternalStore(subscribe, snapshot, snapshot);
91
+ const [selectedLanguage, setLanguage] = React.useState(uiLanguage);
89
92
  /* Once the reader picks a language, the host locale stops driving it. */
90
93
  const [pinned, setPinned] = React.useState(false);
91
94
  const [revision, setRevision] = React.useState(0);
92
95
  const [status, setStatus] = React.useState('loading');
96
+ const language = pinned ? selectedLanguage : uiLanguage;
93
97
  const url = language === 'zh' ? pages : `${pages}en/`;
94
- const chinese = language === 'zh';
95
-
96
- React.useEffect(() => {
97
- if (pinned) return undefined;
98
- return hostLocale.subscribe(() => setLanguage(hostLanguage(hostLocale)));
99
- }, [hostLocale, pinned]);
98
+ const chinese = uiLanguage === 'zh';
100
99
 
101
100
  React.useEffect(() => {
102
101
  setStatus('loading');
@@ -107,7 +106,7 @@ const css = `
107
106
  function reload() { setRevision(value => value + 1); }
108
107
  function choose(nextLanguage) {
109
108
  setPinned(true);
110
- if (nextLanguage !== language) setLanguage(nextLanguage);
109
+ setLanguage(nextLanguage);
111
110
  }
112
111
 
113
112
  const open = h('a', {
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "@klarkxy/dsh-dev-index",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "main": "lib/index.js",
5
5
  "description": "DSH Docs: read the official DSH documentation in the Plugins page; Creator mode searches and fetches it with native tools.",
6
6
  "engines": {
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
+ import { CREATOR_PRESET_ID } from "@klarkxy/dsh-plugin-kit/contracts";
2
3
  import { CREATOR_GUIDANCE } from "./creator-guidance.js";
3
4
  import { DocsClient } from "./docs.js";
4
5
  import { docsTools } from "./docs-tools.js";
@@ -30,7 +31,7 @@ export function apply(ctx, config) {
30
31
  ctx.effect(() => ctx.systemPrompt.section({
31
32
  name: "dsh-dev-index.creator-docs",
32
33
  order: 100,
33
- text: ({ agent }) => agent !== undefined && ctx.agentPresets.composedPreset(agent.ctx) === "cordis"
34
+ text: ({ agent }) => agent !== undefined && ctx.agentPresets.composedPreset(agent.ctx) === CREATOR_PRESET_ID
34
35
  ? CREATOR_GUIDANCE
35
36
  : "",
36
37
  }), "dsh-dev-index.creator-docs");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klarkxy/dsh-dev-index",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "DSH Docs: read the official DSH documentation in the Plugins page; Creator mode searches docs and checks plugin npm metadata with native tools.",
5
5
  "icon": "./icon.svg",
6
6
  "keywords": [
@@ -38,6 +38,7 @@
38
38
  },
39
39
  "files": [
40
40
  "icon.svg",
41
+ "scripts/prepare.mjs",
41
42
  "client.js",
42
43
  "lib/**/*.js",
43
44
  "lib/**/*.d.ts",
@@ -49,7 +50,7 @@
49
50
  ],
50
51
  "scripts": {
51
52
  "build": "tsc -p tsconfig.build.json",
52
- "prepare": "pnpm build",
53
+ "prepare": "node scripts/prepare.mjs",
53
54
  "prepack": "pnpm build",
54
55
  "typecheck": "tsc -p tsconfig.json",
55
56
  "test": "vitest run"
@@ -78,6 +79,9 @@
78
79
  "@deepseek-ai/schemastery": ">=3.18.4",
79
80
  "@deepseek-ai/dsh-tools": ">=0.2.0-rc.2"
80
81
  },
82
+ "dependencies": {
83
+ "@klarkxy/dsh-plugin-kit": "0.3.1"
84
+ },
81
85
  "peerDependenciesMeta": {
82
86
  "@deepseek-ai/dsh-agent-preset-registry": {
83
87
  "optional": true
@@ -103,6 +107,6 @@
103
107
  "registry": "https://registry.npmjs.org/"
104
108
  },
105
109
  "dshRelease": {
106
- "contentHash": "535677b4a757c53e81a174500ca1408591b3bc10c5bf6c5969cdcb0863ca8df8"
110
+ "contentHash": "fda890d3919ae02dff3dcb2f4d33894921a5e36885e019a50ed8705e48124202"
107
111
  }
108
112
  }
@@ -0,0 +1,39 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, realpathSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const require = createRequire(import.meta.url);
7
+ const packageRoot = new URL('../', import.meta.url);
8
+
9
+ try {
10
+ require.resolve('@klarkxy/dsh-plugin-kit/contracts');
11
+ } catch (error) {
12
+ // Only defer a clean monorepo install. Missing/broken published dependencies
13
+ // must fail Git installs, not silently produce a package without lib/.
14
+ const workspaceKit = new URL('../../dsh-plugin-kit/package.json', import.meta.url);
15
+ const workspaceFile = new URL('../../../pnpm-workspace.yaml', import.meta.url);
16
+ if (
17
+ error.code !== 'MODULE_NOT_FOUND' ||
18
+ !existsSync(workspaceFile) ||
19
+ !existsSync(workspaceKit) ||
20
+ realpathSync(require.resolve('@klarkxy/dsh-plugin-kit/package.json')) !== realpathSync(workspaceKit)
21
+ ) {
22
+ throw error;
23
+ }
24
+ console.log('prepare: deferred until workspace plugin-kit is built; prepack still requires a build');
25
+ process.exit(0);
26
+ }
27
+
28
+ // npm and pnpm supply their JS entry point to lifecycle scripts. Launch it
29
+ // through Node so paths with spaces and Windows .cmd wrappers need no shell.
30
+ if (!process.env.npm_execpath) {
31
+ throw new Error('prepare must run through a package manager (npm_execpath is missing)');
32
+ }
33
+ const result = spawnSync(process.execPath, [process.env.npm_execpath, 'run', 'build'], {
34
+ cwd: fileURLToPath(packageRoot),
35
+ stdio: 'inherit',
36
+ });
37
+ if (result.error) throw result.error;
38
+ if (result.signal) throw new Error(`prepare build terminated by ${result.signal}`);
39
+ process.exitCode = result.status ?? 1;