acdev 1.0.2 → 1.0.4
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 +66 -24
- package/bin/acdev.js +13 -25
- package/package.json +1 -1
- package/public/app.js +469 -93
- package/public/index.html +201 -63
- package/public/styles.css +105 -21
- package/src/afterPrRules.js +63 -8
- package/src/claude-auth.js +30 -0
- package/src/config.js +130 -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 +142 -13
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,11 +5,13 @@ 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`)
|
|
9
|
-
- Claude authentication (see [Authentication](#authentication) below)
|
|
8
|
+
- [GitHub CLI](https://cli.github.com/) (`gh`) on your `PATH` — required to fetch GitHub issues and open PRs. You can install `gh` first and authenticate later (see below).
|
|
10
9
|
- A git repository with a `develop` branch on `origin` (or configure another base branch)
|
|
10
|
+
- Optional: Claude authentication for real agent runs (or use `--stub-agent` for UI-only testing)
|
|
11
11
|
- Optional: Jira Cloud credentials when using Jira as the ticket source (see [Jira](#jira-ticket-source))
|
|
12
12
|
|
|
13
|
+
You do **not** need GitHub or Claude tokens before starting `acdev`. The server always starts (as long as you are inside a git repo); configure auth in **Settings → Authentication**, then enqueue jobs.
|
|
14
|
+
|
|
13
15
|
## Install
|
|
14
16
|
|
|
15
17
|
```bash
|
|
@@ -27,9 +29,27 @@ npm link # optional — makes `acdev` available globally
|
|
|
27
29
|
|
|
28
30
|
## Authentication
|
|
29
31
|
|
|
30
|
-
`acdev`
|
|
32
|
+
`acdev` starts even when auth is missing and prints a warning. Configure GitHub and Claude from **Settings → Authentication** 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 so status refreshes without a restart.
|
|
33
|
+
|
|
34
|
+
Enqueueing issues, retrying jobs, and applying review feedback require Claude (unless `--stub-agent`). Opening a PR always requires GitHub auth. The Overview banner prompts you when auth is incomplete.
|
|
35
|
+
|
|
36
|
+
`.env` is optional when you already use `gh auth login` and `claude auth login` on the machine.
|
|
37
|
+
|
|
38
|
+
### GitHub (issues / PRs)
|
|
39
|
+
|
|
40
|
+
`acdev` talks to GitHub through `gh`. **Any one** of these is enough:
|
|
41
|
+
|
|
42
|
+
1. **Existing CLI login** — `gh auth login` (browser/device). Settings shows this as authenticated.
|
|
43
|
+
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`.
|
|
44
|
+
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.
|
|
31
45
|
|
|
32
|
-
|
|
46
|
+
On a fresh machine: install `gh`, start `acdev`, then paste a PAT in Settings (or set `GH_TOKEN` in `.acdev/.env`). You can also copy `.acdev/.env.example` to `.acdev/.env` before starting.
|
|
47
|
+
|
|
48
|
+
### Claude
|
|
49
|
+
|
|
50
|
+
`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):
|
|
51
|
+
|
|
52
|
+
#### Option A — Claude Pro / Max subscription (browser login)
|
|
33
53
|
|
|
34
54
|
Best when you already pay for claude.ai and are not allowed to use API keys.
|
|
35
55
|
|
|
@@ -44,14 +64,18 @@ claude auth status
|
|
|
44
64
|
|
|
45
65
|
3. Run `acdev` with **no** `ANTHROPIC_API_KEY` set (an API key would take precedence and bill the Console instead of your subscription)
|
|
46
66
|
|
|
67
|
+
Settings cannot complete browser OAuth — that still needs `claude auth login` on the host. Detected method in Settings: `claude-code-login`.
|
|
68
|
+
|
|
47
69
|
For CI / non-interactive shells, generate a long-lived subscription token instead:
|
|
48
70
|
|
|
49
71
|
```bash
|
|
50
72
|
claude setup-token
|
|
51
|
-
export CLAUDE_CODE_OAUTH_TOKEN=... # or
|
|
73
|
+
export CLAUDE_CODE_OAUTH_TOKEN=... # or paste it in Settings → Claude authentication
|
|
52
74
|
```
|
|
53
75
|
|
|
54
|
-
|
|
76
|
+
#### Option B — Anthropic API key (Console / pay-as-you-go)
|
|
77
|
+
|
|
78
|
+
Paste the key in **Settings → Claude authentication**, or:
|
|
55
79
|
|
|
56
80
|
```bash
|
|
57
81
|
cp .acdev/.env.example .acdev/.env
|
|
@@ -66,7 +90,7 @@ export ANTHROPIC_API_KEY=sk-ant-...
|
|
|
66
90
|
acdev
|
|
67
91
|
```
|
|
68
92
|
|
|
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.
|
|
93
|
+
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
94
|
|
|
71
95
|
## Jira ticket source
|
|
72
96
|
|
|
@@ -101,13 +125,13 @@ Optional **Rules** in Settings can move the Jira ticket to a target status (e.g.
|
|
|
101
125
|
|
|
102
126
|
## Usage
|
|
103
127
|
|
|
104
|
-
From inside a cloned git repository
|
|
128
|
+
From inside a cloned git repository:
|
|
105
129
|
|
|
106
130
|
```bash
|
|
107
131
|
acdev
|
|
108
132
|
```
|
|
109
133
|
|
|
110
|
-
The tool starts a local server (default port `4848`), opens the browser, and shows the web UI.
|
|
134
|
+
The tool starts a local server (default port `4848`), opens the browser, and shows the web UI. If GitHub or Claude auth is missing, the CLI warns and the UI shows a banner — open **Settings → Authentication** to add tokens, then enqueue jobs.
|
|
111
135
|
|
|
112
136
|
### CLI flags
|
|
113
137
|
|
|
@@ -136,13 +160,13 @@ The tool starts a local server (default port `4848`), opens the browser, and sho
|
|
|
136
160
|
| **Review** | Edit PR title/body, colored diff, approve draft or ready, reject, or Clear |
|
|
137
161
|
| **Logs** | Cross-job activity log with job filter |
|
|
138
162
|
| **Alerts** | Failures / warnings with Retry, Clear, and dismiss |
|
|
139
|
-
| **Settings** | Ticket source (GitHub / Jira), Jira connection, post-PR rules, and `.acdev/config.json` fields |
|
|
163
|
+
| **Settings** | Ticket source (GitHub / Jira), GitHub + Claude authentication, Jira connection, post-PR rules, and `.acdev/config.json` fields |
|
|
140
164
|
|
|
141
|
-
Model selection lives in
|
|
165
|
+
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
166
|
|
|
143
167
|
## Configuration
|
|
144
168
|
|
|
145
|
-
Optional secrets go in `.acdev/.env` (copy from `.acdev/.env.example`)
|
|
169
|
+
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
170
|
|
|
147
171
|
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
172
|
|
|
@@ -160,26 +184,41 @@ On first run, creates `.acdev/config.json`:
|
|
|
160
184
|
"jiraBaseUrl": "",
|
|
161
185
|
"jiraPrLinkPhrase": "Relates to",
|
|
162
186
|
"jiraRules": {
|
|
163
|
-
"afterPrOpened": {
|
|
187
|
+
"afterPrOpened": {
|
|
188
|
+
"enabled": false,
|
|
189
|
+
"action": "none",
|
|
190
|
+
"targetStatus": "In Review",
|
|
191
|
+
"label": ""
|
|
192
|
+
}
|
|
164
193
|
},
|
|
165
194
|
"githubRules": {
|
|
166
|
-
"afterPrOpened": {
|
|
195
|
+
"afterPrOpened": {
|
|
196
|
+
"enabled": false,
|
|
197
|
+
"action": "none",
|
|
198
|
+
"targetStatus": "In Review",
|
|
199
|
+
"label": ""
|
|
200
|
+
}
|
|
167
201
|
}
|
|
168
202
|
}
|
|
169
203
|
```
|
|
170
204
|
|
|
171
|
-
`jiraRules.afterPrOpened`
|
|
205
|
+
`jiraRules.afterPrOpened` and `githubRules.afterPrOpened` share the same shape: `enabled`, `action` (`none` | `set_status` | `add_label` | `close_issue`), `targetStatus`, and `label`.
|
|
206
|
+
|
|
207
|
+
| Action | Jira | GitHub |
|
|
208
|
+
|--------|------|--------|
|
|
209
|
+
| `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) |
|
|
210
|
+
| `add_label` | Adds the Jira label via REST `update.labels` `{ add }` | Adds the issue label via `gh` |
|
|
211
|
+
| `close_issue` | Transitions to a Done-category status, or else a Done/Closed/Resolved-like name | Closes the GitHub issue |
|
|
172
212
|
|
|
173
|
-
|
|
213
|
+
Legacy Jira configs that only had `enabled` + `targetStatus` (no `action`) still work: when enabled, they migrate to `action: "set_status"`.
|
|
214
|
+
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
215
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
| Sonnet 5 (default) | `claude-sonnet-5` |
|
|
178
|
-
| Opus 5 | `claude-opus-5` |
|
|
216
|
+
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.
|
|
217
|
+
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
218
|
|
|
180
|
-
|
|
219
|
+
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
220
|
|
|
182
|
-
Change via **Settings
|
|
221
|
+
Change via **Settings → Configuration** (`PATCH /api/config`) or `--model`. Takes effect for the next agent run without restart.
|
|
183
222
|
|
|
184
223
|
Job state is persisted in `.acdev/state.json`.
|
|
185
224
|
|
|
@@ -193,11 +232,13 @@ npm test
|
|
|
193
232
|
|
|
194
233
|
## Architecture
|
|
195
234
|
|
|
196
|
-
- `bin/acdev.js` — CLI entry
|
|
235
|
+
- `bin/acdev.js` — CLI entry; soft-checks `gh` / Claude auth (warns, does not exit). Tokens in `.acdev/.env` are loaded before auth checks. Job APIs reject until auth is OK.
|
|
197
236
|
- `src/claude-auth.js` — Anthropic API key / Claude Code subscription auth detection
|
|
237
|
+
- `src/gh-auth.js` — GitHub CLI auth (`gh auth login` or `GH_TOKEN`)
|
|
198
238
|
- `src/server.js` — Express API, SSE logs, job queue, config + Jira test endpoints
|
|
199
239
|
- `src/git.js` — Worktree lifecycle (`issue-<id>` paths), `feat/`/`fix/` branch naming, diff, push
|
|
200
240
|
- `src/agent.js` — Claude Agent SDK integration (`options.model`); GitHub vs Jira prompts
|
|
241
|
+
- `src/models.js` — `GET /api/models` list (Anthropic Models API + curated fallback)
|
|
201
242
|
- `src/github.js` — Issue URL parsing, issue fetch via `gh`, `createPr({ draft })`
|
|
202
243
|
- `src/jira.js` — Jira Cloud parse/fetch/test + issuetype → feat/fix
|
|
203
244
|
- `src/config.js` — Load/save `.acdev/config.json` including ticket source
|
|
@@ -217,7 +258,8 @@ npm test
|
|
|
217
258
|
| `POST` | `/api/jobs/:id/reject` | Discard worktree (keeps job as `discarded`) |
|
|
218
259
|
| `DELETE` | `/api/jobs/:id` | Clear job from history (worktree best-effort); 409 if in-flight |
|
|
219
260
|
| `POST` | `/api/jobs/:id/retry` | Re-queue failed/discarded |
|
|
220
|
-
| `GET` | `/api/config` | Editable config + models + Jira status (token masked) |
|
|
261
|
+
| `GET` | `/api/config` | Editable config + curated models + Jira status (token masked) |
|
|
262
|
+
| `GET` | `/api/models` | `{ models, selected, source }` — live Anthropic list or curated fallback |
|
|
221
263
|
| `PATCH` | `/api/config` | Partial update including `ticketSource`, `jiraBaseUrl`; `jiraEmail` / `jiraApiToken` → `.env` |
|
|
222
264
|
| `POST` | `/api/jira/test` | Test Jira credentials (`GET /rest/api/3/myself`) |
|
|
223
265
|
|
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';
|
|
@@ -58,38 +58,26 @@ async function main() {
|
|
|
58
58
|
migrateLegacyWorktreesDir(repoRoot);
|
|
59
59
|
loadEnv(repoRoot);
|
|
60
60
|
|
|
61
|
+
// Soft auth: always start the server so Settings can add tokens.
|
|
62
|
+
// Job endpoints reject with a clear 4xx until auth is configured.
|
|
61
63
|
const ghAuth = checkGhAuth();
|
|
62
64
|
if (!ghAuth.ok) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
} else {
|
|
68
|
-
console.error(
|
|
69
|
-
'✖ GitHub CLI not authenticated for github.com. Run `gh auth login -h github.com` first.'
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
process.exit(1);
|
|
65
|
+
console.warn(formatGhAuthError(ghAuth).replace(/^✖/m, '⚠'));
|
|
66
|
+
console.warn(
|
|
67
|
+
'⚠ Continuing without GitHub auth — configure in Settings → Authentication, then enqueue jobs.'
|
|
68
|
+
);
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
if (!opts.stubAgent) {
|
|
76
72
|
const claudeAuth = checkClaudeAuth();
|
|
77
73
|
if (!claudeAuth.ok) {
|
|
78
|
-
console.
|
|
79
|
-
|
|
80
|
-
|
|
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')
|
|
74
|
+
console.warn(formatClaudeAuthError(claudeAuth).replace(/^✖/m, '⚠'));
|
|
75
|
+
console.warn(
|
|
76
|
+
'⚠ Continuing without Claude auth — configure in Settings → Authentication (or pass --stub-agent).'
|
|
90
77
|
);
|
|
91
|
-
process.exit(1);
|
|
92
78
|
}
|
|
79
|
+
} else {
|
|
80
|
+
console.log('✓ Stub agent enabled (Claude auth not required)');
|
|
93
81
|
}
|
|
94
82
|
|
|
95
83
|
const config = loadConfig(repoRoot);
|