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.
- package/.acdev/.env.example +8 -2
- package/README.md +59 -21
- package/bin/acdev.js +4 -24
- package/package.json +1 -1
- package/public/app.js +438 -93
- package/public/index.html +195 -63
- package/public/styles.css +81 -21
- package/src/afterPrRules.js +63 -8
- package/src/claude-auth.js +30 -0
- package/src/config.js +128 -88
- package/src/env.js +1 -1
- package/src/gh-auth.js +123 -6
- package/src/jira.js +171 -0
- package/src/models.js +366 -0
- package/src/server.js +44 -11
package/.acdev/.env.example
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
# Optional.
|
|
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`)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
69
|
+
export CLAUDE_CODE_OAUTH_TOKEN=... # or paste it in Settings → Claude authentication
|
|
52
70
|
```
|
|
53
71
|
|
|
54
|
-
|
|
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
|
|
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`)
|
|
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": {
|
|
183
|
+
"afterPrOpened": {
|
|
184
|
+
"enabled": false,
|
|
185
|
+
"action": "none",
|
|
186
|
+
"targetStatus": "In Review",
|
|
187
|
+
"label": ""
|
|
188
|
+
}
|
|
164
189
|
},
|
|
165
190
|
"githubRules": {
|
|
166
|
-
"afterPrOpened": {
|
|
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`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
}
|