Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: CI

on:
push:
branches: [main]
pull_request:

permissions:
Expand Down Expand Up @@ -46,9 +47,13 @@ jobs:
if: runner.os == 'Windows'
run: pnpm exec vitest run tests/config.spec.ts tests/runner.spec.ts tests/version-updates.spec.ts

- name: Build package on Windows
- name: Verify deterministic build on Windows
if: runner.os == 'Windows'
run: pnpm run build
run: pnpm run verify:build

- name: Verify published package on Windows
if: runner.os == 'Windows'
run: pnpm run verify:package

- name: Download and verify Mnemon Windows release
if: runner.os == 'Windows'
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ jobs:
- name: Verify package
run: pnpm run verify

- name: Publish package
run: npm publish --access public --ignore-scripts
- name: Pack release
run: npm pack --ignore-scripts

- name: Publish packed release
run: npm publish "dsh-mnemon-$(node --print "require('./package.json').version").tgz" --access public --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/
coverage/
/lib/
*.log
.DS_Store
*.tgz
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ pnpm install
pnpm run verify
```

`verify` runs TypeScript checks, Vitest, and the production build. Generated artifacts are committed under `lib/`.
`verify` runs TypeScript checks, Vitest, a reproducible double build, and published-package validation. `lib/` is generated and intentionally not tracked.

## License

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ pnpm install
pnpm run verify
```

`verify` 依次运行 TypeScript 检查、Vitest 和生产构建。构建产物提交在 `lib/`
`verify` 依次运行 TypeScript 检查、Vitest、两次可复现构建和发布包校验。`lib/` 是生成目录,不再提交到仓库

## License

Expand Down
39 changes: 22 additions & 17 deletions docs/en/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Environment

The repository does not declare minimum Node, pnpm, DSH, or Mnemon versions in `package.json`. Use the current DSH development environment and verify compatibility through the full validation chain whenever dependencies are upgraded.
`package.json` requires Node.js 20 or newer. CI uses Node.js 24 and pnpm 10.13.1. Verify DSH and Mnemon compatibility through the full validation chain whenever dependencies are upgraded.

Install dependencies:

Expand All @@ -18,7 +18,7 @@ pnpm install
pnpm run typecheck # tsc --noEmit
pnpm test # vitest run
pnpm run build # declarations + host/client bundles
pnpm run verify # typecheck + test + build
pnpm run verify # typecheck + tests + reproducible build + package validation
```

## Directory Structure
Expand All @@ -38,9 +38,11 @@ src/
+-- tools.ts / commands.ts # model and human interfaces
+-- rpc.ts / settings.ts # Web bridges
+-- storage-scope.ts # storage inventory
+-- shared/contracts.ts # canonical Host/Client wire contracts
+-- client/ # React workspace and locales
tests/ # Vitest suites
lib/ # committed build artifacts
scripts/ # deterministic build and package checks
lib/ # generated, ignored publish artifacts
docs/zh-CN/ # Chinese documentation
docs/en/ # English mirror
cordis.patch.yml # DSH profile bundle patch
Expand All @@ -49,23 +51,22 @@ cordis.patch.yml # DSH profile bundle patch
## Build Artifacts

```text
tsc -p tsconfig.build.json
-> lib/types/* declarations, maps, intermediate ESM

tsdown host bundle
tsdown (directly from src/)
-> lib/index.js Node ES2024 ESM

tsdown client bundle
-> lib/client.js DSH browser module wrapper
-> lib/client.js.map

tsc -p tsconfig.types.json
-> lib/types/**/*.d.ts declarations only

lightningcss plugin
-> CSS Modules compiled and injected as scoped <style>
```

The Host keeps `cordis` and `schemastery` external. The client keeps React, ReactDOM, the JSX runtime, and Cordis external; all other dependencies are included in the bundle.
The Host keeps all package dependencies external. The client keeps React, ReactDOM, the JSX runtime, Cordis, and DSH UI primitives external; only `markdown-to-jsx` is allowed to be bundled from `node_modules`.

`lib/` is part of the publishing input. After modifying `src/`, rebuild and inspect the generated diff. Do not edit `lib/` manually.
`lib/` is a publishing input but is ignored by Git. Never edit it manually. `pnpm run verify:build` builds twice and compares every output hash, so unstable CSS export ordering or other generated churn fails verification.

`src/shared/contracts.ts` is the canonical boundary for configuration shapes, RPC channels, settings protocol, and Client-visible DTOs. Files under `src/client/` may import parent modules only through that contract. Host modules may re-export shared types for compatibility, but must not redefine wire DTOs.

## Test Layers

Expand All @@ -80,6 +81,7 @@ The existing Vitest suites cover:
- lifecycle cues, scoring, idle debounce, cancellation, and watermark retention;
- RPC authority, read-only behavior, and settings revisions;
- the Web workspace, bilingual copy, and key interactions.
- Client/Host source boundaries, deterministic build hashes, package contents, exports, and TypeScript resolution.

These are primarily integration tests using temporary directories, fake runners, and a mock Host. They are not equivalent to automated end-to-end tests of the real DSH + Mnemon WebUI.

Expand Down Expand Up @@ -170,8 +172,8 @@ When the Web locale changes, the Chinese key set remains the type source of trut

```text
[ ] pnpm run verify
[ ] review source and generated lib diffs
[ ] validate package file list includes README.md, README.zh-CN.md, docs/assets, and bilingual docs
[ ] confirm the worktree contains no generated lib changes
[ ] confirm package validation reports only runtime files, declarations, root documents, and cordis.patch.yml
[ ] install the built/local bundle into an isolated Web profile
[ ] run real Mnemon CLI and WebUI smoke tests
[ ] verify Chinese and English workspaces
Expand All @@ -180,17 +182,20 @@ When the Web locale changes, the Chinese key set remains the type source of trut
[ ] back up any data root used for upgrade testing
```

`package.json.files` currently publishes `lib`, the patch, both root READMEs, centrally managed documentation visuals, the public bilingual docs, and the License.
`package.json.files` publishes `lib`, the patch, both root READMEs, `SECURITY.md`, and the License. The documentation site and media stay in GitHub and are intentionally excluded from npm.

## Publishing to npm

After publication, `dsh plugin --profile web add dsh-mnemon` resolves by registry name — the same path as dsh-better-sidebar. Steps:

```sh
npm pack --dry-run # inspect the tarball file list (cordis.patch.yml, lib, docs)
pnpm publish --access public # prepublishOnly runs pnpm run verify first
pnpm run verify
npm pack --ignore-scripts
npm publish dsh-mnemon-<version>.tgz --access public --ignore-scripts
```

Publishing the already-packed tarball ensures npm receives the same artifact that was inspected. The GitHub release workflow follows this sequence after checking that the tag matches `package.json`.

Credential convention: write NPM_TOKEN only to the user-level `~/.npmrc` (`npm config set "//registry.npmjs.org/:_authToken" "${NPM_TOKEN}" --userconfig ~/.npmrc`) and remove it after publishing. Do **not** commit the credential line to the repository `.npmrc`: pnpm 11 deliberately ignores unexpanded environment-variable credentials in project-level `.npmrc` (with a warning), and that file travels with the repo.

2FA note: when the npm account has publish-level two-factor authentication, an interactive `pnpm publish --access public` prompts for the OTP; scripted/CI publishing needs a Classic **Automation** token or a Granular token allowed to bypass 2FA (a plain token from `npm login` cannot publish and fails with 403 Two-factor authentication required).
Expand Down
39 changes: 22 additions & 17 deletions docs/zh-CN/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 环境

仓库没有在 `package.json` 中声明 Node、pnpm、DSH 或 Mnemon 的最低版本。使用当前 DSH 开发环境,并在升级依赖时通过完整验证链路确认兼容性
`package.json` 要求 Node.js 20 或更高版本。CI 使用 Node.js 24 和 pnpm 10.13.1。升级依赖时,应通过完整验证链路确认 DSH 与 Mnemon 兼容性

安装依赖:

Expand All @@ -18,7 +18,7 @@ pnpm install
pnpm run typecheck # tsc --noEmit
pnpm test # vitest run
pnpm run build # declarations + host/client bundles
pnpm run verify # typecheck + test + build
pnpm run verify # typecheck + tests + reproducible build + package validation
```

## 目录结构
Expand All @@ -38,9 +38,11 @@ src/
+-- tools.ts / commands.ts # model and human interfaces
+-- rpc.ts / settings.ts # Web bridges
+-- storage-scope.ts # storage inventory
+-- shared/contracts.ts # Host/Client wire contract 唯一事实源
+-- client/ # React workspace and locales
tests/ # Vitest suites
lib/ # committed build artifacts
scripts/ # 确定性构建与发布包检查
lib/ # 生成且忽略的发布产物
docs/zh-CN/ # Chinese documentation
docs/en/ # English mirror
cordis.patch.yml # DSH profile bundle patch
Expand All @@ -49,23 +51,22 @@ cordis.patch.yml # DSH profile bundle patch
## 构建产物

```text
tsc -p tsconfig.build.json
-> lib/types/* declarations, maps, intermediate ESM

tsdown host bundle
tsdown(直接读取 src/)
-> lib/index.js Node ES2024 ESM

tsdown client bundle
-> lib/client.js DSH browser module wrapper
-> lib/client.js.map

tsc -p tsconfig.types.json
-> lib/types/**/*.d.ts 只生成声明

lightningcss plugin
-> CSS Modules compiled and injected as scoped <style>
```

Host 保持 `cordis` 和 `schemastery` external。Client 保持 React、ReactDOM、JSX runtime 和 Cordis external,其余依赖打入 bundle
Host 将所有 package dependency 保持为 external。Client React、ReactDOM、JSX runtime、CordisDSH UI primitives 保持为 external;来自 `node_modules` 的依赖只允许打入 `markdown-to-jsx`

`lib/` 是发布输入的一部分。修改 `src/` 后必须重新构建并检查生成 diff;不要手工编辑 `lib/`。
`lib/` 是发布输入,但已被 Git 忽略,禁止手工编辑。`pnpm run verify:build` 会连续构建两次并比较每个输出文件的 hash;CSS export 顺序或其他非确定性变化会直接失败。

`src/shared/contracts.ts` 是配置结构、RPC 通道、设置协议和 Client 可见 DTO 的唯一事实源。`src/client/` 下的文件只能通过该 contract 导入父级模块。Host 模块可以为兼容性 re-export shared 类型,但不应重新定义 wire DTO。

## 测试层次

Expand All @@ -80,6 +81,7 @@ Host 保持 `cordis` 和 `schemastery` external。Client 保持 React、ReactDOM
- 生命周期 cue、评分、idle debounce、取消和水位保留;
- RPC authority、只读行为和设置 revision;
- Web 工作台、双语文案和关键交互。
- Client/Host 源码边界、确定性构建 hash、发布包内容、exports 和 TypeScript 解析。

这些主要是临时目录、fake runner 和 mock Host 集成测试,不等同于自动化的真实 DSH + Mnemon WebUI E2E。

Expand Down Expand Up @@ -170,8 +172,8 @@ Web locale 变更时,中文键集合仍是类型事实源;英文词典必须

```text
[ ] pnpm run verify
[ ] review source and generated lib diffs
[ ] validate package file list includes README.md, README.zh-CN.md, docs/assets and bilingual docs
[ ] 确认 worktree 中没有生成的 lib diff
[ ] 确认发布包只包含运行时、声明、根文档和 cordis.patch.yml
[ ] install the built/local bundle into an isolated Web profile
[ ] run real Mnemon CLI and WebUI smoke tests
[ ] verify Chinese and English workspaces
Expand All @@ -180,17 +182,20 @@ Web locale 变更时,中文键集合仍是类型事实源;英文词典必须
[ ] back up any data root used for upgrade testing
```

`package.json.files` 当前发布 `lib`、patch、两份根 README、统一管理的文档视觉素材、双语公开 docs 和 License。
`package.json.files` 当前发布 `lib`、patch、两份根 README、`SECURITY.md` 和 License。文档站点与媒体继续保留在 GitHub,不进入 npm 包

## 发布到 npm

发布后 `dsh plugin --profile web add dsh-mnemon` 即按 registry 名称解析(与 dsh-better-sidebar 同路径)。发布步骤:

```sh
npm pack --dry-run # 检查 tarball 文件清单(含 cordis.patch.yml、lib、docs)
pnpm publish --access public # prepublishOnly 会先跑 pnpm run verify
pnpm run verify
npm pack --ignore-scripts
npm publish dsh-mnemon-<version>.tgz --access public --ignore-scripts
```

发布已经打好的 tarball,能确保 npm 收到的就是人工检查过的制品。GitHub release workflow 会在核对 tag 与 `package.json` 后执行同一流程。

凭据约定:NPM_TOKEN 只写入用户级 `~/.npmrc`(`npm config set "//registry.npmjs.org/:_authToken" "${NPM_TOKEN}" --userconfig ~/.npmrc`),发布后删除。**不要**把凭据行提交进仓库 `.npmrc`:pnpm 11 出于安全会忽略项目级 `.npmrc` 中未展开的环境变量凭据并告警,且该文件会随仓库传播。

2FA 注意:若 npm 账号开启发布级两步验证,交互发布直接执行 `pnpm publish --access public`,按提示输入 OTP;脚本/CI 发布需改用 Classic **Automation** 令牌或允许 bypass 2FA 的 Granular 令牌(`npm login` 生成的普通令牌无法发布,会报 403 Two-factor authentication required)。
Expand Down
Loading