acdev 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,16 @@
1
- # Optional. Prefer Claude Code subscription auth instead:
1
+ # Optional. GitHub CLI for issues/PRs — alternatives to interactive `gh auth login`:
2
+ # GH_TOKEN=ghp_your_personal_access_token
3
+ # GITHUB_TOKEN is also honored if GH_TOKEN is unset.
4
+ # SSH remotes can push/fetch git but do not authenticate gh for issues/PRs.
5
+ #
6
+ # Claude — prefer Claude Code subscription auth:
2
7
  # claude auth login
3
8
  # Or a long-lived subscription token:
4
9
  # claude setup-token
5
10
  # CLAUDE_CODE_OAUTH_TOKEN=...
6
11
  #
7
- # API Console billing (pay-as-you-go) — only if you have an Anthropic API key:
12
+ # API Console billing (pay-as-you-go) — only if you have an Anthropic API key.
13
+ # An API key takes precedence over subscription login:
8
14
  # ANTHROPIC_API_KEY=sk-ant-your-key-here
9
15
  #
10
16
  # Jira Cloud (only when ticketSource is "jira" in Settings / config.json):
package/README.md CHANGED
@@ -5,7 +5,7 @@ Local CLI + web UI for running AI coding agents on GitHub Issues or Jira tickets
5
5
  ## Prerequisites
6
6
 
7
7
  - Node.js 20+
8
- - [GitHub CLI](https://cli.github.com/) (`gh`) authenticated (`gh auth login`) — required for PRs (and for GitHub Issues when that is the ticket source)
8
+ - [GitHub CLI](https://cli.github.com/) (`gh`) — required for PRs (and for GitHub Issues when that is the ticket source). Authenticate with `gh auth login` **or** a PAT in Settings / `GH_TOKEN` (see [Authentication](#authentication))
9
9
  - Claude authentication (see [Authentication](#authentication) below)
10
10
  - A git repository with a `develop` branch on `origin` (or configure another base branch)
11
11
  - Optional: Jira Cloud credentials when using Jira as the ticket source (see [Jira](#jira-ticket-source))
@@ -27,9 +27,25 @@ npm link # optional — makes `acdev` available globally
27
27
 
28
28
  ## Authentication
29
29
 
30
- `acdev` uses the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), which shares credentials with [Claude Code](https://code.claude.com/docs/en/authentication). You need **one** of the following (`.env` is optional):
30
+ Configure GitHub and Claude from **Settings** in the web UI (tokens are written to `.acdev/.env`, gitignored) or by editing that file directly. Leave a Settings field blank to keep the current secret. Shell environment variables override `.env` on startup; saving in Settings updates the running process immediately.
31
31
 
32
- ### Option A Claude Pro / Max subscription (browser login)
32
+ `.env` is optional when you already use `gh auth login` and `claude auth login` on the machine.
33
+
34
+ ### GitHub (issues / PRs)
35
+
36
+ `acdev` talks to GitHub through `gh`. **Any one** of these is enough:
37
+
38
+ 1. **Existing CLI login** — `gh auth login` (browser/device). Settings shows this as authenticated.
39
+ 2. **Personal access token** — paste a PAT in **Settings → GitHub / PR auth**, or set `GH_TOKEN` (or `GITHUB_TOKEN`) in `.acdev/.env`. `gh` reads those env vars, so no interactive login is required. Non-interactive CLI equivalent: `echo YOUR_PAT | gh auth login --with-token -h github.com`.
40
+ 3. **SSH remotes are not a substitute.** An SSH `origin` can push/fetch git, but it does **not** authenticate `gh` for issues or PRs. Settings may show the origin URL as read-only info.
41
+
42
+ On a machine with no browser, copy `.acdev/.env.example` to `.acdev/.env`, set `GH_TOKEN`, then start `acdev`. After the UI is running you can update the token in Settings.
43
+
44
+ ### Claude
45
+
46
+ `acdev` uses the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), which shares credentials with [Claude Code](https://code.claude.com/docs/en/authentication). You need **one** of the following (API key wins if more than one is set):
47
+
48
+ #### Option A — Claude Pro / Max subscription (browser login)
33
49
 
34
50
  Best when you already pay for claude.ai and are not allowed to use API keys.
35
51
 
@@ -44,14 +60,18 @@ claude auth status
44
60
 
45
61
  3. Run `acdev` with **no** `ANTHROPIC_API_KEY` set (an API key would take precedence and bill the Console instead of your subscription)
46
62
 
63
+ Settings cannot complete browser OAuth — that still needs `claude auth login` on the host. Detected method in Settings: `claude-code-login`.
64
+
47
65
  For CI / non-interactive shells, generate a long-lived subscription token instead:
48
66
 
49
67
  ```bash
50
68
  claude setup-token
51
- export CLAUDE_CODE_OAUTH_TOKEN=... # or put it in `.acdev/.env`
69
+ export CLAUDE_CODE_OAUTH_TOKEN=... # or paste it in Settings → Claude authentication
52
70
  ```
53
71
 
54
- ### Option B — Anthropic API key (Console / pay-as-you-go)
72
+ #### Option B — Anthropic API key (Console / pay-as-you-go)
73
+
74
+ Paste the key in **Settings → Claude authentication**, or:
55
75
 
56
76
  ```bash
57
77
  cp .acdev/.env.example .acdev/.env
@@ -66,7 +86,7 @@ export ANTHROPIC_API_KEY=sk-ant-...
66
86
  acdev
67
87
  ```
68
88
 
69
- A Claude.ai browser-only subscription does **not** give you an API key. API keys come from the [Claude Console](https://platform.claude.com/) and are billed separately from Pro/Max.
89
+ A Claude.ai browser-only subscription does **not** give you an API key. API keys come from the [Claude Console](https://platform.claude.com/) and are billed separately from Pro/Max. To switch back to subscription login, clear the saved API key in Settings (or omit it from `.env`).
70
90
 
71
91
  ## Jira ticket source
72
92
 
@@ -136,13 +156,13 @@ The tool starts a local server (default port `4848`), opens the browser, and sho
136
156
  | **Review** | Edit PR title/body, colored diff, approve draft or ready, reject, or Clear |
137
157
  | **Logs** | Cross-job activity log with job filter |
138
158
  | **Alerts** | Failures / warnings with Retry, Clear, and dismiss |
139
- | **Settings** | Ticket source (GitHub / Jira), Jira connection, post-PR rules, and `.acdev/config.json` fields |
159
+ | **Settings** | Ticket source (GitHub / Jira), GitHub + Claude authentication, Jira connection, post-PR rules, and `.acdev/config.json` fields |
140
160
 
141
- Model selection lives in the sidebar (and Settings). Default is **Sonnet 5** (`claude-sonnet-5`).
161
+ Model selection lives in **Settings → Configuration**. The sidebar shows the current model as a read-only label. Default is **Sonnet 5** (`claude-sonnet-5`).
142
162
 
143
163
  ## Configuration
144
164
 
145
- Optional secrets go in `.acdev/.env` (copy from `.acdev/.env.example`). The file is gitignored and not required when using `claude auth login` with GitHub Issues only.
165
+ Optional secrets go in `.acdev/.env` (copy from `.acdev/.env.example`), or paste them in **Settings**. The file is gitignored and not required when using `gh auth login` and `claude auth login` with GitHub Issues only.
146
166
 
147
167
  Prefer **Settings** in the web UI to change runtime config — values persist to `.acdev/config.json` and apply to the next job without restart. You can still edit the file by hand if you prefer.
148
168
 
@@ -160,26 +180,41 @@ On first run, creates `.acdev/config.json`:
160
180
  "jiraBaseUrl": "",
161
181
  "jiraPrLinkPhrase": "Relates to",
162
182
  "jiraRules": {
163
- "afterPrOpened": { "enabled": false, "targetStatus": "In Review" }
183
+ "afterPrOpened": {
184
+ "enabled": false,
185
+ "action": "none",
186
+ "targetStatus": "In Review",
187
+ "label": ""
188
+ }
164
189
  },
165
190
  "githubRules": {
166
- "afterPrOpened": { "enabled": false, "action": "none", "label": "" }
191
+ "afterPrOpened": {
192
+ "enabled": false,
193
+ "action": "none",
194
+ "targetStatus": "In Review",
195
+ "label": ""
196
+ }
167
197
  }
168
198
  }
169
199
  ```
170
200
 
171
- `jiraRules.afterPrOpened` transitions the issue to a workflow status whose name matches `targetStatus` (case-insensitive). `githubRules.afterPrOpened.action` is `none`, `add_label`, or `close_issue` (GitHub issues have no built-in board statuses; Projects API is not used).
201
+ `jiraRules.afterPrOpened` and `githubRules.afterPrOpened` share the same shape: `enabled`, `action` (`none` | `set_status` | `add_label` | `close_issue`), `targetStatus`, and `label`.
202
+
203
+ | Action | Jira | GitHub |
204
+ |--------|------|--------|
205
+ | `set_status` | Workflow transition to a status whose name matches `targetStatus` (case-insensitive) | Applies a label named after `targetStatus` via `gh issue edit --add-label` (Projects board API is not used) |
206
+ | `add_label` | Adds the Jira label via REST `update.labels` `{ add }` | Adds the issue label via `gh` |
207
+ | `close_issue` | Transitions to a Done-category status, or else a Done/Closed/Resolved-like name | Closes the GitHub issue |
172
208
 
173
- Supported `model` values (Claude Agent SDK):
209
+ Legacy Jira configs that only had `enabled` + `targetStatus` (no `action`) still work: when enabled, they migrate to `action: "set_status"`.
210
+ Supported `model` values are Claude Agent SDK / Claude Code model ids (aliases like `claude-sonnet-5` / `claude-opus-5` / `sonnet`, or Anthropic API model ids). The Settings dropdown is populated by `GET /api/models`:
174
211
 
175
- | UI label | Model ID |
176
- |----------|----------|
177
- | Sonnet 5 (default) | `claude-sonnet-5` |
178
- | Opus 5 | `claude-opus-5` |
212
+ 1. When `ANTHROPIC_API_KEY` (or `ANTHROPIC_AUTH_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN`) is set — or Claude Code browser login credentials are readable from the local store — acdev calls Anthropic’s Models API (`GET /v1/models`) and merges results with curated Claude Code aliases.
213
+ 2. Otherwise (or if the live fetch fails), the UI falls back to a curated list (Sonnet/Opus/Fable/Haiku generations + common Code aliases such as `sonnet` / `opus`) so the dropdown stays useful without an API key. The Settings hint notes when the list is static (`source: "fallback"`).
179
214
 
180
- Unknown or removed model IDs in an existing config are migrated to `claude-sonnet-5` on load.
215
+ Empty or malformed model IDs in an existing config are migrated to `claude-sonnet-5` on load. Other valid ids are kept as-is.
181
216
 
182
- Change via **Settings** / the sidebar model toggle (`PATCH /api/config`) or `--model`. Takes effect for the next agent run without restart.
217
+ Change via **Settings Configuration** (`PATCH /api/config`) or `--model`. Takes effect for the next agent run without restart.
183
218
 
184
219
  Job state is persisted in `.acdev/state.json`.
185
220
 
@@ -193,11 +228,13 @@ npm test
193
228
 
194
229
  ## Architecture
195
230
 
196
- - `bin/acdev.js` — CLI entry, startup checks (`gh` always; Jira not required at startup)
231
+ - `bin/acdev.js` — CLI entry, startup checks (`gh` always; Jira not required at startup). Tokens in `.acdev/.env` are loaded before auth checks
197
232
  - `src/claude-auth.js` — Anthropic API key / Claude Code subscription auth detection
233
+ - `src/gh-auth.js` — GitHub CLI auth (`gh auth login` or `GH_TOKEN`)
198
234
  - `src/server.js` — Express API, SSE logs, job queue, config + Jira test endpoints
199
235
  - `src/git.js` — Worktree lifecycle (`issue-<id>` paths), `feat/`/`fix/` branch naming, diff, push
200
236
  - `src/agent.js` — Claude Agent SDK integration (`options.model`); GitHub vs Jira prompts
237
+ - `src/models.js` — `GET /api/models` list (Anthropic Models API + curated fallback)
201
238
  - `src/github.js` — Issue URL parsing, issue fetch via `gh`, `createPr({ draft })`
202
239
  - `src/jira.js` — Jira Cloud parse/fetch/test + issuetype → feat/fix
203
240
  - `src/config.js` — Load/save `.acdev/config.json` including ticket source
@@ -217,7 +254,8 @@ npm test
217
254
  | `POST` | `/api/jobs/:id/reject` | Discard worktree (keeps job as `discarded`) |
218
255
  | `DELETE` | `/api/jobs/:id` | Clear job from history (worktree best-effort); 409 if in-flight |
219
256
  | `POST` | `/api/jobs/:id/retry` | Re-queue failed/discarded |
220
- | `GET` | `/api/config` | Editable config + models + Jira status (token masked) |
257
+ | `GET` | `/api/config` | Editable config + curated models + Jira status (token masked) |
258
+ | `GET` | `/api/models` | `{ models, selected, source }` — live Anthropic list or curated fallback |
221
259
  | `PATCH` | `/api/config` | Partial update including `ticketSource`, `jiraBaseUrl`; `jiraEmail` / `jiraApiToken` → `.env` |
222
260
  | `POST` | `/api/jira/test` | Test Jira credentials (`GET /rest/api/3/myself`) |
223
261
 
package/bin/acdev.js CHANGED
@@ -3,8 +3,8 @@
3
3
  import { execSync } from 'node:child_process';
4
4
  import http from 'node:http';
5
5
  import open from 'open';
6
- import { checkClaudeAuth } from '../src/claude-auth.js';
7
- import { checkGhAuth } from '../src/gh-auth.js';
6
+ import { checkClaudeAuth, formatClaudeAuthError } from '../src/claude-auth.js';
7
+ import { checkGhAuth, formatGhAuthError } from '../src/gh-auth.js';
8
8
  import { loadConfig } from '../src/config.js';
9
9
  import { loadEnv } from '../src/env.js';
10
10
  import { migrateLegacyDataDir, migrateLegacyWorktreesDir } from '../src/paths.js';
@@ -60,34 +60,14 @@ async function main() {
60
60
 
61
61
  const ghAuth = checkGhAuth();
62
62
  if (!ghAuth.ok) {
63
- if (ghAuth.reason === 'not-found') {
64
- console.error(
65
- '✖ GitHub CLI (gh) not found in PATH. Install it from https://cli.github.com/'
66
- );
67
- } else {
68
- console.error(
69
- '✖ GitHub CLI not authenticated for github.com. Run `gh auth login -h github.com` first.'
70
- );
71
- }
63
+ console.error(formatGhAuthError(ghAuth));
72
64
  process.exit(1);
73
65
  }
74
66
 
75
67
  if (!opts.stubAgent) {
76
68
  const claudeAuth = checkClaudeAuth();
77
69
  if (!claudeAuth.ok) {
78
- console.error(
79
- [
80
- '✖ No Anthropic / Claude Code authentication found.',
81
- '',
82
- 'Authenticate with one of:',
83
- ' 1. Claude Pro/Max subscription (browser): install Claude Code, then run',
84
- ' `claude auth login` (or `claude setup-token` and set CLAUDE_CODE_OAUTH_TOKEN)',
85
- ' 2. Anthropic API key (API billing): set ANTHROPIC_API_KEY in the environment',
86
- ' or in `.acdev/.env` (optional file; copy from `.acdev/.env.example`)',
87
- '',
88
- 'For UI-only testing without auth: pass `--stub-agent`.',
89
- ].join('\n')
90
- );
70
+ console.error(formatClaudeAuthError(claudeAuth));
91
71
  process.exit(1);
92
72
  }
93
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acdev",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Local CLI + web UI for running AI agents on GitHub issues via git worktrees",
5
5
  "type": "module",
6
6
  "bin": {