diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml
index 51fb5423..1a9e93ce 100644
--- a/.github/workflows/release-assets.yml
+++ b/.github/workflows/release-assets.yml
@@ -144,7 +144,7 @@ jobs:
name: GitHub Release
if: ${{ always() && !cancelled() && (startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') }}
runs-on: ubuntu-latest
- timeout-minutes: 15
+ timeout-minutes: 60
needs: build-assets
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
@@ -267,6 +267,49 @@ jobs:
if: env.CARGO_REGISTRY_TOKEN != ''
uses: dtolnay/rust-toolchain@1.97.1
+ - name: Cache cargo registry
+ if: env.CARGO_REGISTRY_TOKEN != ''
+ uses: Swatinem/rust-cache@v2
+ with:
+ shared-key: crates-io-publish
+ cache-targets: false
+ cache-on-failure: true
+
+ # Members first (path+version deps), then root. Re-runs on workflow_dispatch
+ # treat "already uploaded" as success. A publish failure after GitHub
+ # Release is intentional so the missing crates.io crate is visible.
- name: Publish to crates.io
if: env.CARGO_REGISTRY_TOKEN != ''
- run: cargo publish --locked --token "$CARGO_REGISTRY_TOKEN"
+ run: |
+ set -euo pipefail
+ publish_one() {
+ local pkg="$1"
+ local attempt
+ for attempt in 1 2 3 4 5; do
+ local log
+ log="$(mktemp)"
+ set +e
+ cargo publish -p "$pkg" --locked --token "$CARGO_REGISTRY_TOKEN" 2>&1 | tee "$log"
+ local status="${PIPESTATUS[0]}"
+ set -e
+ if [ "$status" -eq 0 ]; then
+ return 0
+ fi
+ if grep -qiE 'already exists|already uploaded' "$log"; then
+ echo "skip $pkg (already on crates.io)"
+ return 0
+ fi
+ if grep -qiE 'no matching package named|not found in the registry|try again later|timed out|timeout|503|502|429' "$log"; then
+ echo "retry $pkg after index/network delay (attempt ${attempt})"
+ sleep $((attempt * 15))
+ continue
+ fi
+ echo "::error::cargo publish -p $pkg failed"
+ return 1
+ done
+ echo "::error::cargo publish -p $pkg failed after retries"
+ return 1
+ }
+ publish_one amber_transpile
+ publish_one amber_sandbox
+ publish_one amberjs
diff --git a/Cargo.toml b/Cargo.toml
index 22d916bf..00a967ab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,51 +13,19 @@ homepage = "https://amberjs.com"
documentation = "https://docs.rs/amberjs"
keywords = ["javascript", "typescript", "runtime", "v8"]
categories = ["command-line-utilities", "development-tools"]
+# Whitelist: enough to build the default `amber` binary after `cargo publish`,
+# without shipping target/, node_modules/, apps/, or the 46MB benchmarks/ tree.
+# `/src/**` is required — lib.rs compiles many modules the old file-by-file
+# list omitted, and include_str! also needs src/web_api/*.js plus types/.
include = [
"/Cargo.toml",
"/Cargo.lock",
"/README.md",
"/LICENSE",
"/build.rs",
- "/src/lib.rs",
- "/src/napi/*.rs",
- "/src/main.rs",
- "/src/event_loop.rs",
- "/src/runtime_minimal.rs",
- "/src/package_manager.rs",
- "/src/watcher.rs",
- "/src/watcher_websocket.rs",
- "/src/ecosystem_lite.rs",
- "/src/performance_analyzer.rs",
- "/src/performance_comparison.rs",
- "/src/performance_regression.rs",
- "/src/performance_reporter.rs",
- "/src/ai/*.rs",
- "/src/ai_inference/*.rs",
- "/src/aiops/**/*.rs",
- "/src/benchmarks/*.rs",
- "/src/cloud_native/**/*.rs",
- "/src/error/*.rs",
- "/src/fallback/*.rs",
- "/src/memory/*.rs",
- "/src/monitor/**/*.rs",
- "/src/multilang/*.rs",
- "/src/nodejs_core/*.rs",
- "/src/observability/**/*.rs",
- "/src/platform/*.rs",
- "/src/security/*.rs",
- "/src/testing/**/*.rs",
- "/src/typescript/*.rs",
- "/src/v8_snapshot/*.rs",
- "/src/web_api/*.rs",
- "/types/*.d.ts",
- "/tests/*.rs",
- "/tests/integration/*.rs",
- "/examples/basics/*.js",
- "/examples/basics/*.ts",
- "/examples/testing/*.js",
- "/docs/CLI_USAGE_GUIDE.md",
- "/docs/QUICK_START.md",
+ "/src/**",
+ "/types/**",
+ "/benches/runtime_startup.rs",
]
[workspace]
@@ -91,9 +59,11 @@ wasmtime-wasi = "38.0"
# WebAssembly bindings
wasm-bindgen = "0.2"
-# Workspace member crates
-amber_transpile = { path = "crates/amber_transpile" }
-amber_sandbox = { path = "crates/amber_sandbox" }
+# Workspace member crates (path for local builds; version for crates.io).
+# `cargo publish -p amberjs --dry-run` cannot resolve these until the same
+# versions exist on crates.io; Release Assets publishes the members first.
+amber_transpile = { path = "crates/amber_transpile", version = "1.16.0" }
+amber_sandbox = { path = "crates/amber_sandbox", version = "1.16.0" }
wasm-bindgen-futures = "0.4"
# WebAssembly binary format
diff --git a/README.md b/README.md
index fc3ba9c3..ca297be0 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@
+
@@ -74,6 +75,12 @@ Homebrew (formula in this repo; SHA256 is rewritten on each GitHub Release):
brew install zh30/tap/amber
```
+crates.io (each GitHub `v*` tag publishes via Release Assets + `CARGO_REGISTRY_TOKEN`; install the `amber` binary):
+
+```sh
+cargo install amberjs
+```
+
```sh
amber --version
amber eval "1 + 1"
diff --git a/apps/website/src/docs/installation.md b/apps/website/src/docs/installation.md
index 04c1c554..b0992301 100644
--- a/apps/website/src/docs/installation.md
+++ b/apps/website/src/docs/installation.md
@@ -28,6 +28,14 @@ Homebrew (formula in the Amber repo; tap hashes are filled after each GitHub Rel
brew install zh30/tap/amber
```
+From crates.io (GitHub `v*` tags publish `amber_transpile`, `amber_sandbox`, then `amberjs` via Release Assets + `CARGO_REGISTRY_TOKEN`):
+
+```bash
+cargo install amberjs
+```
+
+This installs the `amber` binary. Needs Rust **1.97.1** and a C++ toolchain for V8.
+
### What the Install Script Does
1. **Detects Environment**: Automatically identifies your OS (macOS / Linux) and CPU architecture (Apple Silicon `arm64` or Intel `x86_64`).
diff --git a/apps/website/src/docs/installation.zh.md b/apps/website/src/docs/installation.zh.md
index e60bc175..681faca6 100644
--- a/apps/website/src/docs/installation.zh.md
+++ b/apps/website/src/docs/installation.zh.md
@@ -28,6 +28,14 @@ Homebrew(配方在 Amber 仓库内;每次 GitHub Release 后填写 sha256)
brew install zh30/tap/amber
```
+crates.io(GitHub `v*` 标签通过 Release Assets + `CARGO_REGISTRY_TOKEN` 按 `amber_transpile` → `amber_sandbox` → `amberjs` 发布):
+
+```bash
+cargo install amberjs
+```
+
+会安装 `amber` 二进制。需要 Rust **1.97.1** 以及编译 V8 的 C++ 工具链。
+
### 安装脚本执行过程说明
1. **自动识别硬件与系统**:自动检测你的系统(macOS / Linux)与 CPU 架构(Apple Silicon `arm64`、Intel `x86_64`);
diff --git a/crates/amber_sandbox/Cargo.toml b/crates/amber_sandbox/Cargo.toml
index 0f2a819b..c195af97 100644
--- a/crates/amber_sandbox/Cargo.toml
+++ b/crates/amber_sandbox/Cargo.toml
@@ -2,8 +2,15 @@
name = "amber_sandbox"
version = "1.16.0"
edition = "2021"
+authors = ["Henry Zhang"]
description = "Capability sandbox and in-memory virtual filesystem for Amber runtime"
license = "MIT"
+readme = "README.md"
+repository = "https://github.com/zh30/amberjs"
+homepage = "https://amberjs.com"
+documentation = "https://docs.rs/amber_sandbox"
+keywords = ["sandbox", "vfs", "permissions"]
+categories = ["development-tools"]
[dependencies]
once_cell = "1.0"
diff --git a/crates/amber_sandbox/README.md b/crates/amber_sandbox/README.md
new file mode 100644
index 00000000..8d56bc85
--- /dev/null
+++ b/crates/amber_sandbox/README.md
@@ -0,0 +1,9 @@
+# amber_sandbox
+
+Capability sandbox and in-memory virtual filesystem used by the [Amber](https://github.com/zh30/amberjs) runtime (`--sandbox`, permission policy, deterministic VFS).
+
+Published as a workspace crate so `amberjs` can be released to crates.io. The CLI users want is:
+
+```sh
+cargo install amberjs
+```
diff --git a/crates/amber_transpile/Cargo.toml b/crates/amber_transpile/Cargo.toml
index 08d25d13..29e28a4e 100644
--- a/crates/amber_transpile/Cargo.toml
+++ b/crates/amber_transpile/Cargo.toml
@@ -2,8 +2,15 @@
name = "amber_transpile"
version = "1.16.0"
edition = "2021"
+authors = ["Henry Zhang"]
description = "Fast TypeScript transpile and bundling engine for Amber runtime"
license = "MIT"
+readme = "README.md"
+repository = "https://github.com/zh30/amberjs"
+homepage = "https://amberjs.com"
+documentation = "https://docs.rs/amber_transpile"
+keywords = ["javascript", "typescript", "transpile"]
+categories = ["development-tools"]
[dependencies]
oxc = { version = "0.147", default-features = false, features = [
diff --git a/crates/amber_transpile/README.md b/crates/amber_transpile/README.md
new file mode 100644
index 00000000..72b416f6
--- /dev/null
+++ b/crates/amber_transpile/README.md
@@ -0,0 +1,9 @@
+# amber_transpile
+
+TypeScript/TSX transpile engine for the [Amber](https://github.com/zh30/amberjs) runtime. It uses [oxc](https://oxc.rs/) and is transpile-only (no `tsc` typecheck).
+
+Published as a workspace crate so `amberjs` can be released to crates.io. The CLI users want is:
+
+```sh
+cargo install amberjs
+```
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index eddfdb37..7d083216 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -596,6 +596,8 @@ pub fn execute_string(&self, code: &str) -> Result