Skip to content
Open
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
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ English | [简体中文](README.zh-CN.md)

- **No new project management tool**: keep using your existing Linear — no new platform, no migration cost
- **Subscription, not API**: runs on the Claude Code (Pro / Max), Codex (ChatGPT Plus / Pro / Team), or Cursor (Pro) you're already paying for — usage is billed against your subscription
- **Swap agents in one line**: set `DEFAULT_AGENT=claude-code`, `codex`, or `cursor`; all backends share the same dispatcher, plan-sync, stop-signal, and session-resume plumbing
- **Swap agents in one line**: set `DEFAULT_AGENT=claude-code`, `codex`, `cursor`, or `antigravity`; all backends share the same dispatcher, plan-sync, stop-signal, and session-resume plumbing
- **Fully local execution**: the agent touches code on your own machine; sessions, permissions, and files stay with you

## Architecture
Expand All @@ -21,7 +21,7 @@ Three layers:

- **Issue Tracker Adapter** — currently Linear: listens to webhooks, normalizes events into TaskRequests
- **Task Dispatcher** — queues tasks, controls concurrency, forwards progress updates
- **Agent Adapter** — Claude Code CLI, Codex (via [`@openai/codex-sdk`](https://www.npmjs.com/package/@openai/codex-sdk), which bundles the Rust `codex` binary per platform), or [Cursor CLI](https://cursor.com/docs/cli) (`cursor-agent` in `--print` mode): spawns the agent, streams output back
- **Agent Adapter** — Claude Code CLI, Codex (via [`@openai/codex-sdk`](https://www.npmjs.com/package/@openai/codex-sdk), which bundles the Rust `codex` binary per platform), [Cursor CLI](https://cursor.com/docs/cli) (`cursor-agent` in `--print` mode), or [Antigravity CLI](https://antigravity.google/docs/cli-overview) (`agy` in `--print --dangerously-skip-permissions` mode): spawns the agent, streams output back

## Quick Start

Expand All @@ -31,7 +31,8 @@ Three layers:
- At least one agent set up:
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) (`claude login`), and/or
- [Codex CLI](https://github.com/openai/codex) (`codex login`) — the bundled binary is installed automatically via `@openai/codex-sdk`, and/or
- [Cursor CLI](https://cursor.com/docs/cli) (`cursor-agent login`) — uses your Cursor subscription via OAuth; usage is billed against the logged-in account
- [Cursor CLI](https://cursor.com/docs/cli) (`cursor-agent login`) — uses your Cursor subscription via OAuth; usage is billed against the logged-in account, and/or
- [Antigravity CLI](https://antigravity.google/docs/cli-overview) (`agy`, first run completes Google Sign-In) — uses your Google AI Pro/Ultra or Code Assist quota
- A Linear workspace (admin access required to set up the OAuth app)
- A public URL reachable by Linear — [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) is recommended

Expand Down Expand Up @@ -97,7 +98,7 @@ Three layers:
3. Stream progress (thinking, tool use, plan) back to Linear
4. Post the final result as a response activity

Follow-up replies in the same thread automatically resume the previous session (`claude --resume`, `codex.resumeThread()`, or `cursor-agent --resume`), so context is preserved.
Follow-up replies in the same thread automatically resume the previous session (`claude --resume`, `codex.resumeThread()`, `cursor-agent --resume`, or `agy --resume`), so context is preserved.

### Project Directory Mapping

Expand All @@ -116,6 +117,7 @@ Set `DEFAULT_AGENT` in `.env`:
- `claude-code` (default) — drives Claude Code CLI
- `codex` — drives Codex via `@openai/codex-sdk`
- `cursor` — drives the Cursor CLI (`cursor-agent`)
- `antigravity` — drives Google's Antigravity CLI (`agy`)

All backends are registered at startup and detected independently; an unavailable backend is logged as a warning but doesn't block the others.

Expand Down Expand Up @@ -159,7 +161,22 @@ Cursor runs via the [`cursor-agent` CLI](https://cursor.com/docs/cli) in `--prin

Sessions resume via `cursor-agent --resume <session_id>`, mirroring Claude Code's `--resume` flow.

> **Note:** the [`@cursor/sdk`](https://www.npmjs.com/package/@cursor/sdk) TypeScript SDK is **not** used. Its local runtime talks to its embedded binary over connect-rpc/HTTP/2, which currently fails under Bun ([oven-sh/bun#25589](https://github.com/oven-sh/bun/issues/25589) and related). The CLI uses plain stdio, so Bun stays out of the protocol critical path.
> **Note:** the [`@cursor/sdk`](https://www.npmjs.com/package/@cursor/sdk)
> TypeScript SDK is **not** used. Its local runtime talks to its embedded binary over connect-rpc/HTTP/2, which currently fails under Bun ([oven-sh/bun#25589](https://github.com/oven-sh/bun/issues/25589) and related). The CLI uses plain stdio, so Bun stays out of the protocol critical path.

### Antigravity

Google's [Antigravity CLI](https://antigravity.google/docs/cli-overview) (the Go-based replacement for Gemini CLI, binary name `agy`) runs in headless mode via `agy --print --dangerously-skip-permissions --add-dir <cwd> "<prompt>"`. Authentication is handled by the CLI itself — first run of `agy` opens a Google Sign-In browser flow (credentials cached in the OS keyring), or set `ANTIGRAVITY_API_KEY` for CI/scripted use. `--dangerously-skip-permissions` auto-accepts tool execution since the webhook flow has no TTY for approval prompts.

| Variable | Values | Default |
| -------------------- | -------------------------------------------------------- | -------------------- |
| `ANTIGRAVITY_PATH` | Path to the `agy` binary | `agy` on PATH |
| `ANTIGRAVITY_MODEL` | Any model accepted by your Antigravity account (e.g. `gemini-3.5-flash`, `gemini-3.1-pro`, `claude-opus`, `gpt-oss-120b`) | CLI default |
| `ANTIGRAVITY_API_KEY` | (Optional) API key fallback if you haven't completed Google Sign-In | unset (uses keyring) |

Sessions resume via `agy --conversation <session_id>`, mirroring the Claude Code / Cursor flow.

> **Note on SDK vs CLI:** Antigravity ships an SDK alongside the CLI, but issuely uses the CLI for the same reasons as Cursor — plain stdio keeps Bun out of the protocol critical path and matches the established backend pattern (`claude-code` and `cursor` are both CLI-driven). Switching to the SDK would only be worth it if the CLI's stream-json event surface turns out to be insufficient.

## Development

Expand Down
24 changes: 20 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

- **不换项目管理工具**:继续用你现有的 Linear 来做项目管理,没有新平台、没有迁移成本
- **用订阅,不是 API**:跑在你已经付费的 Claude Code(Pro / Max)、Codex(ChatGPT Plus / Pro / Team)或 Cursor(Pro)上,用量直接走订阅额度
- **一行切换 agent**:`DEFAULT_AGENT=claude-code`、`codex` 或 `cursor`,所有 backend 共用同一套 dispatcher、plan 同步、stop 信号、会话 resume
- **一行切换 agent**:`DEFAULT_AGENT=claude-code`、`codex`、`cursor` 或 `antigravity`,所有 backend 共用同一套 dispatcher、plan 同步、stop 信号、会话 resume
- **完全本地执行**:agent 动的是你自己机器上的代码,session、权限、文件都在你手里

## 架构
Expand All @@ -21,7 +21,7 @@ Linear(webhook) → Issuely Bridge → 本地 Claude Code / Codex / Cursor

- **Issue Tracker Adapter** — 目前接的是 Linear:监听 webhook、把事件统一成 TaskRequest
- **Task Dispatcher** — 排队、控制并发、转发进度更新
- **Agent Adapter** — Claude Code CLI、Codex(通过 [`@openai/codex-sdk`](https://www.npmjs.com/package/@openai/codex-sdk),会按平台自带 Rust `codex` 二进制)[Cursor CLI](https://cursor.com/docs/cli)(`cursor-agent` 的 `--print` 模式):启动 agent、流式回传输出
- **Agent Adapter** — Claude Code CLI、Codex(通过 [`@openai/codex-sdk`](https://www.npmjs.com/package/@openai/codex-sdk),会按平台自带 Rust `codex` 二进制)[Cursor CLI](https://cursor.com/docs/cli)(`cursor-agent` 的 `--print` 模式)或 [Antigravity CLI](https://antigravity.google/docs/cli-overview)(`agy` 的 `--print --dangerously-skip-permissions` 模式):启动 agent、流式回传输出

## 快速开始

Expand All @@ -31,7 +31,8 @@ Linear(webhook) → Issuely Bridge → 本地 Claude Code / Codex / Cursor
- 至少配好一个 agent:
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)(`claude login`),和/或
- [Codex CLI](https://github.com/openai/codex)(`codex login`)——`@openai/codex-sdk` 会自动带上对应平台的原生二进制,和/或
- [Cursor CLI](https://cursor.com/docs/cli)(`cursor-agent login`)——通过 OAuth 登录,用量走你的 Cursor 订阅
- [Cursor CLI](https://cursor.com/docs/cli)(`cursor-agent login`)——通过 OAuth 登录,用量走你的 Cursor 订阅,和/或
- [Antigravity CLI](https://antigravity.google/docs/cli-overview)(`agy`,首次运行会拉起 Google Sign-In)——用量走你的 Google AI Pro/Ultra 或 Code Assist 配额
- 一个 Linear workspace(需要 admin 权限用来配 OAuth app)
- 一个可以被 Linear 访问到的公网 URL,推荐用 [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) 起一个

Expand Down Expand Up @@ -103,7 +104,7 @@ Linear(webhook) → Issuely Bridge → 本地 Claude Code / Codex / Cursor
3. 把中间进度(thinking、工具调用、plan)流式同步回 Linear
4. 把最终结果作为 response activity 贴回去

同一 thread 里的 follow-up 回复会自动续上之前的 session(`claude --resume`、`codex.resumeThread()``cursor-agent --resume`),上下文不会丢。
同一 thread 里的 follow-up 回复会自动续上之前的 session(`claude --resume`、`codex.resumeThread()``cursor-agent --resume` 或 `agy --resume`),上下文不会丢。

### 项目目录映射

Expand All @@ -122,6 +123,7 @@ key 是 Linear 里的**项目名**,大小写不敏感。
- `claude-code`(默认)—— 走 Claude Code CLI
- `codex` —— 通过 `@openai/codex-sdk` 走 Codex
- `cursor` —— 走 Cursor CLI(`cursor-agent`)
- `antigravity` —— 走 Google Antigravity CLI(`agy`)

所有 backend 启动时都会注册、独立做可用性探测;某一个不可用只会打 warning,不会影响其它。

Expand Down Expand Up @@ -167,6 +169,20 @@ Cursor 通过 [`cursor-agent` CLI](https://cursor.com/docs/cli) 的 `--print --o

> **注:** 我们**不**用 [`@cursor/sdk`](https://www.npmjs.com/package/@cursor/sdk) TypeScript SDK。它的本地 runtime 走 connect-rpc/HTTP/2 跟内嵌 binary 通信,目前在 Bun 下有 bug([oven-sh/bun#25589](https://github.com/oven-sh/bun/issues/25589) 等),工具调用会静默失败。CLI 走 stdio,把 Bun 从协议关键路径里摘了出去。

### Antigravity

Google 的 [Antigravity CLI](https://antigravity.google/docs/cli-overview)(Gemini CLI 的 Go 重写版本,二进制名是 `agy`)以 `agy --print --dangerously-skip-permissions --add-dir <cwd> "<prompt>"` 的 headless 模式运行。认证由 CLI 自己处理:第一次跑 `agy` 会拉起 Google Sign-In 浏览器流程(凭证存到系统 keyring),或者设 `ANTIGRAVITY_API_KEY` 用于 CI/脚本场景。`--dangerously-skip-permissions` 自动接受所有工具执行——webhook 模式没有 TTY 应答审批提示。

| 变量 | 取值 | 默认值 |
| --------------------- | --------------------------------------------------- | -------------------- |
| `ANTIGRAVITY_PATH` | `agy` 二进制路径 | PATH 上找 `agy` |
| `ANTIGRAVITY_MODEL` | 你账号支持的任意 Antigravity 模型(如 `gemini-3.5-flash`、`gemini-3.1-pro`、`claude-opus`、`gpt-oss-120b`) | CLI 默认值 |
| `ANTIGRAVITY_API_KEY` | (可选)没完成 Google Sign-In 时的 API key 兜底 | 未设(走 keyring) |

会话 resume 走 `agy --conversation <session_id>`,跟 Claude Code / Cursor 的 `--resume` 流程对齐。

> **关于 SDK vs CLI:** Antigravity 同时发布了 SDK,issuely 出于和 Cursor 一样的考虑选用 CLI——stdio 把 Bun 从协议关键路径里摘出去,也跟现有 backend 模式(`claude-code`、`cursor` 都是 CLI 驱动)对齐。除非 CLI 的 stream-json 事件不够用,否则没必要切到 SDK。

## 开发

```bash
Expand Down
Loading