@idea1/cli 1.5.2 → 1.6.1
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 +123 -92
- package/dist/commands/approve-pr.d.ts.map +1 -1
- package/dist/commands/approve-pr.js +7 -163
- package/dist/commands/approve-pr.js.map +1 -1
- package/dist/commands/attach-project-item.d.ts.map +1 -1
- package/dist/commands/attach-project-item.js +38 -89
- package/dist/commands/attach-project-item.js.map +1 -1
- package/dist/commands/close-worktree.d.ts.map +1 -1
- package/dist/commands/close-worktree.js +3 -2
- package/dist/commands/close-worktree.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +17 -14
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/index.d.ts +3 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +5 -3
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/join-project-item.d.ts.map +1 -1
- package/dist/commands/join-project-item.js +38 -77
- package/dist/commands/join-project-item.js.map +1 -1
- package/dist/commands/next-workflow-step.d.ts.map +1 -1
- package/dist/commands/next-workflow-step.js +66 -51
- package/dist/commands/next-workflow-step.js.map +1 -1
- package/dist/commands/ready-for-approval.d.ts.map +1 -1
- package/dist/commands/ready-for-approval.js +7 -66
- package/dist/commands/ready-for-approval.js.map +1 -1
- package/dist/commands/start-agent-implementation.d.ts +3 -0
- package/dist/commands/start-agent-implementation.d.ts.map +1 -0
- package/dist/commands/start-agent-implementation.js +41 -0
- package/dist/commands/start-agent-implementation.js.map +1 -0
- package/dist/commands/start-dev-implementation.d.ts.map +1 -1
- package/dist/commands/start-dev-implementation.js +8 -55
- package/dist/commands/start-dev-implementation.js.map +1 -1
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +81 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +29 -9
- package/dist/interactive.js.map +1 -1
- package/dist/lib/claude-options.d.ts +33 -0
- package/dist/lib/claude-options.d.ts.map +1 -0
- package/dist/lib/claude-options.js +83 -0
- package/dist/lib/claude-options.js.map +1 -0
- package/dist/lib/settings.d.ts.map +1 -1
- package/dist/lib/settings.js +5 -5
- package/dist/lib/settings.js.map +1 -1
- package/dist/lib/workflow-states.d.ts +21 -3
- package/dist/lib/workflow-states.d.ts.map +1 -1
- package/dist/lib/workflow-states.generated.d.ts +21 -0
- package/dist/lib/workflow-states.generated.d.ts.map +1 -0
- package/dist/lib/workflow-states.generated.js +34 -0
- package/dist/lib/workflow-states.generated.js.map +1 -0
- package/dist/lib/workflow-states.js +47 -26
- package/dist/lib/workflow-states.js.map +1 -1
- package/dist/services/branch-setup.d.ts +42 -0
- package/dist/services/branch-setup.d.ts.map +1 -0
- package/dist/services/branch-setup.js +116 -0
- package/dist/services/branch-setup.js.map +1 -0
- package/dist/services/claude.d.ts +14 -4
- package/dist/services/claude.d.ts.map +1 -1
- package/dist/services/claude.js +39 -4
- package/dist/services/claude.js.map +1 -1
- package/dist/services/git.d.ts +66 -0
- package/dist/services/git.d.ts.map +1 -1
- package/dist/services/git.js +161 -6
- package/dist/services/git.js.map +1 -1
- package/dist/services/workflow-engine.d.ts +67 -0
- package/dist/services/workflow-engine.d.ts.map +1 -0
- package/dist/services/workflow-engine.js +371 -0
- package/dist/services/workflow-engine.js.map +1 -0
- package/dist/services/workflow-handlers/agent-implementation.d.ts +9 -0
- package/dist/services/workflow-handlers/agent-implementation.d.ts.map +1 -0
- package/dist/services/workflow-handlers/agent-implementation.js +37 -0
- package/dist/services/workflow-handlers/agent-implementation.js.map +1 -0
- package/dist/services/workflow-handlers/approve-pr.d.ts +8 -0
- package/dist/services/workflow-handlers/approve-pr.d.ts.map +1 -0
- package/dist/services/workflow-handlers/approve-pr.js +161 -0
- package/dist/services/workflow-handlers/approve-pr.js.map +1 -0
- package/dist/services/workflow-handlers/dev-implementation.d.ts +8 -0
- package/dist/services/workflow-handlers/dev-implementation.d.ts.map +1 -0
- package/dist/services/workflow-handlers/dev-implementation.js +34 -0
- package/dist/services/workflow-handlers/dev-implementation.js.map +1 -0
- package/dist/services/workflow-handlers/index.d.ts +18 -0
- package/dist/services/workflow-handlers/index.d.ts.map +1 -0
- package/dist/services/workflow-handlers/index.js +36 -0
- package/dist/services/workflow-handlers/index.js.map +1 -0
- package/dist/services/workflow-handlers/ready-for-approval.d.ts +8 -0
- package/dist/services/workflow-handlers/ready-for-approval.d.ts.map +1 -0
- package/dist/services/workflow-handlers/ready-for-approval.js +60 -0
- package/dist/services/workflow-handlers/ready-for-approval.js.map +1 -0
- package/dist/services/workflow.d.ts +1 -21
- package/dist/services/workflow.d.ts.map +1 -1
- package/dist/services/workflow.js +1 -67
- package/dist/services/workflow.js.map +1 -1
- package/dist/services/worktree.d.ts +21 -23
- package/dist/services/worktree.d.ts.map +1 -1
- package/dist/services/worktree.js +35 -71
- package/dist/services/worktree.js.map +1 -1
- package/dist/types/index.d.ts +41 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/dist/commands/start-project-item.d.ts +0 -27
- package/dist/commands/start-project-item.d.ts.map +0 -1
- package/dist/commands/start-project-item.js +0 -325
- package/dist/commands/start-project-item.js.map +0 -1
package/README.md
CHANGED
|
@@ -15,15 +15,19 @@ npm install -g @idea1/cli
|
|
|
15
15
|
Run commands directly from the command line:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
#
|
|
19
|
-
idea1 start
|
|
20
|
-
idea1 -s https://app.idea1.ai/project/items/590
|
|
18
|
+
# Put a project item under workflow management (branch + metadata, no code changes)
|
|
19
|
+
idea1 start --url https://app.idea1.ai/project/items/590
|
|
21
20
|
|
|
22
|
-
#
|
|
21
|
+
# Advance the item to its next workflow state (runs that state's automation)
|
|
22
|
+
idea1 next --url https://app.idea1.ai/project/items/590 # or just `idea1 next` on the item's branch
|
|
23
|
+
|
|
24
|
+
# Jump straight to Agent Implementation (worktree + Claude) — the "send for implementation" path
|
|
25
|
+
idea1 start-agent-implementation --url https://app.idea1.ai/project/items/590 # alias: start-project-item
|
|
26
|
+
|
|
27
|
+
# Dedicated transitions (each is one `next` step)
|
|
23
28
|
idea1 start-dev-implementation # or: idea1 dev
|
|
24
|
-
idea1 ready-for-approval
|
|
29
|
+
idea1 ready-for-approval # or: idea1 rfa
|
|
25
30
|
idea1 approve-pr # or: idea1 approve
|
|
26
|
-
idea1 next-workflow-step # or: idea1 next
|
|
27
31
|
|
|
28
32
|
# Show help
|
|
29
33
|
idea1 --help
|
|
@@ -37,45 +41,99 @@ Run `idea1` without arguments to enter interactive mode with a searchable comman
|
|
|
37
41
|
|
|
38
42
|
## Workflow Commands
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
Every project item moves through the same sequence of workflow states:
|
|
41
45
|
|
|
42
46
|
```
|
|
43
|
-
|
|
47
|
+
Build Spec in Progress → Refinement - Build Spec → Refinement - Implementation → Ready for Agent Implementation
|
|
48
|
+
→ Agent Implementation → Dev Implementation → Needs Approval for Release → Approved and Merged → Released
|
|
44
49
|
```
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
The state names and their order are defined once, in `shared-config/workflow-states.json`, and shared with the backend and the web client (see `scripts/generate-workflow-states.js`).
|
|
52
|
+
|
|
53
|
+
### How the workflow engine works
|
|
54
|
+
|
|
55
|
+
An item **under workflow management** has exactly one branch on origin that carries `.idea1/<branch>.json` with the item's URL and current `workflowState`. That committed file is the durable, shared record: the idea1.ai web client writes the same file when a state is advanced from the browser, and every CLI command first syncs the branch's state from origin (adopting the metadata into local git config and fast-forwarding a local checkout when it is behind) — so the CLI and the web client never disagree.
|
|
56
|
+
|
|
57
|
+
A transition is "enter state X". Entering a state runs that state's automation (a *handler*), then records the new state in the branch metadata, in local git config and on the idea1.ai item. Most states have no automation; the implementation states do:
|
|
58
|
+
|
|
59
|
+
| Entering | Automation |
|
|
60
|
+
|----------|-----------|
|
|
61
|
+
| Build Spec in Progress … Ready for Agent Implementation | none — status only |
|
|
62
|
+
| **Agent Implementation** | ensures the branch is checked out locally (worktree or main repo), then **launches Claude** to implement the item. This is the only transition that starts code-writing automation |
|
|
63
|
+
| **Dev Implementation** | commits and pushes the agent's work, creates the PR, removes the worktree if `removeWorktreeAtState` says so |
|
|
64
|
+
| **Needs Approval for Release** | requires the PR, requests reviewers / sets the assignee, removes the worktree if configured |
|
|
65
|
+
| **Approved and Merged** | approves (when you are a requested reviewer), removes the metadata file, merges the PR, deletes the branch and worktree |
|
|
66
|
+
| Released | none — normally set by GitHub automation when the work merges to `main` |
|
|
47
67
|
|
|
48
|
-
|
|
68
|
+
`start` begins state management, `next` advances one state, and `start-agent-implementation` jumps to Agent Implementation — all three reduce to the same engine, so branches and items always end up consistent with the state they are in.
|
|
49
69
|
|
|
50
|
-
|
|
70
|
+
### start
|
|
71
|
+
|
|
72
|
+
Put a project item under workflow management. An item that has never been started enters **Build Spec in Progress**; an item that already has a state keeps it. The branch is created on origin from the base branch with the metadata file as its first commit — nothing is checked out, no code is written and Claude is not launched. Idempotent: running it again for a managed item just reports the branch and state.
|
|
51
73
|
|
|
52
74
|
```bash
|
|
53
|
-
idea1 start
|
|
54
|
-
idea1
|
|
75
|
+
idea1 start --url <url> [options]
|
|
76
|
+
idea1 start # prompts for the URL (blank to create a new item)
|
|
77
|
+
idea1 s --url <url>
|
|
55
78
|
```
|
|
56
79
|
|
|
57
|
-
**
|
|
58
|
-
-
|
|
59
|
-
-
|
|
80
|
+
**Options:**
|
|
81
|
+
- `-u, --url <url>` - The Idea1.ai project item URL. Leave blank to create a new item (you'll be prompted for a `--title`).
|
|
82
|
+
- `-t, --title <title>` - Title for the new project item (only when no URL is given).
|
|
83
|
+
- `-p, --source-path <path>` - Path to source directory.
|
|
84
|
+
- `-n, --branch-name <name>` - Branch name (auto-generated from the item description if not provided).
|
|
85
|
+
- `-b, --base-branch <branch>` - Base branch / PR target (default: `working/release`).
|
|
86
|
+
- `-w, --workflow-type <type>` - `independent` or `integration`; you also choose any stack branch and (for integration) the integration branch.
|
|
87
|
+
|
|
88
|
+
### next-workflow-step
|
|
89
|
+
|
|
90
|
+
Advance a project item to its next workflow state and run that state's automation. On the item's branch no arguments are needed; from anywhere else pass the item URL — the CLI finds the branch on origin (moving into its local checkout when one exists) or, for an item without a branch yet, reads the current state from idea1.ai and creates the branch first.
|
|
91
|
+
|
|
92
|
+
With `--to <state>` the item advances through every state up to that one in a single run — the same as running `next` once per state, with each state's automation in order. The CLI only moves forward; an item already at or past the requested state is reported as an error.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
idea1 next # on the item's branch
|
|
96
|
+
idea1 next --url <url> # from anywhere in the repository
|
|
97
|
+
idea1 next --to "Dev Implementation" # several states at once
|
|
98
|
+
idea1 n
|
|
99
|
+
```
|
|
60
100
|
|
|
61
101
|
**Options:**
|
|
62
|
-
- `-
|
|
63
|
-
-
|
|
64
|
-
- `-
|
|
65
|
-
-
|
|
66
|
-
- `--claude-entry-point <mode>` - How Claude is invoked after setup (default: `launch`). Valid values: `launch` (start a new Claude session), `inline` (output structured prompt for an already-running Claude session), `none` (do not invoke Claude)
|
|
102
|
+
- `-u, --url <url>` - Project item URL (required when not on the item's branch).
|
|
103
|
+
- `--to <state>` - Workflow state to advance to (default: the next state).
|
|
104
|
+
- `-p, --source-path <path>` - Path to source directory.
|
|
105
|
+
- Any option of the state being entered (for example `--model`/`--effort` for Agent Implementation, `--assignee`/`--reviewers` for Needs Approval for Release). Options that were not supplied are prompted for when that state is reached.
|
|
67
106
|
|
|
68
107
|
**What it does:**
|
|
69
|
-
1.
|
|
70
|
-
2.
|
|
71
|
-
3.
|
|
72
|
-
4.
|
|
73
|
-
|
|
74
|
-
|
|
108
|
+
1. Syncs the branch's workflow state from origin (picking up changes made in the web client).
|
|
109
|
+
2. Puts the item under workflow management if it is not yet (a never-started item enters Build Spec in Progress, which is the whole step).
|
|
110
|
+
3. Runs the automation of every state entered, records the new state on the branch, in git config and on idea1.ai.
|
|
111
|
+
4. Reports "Workflow is complete" at `Released`.
|
|
112
|
+
|
|
113
|
+
The automation is idempotent, so re-running a transition after the item was moved back in the web client does not repeat work that is already done: an existing PR is reused, an already-merged PR is left alone and the item simply moves on.
|
|
114
|
+
|
|
115
|
+
### start-agent-implementation
|
|
116
|
+
|
|
117
|
+
Start implementing a project item: put it under workflow management if needed, move it to **Agent Implementation** (through any intermediate states, which have no automation), set up the working environment and launch Claude Code with the implementation prompt. This is the command behind "Send for Implementation" in the web client; `start-project-item` remains an alias so existing team command templates keep working.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
idea1 start-agent-implementation --url <url> [options]
|
|
121
|
+
idea1 implement --url <url>
|
|
122
|
+
idea1 start-project-item --url <url> # alias
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Options:** all `start` options, plus the Agent Implementation options:
|
|
126
|
+
- `-iso, --isolation <mode>` - Where to work on the branch (default: `worktree`). See [Isolation mode](#isolation-mode).
|
|
127
|
+
- `-pm, --permission-mode <mode>` - Claude permission mode (default: `plan`). Valid values: `acceptEdits`, `bypassPermissions`, `default`, `delegate`, `dontAsk`, `plan`
|
|
128
|
+
- `-m, --model <model>` - Claude model for the implementation session (default: `opus`). Valid values: `fable`, `opus`, `sonnet`, `haiku`
|
|
129
|
+
- `-e, --effort <level>` - Claude effort level (default: `high`). Valid values: `low`, `medium`, `high`, `xhigh`, `max`
|
|
130
|
+
- `-im, --claude-entry-point <mode>` - How Claude is invoked once the environment is ready (default: `launch`). Valid values: `launch` (start a new Claude session), `inline` (output a structured prompt for an already-running Claude session), `none` (do not invoke Claude)
|
|
131
|
+
|
|
132
|
+
An item already in Agent Implementation is not transitioned again: the working environment is set up (or reused) and Claude is launched.
|
|
75
133
|
|
|
76
134
|
### Isolation mode
|
|
77
135
|
|
|
78
|
-
`start-
|
|
136
|
+
`start-agent-implementation`, `next` (when entering Agent Implementation) and `join-project-item` all ask where you want to work on the branch. The prompt is always shown, with `worktree` preselected:
|
|
79
137
|
|
|
80
138
|
- `worktree` (default) - creates/uses a git worktree in a sibling directory (`<repo>-<branch>`), leaving the main repository on its own branch. Runs the `setup-worktree` hook.
|
|
81
139
|
- `main-repo` - checks the branch out in the main repository, in place. Requires a clean working directory and fails if the branch is already checked out in a worktree. The `setup-worktree` hook is skipped, since the main repository is already set up.
|
|
@@ -84,62 +142,57 @@ Supply `-iso worktree` or `-iso main-repo` on the command line to skip the promp
|
|
|
84
142
|
|
|
85
143
|
### join-project-item
|
|
86
144
|
|
|
87
|
-
Join an **in-progress** project item by setting up a working environment on its existing branch — for picking up work started elsewhere (e.g. on another machine
|
|
145
|
+
Join an **in-progress** project item by setting up a working environment on its existing branch — for picking up work started elsewhere (e.g. on another machine, by another developer, or from the web client). It does not change the workflow state and never launches a Claude implementation session.
|
|
88
146
|
|
|
89
147
|
```bash
|
|
90
148
|
idea1 join-project-item --project-item-url <url>
|
|
91
149
|
idea1 join-project-item --branch-name <branch>
|
|
92
|
-
idea1 -
|
|
150
|
+
idea1 join-project-item --pull-request-url <pr url>
|
|
151
|
+
idea1 j --branch-name <branch>
|
|
93
152
|
```
|
|
94
153
|
|
|
95
|
-
**Options (exactly one of the first
|
|
154
|
+
**Options (exactly one of the first three must be supplied — they are mutually exclusive):**
|
|
96
155
|
- `--project-item-url <url>` - The Idea1.ai project item URL; its branch is discovered automatically.
|
|
97
156
|
- `-n, --branch-name <branch>` - The branch to join; its associated project item is discovered automatically.
|
|
157
|
+
- `--pull-request-url <url>` - A GitHub PR URL; its head branch is joined.
|
|
98
158
|
- `-p, --source-path <path>` - Path to source directory.
|
|
99
159
|
- `-iso, --isolation <mode>` - Where to work on the branch (default: `worktree`). See [Isolation mode](#isolation-mode).
|
|
100
|
-
- `-pm, --permission-mode <mode>` - Claude
|
|
101
|
-
- `-e, --effort <level>` - Claude effort level (default: `high`).
|
|
102
|
-
|
|
103
|
-
In interactive mode, if neither option is supplied you are prompted to choose which to use.
|
|
160
|
+
- `-pm, --permission-mode <mode>`, `-m, --model <model>`, `-e, --effort <level>` - Claude session settings recorded for the environment (defaults: `plan`, `opus`, `high`).
|
|
104
161
|
|
|
105
162
|
**What it does:**
|
|
106
163
|
1. Resolves the branch from the URL (or the URL from the branch) using the committed branch metadata.
|
|
107
|
-
2.
|
|
108
|
-
3.
|
|
109
|
-
4.
|
|
110
|
-
5. Runs any setup hooks defined in `.idea1/settings.json` (worktree mode only). It does **not** launch a Claude implementation session.
|
|
164
|
+
2. Reuses the checkout that already holds the branch, or sets one up — a git worktree, or the branch checked out in the main repository (creating a local tracking branch if it only exists on origin).
|
|
165
|
+
3. Syncs the workflow state from the metadata committed on origin into local git config, defaulting a legacy branch with no recorded state to `Agent Implementation`, and pushes any recovered metadata back to origin.
|
|
166
|
+
4. Runs any setup hooks defined in `.idea1/settings.json` (newly created worktrees only).
|
|
111
167
|
|
|
112
|
-
If a project item URL is supplied but no branch exists for it yet
|
|
168
|
+
If a project item URL is supplied but no branch exists for it yet, `join-project-item` puts the item under workflow management first (as `start` does) and then sets up the environment.
|
|
113
169
|
|
|
114
170
|
### attach-project-item
|
|
115
171
|
|
|
116
|
-
Attach the **current branch** to a project item,
|
|
172
|
+
Attach the **current branch** to a project item, putting it under workflow management at the item's current state (or `Build Spec in Progress` when it has none). Use this when you already have a branch with work on it and want to bring it into the workflow. It does not create a branch or a worktree and never invokes Claude.
|
|
117
173
|
|
|
118
174
|
```bash
|
|
119
175
|
idea1 attach-project-item --url <url>
|
|
120
176
|
idea1 attach-project-item # prompts for the URL (blank to create a new item)
|
|
121
|
-
idea1
|
|
177
|
+
idea1 a --url <url>
|
|
122
178
|
```
|
|
123
179
|
|
|
124
180
|
**Options:**
|
|
125
|
-
-
|
|
181
|
+
- `-u, --url <url>` - The Idea1.ai project item URL. Leave blank to create a new item (you'll be prompted for a `--title`).
|
|
126
182
|
- `-t, --title <title>` - Title for the new project item (only when no URL is given).
|
|
127
183
|
- `-p, --source-path <path>` - Path to source directory.
|
|
128
184
|
- `-b, --base-branch <branch>` - Base branch / PR target for an independent feature (default: `working/release`).
|
|
129
|
-
- `-w, --workflow-type <type>` - Development workflow type: `independent` or `integration`.
|
|
185
|
+
- `-w, --workflow-type <type>` - Development workflow type: `independent` or `integration`. You also choose any stack branch and (for integration) the integration branch.
|
|
130
186
|
|
|
131
187
|
**What it does:**
|
|
132
188
|
1. Verifies the current branch is not already attached to a project item (errors if it is — use `join-project-item` to resume instead).
|
|
133
|
-
2. Creates the project item if no URL was supplied.
|
|
134
|
-
3.
|
|
135
|
-
4.
|
|
136
|
-
5. Records the per-branch metadata (project item URL, base branch, workflow state, dev workflow type, stack/integration branch) in git config and the committed `.idea1/<branch>.json` file.
|
|
137
|
-
6. Commits the metadata and pushes the current branch so it is up to date with its metadata.
|
|
138
|
-
7. Sets up a PR into the base branch (the integration branch for integration work), just like `start-project-item` targets it.
|
|
189
|
+
2. Creates the project item if no URL was supplied, and reads its current workflow state from idea1.ai.
|
|
190
|
+
3. Records the per-branch metadata (project item URL, base branch, workflow state, dev workflow type, stack/integration branch) in git config and the committed `.idea1/<branch>.json` file, and pushes the branch.
|
|
191
|
+
4. Records the branch on the idea1.ai item. If the item is already at `Dev Implementation` or later, makes sure a PR into the base branch exists.
|
|
139
192
|
|
|
140
193
|
### start-dev-implementation
|
|
141
194
|
|
|
142
|
-
|
|
195
|
+
Enter **Dev Implementation** from Agent Implementation — the same step `next` takes from that state.
|
|
143
196
|
|
|
144
197
|
```bash
|
|
145
198
|
idea1 start-dev-implementation [options]
|
|
@@ -150,39 +203,35 @@ idea1 dev [options]
|
|
|
150
203
|
- `-p, --source-path <path>` - Path to worktree directory
|
|
151
204
|
|
|
152
205
|
**What it does:**
|
|
153
|
-
1. Validates current state is "Agent Implementation"
|
|
206
|
+
1. Validates the current state is "Agent Implementation" (after syncing from origin)
|
|
154
207
|
2. Commits and pushes all changes in the branch
|
|
155
208
|
3. Creates a PR of the branch into its base branch
|
|
156
|
-
4.
|
|
157
|
-
5.
|
|
158
|
-
6. Updates Idea1.ai workflow status
|
|
209
|
+
4. Records "Dev Implementation" in the branch metadata, git config and on Idea1.ai
|
|
210
|
+
5. If in a worktree and `removeWorktreeAtState` is `Dev Implementation`, removes the worktree. The main repo stays on its current branch; use `join-project-item` to work on the item in the main repo or a new worktree.
|
|
159
211
|
|
|
160
212
|
### ready-for-approval
|
|
161
213
|
|
|
162
|
-
|
|
214
|
+
Enter **Needs Approval for Release** from Dev Implementation — the same step `next` takes from that state.
|
|
163
215
|
|
|
164
216
|
```bash
|
|
165
|
-
idea1 ready-for-approval [
|
|
166
|
-
idea1 rfa
|
|
217
|
+
idea1 ready-for-approval [options]
|
|
218
|
+
idea1 rfa --assignee octocat --reviewers octocat,hubot
|
|
167
219
|
```
|
|
168
220
|
|
|
169
|
-
**Arguments:**
|
|
170
|
-
- `[reviewer]` - GitHub username of reviewer (optional)
|
|
171
|
-
|
|
172
221
|
**Options:**
|
|
173
|
-
- `-
|
|
222
|
+
- `-a, --assignee <username>` - Who to assign the PR to (prompted from the repository's assignable users when omitted; choose "(none)" to skip)
|
|
223
|
+
- `-r, --reviewers <user1,user2>` - Who to request a review from (multi-select when omitted)
|
|
174
224
|
|
|
175
225
|
**What it does:**
|
|
176
|
-
1. Validates current state is "Dev Implementation"
|
|
177
|
-
2. Ensures no uncommitted or unpushed changes
|
|
178
|
-
3.
|
|
179
|
-
4.
|
|
180
|
-
5.
|
|
181
|
-
6. If in a worktree and `removeWorktreeAtState` is `Needs Approval for Release` (the default) or earlier, removes the worktree and checks the branch out in the main repo
|
|
226
|
+
1. Validates the current state is "Dev Implementation" (after syncing from origin)
|
|
227
|
+
2. Ensures no uncommitted or unpushed changes in the local checkout
|
|
228
|
+
3. Requires the PR to exist, then requests reviews and sets the assignee
|
|
229
|
+
4. Records "Needs Approval for Release" in the branch metadata, git config and on Idea1.ai
|
|
230
|
+
5. If in a worktree and `removeWorktreeAtState` is `Needs Approval for Release` (the default) or earlier, removes the worktree
|
|
182
231
|
|
|
183
232
|
### approve-pr
|
|
184
233
|
|
|
185
|
-
|
|
234
|
+
Enter **Approved and Merged** from Needs Approval for Release — the same step `next` takes from that state.
|
|
186
235
|
|
|
187
236
|
```bash
|
|
188
237
|
idea1 approve-pr [options]
|
|
@@ -193,29 +242,11 @@ idea1 approve [options]
|
|
|
193
242
|
- `-c, --comment <message>` - Custom approval comment (default: "Approved via idea1 CLI workflow")
|
|
194
243
|
|
|
195
244
|
**What it does:**
|
|
196
|
-
1. Validates current state is "Needs Approval for Release"
|
|
197
|
-
2.
|
|
198
|
-
3.
|
|
199
|
-
4.
|
|
200
|
-
5.
|
|
201
|
-
6. Updates Idea1.ai workflow status
|
|
202
|
-
7. Switches to base branch and deletes the feature branch. If still running inside a worktree, removes the worktree instead of switching branches — this always happens, since the base branch can't be checked out in place there
|
|
203
|
-
|
|
204
|
-
### next-workflow-step
|
|
205
|
-
|
|
206
|
-
Automatically perform the next workflow transition based on current state.
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
idea1 next-workflow-step
|
|
210
|
-
idea1 next
|
|
211
|
-
idea1 n
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
**What it does:**
|
|
215
|
-
1. Detects current workflow state
|
|
216
|
-
2. Determines the next valid transition
|
|
217
|
-
3. Executes the appropriate command automatically
|
|
218
|
-
4. If workflow is complete, informs user
|
|
245
|
+
1. Validates the current state is "Needs Approval for Release" (after syncing from origin)
|
|
246
|
+
2. Approves the PR when you are a requested reviewer who has not approved yet
|
|
247
|
+
3. Removes the branch's `.idea1/<branch>.json` so it does not leak into the target branch, then merges the PR (offering an admin override when branch protections block the merge)
|
|
248
|
+
4. Records "Approved and Merged" in git config and on Idea1.ai
|
|
249
|
+
5. Switches to the base branch and deletes the feature branch. If still running inside a worktree, removes the worktree instead of switching branches — this always happens, since the base branch can't be checked out in place there
|
|
219
250
|
|
|
220
251
|
## Configuration
|
|
221
252
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve-pr.d.ts","sourceRoot":"","sources":["../../src/commands/approve-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"approve-pr.d.ts","sourceRoot":"","sources":["../../src/commands/approve-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAKjD,eAAO,MAAM,gBAAgB,EAAE,OAW9B,CAAC"}
|
|
@@ -1,171 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import * as claude from '../services/claude.js';
|
|
5
|
-
import * as workflow from '../services/workflow.js';
|
|
6
|
-
import { resolveBaseBranch, removeCurrentWorktree } from '../services/worktree.js';
|
|
7
|
-
import { promptConfirm } from '../lib/prompt.js';
|
|
1
|
+
import { WorkflowStates } from '../lib/workflow-states.js';
|
|
2
|
+
import { advanceTo, requireCurrentState, resolveContext } from '../services/workflow-engine.js';
|
|
3
|
+
import { approvePrHandler } from '../services/workflow-handlers/approve-pr.js';
|
|
8
4
|
export const approvePrCommand = {
|
|
9
5
|
name: 'approve-pr',
|
|
10
6
|
aliases: ['approve'],
|
|
11
7
|
description: 'Approve and merge the PR, completing the workflow',
|
|
12
|
-
options:
|
|
13
|
-
{
|
|
14
|
-
longName: 'comment',
|
|
15
|
-
shortName: 'c',
|
|
16
|
-
description: 'Custom approval comment',
|
|
17
|
-
defaultValue: '',
|
|
18
|
-
promptWhenDefaultExists: false
|
|
19
|
-
}
|
|
20
|
-
],
|
|
8
|
+
options: approvePrHandler.options,
|
|
21
9
|
async execute(resolved) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!validation.valid) {
|
|
26
|
-
throw new Error(validation.error ?? 'Invalid transition');
|
|
27
|
-
}
|
|
28
|
-
// Ensure workflow preconditions
|
|
29
|
-
await workflow.ensureWorkflowPreconditions();
|
|
30
|
-
// Get branch info
|
|
31
|
-
const branchName = await git.getCurrentBranch();
|
|
32
|
-
const projectItemUrl = await git.getProjectItemUrl();
|
|
33
|
-
const baseBranch = await git.getBaseBranch() ?? 'working/release';
|
|
34
|
-
const isWorktree = await git.isInsideWorktree();
|
|
35
|
-
const mainRepoRoot = await git.getMainRepoRoot();
|
|
36
|
-
if (!projectItemUrl) {
|
|
37
|
-
throw new Error('No project item URL found for this branch.');
|
|
38
|
-
}
|
|
39
|
-
logger.info(`Current branch: ${branchName}`);
|
|
40
|
-
logger.info(`Base branch: ${baseBranch}`);
|
|
41
|
-
// Check PR exists
|
|
42
|
-
const prInfo = await github.getPrInfo(branchName);
|
|
43
|
-
if (!prInfo) {
|
|
44
|
-
logger.warning('No PR found for this branch. Nothing to approve.');
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
logger.info(`PR #${prInfo.number} found`);
|
|
48
|
-
// Check if the current user should approve (is a reviewer and hasn't approved)
|
|
49
|
-
const approvalStatus = await github.getUserApprovalStatus(branchName);
|
|
50
|
-
if (approvalStatus) {
|
|
51
|
-
if (approvalStatus.hasAlreadyApproved) {
|
|
52
|
-
logger.dim('You have already approved this PR');
|
|
53
|
-
}
|
|
54
|
-
else if (approvalStatus.isRequestedReviewer) {
|
|
55
|
-
// User is a reviewer and hasn't approved yet - approve
|
|
56
|
-
const approvalComment = comment ?? 'Approved via idea1 CLI workflow';
|
|
57
|
-
const approved = await github.approvePr(branchName, approvalComment);
|
|
58
|
-
if (!approved) {
|
|
59
|
-
logger.warning('Failed to approve PR, continuing with merge...');
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
logger.dim('You are not a requested reviewer on this PR');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
logger.dim('Could not determine approval status, skipping approval');
|
|
68
|
-
}
|
|
69
|
-
// Remove branch metadata file before merge so it doesn't leak into target branch
|
|
70
|
-
await git.removeBranchMetadataAndPush(branchName);
|
|
71
|
-
// Confirm before merging
|
|
72
|
-
const confirmMerge = await promptConfirm(`Merge PR #${prInfo.number} (${branchName} -> ${baseBranch})?`, { default: true });
|
|
73
|
-
if (!confirmMerge) {
|
|
74
|
-
throw new Error('Merge cancelled by user');
|
|
75
|
-
}
|
|
76
|
-
// Merge the PR
|
|
77
|
-
const mergeResult = await github.mergePr(branchName);
|
|
78
|
-
if (!mergeResult.success) {
|
|
79
|
-
// Check if failure is due to branch protections / policies. `gh pr merge`
|
|
80
|
-
// emits a variety of messages depending on the rule that blocked the merge
|
|
81
|
-
// (branch protection rules, rulesets, repository policies). When admin
|
|
82
|
-
// privileges can resolve it, gh explicitly suggests the `--admin` flag, so
|
|
83
|
-
// match on that as the most reliable signal in addition to known wordings.
|
|
84
|
-
const errorText = mergeResult.error?.toLowerCase() ?? '';
|
|
85
|
-
const isBranchProtectionError = errorText.includes('branch protection') ||
|
|
86
|
-
errorText.includes('required status check') ||
|
|
87
|
-
errorText.includes('required review') ||
|
|
88
|
-
errorText.includes('pull request review is required') ||
|
|
89
|
-
errorText.includes('base branch policy') ||
|
|
90
|
-
errorText.includes('policy prohibits the merge') ||
|
|
91
|
-
errorText.includes('--admin');
|
|
92
|
-
if (isBranchProtectionError) {
|
|
93
|
-
logger.warning('Merge failed due to branch protections');
|
|
94
|
-
logger.dim(mergeResult.error ?? '');
|
|
95
|
-
// Ask user if they want to override
|
|
96
|
-
const override = await promptConfirm('Would you like to override branch protections with admin privileges?', { default: false });
|
|
97
|
-
if (override) {
|
|
98
|
-
const adminMergeResult = await github.mergePrWithAdminOverride(branchName);
|
|
99
|
-
if (!adminMergeResult.success) {
|
|
100
|
-
throw new Error(`Failed to merge PR with admin override: ${adminMergeResult.error}`);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
throw new Error('Merge cancelled by user');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
throw new Error(`Failed to merge PR: ${mergeResult.error}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Update workflow state before switching branches
|
|
112
|
-
await git.storeWorkflowState('Approved and Merged');
|
|
113
|
-
await claude.setWorkflowStatus(projectItemUrl, 'Approved and Merged');
|
|
114
|
-
await git.fetchLatest();
|
|
115
|
-
// If running inside a worktree, the feature branch is checked out here and we
|
|
116
|
-
// can't switch back to the base branch in place. Remove the worktree instead
|
|
117
|
-
// and exit so the user can change to whatever folder they need. This happens
|
|
118
|
-
// regardless of removeWorktreeAtState — 'Approved and Merged' is the last CLI-driven workflow state.
|
|
119
|
-
if (isWorktree) {
|
|
120
|
-
const worktreePath = await removeCurrentWorktree(mainRepoRoot);
|
|
121
|
-
// Delete the feature branch locally and remotely (the worktree no longer holds it)
|
|
122
|
-
try {
|
|
123
|
-
await git.deleteBranch(branchName, true);
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
// Branch might already be deleted on remote after merge
|
|
127
|
-
logger.dim(`Note: Branch ${branchName} may have been automatically deleted after merge`);
|
|
128
|
-
}
|
|
129
|
-
logger.newline();
|
|
130
|
-
logger.success('Workflow complete!');
|
|
131
|
-
logger.newline();
|
|
132
|
-
logger.hint(`PR merged into ${baseBranch}`);
|
|
133
|
-
logger.hint(`Worktree removed: ${worktreePath}`);
|
|
134
|
-
logger.hint(`Change to a different folder (e.g. ${mainRepoRoot}) to continue.`);
|
|
135
|
-
logger.hint(`Project item: ${projectItemUrl}`);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
// Switch to base branch (it may be in another worktree, e.g. the main repo)
|
|
139
|
-
const baseWorktreePath = await git.getWorktreePathForBranch(baseBranch);
|
|
140
|
-
if (baseWorktreePath) {
|
|
141
|
-
// Base branch (e.g. integration branch) is in another worktree — pull there,
|
|
142
|
-
// then checkout the settings-level base branch instead
|
|
143
|
-
logger.step(`Base branch ${baseBranch} is in a worktree at ${baseWorktreePath}, pulling there...`);
|
|
144
|
-
await git.updateBranchToLatest(baseBranch);
|
|
145
|
-
const settingsBaseBranch = await resolveBaseBranch();
|
|
146
|
-
logger.step(`Checking out ${settingsBaseBranch}...`);
|
|
147
|
-
await git.checkoutAndPullBranch(settingsBaseBranch);
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
logger.step(`Pulling latest from ${baseBranch}...`);
|
|
151
|
-
await git.checkoutAndPullBranch(baseBranch);
|
|
152
|
-
}
|
|
153
|
-
// Delete the feature branch locally and remotely
|
|
154
|
-
try {
|
|
155
|
-
await git.deleteBranch(branchName, true);
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
// Branch might already be deleted on remote after merge
|
|
159
|
-
logger.dim(`Note: Branch ${branchName} may have been automatically deleted after merge`);
|
|
160
|
-
}
|
|
161
|
-
logger.newline();
|
|
162
|
-
logger.success('Workflow complete!');
|
|
163
|
-
logger.newline();
|
|
164
|
-
logger.hint(`PR merged into ${baseBranch}`);
|
|
165
|
-
if (baseWorktreePath) {
|
|
166
|
-
logger.hint(`Base branch is in worktree at: ${baseWorktreePath}`);
|
|
167
|
-
}
|
|
168
|
-
logger.hint(`Project item: ${projectItemUrl}`);
|
|
10
|
+
const context = await resolveContext({ options: resolved });
|
|
11
|
+
requireCurrentState(context, WorkflowStates.NeedsApprovalForRelease, 'approve-pr');
|
|
12
|
+
await advanceTo(context, WorkflowStates.ApprovedAndMerged);
|
|
169
13
|
}
|
|
170
14
|
};
|
|
171
15
|
//# sourceMappingURL=approve-pr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve-pr.js","sourceRoot":"","sources":["../../src/commands/approve-pr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"approve-pr.js","sourceRoot":"","sources":["../../src/commands/approve-pr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAE/E,MAAM,CAAC,MAAM,gBAAgB,GAAY;IACvC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,WAAW,EAAE,mDAAmD;IAChE,OAAO,EAAE,gBAAgB,CAAC,OAAO;IAEjC,KAAK,CAAC,OAAO,CAAC,QAAgC;QAC5C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAC;QACnF,MAAM,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach-project-item.d.ts","sourceRoot":"","sources":["../../src/commands/attach-project-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"attach-project-item.d.ts","sourceRoot":"","sources":["../../src/commands/attach-project-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AASjD,eAAO,MAAM,wBAAwB,EAAE,OAwFtC,CAAC"}
|