diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..17b1a28 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig — https://editorconfig.org +# 仓库统一编辑器基线;缩进等风格细节以各文件的既有约定为准。 +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +# Makefile 的 recipe 必须用真实 tab(GNU Make 硬性要求)。 +[Makefile] +indent_style = tab diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f10c662..e0494cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,10 @@ jobs: with: # Tests run git log against this repository and need the full history. fetch-depth: 0 + # pnpm version is pinned via packageManager in package.json; the action + # reads it from there (specifying both makes action-setup fail on + # purpose with ERR_PNPM_BAD_PM_VERSION). - uses: pnpm/action-setup@v6 - with: - version: 11 - uses: actions/setup-node@v7 with: node-version: 22 @@ -69,9 +70,10 @@ jobs: with: # Tests run git log against this repository and need the full history. fetch-depth: 0 + # pnpm version is pinned via packageManager in package.json; the action + # reads it from there (specifying both makes action-setup fail on + # purpose with ERR_PNPM_BAD_PM_VERSION). - uses: pnpm/action-setup@v6 - with: - version: 11 - uses: actions/setup-node@v7 with: node-version: 22 @@ -109,9 +111,10 @@ jobs: steps: - uses: actions/checkout@v7 + # pnpm version is pinned via packageManager in package.json; the action + # reads it from there (specifying both makes action-setup fail on + # purpose with ERR_PNPM_BAD_PM_VERSION). - uses: pnpm/action-setup@v6 - with: - version: 11 - uses: actions/setup-node@v7 with: @@ -146,7 +149,7 @@ jobs: - name: Aggregate double-mount regression env: DSH_CMD: dsh - run: bash scripts/e2e-aggregate-mount.sh + run: pnpm test:mount:aggregate - name: Upload Playwright report on failure if: failure() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de47be6..670dfa7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -51,9 +51,10 @@ jobs: # Tests run git log against this repository and need full history. fetch-depth: 0 + # pnpm version is pinned via packageManager in package.json; the action + # reads it from there (specifying both makes action-setup fail on + # purpose with ERR_PNPM_BAD_PM_VERSION). - uses: pnpm/action-setup@v6 - with: - version: 11 - uses: actions/setup-node@v7 with: @@ -84,15 +85,21 @@ jobs: exit 1 fi - - name: Build - run: pnpm build - - name: Typecheck run: pnpm typecheck - name: Test run: pnpm test + - name: Build + run: pnpm build + + # The consumer-facing declaration surface guard — mirrors the ci.yml + # verification order (typecheck → test → build → check:consumer-types) + # so a release is gated on the same checks a PR runs. + - name: Check consumer type surface + run: pnpm check:consumer-types + - name: Dry-run publish (validation only) if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run == 'true' run: pnpm publish --dry-run --no-git-checks diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f703433 --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +# dsh-better-sidebar 命令面薄封装:目标仅转发 package.json scripts(唯一事实源), +# 新增/改名 script 不需要动这里;本文件只补目标发现(help)与 CI 门禁聚合 +# (check / mount / mount-aggregate / registry)。 +# 注:lint 目标留给引入 ESLint 的后续 PR。 + +.DEFAULT_GOAL := help + +help: ## 列出所有可用目标 + @awk -F':.*## ' '/^[a-zA-Z0-9_-]+:.*## / {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +install: ## 安装依赖(pnpm install) + pnpm install + +build: ## 构建(清 lib/ → tsc → tsdown) + pnpm build + +typecheck: ## 类型检查(tsc --noEmit) + pnpm typecheck + +test: ## 单元测试(vitest run) + pnpm test + +check: ## 聚合校验门禁:typecheck → build → test → check:consumer-types(对齐 CI) + pnpm typecheck && pnpm build && pnpm test && pnpm check:consumer-types + +clean: ## 清理构建产物与测试报告(lib/、*.tgz、playwright-report/、test-results/) + rm -rf lib playwright-report test-results + rm -f *.tgz + +pack: ## 打 npm tarball(pnpm pack) + pnpm pack + +mount: ## 真机挂载冒烟:build + pack → Playwright Chromium → pnpm test:mount + pnpm build && pnpm pack && pnpm exec playwright install chromium && pnpm test:mount + +mount-aggregate: ## 聚合双挂载回归:build + pack → pnpm test:mount:aggregate + pnpm build && pnpm pack && pnpm test:mount:aggregate + +registry: ## 组装 plugin-registry 暂存(registry/,不入库):build → node scripts/package-registry.mjs + pnpm build && node scripts/package-registry.mjs + +.PHONY: help install build typecheck test check clean pack mount mount-aggregate registry diff --git a/README.md b/README.md index e6a172d..0787f62 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ dsh plugin --profile web add dsh-better-sidebar@latest # 重跑即成功 遇到报错先查 https://github.com/omdsh-dev/DSH-better-sidebar README 的常见问题表。 ``` +**方式三:一键脚本**——克隆本仓库后执行 `bash scripts/install.sh`(macOS / Linux / Windows Git Bash;Windows 原生环境用 `install.ps1`;`-h` 查看参数),自动完成 add → 放行构建脚本 → 重跑安装。 +
更新 @@ -492,6 +494,16 @@ pnpm test # vitest(含 manifest 一致性守卫,需先 build) pnpm watch # tsdown --watch ``` +**Make 薄封装**(`make help` 查看全部目标;package.json 仍是唯一事实源): + +```sh +make check # 聚合校验门禁:typecheck → build → test → check:consumer-types(对齐 CI) +make mount # 真机挂载冒烟:build + pack → 安装 Chromium → pnpm test:mount +make clean # 清理 lib/、*.tgz、playwright-report/、test-results/ +``` + +`pnpm check:consumer-types`:对外类型声明面守卫——以浏览器-only 消费者(无 `@types/node`、`skipLibCheck: false`)的视角对构建出的 `lib/types` 做类型检查,需先 `pnpm build`。 + **架构**:单 npm 包、host/client 双半结构——host(`src/index.ts`):`/sidebar/api/*` JSON API、`/sidebar/file` 媒体路由、`/sidebar/html` 预览路由、`/sidebar/ws/terminal` WebSocket(fs / git / pty / 预览,全部会话级 + 信任围栏);client(`src/client/index.tsx`):portal 侧边栏 + 各视图 + 拦截;状态按会话持久化 localStorage。插件按 DSH 官方规范组织(无 default 导出、双 client bundle),运行期不依赖 npm / checkout(`@deepseek-ai/*` 由 web profile 提供)。 ## 🔐 安全 @@ -517,7 +529,7 @@ Windows / Linux / macOS 三平台适配(macOS 日常验证;其余经单元 - **代码改动走 PR**:`feat/*` / `fix/*` 分支开发 → `gh pr create`;纯文档改动可直接推 main - **收录生态插件**:给仓库打 `dsh-better-sidebar` topic + 向 [`src/client/plugins-tabs.ts`](./src/client/plugins-tabs.ts) / [`plugins-viewers.ts`](./src/client/plugins-viewers.ts) 提 PR -- **提交前自检**:`pnpm typecheck && pnpm build && pnpm test`(CI 另有 npm 打包 → 真实挂载 → 无头渲染门禁 `pnpm test:mount`) +- **提交前自检**:`pnpm typecheck && pnpm build && pnpm test`(或 `make check` 一键聚合;CI 另有 npm 打包 → 真实挂载 → 无头渲染门禁 `pnpm test:mount`,及聚合双挂载回归 `pnpm test:mount:aggregate`) - 仓库工作规范见 [`AGENTS.md`](./AGENTS.md)(含仓库硬约束与 CI 说明) ## ⭐ Star History diff --git a/README_EN.md b/README_EN.md index a2f8810..be4a7e6 100644 --- a/README_EN.md +++ b/README_EN.md @@ -85,6 +85,8 @@ Install the dsh-better-sidebar plugin (a sidebar workbench for DSH): If anything fails, check the troubleshooting table in the README at https://github.com/omdsh-dev/DSH-better-sidebar ``` +**Option 3: one-shot script** — from a clone of this repo, run `bash scripts/install.sh` (macOS / Linux / Windows Git Bash; native Windows uses `install.ps1`; `-h` for options) — it automates add → approve-builds → re-run. +
Updating @@ -487,6 +489,16 @@ pnpm test # vitest (includes manifest consistency guard; build first) pnpm watch # tsdown --watch ``` +**Make thin wrappers** (`make help` lists every target; package.json stays the single source of truth): + +```sh +make check # aggregate gate: typecheck → build → test → check:consumer-types (mirrors CI) +make mount # real-mount smoke: build + pack → install Chromium → pnpm test:mount +make clean # remove lib/, *.tgz, playwright-report/, test-results/ +``` + +`pnpm check:consumer-types`: the consumer-facing declaration-surface guard — type-checks the built `lib/types` from a browser-only consumer's perspective (no `@types/node`, `skipLibCheck: false`); run `pnpm build` first. + **Architecture**: a single npm package with host/client halves — host (`src/index.ts`): `/sidebar/api/*` JSON API, `/sidebar/file` media route, `/sidebar/html` preview route, `/sidebar/ws/terminal` WebSocket (fs / git / pty / preview, all session-scoped with a trust fence); client (`src/client/index.tsx`): portal sidebar + views + interception; state persisted per session in localStorage. Organized per DSH official conventions (no default export, dual client bundles); no dependency on npm / checkout at runtime (`@deepseek-ai/*` provided by the web profile). ## 🔐 Security @@ -525,7 +537,7 @@ WeChat / QQ group QR codes will live here. After uploading the QR images (drag t - **Code changes go through PRs**: develop on a `feat/*` / `fix/*` branch, then `gh pr create`; docs-only changes may be pushed to main directly - **Curate an ecosystem plugin**: tag your repo with `dsh-better-sidebar` + PR a `PluginEntry` into [`src/client/plugins-tabs.ts`](./src/client/plugins-tabs.ts) / [`plugins-viewers.ts`](./src/client/plugins-viewers.ts) -- **Before submitting**: `pnpm typecheck && pnpm build && pnpm test` (CI additionally gates on npm-pack → real-mount → headless-render via `pnpm test:mount`) +- **Before submitting**: `pnpm typecheck && pnpm build && pnpm test` (or `make check` for the one-shot aggregate; CI additionally gates on npm-pack → real-mount → headless-render via `pnpm test:mount`, plus the aggregate double-mount regression `pnpm test:mount:aggregate`) - See [`AGENTS.md`](./AGENTS.md) for the repository rules (hard constraints, CI lanes, release flow) ## ⭐ Star History diff --git a/package.json b/package.json index 28d9aaf..53f674e 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "engines": { "node": ">=20" }, + "packageManager": "pnpm@11.8.0", "dsh": { "bundle": { "patch": "./cordis.patch.yml" @@ -79,6 +80,8 @@ "prepare": "tsdown", "test": "vitest run", "test:mount": "bash scripts/e2e-mount.sh", + "test:mount:aggregate": "bash scripts/e2e-aggregate-mount.sh", + "clean": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\"", "check:consumer-types": "bash scripts/check-consumer-types.sh" }, "license": "MIT",