Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
797587e
chore: add .gitattributes for cross-platform line endings
Kevin7Qi Mar 1, 2026
d6f1a47
fix: cross-platform paths and process handling for Windows support
Kevin7Qi Mar 1, 2026
2d52f82
fix: use explicit falsy check in getHome() instead of try/catch
Kevin7Qi Mar 1, 2026
134e73c
fix: use os.tmpdir() and path.join() in tests for Windows support
Kevin7Qi Mar 1, 2026
ed9ea78
feat: add install.ps1 Windows installer with .cmd shim
Kevin7Qi Mar 1, 2026
70fec6e
ci: add Windows runner to CI matrix
Kevin7Qi Mar 1, 2026
8f89b48
docs: add Windows installation instructions to README
Kevin7Qi Mar 1, 2026
83ce0a9
fix: harden installer error handling and fix review feedback
Kevin7Qi Mar 1, 2026
ab718f9
docs: restructure README installation section
Kevin7Qi Mar 1, 2026
45fb701
fix: Windows testing and installer issues from real-device feedback
Kevin7Qi Mar 1, 2026
136bc65
fix: work around bun test .rejects flush issue on Windows
Kevin7Qi Mar 1, 2026
2a30f1f
fix: use bash shebang in Windows extensionless shim
Kevin7Qi Mar 1, 2026
bf5c52c
fix: harden Windows process cleanup and installer error handling
Kevin7Qi Mar 1, 2026
3eacb99
fix: suppress spurious taskkill warning on Windows
Kevin7Qi Mar 1, 2026
23d7399
fix: address Codex review findings for Windows support
Kevin7Qi Mar 1, 2026
e6f3500
ci: install codex CLI and fix Windows smoke test invocation
Kevin7Qi Mar 1, 2026
0b4b747
fix: simplify installer shim creation and harden test assertions
Kevin7Qi Mar 2, 2026
1315c85
fix: skip server operations in kill when thread is already killed
Kevin7Qi Mar 2, 2026
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
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Normalize all text files to LF in the repo
* text=auto eol=lf

# Windows scripts use CRLF (required by CMD/BAT; conventional for .ps1)
*.ps1 text eol=crlf
*.cmd text eol=crlf
*.bat text eol=crlf
35 changes: 34 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ on:

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

Expand All @@ -23,3 +27,32 @@ jobs:

- name: Run tests
run: bun test

- name: Install codex CLI
run: npm install -g @openai/codex

- name: Smoke-test installer (Linux/macOS)
if: runner.os != 'Windows'
run: |
./install.sh
Comment thread
Kevin7Qi marked this conversation as resolved.
codex-collab --help
codex-collab health

- name: Smoke-test installer (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Set-ExecutionPolicy Bypass -Scope Process -Force
.\install.ps1
codex-collab --help
codex-collab health

- name: Smoke-test .cmd shim from CMD (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
REM Simulate new terminal: reload PATH from registry, keep session PATH for bun/node
for /f "delims=" %%i in ('powershell -Command "[Environment]::GetEnvironmentVariable('Path','User') + ';' + [Environment]::GetEnvironmentVariable('Path','Machine')"') do set "PATH=%%i;%PATH%"
codex-collab --help
codex-collab health

6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ bun install
./install.sh --dev # symlink for live iteration
```

On Windows (PowerShell):

```powershell
powershell -ExecutionPolicy Bypass -File install.ps1 -Dev
```

## Running Tests

```bash
Expand Down
35 changes: 26 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,46 @@ codex-collab is a [Claude Code skill](https://docs.anthropic.com/en/docs/claude-
- **Thread reuse** — Resume existing threads to send follow-up prompts, build on previous responses, or steer the work in a new direction.
- **Approval control** — Configurable approval policies for tool calls: auto-approve, interactive, or deny.

## Prerequisites

Tested on Linux (Ubuntu 22.04) and macOS. Both must be installed and on your PATH.

- [Bun](https://bun.sh/) >= 1.0 — runs the CLI
- [Codex CLI](https://github.com/openai/codex) — must support `codex app-server` (tested with 0.106.0; `npm install -g @openai/codex`)

## Installation

Requires [Bun](https://bun.sh/) >= 1.0 and [Codex CLI](https://github.com/openai/codex) (`npm install -g @openai/codex`) on your PATH. Tested on Linux (Ubuntu 22.04), macOS, and Windows 10.

```bash
git clone https://github.com/Kevin7Qi/codex-collab.git
cd codex-collab
```

### Linux / macOS

```bash
./install.sh
```

The install script builds a self-contained bundle, copies it to `~/.claude/skills/codex-collab/`, and symlinks the binary. Once installed, Claude discovers the skill automatically and can invoke it without explicit prompting.
### Windows

For development (live-reloading source changes):
```powershell
powershell -ExecutionPolicy Bypass -File install.ps1
```

After installation, **reopen your terminal** so the updated PATH takes effect, then run `codex-collab health` to verify.

The installer builds a self-contained bundle, deploys it to your home directory (`~/.claude/skills/codex-collab/` on Linux/macOS, `%USERPROFILE%\.claude\skills\codex-collab\` on Windows), and adds a binary shim to your PATH. Once installed, Claude discovers the skill automatically.

<details>
<summary>Development mode</summary>

Use `--dev` to symlink source files for live-reloading instead of building a bundle:

```bash
# Linux / macOS
./install.sh --dev

# Windows (may require Developer Mode or an elevated terminal for symlinks)
powershell -ExecutionPolicy Bypass -File install.ps1 -Dev
```

</details>

## Quick Start

```bash
Expand Down
35 changes: 26 additions & 9 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,46 @@ codex-collab 是一个 [Claude Code 技能](https://docs.anthropic.com/en/docs/c
- **会话复用** — 接续先前的会话继续对话,在既有上下文基础上推进,不必从头开始。
- **审批控制** — 按需配置工具调用的审批策略:自动批准、交互确认或拒绝。

## 环境要求

在 Linux (Ubuntu 22.04) 与 macOS 上测试通过。请确保以下工具已安装并加入 PATH:

- [Bun](https://bun.sh/) >= 1.0 — 用于运行 CLI
- [Codex CLI](https://github.com/openai/codex) — 须支持 `codex app-server` 子命令(已测试 0.106.0;`npm install -g @openai/codex`)

## 安装

需要 [Bun](https://bun.sh/) >= 1.0 和 [Codex CLI](https://github.com/openai/codex)(`npm install -g @openai/codex`)并加入 PATH。已在 Linux (Ubuntu 22.04)、macOS 与 Windows 10 上测试通过。

```bash
git clone https://github.com/Kevin7Qi/codex-collab.git
cd codex-collab
```

### Linux / macOS

```bash
./install.sh
```

运行后会自动构建独立 bundle 并部署到 `~/.claude/skills/codex-collab/`。完成后 Claude 即可自动发现该技能,无需额外配置。
### Windows

开发模式(源码变更实时生效):
```powershell
powershell -ExecutionPolicy Bypass -File install.ps1
```

安装完成后,**重新打开终端**以使 PATH 生效,然后运行 `codex-collab health` 验证安装。

安装脚本会自动构建独立 bundle,部署到主目录下(Linux/macOS 为 `~/.claude/skills/codex-collab/`,Windows 为 `%USERPROFILE%\.claude\skills\codex-collab\`),并添加可执行文件到 PATH。完成后 Claude 即可自动发现该技能。

<details>
<summary>开发模式</summary>

使用 `--dev` 以符号链接方式安装,源码变更实时生效:

```bash
# Linux / macOS
./install.sh --dev

# Windows(可能需要启用开发者模式或使用管理员终端以创建符号链接)
powershell -ExecutionPolicy Bypass -File install.ps1 -Dev
```

</details>

## 快速开始

```bash
Expand Down
154 changes: 154 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Install codex-collab on Windows.
.PARAMETER Dev
Symlink source files for live development instead of building.
#>
param(
[switch]$Dev,
[switch]$Help
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$RepoDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$SkillDir = Join-Path $env:USERPROFILE ".claude\skills\codex-collab"
$BinDir = Join-Path $env:USERPROFILE ".local\bin"

function Show-Usage {
Write-Host "Usage: powershell -File install.ps1 [-Dev]"
Write-Host ""
Write-Host " (default) Build and copy a self-contained skill directory"
Write-Host " -Dev Symlink source files for live development"
}

if ($Help) {
Show-Usage
exit 0
}

# Check prerequisites
$missing = @()
if (-not (Get-Command bun -ErrorAction SilentlyContinue)) { $missing += "bun" }
if (-not (Get-Command codex -ErrorAction SilentlyContinue)) { $missing += "codex" }

if ($missing.Count -gt 0) {
Write-Host "Missing prerequisites: $($missing -join ', ')"
Write-Host " bun: https://bun.sh/"
Write-Host " codex: npm install -g @openai/codex"
exit 1
}

# Install dependencies
Write-Host "Installing dependencies..."
Push-Location $RepoDir
try {
bun install
if ($LASTEXITCODE -ne 0) { throw "'bun install' failed with exit code $LASTEXITCODE" }
} catch {
Write-Host "Error: $_"
exit 1
} finally {
Pop-Location
}

if ($Dev) {
Write-Host "Installing in dev mode (symlinks)..."
Write-Host "Note: Symlinks on Windows may require Developer Mode or elevated privileges."

# Create skill directory
New-Item -ItemType Directory -Path (Join-Path $SkillDir "scripts") -Force | Out-Null

# Symlink skill files (requires Developer Mode or elevated privileges)
$links = @(
@{ Path = (Join-Path $SkillDir "SKILL.md"); Target = (Join-Path $RepoDir "SKILL.md") }
@{ Path = (Join-Path $SkillDir "scripts\codex-collab"); Target = (Join-Path $RepoDir "src\cli.ts") }
@{ Path = (Join-Path $SkillDir "LICENSE.txt"); Target = (Join-Path $RepoDir "LICENSE") }
)

foreach ($link in $links) {
if (Test-Path $link.Path) { Remove-Item $link.Path -Force }
try {
New-Item -ItemType SymbolicLink -Path $link.Path -Target $link.Target -Force | Out-Null
} catch {
Write-Host ""
Write-Host "Error: Cannot create symlinks. Dev mode requires one of:"
Write-Host " 1. Enable Developer Mode: Settings > Update & Security > For developers"
Write-Host " 2. Run this script in an elevated (Administrator) terminal"
Write-Host ""
Write-Host "Alternatively, use build mode (without -Dev) which does not need symlinks."
exit 1
}
}
Write-Host "Linked skill to $SkillDir"

$shimTarget = Join-Path $RepoDir "src\cli.ts"

} else {
Write-Host "Building..."

# Build bundled JS
$skillBuild = Join-Path $RepoDir "skill\codex-collab"
if (Test-Path $skillBuild) { Remove-Item $skillBuild -Recurse -Force }
New-Item -ItemType Directory -Path (Join-Path $skillBuild "scripts") -Force | Out-Null

$built = Join-Path $skillBuild "scripts\codex-collab"
try {
bun build (Join-Path $RepoDir "src\cli.ts") --outfile $built --target bun
if ($LASTEXITCODE -ne 0) { throw "'bun build' failed with exit code $LASTEXITCODE" }
} catch {
Write-Host "Error: $_"
exit 1
}

# Prepend shebang if missing (needed for Unix execution; harmless on Windows with Bun)
$content = Get-Content $built -Raw
if (-not $content.StartsWith("#!/")) {
[System.IO.File]::WriteAllText($built, "#!/usr/bin/env bun`n" + $content, [System.Text.UTF8Encoding]::new($false))
}

# Copy SKILL.md and LICENSE
Copy-Item (Join-Path $RepoDir "SKILL.md") (Join-Path $skillBuild "SKILL.md")
Copy-Item (Join-Path $RepoDir "LICENSE") (Join-Path $skillBuild "LICENSE.txt")

# Install skill
if (Test-Path $SkillDir) { Remove-Item $SkillDir -Recurse -Force }
New-Item -ItemType Directory -Path (Split-Path $SkillDir) -Force | Out-Null
Copy-Item $skillBuild $SkillDir -Recurse
Write-Host "Installed skill to $SkillDir"

$shimTarget = Join-Path $SkillDir "scripts\codex-collab"
}

# Create .cmd shim (CMD/PowerShell) and extensionless bash wrapper (Git Bash/MSYS2)
New-Item -ItemType Directory -Path $BinDir -Force | Out-Null
$cmdShim = Join-Path $BinDir "codex-collab.cmd"
[System.IO.File]::WriteAllText($cmdShim, "@bun `"$shimTarget`" %*`r`n", [System.Text.UTF8Encoding]::new($false))
$bashShim = Join-Path $BinDir "codex-collab"
[System.IO.File]::WriteAllText($bashShim, "#!/usr/bin/env bash`nexec bun `"$shimTarget`" `"`$@`"", [System.Text.UTF8Encoding]::new($false))
Write-Host "Created binary shims at $BinDir"

# Add bin dir to user PATH if not already present
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($userPath -notlike "*$BinDir*") {
[Environment]::SetEnvironmentVariable("Path", "$BinDir;$userPath", "User")
Write-Host "Added $BinDir to user PATH (permanent)."
}
# Update current session PATH
if ($env:Path -notlike "*$BinDir*") {
$env:Path = "$BinDir;$env:Path"
}

# Verify and health check
Write-Host ""
codex-collab health
if ($LASTEXITCODE -ne 0) {
Write-Host "Error: 'codex-collab health' failed. The installation may be broken."
exit 1
}

$mode = if ($Dev) { "dev" } else { "build" }
Write-Host ""
Write-Host "Done ($mode mode). Open a new terminal, then run 'codex-collab --help' to get started."
Loading