@code-partner/codepipe 0.1.128-dev.21.gaadc172 → 0.1.128-dev.25.gdf270fe
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/README.md +223 -74
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,79 @@
|
|
|
1
1
|
# @code-partner/codepipe
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
**CodePipe turns your tracker tasks into reviewed pull requests.** Assign a
|
|
4
|
+
YouTrack task to yourself — an AI agent (Claude Code) studies your codebase,
|
|
5
|
+
proposes a solution, waits for your approval, implements it, verifies the
|
|
6
|
+
build and opens a PR. You control every step from a kanban dashboard (works
|
|
7
|
+
from your phone); the agent does the typing.
|
|
8
|
+
|
|
9
|
+
What you get once a project is connected:
|
|
10
|
+
|
|
11
|
+
- **A task pipeline instead of a chat.** Every task moves through explicit
|
|
12
|
+
phases — analysis → your review → implementation → build check → your
|
|
13
|
+
review → PR — visible as cards on a board. Nothing merges without you.
|
|
14
|
+
- **Approval gates.** At each gate you Approve, Reject with a comment (the
|
|
15
|
+
agent redoes the step with your instruction), or just comment.
|
|
16
|
+
- **Rework by comment.** After the PR exists, reply
|
|
17
|
+
`@codepipe rework: <what to change>` in the YouTrack task — the agent picks
|
|
18
|
+
it up and updates the PR.
|
|
19
|
+
- **Your credentials never leave your machine.** The CLI on your laptop is
|
|
20
|
+
the only thing holding YouTrack and git tokens; the orchestrating HUB has
|
|
21
|
+
no git access and no production tokens at all. Agent runners receive
|
|
22
|
+
read-only access encrypted per job and never persist it.
|
|
23
|
+
- **Works with an empty repo or an existing codebase** — you can start a
|
|
24
|
+
brand-new project or point CodePipe at years of history.
|
|
25
|
+
|
|
26
|
+
One package, one `codepipe` bin, two roles — for solo work you run both on
|
|
27
|
+
your machine with a single command (`codepipe up`):
|
|
28
|
+
|
|
29
|
+
- **CLI** — the local daemon that holds your credentials and performs every
|
|
30
|
+
write (branches, pushes, PRs, tracker updates);
|
|
31
|
+
- **worker** — the agent runner (Claude Code headless) that claims jobs and
|
|
32
|
+
does the analysis/implementation work.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Before you start: the checklist
|
|
37
|
+
|
|
38
|
+
Everything you need in place before `codepipe init`:
|
|
39
|
+
|
|
40
|
+
1. **Node.js 22+** and **git** on your machine.
|
|
41
|
+
|
|
42
|
+
2. **Claude Code + a Claude subscription.** Agents run on your Claude
|
|
43
|
+
account. Install [Claude Code](https://claude.com/claude-code), make sure
|
|
44
|
+
`claude` is on `PATH`, then run `claude setup-token` and copy the token
|
|
45
|
+
(`sk-ant-…`) — the setup wizard will ask for it.
|
|
46
|
+
|
|
47
|
+
3. **A YouTrack project.** You need three things:
|
|
48
|
+
- the instance URL (e.g. `https://yourteam.youtrack.cloud`);
|
|
49
|
+
- a permanent token: YouTrack → your avatar → *Account Security* →
|
|
50
|
+
*Tokens* → *New token…*;
|
|
51
|
+
- the project key (e.g. `DEV`).
|
|
52
|
+
|
|
53
|
+
The project must have a **`Stage` custom field** (enum) — that is the
|
|
54
|
+
column set CodePipe reads and moves. The default config expects at least
|
|
55
|
+
the values `Backlog`, `Develop` and `Review`: tasks in `Develop` enter the
|
|
56
|
+
pipeline, `Backlog` shows up as the dashboard TODO section, and `Review`
|
|
57
|
+
is where a task is moved once its PR is open. (Column names are
|
|
58
|
+
configurable later in `.codepipe/project.yaml` / `regimen.yaml`.)
|
|
59
|
+
|
|
60
|
+
4. **A project repository** on **GitHub, GitLab or Bitbucket** — empty or
|
|
61
|
+
with existing code, both work — and an access token for that host:
|
|
62
|
+
- **GitHub**: a classic PAT with `repo` + `workflow`, or a fine-grained
|
|
63
|
+
PAT with *Administration RW + Contents RW + Workflows RW + Metadata R*
|
|
64
|
+
(Administration is what lets the wizard create the Context Repo for
|
|
65
|
+
you; if the repos live in an org, approve the token in the org
|
|
66
|
+
settings);
|
|
67
|
+
- **GitLab**: a PAT with `api` (or `read_api` + `write_repository`);
|
|
68
|
+
- **Bitbucket**: your Atlassian account email + a scoped API token
|
|
69
|
+
(id.atlassian.com → *Security* → *API tokens* → *Create API token with
|
|
70
|
+
scopes*, app *Bitbucket*): `read:account`, `read:repository` +
|
|
71
|
+
`write:repository`, `write:pullrequest`, plus `admin:repository` so the
|
|
72
|
+
wizard can create the Context Repo.
|
|
73
|
+
|
|
74
|
+
5. **A CodePipe account** — nothing to prepare: it is created automatically
|
|
75
|
+
during setup from your email. During the beta, new accounts wait for
|
|
76
|
+
operator approval (you get an email when it happens).
|
|
15
77
|
|
|
16
78
|
## Install
|
|
17
79
|
|
|
@@ -19,72 +81,128 @@ bin, two roles:
|
|
|
19
81
|
npm i -g @code-partner/codepipe
|
|
20
82
|
```
|
|
21
83
|
|
|
22
|
-
|
|
23
|
-
|
|
84
|
+
(`@code-partner/devpipe-cli` and `@code-partner/devpipe-sandbox` are
|
|
85
|
+
deprecated aliases of this package.)
|
|
86
|
+
|
|
87
|
+
## Step 1 — register the project: `codepipe init`
|
|
24
88
|
|
|
25
|
-
|
|
89
|
+
Two ways to start, depending on where your code is:
|
|
26
90
|
|
|
27
91
|
```bash
|
|
92
|
+
# A) fresh workspace — repos will be cloned for you
|
|
28
93
|
mkdir ~/Projects/acme && cd ~/Projects/acme
|
|
29
|
-
codepipe init
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
codepipe
|
|
94
|
+
codepipe init
|
|
95
|
+
|
|
96
|
+
# B) you already have the code checked out — run it inside the repo
|
|
97
|
+
cd ~/Projects/acme-api
|
|
98
|
+
codepipe init
|
|
34
99
|
```
|
|
35
100
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
101
|
+
In case B the wizard detects `origin`, prefills the repo questions and
|
|
102
|
+
registers the checkout in place — no duplicate clone; `.codepipe/` is created
|
|
103
|
+
inside the repo and offered for its `.gitignore`.
|
|
104
|
+
|
|
105
|
+
The wizard asks, in order (Ctrl+C is safe at any point — a re-run resumes
|
|
106
|
+
from where you stopped):
|
|
41
107
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
account
|
|
46
|
-
|
|
108
|
+
1. **Where should this project run** — pick `local` for solo work (`farm` is
|
|
109
|
+
for hosting the daemon on a separate always-on machine).
|
|
110
|
+
2. **HUB URL** — accept the default unless you self-host.
|
|
111
|
+
3. **Your account email** — a browser tab opens to confirm this CLI with one
|
|
112
|
+
click; no account yet means one is created and confirmed by email (plus
|
|
113
|
+
operator approval during the beta — the wizard waits, and it is safe to
|
|
114
|
+
Ctrl+C and re-run later).
|
|
115
|
+
4. **Project id and name** — a short slug (e.g. `acme`) and a display name.
|
|
116
|
+
5. **Automation level** — `assisted`: every phase starts only when you press
|
|
117
|
+
Run on the dashboard (recommended to learn the ropes); `full`: tasks run
|
|
118
|
+
end-to-end to a PR, pausing only at gates you keep. You can change it
|
|
119
|
+
later.
|
|
120
|
+
6. **YouTrack URL, token and project key** — checked live before moving on.
|
|
121
|
+
7. **Allow CodePipe to write to YouTrack?** — yes: it moves tasks between
|
|
122
|
+
columns and comments the PR link; no: YouTrack stays strictly read-only
|
|
123
|
+
(you move cards yourself).
|
|
124
|
+
8. **Project repositories** — paste a clone URL per repo; the host token is
|
|
125
|
+
asked once per host and verified live. Connect one repo or several.
|
|
126
|
+
9. **Context Repo** — the git repo where CodePipe keeps its prompts,
|
|
127
|
+
knowledge base and task artifacts (analysis, patches). Accept the default
|
|
128
|
+
name and the wizard **creates it next to your first project repo**; or
|
|
129
|
+
attach to an existing one.
|
|
130
|
+
10. **Your YouTrack login** — only tasks assigned to you enter the pipeline
|
|
131
|
+
(lift the filter later with `require_assignee: false` in
|
|
132
|
+
`.codepipe/project.yaml`).
|
|
133
|
+
11. **Claude OAuth token** — paste the `claude setup-token` output. Skippable,
|
|
134
|
+
but no agent job runs until you set it (`codepipe login` does it later).
|
|
47
135
|
|
|
48
|
-
|
|
136
|
+
Then init does the actual setup — this is the "first run" work:
|
|
137
|
+
|
|
138
|
+
- **creates (or attaches to) the Context Repo** on your git host and
|
|
139
|
+
scaffolds it;
|
|
140
|
+
- **registers the project on the HUB** under your account (re-running init
|
|
141
|
+
on an existing project is safe — it reuses it);
|
|
142
|
+
- **clones the Context Repo** into `.codepipe/` and writes your local config
|
|
143
|
+
next to it: `project.yaml` (repos, board columns, sync rules) and
|
|
144
|
+
`regimen.yaml` (automation, gates, build/CI loops) — plain YAML you can
|
|
145
|
+
edit any time;
|
|
146
|
+
- **clones the project repos** as siblings of `.codepipe/` (skipped for an
|
|
147
|
+
in-place init — your checkout is the workspace);
|
|
148
|
+
- **saves secrets** to `~/.codepipe/secrets/<project>.json` (mode 0600 —
|
|
149
|
+
tokens never land in a repo);
|
|
150
|
+
- **offers to index the codebase** — a one-time agent job that writes
|
|
151
|
+
`knowledge/INDEX.md` into the Context Repo, a map of your code that makes
|
|
152
|
+
every later analysis faster and better grounded. Say yes; it runs in the
|
|
153
|
+
background once the daemon and worker are up.
|
|
154
|
+
|
|
155
|
+
## Step 2 — start it: `codepipe up`
|
|
49
156
|
|
|
50
157
|
```bash
|
|
51
|
-
|
|
52
|
-
codepipe
|
|
158
|
+
cd ~/Projects/acme # the folder you ran init in
|
|
159
|
+
codepipe up
|
|
53
160
|
```
|
|
54
161
|
|
|
55
|
-
|
|
162
|
+
One command, both roles: the CLI daemon connects to the HUB, and an embedded
|
|
163
|
+
agent worker registers itself automatically on the first run (no dashboard
|
|
164
|
+
visit, no manual tokens) and starts claiming jobs. Leave it running while you
|
|
165
|
+
work; Ctrl+C stops both.
|
|
56
166
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
`codepipe init`) or reuse this machine's CLI account, pick "all my projects"
|
|
60
|
-
or a subset, and the wizard registers the runner and starts the claim-loop.
|
|
61
|
-
Runners are bound to your account and only serve your projects.
|
|
167
|
+
Prefer a terminal UI? `codepipe` (no arguments) opens an interactive REPL
|
|
168
|
+
with the daemon embedded — see the command list below.
|
|
62
169
|
|
|
63
|
-
|
|
170
|
+
## Step 3 — run your first task
|
|
64
171
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
172
|
+
1. Open the dashboard (your HUB URL) and sign in with the same email — your
|
|
173
|
+
project card is there, with the setup/index progress on it.
|
|
174
|
+
2. In YouTrack, take a task, **assign it to yourself** and move it to
|
|
175
|
+
**`Develop`** (or create it in `Backlog` and press *Develop* on the
|
|
176
|
+
dashboard card).
|
|
177
|
+
3. Watch it on the board: the agent analyzes the task and produces
|
|
178
|
+
`SOLUTION.md` (+ questions, if any). In `assisted` mode press **Run** to
|
|
179
|
+
start each phase.
|
|
180
|
+
4. **Review gate:** read the proposed solution, then Approve — or Reject
|
|
181
|
+
with a comment and get a revised one.
|
|
182
|
+
5. The agent implements, the build check runs lint/build/tests, and after
|
|
183
|
+
your second approval the CLI pushes the branch and **opens the PR**
|
|
184
|
+
(task moves to `Review` with a PR-link comment, if writes are on).
|
|
185
|
+
6. Want changes after reviewing the PR? Comment in the YouTrack task:
|
|
72
186
|
|
|
73
|
-
|
|
74
|
-
|
|
187
|
+
```
|
|
188
|
+
@codepipe rework: use the existing retry helper instead of a new one
|
|
189
|
+
```
|
|
75
190
|
|
|
76
|
-
The
|
|
77
|
-
(`--profile <id>` → `~/.codepipe/worker/profiles/<id>/config.json`;
|
|
78
|
-
`CODEPIPE_SANDBOX_CONFIG` overrides). A pre-existing registration at the old
|
|
79
|
-
`~/.devpipe-sandbox/config.json` keeps working without a re-register.
|
|
191
|
+
The task loops back through analysis to an updated PR.
|
|
80
192
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
193
|
+
## Day-to-day commands
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
codepipe up daemon + agent worker in one process (solo mode)
|
|
197
|
+
codepipe interactive REPL with an embedded daemon
|
|
198
|
+
codepipe daemon headless daemon (launchd/systemd; --profile for multi-project)
|
|
199
|
+
codepipe sync clone/fetch the project repos per project.yaml
|
|
200
|
+
codepipe login set/replace the Claude token (--shared for machine-wide)
|
|
201
|
+
codepipe clone <id> reconstruct the workspace on another machine
|
|
202
|
+
codepipe worker … run the agent worker separately (see below)
|
|
203
|
+
```
|
|
86
204
|
|
|
87
|
-
|
|
205
|
+
REPL commands:
|
|
88
206
|
|
|
89
207
|
```
|
|
90
208
|
/status connection, project, Context Repo branch, siblings
|
|
@@ -99,28 +217,59 @@ it also sets up Node 22, the agent toolchain, rootless Podman, an isolated
|
|
|
99
217
|
/quit stop the daemon and exit
|
|
100
218
|
```
|
|
101
219
|
|
|
102
|
-
`/apply` and `/unstash`
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
220
|
+
`/apply` and `/unstash` support the **local apply mode** (`apply.mode: local`
|
|
221
|
+
in `project.yaml`, or per-task with `@codepipe apply: local`): CodePipe never
|
|
222
|
+
pushes for you — you review the staged change locally, commit, push and open
|
|
223
|
+
the PR yourself, then `/applied <key> --pr <url>`.
|
|
106
224
|
|
|
107
|
-
##
|
|
225
|
+
## Running the worker elsewhere (optional)
|
|
108
226
|
|
|
227
|
+
Solo mode embeds the worker, but you can also run it on a separate machine —
|
|
228
|
+
a desktop with spare cores, a home server, a cloud box:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
codepipe worker # interactive wizard on an unregistered machine
|
|
109
232
|
```
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
233
|
+
|
|
234
|
+
Log in by email, pick "all my projects" or a subset — runners are bound to
|
|
235
|
+
your account and only serve your projects. Headless servers register
|
|
236
|
+
non-interactively:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
codepipe worker register \
|
|
240
|
+
--hub https://hub.example.com \ # env CODEPIPE_HUB_URL
|
|
241
|
+
--token <registration token> \ # env CODEPIPE_WORKER_REG_TOKEN
|
|
242
|
+
--llm claude-headless # env CODEPIPE_WORKER_LLM
|
|
243
|
+
# --name / CODEPIPE_WORKER_NAME, --projects / CODEPIPE_WORKER_PROJECTS
|
|
244
|
+
# prints the key fingerprint — confirm it on the CLI (pin-on-register)
|
|
245
|
+
|
|
246
|
+
codepipe worker # connect to HUB and run the claim-loop (= worker start)
|
|
115
247
|
```
|
|
116
248
|
|
|
249
|
+
The worker config lives at `~/.codepipe/worker/config.json`
|
|
250
|
+
(`--profile <id>` → `~/.codepipe/worker/profiles/<id>/config.json`;
|
|
251
|
+
`CODEPIPE_SANDBOX_CONFIG` overrides). For the agent backend, Claude Code
|
|
252
|
+
(`claude`) must be on `PATH`. On a fresh Linux server use the installer
|
|
253
|
+
served by your HUB instead
|
|
254
|
+
(`curl -fsSL https://<your-hub>/install-sandbox.sh | sudo bash -s -- …`) —
|
|
255
|
+
it also sets up Node 22, the agent toolchain, rootless Podman, an isolated
|
|
256
|
+
`devpipe` user and systemd units.
|
|
257
|
+
|
|
117
258
|
## Where things live
|
|
118
259
|
|
|
119
|
-
- `.codepipe/` in the workspace — the cloned Context Repo
|
|
120
|
-
|
|
121
|
-
- Project repos — siblings of `.codepipe
|
|
260
|
+
- `.codepipe/` in the workspace — the cloned Context Repo, your local
|
|
261
|
+
`project.yaml` / `regimen.yaml`, plus runtime state (gitignored).
|
|
262
|
+
- Project repos — siblings of `.codepipe/` (or the checkout itself for an
|
|
263
|
+
in-place init).
|
|
122
264
|
- `~/.codepipe/secrets/<project>.json` — tokens, mode 0600, never in a repo.
|
|
123
|
-
- `~/.codepipe
|
|
124
|
-
|
|
265
|
+
- `~/.codepipe/worker/config.json` — worker registration (HUB URL, runner
|
|
266
|
+
id, keypair), mode 0600.
|
|
267
|
+
|
|
268
|
+
## Continuing on another machine
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
mkdir ~/Projects/acme && cd ~/Projects/acme
|
|
272
|
+
codepipe clone acme # re-clone the workspace; re-enter your tokens
|
|
273
|
+
```
|
|
125
274
|
|
|
126
275
|
See the platform docs for architecture and the pipeline state machine.
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var ce="0.1.128-dev.
|
|
2
|
+
var ce="0.1.128-dev.25.gdf270fe",me="https://hub.dev.codepipe.dev";var ge=2,Dc=1;function fr(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Dc&&t<=ge}var xe=".devpipe-context.yaml",$n=[{version:1,summary:"ADR section: adr/ scaffold (README, template, derived INDEX) + the format-version stamp itself",addedPaths:["adr/README.md","adr/0000-template.md","adr/INDEX.md",xe]}];function mr(t=1){return`# CodePipe Context Repo format version.
|
|
3
3
|
# Bumped by the scaffold / the format-migration PR \u2014 do not edit by hand.
|
|
4
4
|
template_version: ${t}
|
|
5
5
|
`}function xn(t){if(!t)return 0;let e=/^\s*template_version:\s*(\d+)\s*$/m.exec(t),r=e?parseInt(e[1]??"",10):NaN;return Number.isFinite(r)&&r>=0?r:0}function vn(t,e=$n){let r=[];for(let o of e)if(!(o.version<=t))for(let n of o.addedPaths)r.includes(n)||r.push(n);return r}function Sn(t,e=$n){return e.filter(r=>r.version>t)}function gr(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var ze=/^[a-z][a-z0-9-]{1,30}$/,Bc="-codepipe-ctx";function ve(t){return`${t}${Bc}`}var Bt={github:"github.com",gitlab:"gitlab.com",bitbucket:"bitbucket.org"};function ut(t){let e=t.match(/^git@([^:/]+):/);if(e)return e[1]??null;let r=t.match(/^ssh:\/\/(?:[^@/]+@)?([^/:]+)/);if(r)return r[1]??null;let o=t.match(/^https?:\/\/(?:[^@/]+@)?([^/:]+)/);return o?o[1]??null:null}var Je="x-bitbucket-api-token-auth";function hr(t){switch(t){case Bt.gitlab:return"oauth2";case Bt.bitbucket:return"x-token-auth";default:return"x-access-token"}}var Cn=20;function O(t){return process.env[`CODEPIPE_${t}`]??process.env[`DEVPIPE_${t}`]}import{Command as rm}from"commander";import{homedir as En}from"node:os";import{mkdirSync as zc,readFileSync as Jc,writeFileSync as Xc,existsSync as go}from"node:fs";import{dirname as An,join as br,resolve as Qc}from"node:path";import{fileURLToPath as Zc}from"node:url";import{existsSync as wr,readFileSync as Tn,readdirSync as Mc,writeFileSync as Hc}from"node:fs";import{dirname as Fc,join as je}from"node:path";import{parse as Kc}from"yaml";import{existsSync as Rn,renameSync as Gc}from"node:fs";function Xe(t,e,r=o=>console.error(o)){if(Rn(e)||!Rn(t))return!1;try{return Gc(t,e),r(`migrated ${t} \u2192 ${e} (DevPipe \u2192 CodePipe)`),!0}catch(o){return r(`failed to migrate ${t} \u2192 ${e}: ${o instanceof Error?o.message:String(o)} \u2014 continuing with the legacy path untouched`),!1}}var he=".codepipe",mo=".devpipe";function Wc(t=process.cwd()){let e=t;for(;;){if(wr(je(e,he,"project.yaml")))return e;if(wr(je(e,mo,"project.yaml")))return Xe(je(e,mo),je(e,he))&&Yc(e),e;let r=Fc(e);if(r===e)return null;e=r}}function qc(t){let e=je(t,he);return wr(e)?e:je(t,mo)}function Yc(t){let e=je(t,".gitignore");if(!wr(e))return;let r=Tn(e,"utf-8"),o=r.split(/\r?\n/).map(n=>{let i=n.trim();return i===".devpipe"||i===".devpipe/"||i==="/.devpipe"||i==="/.devpipe/"?n.replace(".devpipe",".codepipe"):n}).join(`
|