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
8 changes: 8 additions & 0 deletions docmd-main/v08/de/navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@
"icon": "package-check",
"collapsible": true,
"children": [
{
"title": "v0.8.12 - Auto-Install-Härtung und GitHub-Pages-Fix",
"path": "/release-notes/0-8-12"
},
{
"title": "v0.8.11 - Sicherheits-Updates und Cross-Locale-Routing",
"path": "/release-notes/0-8-11"
},
{
"title": "v0.8.10 - CLI-Politur und Workspace-UX",
"path": "/release-notes/0-8-10"
Expand Down
57 changes: 57 additions & 0 deletions docmd-main/v08/de/release-notes/0-8-12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "v0.8.12 - Auto-Install-Härtung und GitHub-Pages-Fix"
description: "Release-Notes für docmd v0.8.12 - gehärtete Auto-Install-Pipeline (CWE-78), Engine-Auto-Install, korrigierte Core-Abhängigkeiten und automatische Basispfad-Ableitung für GitHub-Pages-Projektseiten."
date: "2026-07-12"
---

### ✨ Highlights

Diese Version behebt eine Regression, die das Laden von Assets auf GitHub-Pages-Projektseiten kaputt gemacht hat (#175), härtet die Auto-Install-Pipeline gegen Shell-Injection (CWE-78) und entfernt `@docmd/plugin-pwa` aus der Standardinstallation (es war nie ein Core-Plugin).

Keine Breaking Changes. Keine neuen erforderlichen Konfigurationen. Bestehende Configs, Plugins und CI-Pipelines funktionieren unverändert.

### 🐛 Fix: GitHub-Pages-Projektseiten — alle Assets 404 (#175)

Benutzer, die auf `https://username.github.io/repo-name/` deployten, sahen nach dem Upgrade von 0.8.9 für jede CSS-, JS- und Bilddatei einen 404. Die Ursache: 0.8.10 fügte ein `<base href="/">`-Tag hinzu, um ein separates Workspace-Problem zu beheben, wodurch der Browser alle relativen URLs gegen den Domain-Root statt gegen den Unterpfad auflöste.

**Der Fix:** docmd leitet den Asset-Basispfad nun automatisch aus Ihrer `url`-Konfiguration ab. Wenn `url` `https://username.github.io/my-repo` ist, setzt docmd `base` intern auf `/my-repo/`. Es ist keine manuelle `base`-Konfiguration erforderlich.

```json "docmd.config.json"
{
"url": "https://username.github.io/my-repo"
}
```

Das ist alles. docmd übernimmt den Rest.

Benutzer, die `base` explizit gesetzt haben, sind nicht betroffen. Die Ableitung istSlash-tolerant bei `url` und `base` — `"my-repo"`, `"/my-repo"` und `"/my-repo/"` funktionieren alle.

### 🔒 Sicherheit: Shell-Injection im Auto-Install (CWE-78)

Der Auto-Install-Pfad für Plugins baute einen Shell-String-Befehl, indem der Paketname in `pnpm add ${pkg}` interpoliert wurde. Ein Paketname mit Shell-Metazeichen konnte beliebige Befehle unter dem Benutzerkonto ausführen.

**Der Fix:** ein neues gemeinsames Modul (`packages/api/src/runtime-deps.ts`) ersetzt den Shell-String durch `spawn(pm, args, { shell: false })` mit einem festen Argument-Array. Ein strenger Regex-Validator und ein Registry-Lookup wirken als Defence-in-Depth. Der Auto-Install-Pfad kann nicht mehr zu einem generischen `npm install`-Loader umfunktioniert werden.

### 🧰 Gemeinsames runtime-deps-Modul

Der Plugin-Loader (`hooks.ts`) und der Engine-Loader (`engine.ts`) pflegten jeweils eine eigene Kopie der Auto-Install-Pipeline. Beide nutzen nun `runtime-deps.ts`. Ein Installationsverhalten, überall angewendet. Der TUI-Status-Reporter ist pro Build idempotent, sodass Dev-Server-Rebuilds keine doppelten `[ WAIT ]`- / `[ DONE ]`-Zeilen erzeugen.

### 🛠 Engine-Auto-Install

Das Anfordern von `engine: "rust"` in der Konfiguration fiel bisher direkt auf JS zurück, wenn `@docmd/engine-rust` nicht installiert war. Der neue Ablauf versucht, `engine-rust` zuerst zu installieren; schlägt die Installation fehl oder ist die native Binärdatei auf der Plattform nicht verwendbar, wird auf JS zurückgegriffen und der Grund wird in einer `[ FAIL ]`-Zeile angezeigt.

### 📦 Korrigierte Core-Abhängigkeiten

`@docmd/plugin-pwa` war als direkte Abhängigkeit von `@docmd/core` gelistet, gehörte aber nie zu `CORE_PLUGINS`. Jedes `npm install @docmd/core` hat es installiert, auch für Benutzer, die PWA nie aktiviert haben.

**Der Fix:** `@docmd/plugin-pwa` aus `packages/core/package.json#dependencies` entfernt. Es wird nun bei Bedarf installiert, genauso wie `math`, `threads` und alle anderen optionalen Plugins.

### 📐 Testabdeckung

51 neue Assertions in `tests/cli-contracts/runtime-deps.test.js`: öffentliche API, Validator (12 positive, 13 negative Fälle inklusive Shell-Metazeichen), Registry-Cache-Idempotenz, Install-Verweigerungs-Pfade und statische Quellcode-Prüfungen.

### Migration

Null. Bestehende Configs, Plugins und CI-Pipelines funktionieren unverändert.

**Vollständiges Changelog**: https://github.com/docmd-io/docmd/compare/0.8.11...0.8.12
19 changes: 19 additions & 0 deletions docmd-main/v08/en/deployment/github-action.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ After this, every push to `main` triggers a deployment automatically.

If your `docmd.config.json` lives in a subdirectory — for example, `packages/docs/docmd.config.json` in a monorepo — the action detects it and passes `--cwd` to docmd automatically. No manual path configuration is required.

## Project Pages (Subpath Deployment)

GitHub Pages serves project sites at `https://<username>.github.io/<repo-name>/`, not at the domain root. docmd handles this automatically — set `url` to your full GitHub Pages URL and docmd derives the correct asset paths from it:

```json "docmd.config.json"
{
"url": "https://username.github.io/my-repo"
}
```

That's it. docmd reads the `/my-repo/` subpath from your URL and uses it for every internal link and asset reference. No additional configuration is needed.

::: callout tip "How docmd knows your deployment path"
docmd derives the asset base path from your `url` config. The `url` you set for SEO and sitemaps is the same value docmd uses to figure out where your assets live. Set it once, everything follows.

If your deployment path ever differs from your URL path (rare, e.g. a CDN that strips a prefix), you can override with `base`. docmd normalises slashes for you, so any of these work:
`"my-repo"`, `"/my-repo"`, `"/my-repo/"`. You don't have to remember which slashes are required.
:::

## Custom Domain

To use a custom domain:
Expand Down
8 changes: 8 additions & 0 deletions docmd-main/v08/en/navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@
"icon": "package-check",
"collapsible": true,
"children": [
{
"title": "v0.8.12 - Auto-Install Hardening and GitHub Pages Fix",
"path": "/release-notes/0-8-12"
},
{
"title": "v0.8.11 - Security Fixes and Cross-Locale Routing",
"path": "/release-notes/0-8-11"
},
{
"title": "v0.8.10 - CLI Polish and Workspace UX",
"path": "/release-notes/0-8-10"
Expand Down
57 changes: 57 additions & 0 deletions docmd-main/v08/en/release-notes/0-8-12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "v0.8.12 - Auto-Install Hardening and GitHub Pages Fix"
description: "Release notes for docmd v0.8.12 - hardened auto-install pipeline (CWE-78), engine auto-install, corrected core dependency manifest, and automatic base path derivation for GitHub Pages project sites."
date: "2026-07-12"
---

### ✨ Highlights

This release fixes a regression that broke asset loading on GitHub Pages project sites (#175), hardens the plugin/template/engine auto-install pipeline against shell injection (CWE-78), and removes `@docmd/plugin-pwa` from the default install (it was never a core plugin).

No breaking changes. No new required config. Existing configs, plugins, and CI pipelines work unchanged.

### 🐛 Fix: GitHub Pages project sites 404 on all assets (#175)

Users deploying to `https://username.github.io/repo-name/` saw every CSS, JS, and image file 404 after upgrading from 0.8.9. The cause: 0.8.10 added a `<base href="/">` tag to fix a separate workspace issue, which made the browser resolve all relative URLs against the domain root instead of the subpath.

**The fix:** docmd now derives the asset base path from your `url` config automatically. If `url` is `https://username.github.io/my-repo`, docmd sets `base` to `/my-repo/` internally. No manual `base` config is needed.

```json "docmd.config.json"
{
"url": "https://username.github.io/my-repo"
}
```

That's it. docmd handles the rest.

Users who explicitly set `base` are unaffected. The derivation is slash-tolerant on both `url` and `base` — `"my-repo"`, `"/my-repo"`, and `"/my-repo/"` all work.

### 🔒 Security: shell injection in auto-install (CWE-78)

The plugin auto-install path built a shell-string command by interpolating the package name into `pnpm add ${pkg}`. A package name with shell metacharacters that ever reached this code path would execute arbitrary commands under the user's account.

**The fix:** a new shared module (`packages/api/src/runtime-deps.ts`) replaces the shell-string with `spawn(pm, args, { shell: false })` using a fixed arg array. A strict regex validator (`/^@docmd\/(plugin|template|engine)-[a-z0-9][a-z0-9.-]*$/`) and a registry lookup act as defence-in-depth. The auto-install path can no longer be turned into a generic `npm install` loader.

### 🧰 Shared runtime-deps module

The plugin loader (`hooks.ts`) and the engine loader (`engine.ts`) each used to carry their own copy of the auto-install pipeline. Both now go through `runtime-deps.ts`. One install behaviour, applied everywhere. The TUI status reporter is idempotent per-build, so dev-server rebuilds do not spam duplicate `[ WAIT ]` / `[ DONE ]` lines.

### 🛠 Engine auto-install

Requesting `engine: "rust"` in config used to fall straight through to JS if `@docmd/engine-rust` was not installed. The new flow tries to install `engine-rust` first; if the install fails or the native binary is not usable on the platform, it falls back to JS and surfaces the reason in a `[ FAIL ]` line. The same applies to `loadEngine('js')` as a last resort.

### 📦 Corrected core dependency manifest

`@docmd/plugin-pwa` was listed as a direct dependency of `@docmd/core` but was never in `CORE_PLUGINS` (the source-of-truth constant that drives auto-loading). Every `npm install @docmd/core` pulled it in, even for users who never enabled PWA.

**The fix:** removed `@docmd/plugin-pwa` from `packages/core/package.json#dependencies`. It now installs on demand, the same as `math`, `threads`, and every other optional plugin. The dependency list now matches `CORE_PLUGINS` exactly.

### 📐 Test coverage

51 new assertions in `tests/cli-contracts/runtime-deps.test.js`: public surface, validator (12 positive, 13 negative cases including shell metacharacters), registry cache idempotency, install refusal paths, and static source checks proving no `execSync` shell-string remains in `hooks.ts` or `engine.ts`.

### Migration

Zero. Existing configs, plugins, and CI pipelines work unchanged.

**Full changelog**: https://github.com/docmd-io/docmd/compare/0.8.11...0.8.12
8 changes: 8 additions & 0 deletions docmd-main/v08/zh/navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@
"icon": "package-check",
"collapsible": true,
"children": [
{
"title": "v0.8.12 - 自动安装加固与 GitHub Pages 修复",
"path": "/release-notes/0-8-12"
},
{
"title": "v0.8.11 - 安全修复与跨语言路由",
"path": "/release-notes/0-8-11"
},
{
"title": "v0.8.10 - CLI 打磨与 Workspace UX",
"path": "/release-notes/0-8-10"
Expand Down
57 changes: 57 additions & 0 deletions docmd-main/v08/zh/release-notes/0-8-12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "v0.8.12 - 自动安装加固与 GitHub Pages 修复"
description: "docmd v0.8.12 发布说明 - 加固自动安装管道 (CWE-78)、引擎自动安装、修正核心依赖清单,以及 GitHub Pages 项目页面的自动 base 路径推导。"
date: "2026-07-12"
---

### ✨ 亮点

本版本修复了 GitHub Pages 项目页面资源加载失败的回归问题 (#175),加固了插件/模板/引擎自动安装管道以防御 Shell 注入 (CWE-78),并从默认安装中移除了 `@docmd/plugin-pwa`(它从来不是核心插件)。

无破坏性变更。无需新增配置。现有配置、插件和 CI 管道无需修改即可正常工作。

### 🐛 修复:GitHub Pages 项目页面所有资源 404 (#175)

部署到 `https://username.github.io/repo-name/` 的用户在从 0.8.9 升级后发现所有 CSS、JS 和图片文件都返回 404。原因:0.8.10 添加了 `<base href="/">` 标签以修复另一个工作区问题,导致浏览器将所有相对 URL 解析到域名根路径而非子路径。

**修复方案:** docmd 现在自动从您的 `url` 配置推导资源基础路径。如果 `url` 为 `https://username.github.io/my-repo`,docmd 会在内部将 `base` 设为 `/my-repo/`。无需手动配置 `base`。

```json "docmd.config.json"
{
"url": "https://username.github.io/my-repo"
}
```

就是这样。docmd 会处理其余工作。

显式设置 `base` 的用户不受影响。推导对 `url` 和 `base` 的斜杠都容错 — `"my-repo"`、`"/my-repo"` 和 `"/my-repo/"` 都可以正常工作。

### 🔒 安全:自动安装中的 Shell 注入 (CWE-78)

插件自动安装路径通过将包名插入 `pnpm add ${pkg}` 来构建 Shell 字符串命令。包含 Shell 元字符的包名可以在用户账户下执行任意命令。

**修复方案:** 新的共享模块 (`packages/api/src/runtime-deps.ts`) 用 `spawn(pm, args, { shell: false })` 替换了 Shell 字符串,使用固定参数数组。严格的正则验证器和注册表查找作为纵深防御。自动安装路径无法再被转为通用的 `npm install` 加载器。

### 🧰 共享 runtime-deps 模块

插件加载器 (`hooks.ts`) 和引擎加载器 (`engine.ts`) 各自维护一份自动安装管道的副本。两者现在都通过 `runtime-deps.ts`。一处安装行为,处处适用。TUI 状态报告器在每次构建中是幂等的,因此开发服务器重建不会产生重复的 `[ WAIT ]` / `[ DONE ]` 行。

### 🛠 引擎自动安装

在配置中请求 `engine: "rust"` 时,如果未安装 `@docmd/engine-rust`,以前会直接回退到 JS。新流程会先尝试安装 `engine-rust`;如果安装失败或原生二进制文件在当前平台不可用,则回退到 JS 并在 `[ FAIL ]` 行中显示原因。

### 📦 修正核心依赖清单

`@docmd/plugin-pwa` 被列为 `@docmd/core` 的直接依赖,但从未包含在 `CORE_PLUGINS` 中。每次 `npm install @docmd/core` 都会安装它,即使用户从未启用 PWA。

**修复方案:** 从 `packages/core/package.json#dependencies` 中移除 `@docmd/plugin-pwa`。它现在按需安装,与 `math`、`threads` 及其他可选插件一样。

### 📐 测试覆盖

`tests/cli-contracts/runtime-deps.test.js` 中新增 51 个断言:公共 API、验证器(12 个正向用例、13 个负向用例,包括 Shell 元字符)、注册表缓存幂等性、安装拒绝路径,以及静态源码检查。

### 迁移

无需迁移。现有配置、插件和 CI 管道无需修改即可正常工作。

**完整变更日志**: https://github.com/docmd-io/docmd/compare/0.8.11...0.8.12