Project-specific Rust + Tauri rules:
.claude/rules/rust.md. Release runbook:.claude/skills/release/SKILL.md(run/release).
Pake - Turn any webpage into a lightweight desktop app with one command.
- Purpose: Package any website into a ~5MB desktop app (20x smaller than Electron)
- Stack: Tauri v2 (Rust) + TypeScript CLI
- Platforms: macOS, Windows, Linux
- Mechanism: Uses system webview (WebKit on macOS/Linux, WebView2 on Windows)
Pake/
├── bin/ # CLI source code (TypeScript)
│ └── cli.ts # Main CLI entry (Commander.js)
├── src-tauri/ # Tauri Rust application
│ ├── src/ # Rust source code
│ ├── src/app/ # window creation, setup, menu, config, and invokes
│ ├── src/inject/ # injected JS/CSS behavior
│ ├── Cargo.toml # Rust dependencies and version
│ ├── tauri.conf.json # Tauri configuration and version
│ └── .cargo/ # Cargo configuration (gitignored)
├── dist/ # Compiled CLI output
├── docs/ # Documentation
│ ├── cli-usage.md # CLI parameters
│ ├── advanced-usage.md # Customization guide
│ └── faq.md # Troubleshooting
├── scripts/ # Utility scripts
├── tests/ # Unit, integration, and release-flow tests
├── .github/workflows/ # quality/test and release automation
├── default_app_list.json # Popular apps config for release builds
├── package.json # Node.js dependencies and version
└── rollup.config.js # CLI build configuration
| Command | Purpose |
|---|---|
pnpm install |
Install dependencies |
pnpm run dev |
Tauri development mode |
pnpm run cli:dev -- <url> |
CLI wrapper + Tauri (recommended) |
pnpm run cli:dev --iterative-build |
Faster dev (skip checks) |
pnpm run cli:build |
Rollup + TypeScript check (catches type errors Prettier misses) |
pnpm run build |
Build for current platform |
pnpm run build:mac |
macOS universal binary |
pnpm run format |
Format code (prettier + cargo fmt) |
npx vitest run |
Unit and integration tests only (sub-second) |
pnpm test -- --no-build |
Full suite minus the multi-arch real build |
pnpm test |
Full suite including release workflow |
Keep shared project facts in this file so Codex, Claude Code, and other agents use the same source of truth. CLAUDE.md is a symlink to this file, so edit AGENTS.md only. Local-only overrides (CLAUDE.local.md, AGENTS.override.md, .claude/settings.local.json) stay ignored.
- No Chinese comments in any source (Rust / TypeScript / any file). Comments and identifiers in English; follow the existing language of surrounding prose.
Prefer requests with:
Goal: exact bug, feature, refactor, or review targetScope: files, directories, or subsystem boundaries to inspect firstRepro: command, input, fixture, or failing testExpected: expected behaviorActual: current behavior, error text, or regression noteConstraints: what must not changeVerify: minimum command or test that proves the result
When task scope is incomplete, inspect in this order:
- CLI entry and option parsing under
bin/cli.ts,bin/options/, andbin/helpers/ - Target TypeScript module under
bin/ - Tauri runtime or packaging files under
src-tauri/src/andsrc-tauri/tauri*.conf.json - Narrow tests under
tests/unit/ortests/integration/ - Release workflow files under
.github/workflows/only for CI or release issues - Docs only if behavior, ownership, or expected usage is still unclear
Execution rules:
- Start with the smallest plausible file set
- Prefer targeted search (
rg <symbol|string> <paths>) over repository-wide scans - Ignore generated or output-heavy areas unless the task directly targets them, especially
dist/,node_modules/,src-tauri/target/,.app/,src-tauri/icons/, andsrc-tauri/png/. Exception:dist/cli.jsis the shipped CLI build artifact (seepackage.jsonfiles); when you change anything underbin/, rebuild it viapnpm run cli:buildand commit the regenerateddist/cli.jsalongside the source change - If a task touches release status, issue closeout, npm delivery, or GitHub assets, verify live surfaces separately: source commit/tag, workflow run, npm registry, GitHub Release/assets, and issue state. Do not let one passing surface imply another
- Keep changes local to one subsystem when possible
- Run the narrowest relevant verification first, expand only if needed
- If key context is missing, make one reasonable assumption and proceed
- CLI options are user-facing and must stay synchronized across
bin/helpers/cli-program.ts,bin/types.ts,bin/defaults.ts,bin/helpers/merge.ts, generateddist/cli.js, anddocs/cli-usage*.md. - Recent window/runtime options include
--incognito,--new-window,--min-width,--min-height,--maximize, multi-window behavior, notification click handling, and Linux/Wayland WebKit compositing defaults. --incognitointentionally trades persistence for clean private sessions; be careful around login, cookies, local storage, and WeChat-style WebView detection.--new-windowand--multi-windowdo not bypass every provider policy. Google OAuth and similar embedded-WebView restrictions may still require a normal browser or native client.- macOS auth-popup behavior is fragile. Auth/sign-in URLs that trigger WebKit
SOAuthorizationpopup creation should stay in the current window when that path can abort the app; changes insrc-tauri/src/inject/event.jsneed targeted tests. - Notification flows cross injected JS, Tauri invokes, capabilities, and native notification plugins. Verify the Rust capability and JS caller together.
- WebKit compositing behavior is platform-sensitive on Linux/Wayland. Runtime flag decisions live in
src-tauri/src/lib.rs; keep the default conservative, cover compositor exceptions with unit tests, and document user-facing fallbacks indocs/faq*.md. - Linux AppImage reports often include harmless GTK, appindicator, or GStreamer warnings. Separate optional runtime warnings from the actual symptom before changing code; input/click failures on pure Wayland compositors are not the same class as blank-window failures.
- Release state can be split. npm Trusted Publishing can succeed before the popular-app release workflow finishes, and GitHub Release assets can exist while a workflow run still shows queued or in progress. Report each surface explicitly.
- Universal builds via
--multi-arch(Intel + Apple Silicon). - Icons:
.icns. - Title bar can be customized via Tauri window options.
- Requires Visual Studio Build Tools to compile.
- Icons:
.ico. - MSI installer supported via Tauri bundler.
- Multiple package formats:
.deb,.AppImage,.rpm. - Runtime depends on
libwebkit2gtkand its companion libraries. - Icons:
.png. - WebKit compositing is platform-sensitive on Wayland; see Current Risk Areas before changing defaults.
main- Only branch. All development and releases happen here directly.
Four files must be updated in sync for every release:
| File | Field |
|---|---|
package.json |
"version" |
src-tauri/Cargo.toml |
version under [package] |
src-tauri/Cargo.lock |
version for package pake |
src-tauri/tauri.conf.json |
"version" |
Tag format: V0.x.x (uppercase V). Current version: check package.json.
Pushing a V* tag triggers .github/workflows/release.yml:
- release-apps - reads
default_app_list.jsonfor app list - create-release - creates the GitHub Release placeholder
- build-cli - builds and uploads the
dist/CLI artifact - build-popular-apps - builds all apps in parallel across macOS/Windows/Linux
- publish-docker - builds and pushes Docker image to GHCR
The workflow can also be triggered manually via workflow_dispatch with options to build popular apps or publish Docker independently.
Pushing the same V* tag also triggers .github/workflows/npm-publish.yml, which publishes pake-cli to npm through Trusted Publishing. Configure the npm package's Trusted Publisher as GitHub Actions, tw93/Pake, workflow file npm-publish.yml, with no environment. Local npm publish is only a fallback when CI or npm registry state blocks the trusted path.
Before treating an npm release as shipped, verify both gh workflow list --all | grep "Publish npm Package" and npm view pake-cli@X.Y.Z version. Prefer npm view pake-cli@X.Y.Z version gitHead dist.tarball --json so the published package can be tied back to the intended commit. Do not reply to or close GitHub issues as released until the public registry returns the expected version.
For release follow-through, keep these boundaries explicit:
workflow_dispatchruns on a branch unless a tag ref or input is supplied. Do not infer a release tag from the branch name, run title, or compare UI.- For CLI/npm issue closeout, the npm registry is the decisive public surface. GitHub app release assets and quality workflows should still be reported, but they are separate surfaces.
- For app-release claims, inspect the GitHub Release directly with
gh release view <tag> --json assetsand check asset count/state instead of trusting source state or workflow names alone. - If CI pushes an automatic
chore: update contributors [skip ci]commit after release, fast-forward localmain; do not move an already pushed release tag to include it.
.github/workflows/quality-and-test.yml runs auto-format on push, Rust quality checks, and CLI/build validation across Linux, Windows, and macOS.
Pake uses official npm and Rust sources by default. CN mirrors are explicit opt-in only:
- Set
PAKE_USE_CN_MIRROR=1only when the user or CI environment intentionally wants npmmirror/rsProxy. - Do not reintroduce automatic China-domain mirror switching.
- If an install fails against a CN mirror, retry the same install command to separate network availability from a product regression.
bin/utils/mirror.tsandbin/builders/BaseBuilder.tsown this behavior; keep docs and tests aligned when changing it.
# Install CLI
pnpm install -g pake-cli
# Basic usage
pake https://github.com --name GitHub
# Advanced usage
pake https://weekly.tw93.fun --name Weekly --width 1200 --height 800See docs/faq.md for common issues and solutions.
If compilation errors occur (e.g. on macOS beta), create src-tauri/.cargo/config.toml:
[env]
MACOSX_DEPLOYMENT_TARGET = "15.0"
SDKROOT = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"This file is already in .gitignore.
Symptom: tests or release builds use stale CLI behavior after a bin/ edit. Fix with pnpm run cli:build and commit the regenerated dist/cli.js.
The first cargo build on a fresh clone takes 10+ minutes as Cargo compiles every Tauri dependency from source. Subsequent builds reuse the src-tauri/target/ cache. This is expected, not a bug.
- Main README: keep only common, frequently-used parameters to avoid clutter.
- CLI Documentation (
docs/cli-usage.mdand locale variants): include all CLI parameters with detailed usage examples. - Rare or advanced parameters: should have full documentation in
docs/cli-usage*.mdbut minimal or no mention in the main README. Examples:--title,--incognito,--system-tray-icon,--multi-window,--min-width,--min-height. - Key configuration files:
pake.json- default app configuration.src-tauri/tauri.conf.json- shared Tauri settings.src-tauri/tauri.{macos,windows,linux}.conf.json- per-platform overrides.