Skip to content
Closed
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
3 changes: 3 additions & 0 deletions .agents/skills/codexhost-release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ description: 发布 codexhost 正式版、预览版,编写或确认 Release No
- `.github/workflows/release-packages.yml` 与 `.github/workflows/ci.yml`
- `packages/repository-automation/src/release.mjs`
- `docs/operations/repository-maintenance.md`
- 本仓库若是 fork `karlorz/codex-host`:先读 [fork versioning](../../../docs/operations/fork-versioning.md)(`0.13.2-0` / `0.13.2-1`…,控制台版本同源),再读本 Skill 的上游渠道表
- 涉及更新提示时:`packages/update-manager/src/github-release.ts`

源码和工作流是执行行为的依据。发现指南与当前实现不一致时,说明差异;不要假装已有不支持的发布能力。
Expand All @@ -38,6 +39,8 @@ description: 发布 codexhost 正式版、预览版,编写或确认 Release No

用户意图不清楚时,先问清两个渠道的目标。最终执行前明确报告版本、npm dist-tag、GitHub 状态与是否提示更新。

在 `karlorz/codex-host` 上,上表的 BytePioneer npm `@codexhost/cli` / 正式 GitHub latest **不适用**。Fork 标签跟随当前 upstream 版本加计数器(upstream 仍为 `0.13.2` 时用 `v0.13.2-0`、`v0.13.2-1`,不要写成 `0.13.3-cpa.1`)。不向 `upstream` 推送。Fork **必须**把同一版本发布为 `@karlorz/codexhost-cli@latest`(及对应平台包),并把 `karlorz/codex-host` 上的 GitHub Release 标成 latest,这样 Settings 的 `npm install -g @karlorz/codexhost-cli@latest` 和 in-app Update 才指向 fork。禁止发布 `@codexhost/*`。`Release packages` 在未改成 `@karlorz` Trusted Publisher 前保持 disabled。控制台「codexhost 版本」必须与该准备版本一致。规则全文:[fork versioning](../../../docs/operations/fork-versioning.md)。

## 2. 检查现场与验证

1. 检查工作区、当前分支、远端与已有标签;快进同步 `main`,不覆盖无关修改。
Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/codexhost-release/references/release-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
| 稳定 SemVer,默认发布 | `latest` | 正式 Release、latest |
| 稳定 SemVer,手动发布且 `github_prerelease=true` | `latest` | Prerelease、非 latest |

静默预览发行用于“小修复让用户自行下载,但不推送更新提示”:npm 正常发布到 `latest`,GitHub 标记为 Prerelease。当前更新检查读取 GitHub 正式 latest Release,不读取 npm dist-tag;预览发行仍公开可下载。SemVer 预发布则在 npm 使用 `next`,用户需显式安装 `@codexhost/cli@next`。
静默预览发行用于“小修复让用户自行下载,但不推送更新提示”:npm 正常发布到 `latest`,GitHub 标记为 Prerelease。当前更新检查读取 GitHub 正式 latest Release,不读取 npm dist-tag;预览发行仍公开可下载。SemVer 预发布则在 npm 使用 `next`,用户需显式安装 `@karlorz/codexhost-cli@next`。

## 发布步骤

Expand Down Expand Up @@ -104,7 +104,7 @@ Composer 增加 Harness 命令按钮和模型搜索。Grok 支持自动或手动
### npm

```bash
npm install -g @codexhost/cli
npm install -g @karlorz/codexhost-cli
codexhost
```

Expand Down Expand Up @@ -178,7 +178,7 @@ Tag 推送后,GitHub Actions 会自动:
- 校验 Tag、npm 版本和 Cargo Workspace 版本一致。
- 构建 Windows x64/arm64 EXE。
- 构建 macOS x64/arm64 DMG。
- 发布 macOS、Windows、Linux 的 x64/arm64 共六个平台 npm 包和 `@codexhost/cli` 元包。
- 发布 macOS、Windows、Linux 的 x64/arm64 共六个平台 npm 包和 `@karlorz/codexhost-cli` 元包。
- 根据版本及手动发布输入创建公开 GitHub Release Prerelease 或正式 Release;`test` 渠道不创建 GitHub Release。
- GitHub Release 只上传四个安装包,不上传 npm tarball。

Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ default-members = [
resolver = "3"

[workspace.package]
version = "0.13.2"
version = "0.13.2-1"
edition = "2024"
rust-version = "1.97.1"
publish = false
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ But **Codex** isn't the only great **Agent Harness** — **Claude Code** and **P
</p>
<br />

<p align="center"><a href="https://github.com/BytePioneer-AI/codex-host/releases"><strong>Download</strong></a> · <a href="#cross-agent-collaboration">Cross-Agent Collaboration</a> · <a href="#remote-harness">Remote</a> · <a href="#join-the-community">微信交流群</a> · <a href="docs/project/README.zh-CN.md">简体中文</a> · <a href="docs/project/README.ko.md">한국어</a></p>
<p align="center"><a href="https://github.com/karlorz/codex-host/releases"><strong>Download</strong></a> · <a href="#cross-agent-collaboration">Cross-Agent Collaboration</a> · <a href="#remote-harness">Remote</a> · <a href="#join-the-community">微信交流群</a> · <a href="docs/project/README.zh-CN.md">简体中文</a> · <a href="docs/project/README.ko.md">한국어</a></p>

<br />

Expand Down Expand Up @@ -67,13 +67,13 @@ https://github.com/user-attachments/assets/c48192d7-23ff-4f6e-b61a-6345a655bb76
**Option 1: npm** (macOS / Windows / Linux)

```bash
npm install -g @codexhost/cli
npm install -g @karlorz/codexhost-cli
codexhost
```

**Option 2: Installer** (macOS / Windows)

Grab the installer for your platform from [Releases](https://github.com/BytePioneer-AI/codex-host/releases).
Grab the installer for your platform from [Releases](https://github.com/karlorz/codex-host/releases).

> Linux is supported on x64 and ARM64. See the [Linux guide](docs/platforms/linux/linux.md).

Expand Down Expand Up @@ -225,7 +225,7 @@ Before you start, add the remote machine in Codex Desktop under **Settings → C
1. Install and start codexhost on the remote machine:

```bash
npm install -g @codexhost/cli
npm install -g @karlorz/codexhost-cli
codexhost remote install
codexhost remote start
codexhost remote status
Expand Down Expand Up @@ -290,7 +290,7 @@ Please read the [contributing guide](CONTRIBUTING.md) before opening an issue or
Requirements: the official Codex Desktop, Node.js 22.19+ or 24, and Rust.

```bash
git clone https://github.com/BytePioneer-AI/codex-host
git clone https://github.com/karlorz/codex-host
cd codex-host
npm ci
npm start
Expand Down Expand Up @@ -322,8 +322,8 @@ Tip: point your coding Agent at the in-repo [codexhost-add-harness Skill](.agent

Thanks to everyone who has contributed to CodexHost.

<a href="https://github.com/BytePioneer-AI/codex-host/graphs/contributors">
<img alt="CodexHost contributors" src="https://contrib.rocks/image?repo=BytePioneer-AI/codex-host" />
<a href="https://github.com/karlorz/codex-host/graphs/contributors">
<img alt="CodexHost contributors" src="https://contrib.rocks/image?repo=karlorz/codex-host" />
</a>

## Star History
Expand Down
3 changes: 1 addition & 2 deletions crates/platform/src/desktop_launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ pub type DesktopProcess = super::windows_desktop::WindowsDesktopProcess;
#[cfg(not(target_os = "windows"))]
pub type DesktopProcess = Child;

const CODEXHOST_RELEASES_LATEST_URL: &str =
"https://github.com/BytePioneer-AI/codex-host/releases/latest";
const CODEXHOST_RELEASES_LATEST_URL: &str = "https://github.com/karlorz/codex-host/releases/latest";
const REMOTE_SSH_MANAGED_ENV: &str = "CODEXHOST_REMOTE_SSH_MANAGED";
const REMOTE_PROFILE_ONLY_ENVIRONMENT: [&str; 3] = [
"CODEX_INSTALL_DIR",
Expand Down
2 changes: 1 addition & 1 deletion crates/updater/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::request::{
#[cfg(target_os = "macos")]
use crate::status::unix_seconds;

const NPM_PACKAGE_NAME: &str = "@codexhost/cli";
pub(crate) const NPM_PACKAGE_NAME: &str = "@karlorz/codexhost-cli";
#[cfg(any(target_os = "windows", target_os = "macos"))]
const DISTRIBUTION_FILE: &str = "codexhost-distribution.json";

Expand Down
14 changes: 7 additions & 7 deletions crates/updater/src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn apply_locked(request: &Request) -> Result<(), Box<dyn Error>> {
"npm uses a different global installation; update this remote manually".into(),
);
}
let package = format!("@codexhost/cli@{}", request.version);
let package = format!("{}@{}", crate::install::NPM_PACKAGE_NAME, request.version);
// Unpublished local builds fail here, before touching the installation or service.
run(Command::new(&request.node).arg(&request.npm).args([
"view",
Expand Down Expand Up @@ -231,16 +231,16 @@ fn apply_locked(request: &Request) -> Result<(), Box<dyn Error>> {
.and_then(|name| name.to_str())
.ok_or("Invalid platform package path")?;
if ![
"cli-darwin-arm64",
"cli-darwin-x64",
"cli-linux-arm64",
"cli-linux-x64",
"codexhost-cli-darwin-arm64",
"codexhost-cli-darwin-x64",
"codexhost-cli-linux-arm64",
"codexhost-cli-linux-x64",
]
.contains(&name)
{
return Err("Unknown remote platform package".into());
}
command.arg(format!("@codexhost/{name}@{}", request.version));
command.arg(format!("@karlorz/{name}@{}", request.version));
}
run(&mut command).map_err(|error| format!("npm installation failed; check remote network access and write permissions: {error}"))?;
}
Expand Down Expand Up @@ -285,7 +285,7 @@ mod tests {
std::process::id(),
COUNTER.fetch_add(1, Ordering::Relaxed)
));
let package_root = root.join("node_modules/@codexhost/cli-darwin-arm64");
let package_root = root.join("node_modules/@karlorz/codexhost-cli-darwin-arm64");
fs::create_dir_all(package_root.join("app")).unwrap();
fs::write(
package_root.join("app/codexhost-distribution.json"),
Expand Down
26 changes: 18 additions & 8 deletions crates/updater/src/ssh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use std::{
time::{Duration, Instant},
};

use crate::install::NPM_PACKAGE_NAME;

#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct Request {
Expand Down Expand Up @@ -66,7 +68,8 @@ node -e 'const [major, minor] = process.versions.node.split(".").map(Number); pr
"install" => {
let version = release_version(request)?;
Ok(format!(
"{node}set -e; {lock}[ ! -f \"$HOME/.codexhost/remote/manifest.json\" ] || exit 43; case $(uname -s) in Darwin|Linux) ;; *) exit 44;; esac; command -v npm >/dev/null 2>&1 || exit 56; command -v codex >/dev/null 2>&1 || exit 57; npm install -g @codexhost/cli@{version} >/dev/null 2>&1 || exit 46; codexhost remote install >/dev/null 2>&1 || exit 47; codexhost remote start >/dev/null 2>&1 || {started} || exit 48; printf '\\n__CODEXHOST_SSH_STATE__=installed\\n'"
"{node}set -e; {lock}[ ! -f \"$HOME/.codexhost/remote/manifest.json\" ] || exit 43; case $(uname -s) in Darwin|Linux) ;; *) exit 44;; esac; command -v npm >/dev/null 2>&1 || exit 56; command -v codex >/dev/null 2>&1 || exit 57; npm install -g {package}@{version} >/dev/null 2>&1 || exit 46; codexhost remote install >/dev/null 2>&1 || exit 47; codexhost remote start >/dev/null 2>&1 || {started} || exit 48; printf '\\n__CODEXHOST_SSH_STATE__=installed\\n'",
package = NPM_PACKAGE_NAME,
))
}
// For services too old to update themselves. A newer CLI refuses to stop an installation
Expand All @@ -75,7 +78,8 @@ node -e 'const [major, minor] = process.versions.node.split(".").map(Number); pr
"update" => {
let version = release_version(request)?;
Ok(format!(
"{node}set -e; {lock}[ -f \"$HOME/.codexhost/remote/manifest.json\" ] || exit 52; command -v npm >/dev/null 2>&1 || exit 56; npm view @codexhost/cli@{version} version --fetch-retries=0 --fetch-timeout=30000 >/dev/null 2>&1 || exit 53; if command -v codexhost >/dev/null; then codexhost remote stop >/dev/null 2>&1 || true; fi; npm install -g @codexhost/cli@{version} >/dev/null 2>&1 || {{ codexhost remote start >/dev/null 2>&1 || true; exit 46; }}; command -v codexhost >/dev/null || exit 54; codexhost remote install >/dev/null 2>&1 || exit 47; codexhost remote stop >/dev/null 2>&1 || {stock} || exit 50; codexhost remote start >/dev/null 2>&1 || {started} || exit 48; printf '\\n__CODEXHOST_SSH_STATE__=installed\\n'"
"{node}set -e; {lock}[ -f \"$HOME/.codexhost/remote/manifest.json\" ] || exit 52; command -v npm >/dev/null 2>&1 || exit 56; npm view {package}@{version} version --fetch-retries=0 --fetch-timeout=30000 >/dev/null 2>&1 || exit 53; if command -v codexhost >/dev/null; then codexhost remote stop >/dev/null 2>&1 || true; fi; npm install -g {package}@{version} >/dev/null 2>&1 || {{ codexhost remote start >/dev/null 2>&1 || true; exit 46; }}; command -v codexhost >/dev/null || exit 54; codexhost remote install >/dev/null 2>&1 || exit 47; codexhost remote stop >/dev/null 2>&1 || {stock} || exit 50; codexhost remote start >/dev/null 2>&1 || {started} || exit 48; printf '\\n__CODEXHOST_SSH_STATE__=installed\\n'",
package = NPM_PACKAGE_NAME,
))
}
// A damaged installation is exactly what the CLI refuses to stop, so the first stop is
Expand All @@ -85,18 +89,24 @@ node -e 'const [major, minor] = process.versions.node.split(".").map(Number); pr
)),
"uninstall" => {
let package_check = if request.uninstall_package {
r#"command -v npm >/dev/null 2>&1 || exit 56;
format!(
r#"command -v npm >/dev/null 2>&1 || exit 56;
NPM_ROOT=$(npm root --global 2>/dev/null) || exit 59;
CLI=$(command -v codexhost) || exit 58;
node -e 'const fs = require("node:fs"), path = require("node:path"); try { const expected = path.join(process.argv[1], "@codexhost/cli/bin/codexhost.js"); process.exit(fs.realpathSync(expected) === fs.realpathSync(process.argv[2]) ? 0 : 1); } catch { process.exit(1); }' "$NPM_ROOT" "$CLI" >/dev/null 2>&1 || exit 59;
"#
node -e 'const fs = require("node:fs"), path = require("node:path"); try {{ const expected = path.join(process.argv[1], "{package}/bin/codexhost.js"); process.exit(fs.realpathSync(expected) === fs.realpathSync(process.argv[2]) ? 0 : 1); }} catch {{ process.exit(1); }}' "$NPM_ROOT" "$CLI" >/dev/null 2>&1 || exit 59;
"#,
package = NPM_PACKAGE_NAME,
)
} else {
""
String::new()
};
let package_remove = if request.uninstall_package {
"npm uninstall --global @codexhost/cli >/dev/null 2>&1 || exit 60; [ ! -e \"$NPM_ROOT/@codexhost/cli/package.json\" ] || exit 60;"
format!(
"npm uninstall --global {package} >/dev/null 2>&1 || exit 60; [ ! -e \"$NPM_ROOT/{package}/package.json\" ] || exit 60;",
package = NPM_PACKAGE_NAME,
)
} else {
""
String::new()
};
// Keep the npm package until its CLI has stopped the service and removed the
// managed entrypoint/profile (and the macOS broker). No user data is deleted.
Expand Down
10 changes: 5 additions & 5 deletions crates/updater/src/ssh/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ node(){ case "$2" in *realpathSync*) return "${MATCH_CODE:-0}";; *) return 0;; e
npm(){
case "$1" in
root) printf '%s\n' "$HOME/npm";;
uninstall) printf '%s\n' 'npm uninstall' >> "$HOME/calls"; [ "${FAIL:-}" != npm ] || return 1; rm "$HOME/npm/@codexhost/cli/package.json";;
uninstall) printf '%s\n' 'npm uninstall' >> "$HOME/calls"; [ "${FAIL:-}" != npm ] || return 1; rm "$HOME/npm/@karlorz/codexhost-cli/package.json";;
*) return 99;;
esac
}
Expand Down Expand Up @@ -224,7 +224,7 @@ codexhost(){
] {
let home = root.join(name);
let remote = home.join(".codexhost/remote");
let package = home.join("npm/@codexhost/cli");
let package = home.join("npm/@karlorz/codexhost-cli");
std::fs::create_dir_all(remote.join("data")).unwrap();
std::fs::create_dir_all(&package).unwrap();
std::fs::write(remote.join("manifest.json"), "{}").unwrap();
Expand Down Expand Up @@ -370,7 +370,7 @@ fn install_refuses_to_replace_existing_remote_services() {
r.version = Some("1.2.3".into());
let value = script(&r).unwrap();
assert!(value.contains("exit 43"));
assert!(value.contains("@codexhost/cli@1.2.3"));
assert!(value.contains("@karlorz/codexhost-cli@1.2.3"));
assert!(!value.contains("remote stop"));
}
#[cfg(unix)]
Expand Down Expand Up @@ -399,7 +399,7 @@ fn executes_initial_setup_and_refuses_an_existing_installation() {
let calls = std::fs::read_to_string(root.join("calls")).unwrap();
assert_eq!(
calls,
"install -g @codexhost/cli@1.2.3\nremote install\nremote start\n"
"install -g @karlorz/codexhost-cli@1.2.3\nremote install\nremote start\n"
);
std::fs::create_dir_all(root.join(".codexhost/remote")).unwrap();
std::fs::write(root.join(".codexhost/remote/manifest.json"), "{}").unwrap();
Expand All @@ -421,7 +421,7 @@ fn executes_initial_setup_and_refuses_an_existing_installation() {
.unwrap();
assert!(updated.status.success());
let calls = format!(
"{calls}view @codexhost/cli@1.2.4 version --fetch-retries=0 --fetch-timeout=30000\nremote stop\ninstall -g @codexhost/cli@1.2.4\nremote install\nremote stop\nremote start\n"
"{calls}view @karlorz/codexhost-cli@1.2.4 version --fetch-retries=0 --fetch-timeout=30000\nremote stop\ninstall -g @karlorz/codexhost-cli@1.2.4\nremote install\nremote stop\nremote start\n"
);
assert_eq!(std::fs::read_to_string(root.join("calls")).unwrap(), calls);
assert!(!root.join(".codexhost/ssh-setup.lock").exists());
Expand Down
2 changes: 1 addition & 1 deletion docs/NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ type: warning
- 用户需要采取的临时措施。
- 修复进度或预计恢复时间。

[查看项目发布记录](https://github.com/BytePioneer-AI/codex-host/releases)
[查看项目发布记录](https://github.com/karlorz/codex-host/releases)
2 changes: 1 addition & 1 deletion docs/PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ After stopping CodexHost, you can delete its applicable local data. Native Harne

## Contact

For non-sensitive privacy questions, open an issue at [BytePioneer-AI/codex-host](https://github.com/BytePioneer-AI/codex-host/issues). Do not include credentials, private code, or unredacted logs in public reports.
For non-sensitive privacy questions, open an issue at [karlorz/codex-host](https://github.com/karlorz/codex-host/issues). Do not include credentials, private code, or unredacted logs in public reports.
2 changes: 1 addition & 1 deletion docs/architecture/harness-executable-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ packages/harness-discovery/
}
```

该包参与 TypeScript 构建,但不会作为独立 npm 包发布。正式 npm 发布物仍是 `@codexhost/cli` 及对应的平台包;发现代码随 Host Runtime 和 Adapter 的发布产物一起交付。
该包参与 TypeScript 构建,但不会作为独立 npm 包发布。正式 npm 发布物仍是 `@karlorz/codexhost-cli` 及对应的平台包;发现代码随 Host Runtime 和 Adapter 的发布产物一起交付。

## 公共能力

Expand Down
Loading
Loading