@idea1/cli 1.7.6 → 1.8.0
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 +126 -60
- package/dist/cli/named-lists.d.ts.map +1 -1
- package/dist/cli/named-lists.js +5 -0
- package/dist/cli/named-lists.js.map +1 -1
- package/dist/commands/approve-pr.d.ts.map +1 -1
- package/dist/commands/approve-pr.js +94 -8
- 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 +28 -41
- 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 +50 -84
- package/dist/commands/close-worktree.js.map +1 -1
- package/dist/commands/create-worktree.d.ts.map +1 -1
- package/dist/commands/create-worktree.js +1 -4
- package/dist/commands/create-worktree.js.map +1 -1
- package/dist/commands/get-project-item-url.d.ts.map +1 -1
- package/dist/commands/get-project-item-url.js +3 -1
- package/dist/commands/get-project-item-url.js.map +1 -1
- package/dist/commands/help.js +13 -13
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/index.d.ts +1 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -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 +18 -60
- 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 +16 -22
- package/dist/commands/next-workflow-step.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +4 -3
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/ready-for-approval.d.ts.map +1 -1
- package/dist/commands/ready-for-approval.js +94 -8
- package/dist/commands/ready-for-approval.js.map +1 -1
- package/dist/commands/release.d.ts.map +1 -1
- package/dist/commands/release.js +4 -15
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/start-agent-implementation.d.ts.map +1 -1
- package/dist/commands/start-agent-implementation.js +10 -13
- package/dist/commands/start-agent-implementation.js.map +1 -1
- package/dist/commands/start-dev-implementation.d.ts.map +1 -1
- package/dist/commands/start-dev-implementation.js +7 -8
- package/dist/commands/start-dev-implementation.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +21 -15
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/update-branch.d.ts.map +1 -1
- package/dist/commands/update-branch.js +28 -75
- package/dist/commands/update-branch.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +11 -23
- package/dist/interactive.js.map +1 -1
- package/dist/lib/claude-options.d.ts +11 -10
- package/dist/lib/claude-options.d.ts.map +1 -1
- package/dist/lib/claude-options.js +38 -39
- package/dist/lib/claude-options.js.map +1 -1
- package/dist/lib/settings.d.ts +23 -27
- package/dist/lib/settings.d.ts.map +1 -1
- package/dist/lib/settings.js +35 -50
- package/dist/lib/settings.js.map +1 -1
- package/dist/prompts/platform-prompts.d.ts +30 -0
- package/dist/prompts/platform-prompts.d.ts.map +1 -0
- package/dist/prompts/platform-prompts.js +38 -0
- package/dist/prompts/platform-prompts.js.map +1 -0
- package/dist/prompts/project-item-prompts.d.ts +44 -0
- package/dist/prompts/project-item-prompts.d.ts.map +1 -0
- package/dist/prompts/project-item-prompts.js +41 -0
- package/dist/prompts/project-item-prompts.js.map +1 -0
- package/dist/services/claude.d.ts +27 -33
- package/dist/services/claude.d.ts.map +1 -1
- package/dist/services/claude.js +40 -140
- package/dist/services/claude.js.map +1 -1
- package/dist/services/git.d.ts +24 -121
- package/dist/services/git.d.ts.map +1 -1
- package/dist/services/git.js +73 -470
- package/dist/services/git.js.map +1 -1
- package/dist/services/github.d.ts +20 -4
- package/dist/services/github.d.ts.map +1 -1
- package/dist/services/github.js +77 -6
- package/dist/services/github.js.map +1 -1
- package/dist/services/platform.d.ts +75 -0
- package/dist/services/platform.d.ts.map +1 -0
- package/dist/services/platform.js +237 -0
- package/dist/services/platform.js.map +1 -0
- package/dist/services/setup.d.ts +1 -1
- package/dist/services/setup.js +1 -1
- package/dist/services/template-renderer.d.ts +10 -0
- package/dist/services/template-renderer.d.ts.map +1 -0
- package/dist/services/template-renderer.js +20 -0
- package/dist/services/template-renderer.js.map +1 -0
- package/dist/services/worktree.d.ts +17 -16
- package/dist/services/worktree.d.ts.map +1 -1
- package/dist/services/worktree.js +41 -65
- package/dist/services/worktree.js.map +1 -1
- package/dist/types/index.d.ts +14 -58
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workflow/data/project-item.d.ts +21 -0
- package/dist/workflow/data/project-item.d.ts.map +1 -0
- package/dist/workflow/data/project-item.js +2 -0
- package/dist/workflow/data/project-item.js.map +1 -0
- package/dist/workflow/data/workflow-context.d.ts +46 -0
- package/dist/workflow/data/workflow-context.d.ts.map +1 -0
- package/dist/workflow/data/workflow-context.js +14 -0
- package/dist/workflow/data/workflow-context.js.map +1 -0
- package/dist/{lib → workflow/data}/workflow-states.d.ts +1 -1
- package/dist/workflow/data/workflow-states.d.ts.map +1 -0
- package/dist/{lib → workflow/data}/workflow-states.generated.d.ts +1 -1
- package/dist/workflow/data/workflow-states.generated.d.ts.map +1 -0
- package/dist/{lib → workflow/data}/workflow-states.generated.js +1 -1
- package/dist/workflow/data/workflow-states.generated.js.map +1 -0
- package/dist/{lib → workflow/data}/workflow-states.js +1 -1
- package/dist/workflow/data/workflow-states.js.map +1 -0
- package/dist/workflow/engine/approval-flow.d.ts +53 -0
- package/dist/workflow/engine/approval-flow.d.ts.map +1 -0
- package/dist/workflow/engine/approval-flow.js +111 -0
- package/dist/workflow/engine/approval-flow.js.map +1 -0
- package/dist/{services → workflow/engine}/branch-setup.d.ts +2 -1
- package/dist/workflow/engine/branch-setup.d.ts.map +1 -0
- package/dist/{services → workflow/engine}/branch-setup.js +6 -5
- package/dist/workflow/engine/branch-setup.js.map +1 -0
- package/dist/workflow/engine/handlers/agent-implementation.d.ts +10 -0
- package/dist/workflow/engine/handlers/agent-implementation.d.ts.map +1 -0
- package/dist/workflow/engine/handlers/agent-implementation.js +42 -0
- package/dist/workflow/engine/handlers/agent-implementation.js.map +1 -0
- package/dist/{services/workflow-handlers → workflow/engine/handlers}/approve-pr.d.ts +7 -4
- package/dist/workflow/engine/handlers/approve-pr.d.ts.map +1 -0
- package/dist/workflow/engine/handlers/approve-pr.js +63 -0
- package/dist/workflow/engine/handlers/approve-pr.js.map +1 -0
- package/dist/{services/workflow-handlers → workflow/engine/handlers}/dev-implementation.d.ts +3 -2
- package/dist/workflow/engine/handlers/dev-implementation.d.ts.map +1 -0
- package/dist/workflow/engine/handlers/dev-implementation.js +36 -0
- package/dist/workflow/engine/handlers/dev-implementation.js.map +1 -0
- package/dist/workflow/engine/handlers/index.d.ts +21 -0
- package/dist/workflow/engine/handlers/index.d.ts.map +1 -0
- package/dist/{services/workflow-handlers → workflow/engine/handlers}/index.js +10 -6
- package/dist/workflow/engine/handlers/index.js.map +1 -0
- package/dist/workflow/engine/handlers/ready-for-approval.d.ts +11 -0
- package/dist/workflow/engine/handlers/ready-for-approval.d.ts.map +1 -0
- package/dist/workflow/engine/handlers/ready-for-approval.js +56 -0
- package/dist/workflow/engine/handlers/ready-for-approval.js.map +1 -0
- package/dist/{services → workflow/engine}/release-flow.d.ts +19 -10
- package/dist/workflow/engine/release-flow.d.ts.map +1 -0
- package/dist/{services → workflow/engine}/release-flow.js +33 -16
- package/dist/workflow/engine/release-flow.js.map +1 -0
- package/dist/workflow/engine/workflow-engine.d.ts +162 -0
- package/dist/workflow/engine/workflow-engine.d.ts.map +1 -0
- package/dist/workflow/engine/workflow-engine.js +405 -0
- package/dist/workflow/engine/workflow-engine.js.map +1 -0
- package/package.json +2 -1
- package/dist/commands/integrate.d.ts +0 -13
- package/dist/commands/integrate.d.ts.map +0 -1
- package/dist/commands/integrate.js +0 -128
- package/dist/commands/integrate.js.map +0 -1
- 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/dist/lib/workflow-states.d.ts.map +0 -1
- package/dist/lib/workflow-states.generated.d.ts.map +0 -1
- package/dist/lib/workflow-states.generated.js.map +0 -1
- package/dist/lib/workflow-states.js.map +0 -1
- package/dist/services/branch-setup.d.ts.map +0 -1
- package/dist/services/branch-setup.js.map +0 -1
- package/dist/services/context.d.ts +0 -26
- package/dist/services/context.d.ts.map +0 -1
- package/dist/services/context.js +0 -304
- package/dist/services/context.js.map +0 -1
- package/dist/services/release-flow.d.ts.map +0 -1
- package/dist/services/release-flow.js.map +0 -1
- package/dist/services/workflow-engine.d.ts +0 -67
- package/dist/services/workflow-engine.d.ts.map +0 -1
- package/dist/services/workflow-engine.js +0 -371
- package/dist/services/workflow-engine.js.map +0 -1
- package/dist/services/workflow-handlers/agent-implementation.d.ts +0 -9
- package/dist/services/workflow-handlers/agent-implementation.d.ts.map +0 -1
- package/dist/services/workflow-handlers/agent-implementation.js +0 -38
- package/dist/services/workflow-handlers/agent-implementation.js.map +0 -1
- package/dist/services/workflow-handlers/approve-pr.d.ts.map +0 -1
- package/dist/services/workflow-handlers/approve-pr.js +0 -122
- package/dist/services/workflow-handlers/approve-pr.js.map +0 -1
- package/dist/services/workflow-handlers/dev-implementation.d.ts.map +0 -1
- package/dist/services/workflow-handlers/dev-implementation.js +0 -34
- package/dist/services/workflow-handlers/dev-implementation.js.map +0 -1
- package/dist/services/workflow-handlers/index.d.ts +0 -18
- package/dist/services/workflow-handlers/index.d.ts.map +0 -1
- package/dist/services/workflow-handlers/index.js.map +0 -1
- package/dist/services/workflow-handlers/ready-for-approval.d.ts +0 -10
- package/dist/services/workflow-handlers/ready-for-approval.d.ts.map +0 -1
- package/dist/services/workflow-handlers/ready-for-approval.js +0 -59
- package/dist/services/workflow-handlers/ready-for-approval.js.map +0 -1
- package/dist/services/workflow.d.ts +0 -14
- package/dist/services/workflow.d.ts.map +0 -1
- package/dist/services/workflow.js +0 -37
- package/dist/services/workflow.js.map +0 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install -g @idea1/cli
|
|
|
15
15
|
Run commands directly from the command line:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
# Put a project item under workflow management (branch
|
|
18
|
+
# Put a project item under workflow management (branch recorded on idea1.ai, no code changes)
|
|
19
19
|
idea1 start --url https://app.idea1.ai/project/items/590
|
|
20
20
|
|
|
21
21
|
# Advance the item to its next workflow state (runs that state's automation)
|
|
@@ -29,8 +29,10 @@ idea1 start-dev-implementation # or: idea1 dev
|
|
|
29
29
|
idea1 ready-for-approval # or: idea1 rfa
|
|
30
30
|
idea1 approve-pr # or: idea1 approve
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
|
|
32
|
+
# The same two commands on a branch with no project item, e.g. an integration branch:
|
|
33
|
+
# open its PR into working/release and name the approver, then (as the approver) merge it
|
|
34
|
+
idea1 ready-for-approval --assignee octocat
|
|
35
|
+
idea1 approve-pr --branch working/integration/<name>-main
|
|
34
36
|
|
|
35
37
|
# Release the release branch to production (opens the release PR into main, assigned to you, and merges it once the checks pass)
|
|
36
38
|
idea1 release # or: idea1 r
|
|
@@ -58,20 +60,22 @@ The state names and their order are defined once, in `shared-config/workflow-sta
|
|
|
58
60
|
|
|
59
61
|
### How the workflow engine works
|
|
60
62
|
|
|
61
|
-
An item **under workflow management** has
|
|
63
|
+
An item **under workflow management** has a *workflow context* on idea1.ai: its workflow status together with the one branch on origin that carries its work — the repository and branch name, the PR target (base) branch, the dev workflow type and any stack or integration branch. An item with no context is outside workflow management and has no status. The CLI reads and records the context through the platform's MCP tools (`get_workflow_context_for_branch`, `get_workflow_context_for_item`, `upsert_workflow_context`) and records state changes with `set_item_workflow_status`; the web client works on the same context, so the two always agree, and any clone resolves a branch to its item from the platform. Locally, each clone remembers the item URL a branch was last resolved to in its git config, so ordinary branches are recognized as unmanaged instantly.
|
|
62
64
|
|
|
63
|
-
A
|
|
65
|
+
The branch itself carries the work. A branch's PR is therefore gated on a CI/CD run of exactly what merges, and `approve-pr` merges that run's head. When a branch is deleted on GitHub the context keeps its name and records whether the work merged; a context whose branch is gone without merging gets a new branch the next time the item enters a pre-merge state, while merged work stays merged. Branches put under workflow before the platform kept contexts carry a legacy `.idea1/<branch>.json` file, which the CLI removes from the branch before the approval gate.
|
|
66
|
+
|
|
67
|
+
A transition is "enter state X". Entering a state runs that state's automation (a *handler*), then records the new state on the item's context. An item outside workflow management is put under it by the transition itself - the branch is created on origin and the context recorded before any automation runs - so entering the first state is what starts an item. Handlers are idempotent, so a transition replayed after the item was moved back does not repeat work that is already done. Most states have no automation; the implementation states do:
|
|
64
68
|
|
|
65
69
|
| Entering | Automation |
|
|
66
70
|
|----------|-----------|
|
|
67
71
|
| Build Spec in Progress … Ready for Agent Implementation | none — status only |
|
|
68
72
|
| **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 |
|
|
69
73
|
| **Dev Implementation** | commits and pushes the agent's work, creates the PR, removes the worktree if `removeWorktreeAtState` says so |
|
|
70
|
-
| **Needs Approval for Release** | requires the PR, sets its assignee (required — the approver of record) and any requested reviewers, removes the worktree if configured |
|
|
71
|
-
| **Approved and Merged** | verifies you are the assignee,
|
|
74
|
+
| **Needs Approval for Release** | requires the PR, sets its assignee (required — the approver of record) and any requested reviewers, removes a legacy workflow context file if the branch still carries one (its final commit), and removes the worktree if configured. From here on the branch stays as it is |
|
|
75
|
+
| **Approved and Merged** | verifies you are the assignee, waits for the CI/CD suite, merges the PR as it stands — the merge is the approval — then deletes the branch and worktree |
|
|
72
76
|
| Released | none — normally set by GitHub automation when the work merges to `main` |
|
|
73
77
|
|
|
74
|
-
`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.
|
|
78
|
+
`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. The engine and its layers are described in `src/workflow/README.md`.
|
|
75
79
|
|
|
76
80
|
### Who approves what
|
|
77
81
|
|
|
@@ -79,7 +83,7 @@ A change reaches production through two merges, and **each merge is its approval
|
|
|
79
83
|
|
|
80
84
|
**Into `working/release`** — the PR's **assignee** (required) is its approver. They review the code and approve it by running `idea1 approve-pr`, which waits for the full CI/CD suite and then **merges** the PR. That is not the GitHub "Approve" button, which only leaves a review behind and merges nothing. A red or unfinished suite stops the merge, and there is no override at this stage. `approve-pr` checks that the person merging is the assignee; anyone else has to confirm explicitly, and the evidence report lists that merge as an exception. Requested reviewers are optional and record nothing. GitHub records the approval as `merged_by`, with its timestamp and merge commit.
|
|
81
85
|
|
|
82
|
-
**
|
|
86
|
+
**Any other branch into `working/release`** — a branch with no project item takes the same gate. `idea1 ready-for-approval` opens its PR (with the approval chain of what the branch carries as the body) and names its assignee; `idea1 approve-pr` merges it once the suite passes, with the same no-override rule, and then deletes the branch. Only the idea1.ai status writes are absent. Integration branches work this way: work items PR into `working/integration/<name>-main` and are approved there exactly as above, then the integration branch itself is carried into `working/release` with these two commands — its PR body lists every work-item PR and who approved it, and `approve-pr` refuses while any PR still targets the integration branch.
|
|
83
87
|
|
|
84
88
|
**Into `main`** — `idea1 release` opens the release PR **assigned to whoever ran it**: the releaser is the approver, and their merge is the recorded approval. No review is required — every change in the release was already approved above, and the release PR body lists each contained PR with who approved it. What this stage gates is the build: the required CI/CD checks must pass first. In the default `create` mode the releaser merges the PR in GitHub once the checks are green; in `merge` mode the CLI waits for every check with `gh` and merges here. An emergency admin override past a red check needs an explicit confirmation and a stated reason, and is recorded as a comment on the PR before the merge.
|
|
85
89
|
|
|
@@ -87,7 +91,7 @@ This is the change-management control DataFabrIQ is audited on; see `infrastruct
|
|
|
87
91
|
|
|
88
92
|
### start
|
|
89
93
|
|
|
90
|
-
Put a project item under workflow management. An item
|
|
94
|
+
Put a project item under workflow management. An item yet to be started enters **Build Spec in Progress**; an item that already has a state keeps it. The branch is created on origin at the base branch's tip and recorded in the item's workflow context on idea1.ai; the working tree and the code stay as they are, and Claude stays closed. Idempotent: running it again for a managed item just reports the branch and state.
|
|
91
95
|
|
|
92
96
|
```bash
|
|
93
97
|
idea1 start --url <url> [options]
|
|
@@ -96,8 +100,9 @@ idea1 s --url <url>
|
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
**Options:**
|
|
99
|
-
- `-u, --url <url>` - The Idea1.ai project item URL. Leave blank to create a new item (you'll be prompted for a `--title`).
|
|
103
|
+
- `-u, --url <url>` - The Idea1.ai project item URL. Leave blank to create a new item (you'll be prompted for a `--title` and a `--project`).
|
|
100
104
|
- `-t, --title <title>` - Title for the new project item (only when no URL is given).
|
|
105
|
+
- `-P, --project <name>` - The Project to create the new item in, chosen from the team's live Projects (only when no URL is given; always asked, never defaulted).
|
|
101
106
|
- `-p, --source-path <path>` - Path to source directory.
|
|
102
107
|
- `-n, --branch-name <name>` - Branch name (auto-generated from the item description if not provided).
|
|
103
108
|
- `-b, --base-branch <branch>` - Base branch / PR target (default: `working/release`).
|
|
@@ -107,7 +112,7 @@ idea1 s --url <url>
|
|
|
107
112
|
|
|
108
113
|
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.
|
|
109
114
|
|
|
110
|
-
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
|
|
115
|
+
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: each state's automation runs and the state is recorded on idea1.ai before the next state is entered. A run that stops part way leaves the item at the last state it entered, and running it again continues from there. The CLI only moves forward; an item already at or past the requested state is left as it is.
|
|
111
116
|
|
|
112
117
|
```bash
|
|
113
118
|
idea1 next # on the item's branch
|
|
@@ -123,16 +128,16 @@ idea1 n
|
|
|
123
128
|
- 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.
|
|
124
129
|
|
|
125
130
|
**What it does:**
|
|
126
|
-
1.
|
|
127
|
-
2. Puts the item under workflow management
|
|
128
|
-
3. Runs the automation of every state entered
|
|
131
|
+
1. Reads the item's workflow context from idea1.ai (picking up changes made in the web client) and fast-forwards the local checkout to origin when it is behind.
|
|
132
|
+
2. Puts the item under workflow management when it is outside it yet (an item yet to be started enters Build Spec in Progress, which is the whole step).
|
|
133
|
+
3. Runs the automation of every state entered and records the new state on idea1.ai.
|
|
129
134
|
4. Reports "Workflow is complete" at `Released`.
|
|
130
135
|
|
|
131
136
|
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.
|
|
132
137
|
|
|
133
138
|
### start-agent-implementation
|
|
134
139
|
|
|
135
|
-
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 (or a prompt you supply
|
|
140
|
+
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 — the repository's `prompts.agentImplementation` setting (see [Prompts](#prompts)), the built-in default, or a prompt you supply with `--entry-point-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.
|
|
136
141
|
|
|
137
142
|
```bash
|
|
138
143
|
idea1 start-agent-implementation --url <url> [options]
|
|
@@ -147,8 +152,8 @@ idea1 implement --url <url> --entry-point-prompt "Read the spec in docs/spec.md
|
|
|
147
152
|
- `-m, --model <model>` - Claude model for the implementation session (default: `opus`). Valid values: `fable`, `opus`, `sonnet`, `haiku`
|
|
148
153
|
- `-e, --effort <level>` - Claude effort level (default: `high`). Valid values: `low`, `medium`, `high`, `xhigh`, `max`
|
|
149
154
|
- `-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)
|
|
150
|
-
- `-udp, --use-default-prompt <yes|no>` - Whether to launch Claude with the
|
|
151
|
-
- `-epp, --entry-point-prompt <prompt>` - The prompt to launch Claude with, replacing the
|
|
155
|
+
- `-udp, --use-default-prompt <yes|no>` - Whether to launch Claude with the repository's implementation prompt, or the built-in one when the repository sets none (default: `yes`). Answering `no` asks for the prompt to use instead.
|
|
156
|
+
- `-epp, --entry-point-prompt <prompt>` - The prompt to launch Claude with, replacing the implementation prompt. Supplying it skips the "Use default prompt?" question. It is a Handlebars template like the repository's prompt, so it can use the same [variables](#prompts).
|
|
152
157
|
|
|
153
158
|
An item already in Agent Implementation is not transitioned again: the working environment is set up (or reused) and Claude is launched.
|
|
154
159
|
|
|
@@ -178,12 +183,11 @@ idea1 j --branch-name <branch>
|
|
|
178
183
|
- `--pull-request-url <url>` - A GitHub PR URL; its head branch is joined.
|
|
179
184
|
- `-p, --source-path <path>` - Path to source directory.
|
|
180
185
|
- `-iso, --isolation <mode>` - Where to work on the branch (default: `worktree`). See [Isolation mode](#isolation-mode).
|
|
181
|
-
- `-pm, --permission-mode <mode>`, `-m, --model <model>`, `-e, --effort <level>` - Claude session settings recorded for the environment (defaults: `plan`, `opus`, `high`).
|
|
182
186
|
|
|
183
187
|
**What it does:**
|
|
184
|
-
1. Resolves the branch from the URL (or the URL from the branch)
|
|
188
|
+
1. Resolves the branch from the URL (or the URL from the branch) through the item's workflow context on idea1.ai.
|
|
185
189
|
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).
|
|
186
|
-
3.
|
|
190
|
+
3. Reports the item the branch implements and its state. A branch outside workflow management is joined as plain git work; `attach-project-item` puts it under workflow.
|
|
187
191
|
4. Runs any setup hooks defined in `.idea1/settings.json` (newly created worktrees only).
|
|
188
192
|
|
|
189
193
|
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.
|
|
@@ -206,14 +210,14 @@ idea1 a --url <url>
|
|
|
206
210
|
- `-w, --workflow-type <type>` - Development workflow type: `independent` or `integration`. You also choose any stack branch and (for integration) the integration branch.
|
|
207
211
|
|
|
208
212
|
**What it does:**
|
|
209
|
-
1. Verifies the current branch is
|
|
210
|
-
2. Creates the project item if no URL was supplied
|
|
211
|
-
3. Records the
|
|
212
|
-
4.
|
|
213
|
+
1. Verifies the current branch is free to implement the item (a branch that already implements one is resumed with `join-project-item`).
|
|
214
|
+
2. Creates the project item if no URL was supplied.
|
|
215
|
+
3. Records the branch in the item's workflow context on idea1.ai (base branch, dev workflow type, stack/integration branch) in a single call, which puts an item outside workflow management under it at `Build Spec in Progress` and leaves an item that already has a state at that state. The branch is pushed to origin beforehand and stays as it is.
|
|
216
|
+
4. If the item is already at `Dev Implementation` or later, makes sure a PR into the base branch exists.
|
|
213
217
|
|
|
214
218
|
### start-dev-implementation
|
|
215
219
|
|
|
216
|
-
|
|
220
|
+
Advance the item to **Dev Implementation** — the same as `next --to "Dev Implementation"`. From Agent Implementation that is one step; from an earlier state every state in between is entered first, each with its own automation. An item already at or past Dev Implementation is left as it is.
|
|
217
221
|
|
|
218
222
|
```bash
|
|
219
223
|
idea1 start-dev-implementation [options]
|
|
@@ -224,68 +228,68 @@ idea1 dev [options]
|
|
|
224
228
|
- `-p, --source-path <path>` - Path to worktree directory
|
|
225
229
|
|
|
226
230
|
**What it does:**
|
|
227
|
-
1.
|
|
231
|
+
1. Enters every state before Dev Implementation the item has yet to reach (after syncing from origin)
|
|
228
232
|
2. Commits and pushes all changes in the branch
|
|
229
233
|
3. Creates a PR of the branch into its base branch
|
|
230
|
-
4. Records "Dev Implementation"
|
|
234
|
+
4. Records "Dev Implementation" on Idea1.ai
|
|
231
235
|
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.
|
|
232
236
|
|
|
233
237
|
### ready-for-approval
|
|
234
238
|
|
|
235
|
-
|
|
239
|
+
On a project item's branch, advance the item to **Needs Approval for Release** — the same as `next --to "Needs Approval for Release"`: from an earlier state, every state in between is entered first, each with its own automation (PR creation on the way into Dev Implementation, for one), and an item already at or past it is left as it is. On any other branch (an integration branch, a branch with no project item), open the branch's PR into the base branch when it has none. Either way its job is to name the **assignee**, who will approve the change by merging it.
|
|
236
240
|
|
|
237
241
|
```bash
|
|
238
242
|
idea1 ready-for-approval [options]
|
|
239
243
|
idea1 rfa --assignee octocat
|
|
244
|
+
idea1 rfa --assignee octocat # on working/integration/<name>-main: opens the PR into working/release
|
|
245
|
+
idea1 rfa --assignee octocat -b working/release # a branch with no project item, naming the PR target
|
|
240
246
|
```
|
|
241
247
|
|
|
242
248
|
**Options:**
|
|
243
249
|
- `-a, --assignee <username>` - **Required.** Who approves the PR by merging it (prompted from the repository's assignable users when omitted)
|
|
244
250
|
- `-r, --reviewers <user1,user2>` - Who to request a review from (multi-select when omitted). Optional, and separate from approval — the assignee is the approver
|
|
251
|
+
- `-b, --base-branch <branch>` - Branches with no project item only: the branch the PR targets (default: the open PR's base, else `baseBranch`, then `working/release`)
|
|
252
|
+
- `--title <title>` - Branches with no project item only: PR title when the PR has to be created (default: `Integration <name> <YYYY-MM-DD>` for an integration branch, else the branch name; prompted when omitted)
|
|
245
253
|
|
|
246
|
-
**What it does:**
|
|
247
|
-
1.
|
|
254
|
+
**What it does on a project item's branch:**
|
|
255
|
+
1. Enters every state before Needs Approval for Release the item has yet to reach (after syncing from origin)
|
|
248
256
|
2. Ensures no uncommitted or unpushed changes in the local checkout
|
|
249
257
|
3. Requires the PR to exist, then sets the assignee (the transition refuses to proceed without one) and requests any reviewers
|
|
250
|
-
4.
|
|
251
|
-
5.
|
|
258
|
+
4. Legacy branches only: removes the `.idea1/<branch>.json` workflow context file the branch still carries and pushes — the branch's final commit, so the CI/CD suite runs once more on exactly what will merge and the target branch receives the work alone
|
|
259
|
+
5. Records "Needs Approval for Release" on Idea1.ai. From here on the branch stays as it is
|
|
260
|
+
6. If in a worktree and `removeWorktreeAtState` is `Needs Approval for Release` (the default) or earlier, removes the worktree
|
|
261
|
+
|
|
262
|
+
**What it does on a branch with no project item:**
|
|
263
|
+
1. Requires you to be on the branch with nothing uncommitted, unpushed or behind origin; refuses on the base branch itself and refuses a PR straight into `main` (that is `idea1 release`)
|
|
264
|
+
2. Reuses the branch's open PR (and its base) when one exists; otherwise creates the PR into the base branch with the approval chain of what the branch carries as its body — every PR merged into the branch with its author and approver, and commits pushed straight to the branch listed as the change under review (they are not an exception: this PR is their stage-1 approval)
|
|
265
|
+
3. Sets the assignee and requests any reviewers
|
|
266
|
+
4. Records no workflow status — there is no project item
|
|
252
267
|
|
|
253
268
|
### approve-pr
|
|
254
269
|
|
|
255
|
-
|
|
270
|
+
On a project item's branch, advance the item to **Approved and Merged** — the same as `next --to "Approved and Merged"`: from an earlier state, every state in between is entered first, each with its own automation, and an item already at or past it is left as it is. On any other branch, merge the branch's PR. Run by the PR's **assignee**: it waits for the CI/CD suite and merges the PR, and that merge is the approval of record. There is no admin override at this stage for any branch.
|
|
256
271
|
|
|
257
272
|
```bash
|
|
258
273
|
idea1 approve-pr
|
|
259
274
|
idea1 approve
|
|
275
|
+
idea1 approve-pr --branch working/integration/<name>-main # from anywhere: the branch need not be checked out
|
|
260
276
|
```
|
|
261
277
|
|
|
262
|
-
**
|
|
263
|
-
|
|
278
|
+
**Options:**
|
|
279
|
+
- `-b, --branch <branch>` - Branch whose PR to approve (default: the current branch). A project item's branch is approved through the workflow; any other branch through its PR alone
|
|
280
|
+
|
|
281
|
+
**What it does on a project item's branch:**
|
|
282
|
+
1. Enters every state before Approved and Merged the item has yet to reach (after syncing from origin)
|
|
264
283
|
2. Verifies the approver: refuses when the PR has no assignee, and when you are not the assignee warns that the merge record will name you instead and requires an explicit confirmation (the evidence report lists such a merge as an exception)
|
|
265
|
-
3.
|
|
266
|
-
4. Records "Approved and Merged"
|
|
284
|
+
3. Waits for the required CI/CD checks on the PR — the checks of the branch's tip on origin, which the PR must have picked up first — then merges the PR. A red or unfinished suite stops the merge — there is no admin override at this stage. The branch is merged as it stands. A legacy branch that still carries its workflow context file has the file removed and pushed instead, and the approval is left for a second run once the re-run suite passes
|
|
285
|
+
4. Records "Approved and Merged" on Idea1.ai
|
|
267
286
|
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
|
|
268
287
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
idea1 integrate --assignee octocat # on the integration branch: open the PR and assign its approver
|
|
275
|
-
idea1 integrate --pr-mode merge # run by the assignee: wait for the checks, then merge
|
|
276
|
-
idea1 int
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
**Options:**
|
|
280
|
-
- `-b, --branch <branch>` - Integration branch to integrate (default: the current branch when it is one, otherwise a pick from the integration branches on origin)
|
|
281
|
-
- `-t, --target <branch>` - Branch to integrate into (default: `baseBranch`, then `working/release`)
|
|
282
|
-
- `-a, --assignee <username>` - Who approves the integration by merging its PR (prompted when the PR is created and none is given)
|
|
283
|
-
- `-pr, --pr-mode <mode>` - `create` (default) opens the PR in the browser to merge there once the checks pass; `merge` waits for every check with `gh` and merges here
|
|
284
|
-
- `--title <title>` - PR title (default: `Integration <name> <YYYY-MM-DD>`)
|
|
285
|
-
|
|
286
|
-
**What it does:**
|
|
287
|
-
1. Reuses the open PR from the integration branch into the target if one exists; otherwise requires you to be on the integration branch with nothing uncommitted, unpushed or behind origin, and creates the PR assigned to the approver, with the approval chain of the work-item PRs it carries as its body
|
|
288
|
-
2. In `merge` mode, checks that you are the assignee (anyone else must confirm explicitly), waits for the required CI/CD checks and merges. Checks that fail, never start or never finish stop the merge; the admin override takes an explicit confirmation and a required reason, and the exception is recorded as a comment on the PR before anything is merged
|
|
288
|
+
**What it does on a branch with no project item:**
|
|
289
|
+
1. Finds the branch's PR (run `ready-for-approval` first if there is none) and takes the target branch from it
|
|
290
|
+
2. Refuses while any open PR still targets the branch — merging would retire the branch and orphan them
|
|
291
|
+
3. Verifies the approver exactly as above, waits for the required CI/CD checks and merges. A red or unfinished suite stops the merge — no override
|
|
292
|
+
4. Deletes the branch on origin and locally (removing its worktree, or switching to the base branch first when it is checked out in the main repo). Records no workflow status
|
|
289
293
|
|
|
290
294
|
### release
|
|
291
295
|
|
|
@@ -333,6 +337,9 @@ Create `.idea1/settings.json` in your repository root to configure repo-specific
|
|
|
333
337
|
"hooks": {
|
|
334
338
|
"setup-worktree": "dev/workflow/setup-worktree.sh"
|
|
335
339
|
},
|
|
340
|
+
"prompts": {
|
|
341
|
+
"agentImplementation": "Implement {{projectItemUrl}} on {{branchName}}."
|
|
342
|
+
},
|
|
336
343
|
"defaults": {
|
|
337
344
|
"branchPrefix": "working/agent",
|
|
338
345
|
"baseBranch": "working/release",
|
|
@@ -344,6 +351,9 @@ Create `.idea1/settings.json` in your repository root to configure repo-specific
|
|
|
344
351
|
**Hooks:**
|
|
345
352
|
- `setup-worktree` - Script to run after creating a new worktree (e.g., install dependencies)
|
|
346
353
|
|
|
354
|
+
**Prompts:**
|
|
355
|
+
- `agentImplementation` - The prompt an Agent Implementation session starts with. See [Prompts](#prompts).
|
|
356
|
+
|
|
347
357
|
**Defaults:**
|
|
348
358
|
- `branchPrefix` - Prefix for new branches (default: `working/agent`)
|
|
349
359
|
- `baseBranch` - Default base branch for branching (default: `working/release`)
|
|
@@ -355,8 +365,8 @@ Create `.idea1/settings.json` in your repository root to configure repo-specific
|
|
|
355
365
|
`.idea1/settings.local.json` is an optional, git-ignored file with the same shape as
|
|
356
366
|
`settings.json`. Anything it defines overrides the committed settings for that clone
|
|
357
367
|
only, which keeps developer-specific preferences out of the shared configuration.
|
|
358
|
-
`hooks` and `defaults` are merged section by section, so overriding one value
|
|
359
|
-
the rest of the committed settings in place.
|
|
368
|
+
`hooks`, `prompts` and `defaults` are merged section by section, so overriding one value
|
|
369
|
+
leaves the rest of the committed settings in place.
|
|
360
370
|
|
|
361
371
|
```json
|
|
362
372
|
{
|
|
@@ -366,6 +376,56 @@ the rest of the committed settings in place.
|
|
|
366
376
|
}
|
|
367
377
|
```
|
|
368
378
|
|
|
379
|
+
### Prompts
|
|
380
|
+
|
|
381
|
+
Every prompt the CLI gives Claude is a [Handlebars](https://handlebarsjs.com/) template
|
|
382
|
+
rendered against a data model, so a repository can replace a prompt with its own template
|
|
383
|
+
using the full Handlebars syntax (`{{#if}}`, `{{#each}}`, `{{else}}`, ...).
|
|
384
|
+
|
|
385
|
+
`prompts.agentImplementation` is the prompt an Agent Implementation session starts with
|
|
386
|
+
(`start-agent-implementation`, or `next` entering Agent Implementation). It is either the
|
|
387
|
+
template itself or the file that holds it, relative to the repository root:
|
|
388
|
+
|
|
389
|
+
```json
|
|
390
|
+
{
|
|
391
|
+
"prompts": {
|
|
392
|
+
"agentImplementation": "/df-implement-project-item {{projectItemUrl}}"
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"prompts": {
|
|
400
|
+
"agentImplementation": { "templateFile": ".idea1/prompts/agent-implementation.md" }
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Without the setting, the built-in prompt asks Claude to implement the item from its Idea1
|
|
406
|
+
context. `--entry-point-prompt` replaces both for one session and is rendered the same way.
|
|
407
|
+
The settings are read from the main repository, so an override in its
|
|
408
|
+
`settings.local.json` applies in worktrees too.
|
|
409
|
+
|
|
410
|
+
The template renders against the item and its branch:
|
|
411
|
+
|
|
412
|
+
| Variable | Value |
|
|
413
|
+
|----------|-------|
|
|
414
|
+
| `projectItemUrl` | The project item's URL |
|
|
415
|
+
| `workflowStatus` | The item's workflow state (`Agent Implementation`) |
|
|
416
|
+
| `repositoryFullName` | The repository, as `owner/name` |
|
|
417
|
+
| `branchName` | The item's branch |
|
|
418
|
+
| `baseBranch` | The branch the item's PR targets (the integration branch for integration work) |
|
|
419
|
+
| `devWorkflowType` | `independent` or `integration` |
|
|
420
|
+
| `stackBranch` | The branch this one is stacked on, or null |
|
|
421
|
+
| `integrationBranch` | The integration branch, or null for independent work |
|
|
422
|
+
| `pullRequestUrl` | The item's PR, or empty when there is none yet |
|
|
423
|
+
| `workingPath` | The directory the branch is checked out in |
|
|
424
|
+
|
|
425
|
+
Rendering is strict: a template that outputs a variable not in this list fails with an error
|
|
426
|
+
rather than rendering it empty. Test a null variable with `{{#if}}` before outputting it, e.g.
|
|
427
|
+
`{{#if stackBranch}}Stacked on {{stackBranch}}.{{/if}}`.
|
|
428
|
+
|
|
369
429
|
### Worktree Removal
|
|
370
430
|
|
|
371
431
|
When work happens in a git worktree, `removeWorktreeAtState` decides which workflow
|
|
@@ -395,6 +455,12 @@ Settings include:
|
|
|
395
455
|
Branch names are not user settings: they belong to the repository and are read from
|
|
396
456
|
its `.idea1/settings.json`.
|
|
397
457
|
|
|
458
|
+
## How the CLI uses Claude
|
|
459
|
+
|
|
460
|
+
Every use of Claude Code goes through `src/services/claude.ts`, the only module that spawns `claude`. It always passes `--model` and `--effort`: a caller that states neither gets the documented defaults (`opus`, `high` — the same defaults the implementation session offers), so a run never inherits whatever was last picked in an interactive session.
|
|
461
|
+
|
|
462
|
+
Access to the Idea1 cloud platform — reading a project item's summary (by item or by the branch it implements), recording the item's workflow context, setting its workflow status, creating items, listing Projects, generating a branch name — goes through `src/services/platform.ts`. Its prompts are Handlebars templates in `src/prompts/`, rendered by `src/services/template-renderer.ts` like every other prompt. Today it drives the Idea1 MCP tools through Claude on `sonnet` at `medium` effort (these are simple tool calls, not implementation sessions); that transport is the module's implementation detail and may become direct calls to the platform API. The implementation session launched on entering Agent Implementation is the one place the model and effort are the user's choice (`--model`, `--effort`).
|
|
463
|
+
|
|
398
464
|
## Requirements
|
|
399
465
|
|
|
400
466
|
- Node.js 20+
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"named-lists.d.ts","sourceRoot":"","sources":["../../src/cli/named-lists.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"named-lists.d.ts","sourceRoot":"","sources":["../../src/cli/named-lists.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAYrG"}
|
package/dist/cli/named-lists.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as github from '../services/github.js';
|
|
2
|
+
import * as platform from '../services/platform.js';
|
|
2
3
|
/**
|
|
3
4
|
* Registry of named choice lists. Options reference these by name via
|
|
4
5
|
* CommandOption.choices, letting multiple options share the same
|
|
@@ -8,6 +9,10 @@ const registry = {
|
|
|
8
9
|
'github-members': async () => {
|
|
9
10
|
const logins = await github.listAssignableUsers();
|
|
10
11
|
return logins.map(login => ({ label: login, value: login }));
|
|
12
|
+
},
|
|
13
|
+
'idea1-projects': async () => {
|
|
14
|
+
const projects = await platform.listProjects();
|
|
15
|
+
return projects.map(name => ({ label: name, value: name }));
|
|
11
16
|
}
|
|
12
17
|
};
|
|
13
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"named-lists.js","sourceRoot":"","sources":["../../src/cli/named-lists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"named-lists.js","sourceRoot":"","sources":["../../src/cli/named-lists.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AASpD;;;;GAIG;AACH,MAAM,QAAQ,GAAmC;IAC/C,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAClD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC/C,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,uBAAuB,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -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;AAuFjD,eAAO,MAAM,gBAAgB,EAAE,OAuC9B,CAAC"}
|
|
@@ -1,15 +1,101 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { logger } from '../lib/logger.js';
|
|
2
|
+
import { readBranchSettings } from '../lib/settings.js';
|
|
3
|
+
import * as git from '../services/git.js';
|
|
4
|
+
import * as github from '../services/github.js';
|
|
5
|
+
import * as worktree from '../services/worktree.js';
|
|
6
|
+
import { WorkflowStates } from '../workflow/data/workflow-states.js';
|
|
7
|
+
import { cleanUpMergedBranch, mergeAsApprover } from '../workflow/engine/approval-flow.js';
|
|
8
|
+
import { confirmApproverIdentity } from '../workflow/engine/release-flow.js';
|
|
9
|
+
import { advanceAsNeededTo, getProjectItemSummaryForBranch, resolveTransition, resolveTransitionIfManaged } from '../workflow/engine/workflow-engine.js';
|
|
10
|
+
import { deferredHandlerOptions } from '../workflow/engine/handlers/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Stage 1 approval for a branch with no project item: the assignee merges the branch's PR once
|
|
13
|
+
* the required checks pass (no override), then the branch is cleaned up. No workflow status is
|
|
14
|
+
* recorded. The branch need not be checked out - the assignee can approve from anywhere.
|
|
15
|
+
*/
|
|
16
|
+
async function approvePrOnBranchWithNoItem(branchName) {
|
|
17
|
+
await github.ensureGitHubCli();
|
|
18
|
+
// Captured before anything moves: cleanup may switch branches or remove a worktree.
|
|
19
|
+
const workingPath = await git.getCheckoutPathForBranch(branchName);
|
|
20
|
+
const isCurrentBranch = (await git.getCurrentBranch()) === branchName;
|
|
21
|
+
const prInfo = await github.getPrInfo(branchName);
|
|
22
|
+
if (!prInfo) {
|
|
23
|
+
throw new Error('No PR found for this branch. Run idea1 ready-for-approval first to open it and name its approver.');
|
|
24
|
+
}
|
|
25
|
+
logger.info(`PR #${prInfo.number} found`);
|
|
26
|
+
const state = prInfo.state.toUpperCase();
|
|
27
|
+
if (state === 'CLOSED') {
|
|
28
|
+
throw new Error(`PR #${prInfo.number} is closed without being merged; there is nothing to approve.`);
|
|
29
|
+
}
|
|
30
|
+
const baseBranch = prInfo.baseRefName ?? await worktree.resolveBaseBranch();
|
|
31
|
+
const releaseTargetBranch = (await readBranchSettings(await git.getRepoRoot())).releaseTargetBranch;
|
|
32
|
+
if (baseBranch === releaseTargetBranch) {
|
|
33
|
+
throw new Error(`PR #${prInfo.number} targets ${releaseTargetBranch}: that is a release, not a change to approve. ` +
|
|
34
|
+
'Use idea1 release for it (change-management-policy.md clause 2).');
|
|
35
|
+
}
|
|
36
|
+
logger.header(`Approve: ${branchName} -> ${baseBranch}`);
|
|
37
|
+
logger.info('This branch has no project item, so no workflow status is recorded.');
|
|
38
|
+
logger.newline();
|
|
39
|
+
if (state === 'MERGED') {
|
|
40
|
+
logger.dim(`PR #${prInfo.number} is already merged; cleaning up the branch.`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
if (isCurrentBranch) {
|
|
44
|
+
await git.ensureBranchUpToDate();
|
|
45
|
+
}
|
|
46
|
+
// Merging retires the branch, which would orphan any PR still targeting it.
|
|
47
|
+
const openPrsInto = await github.listOpenPrsInto(branchName);
|
|
48
|
+
if (openPrsInto.length > 0) {
|
|
49
|
+
const list = openPrsInto.map(pr => ` #${pr.number} ${pr.headRefName} ${pr.title}`).join('\n');
|
|
50
|
+
throw new Error(`${openPrsInto.length} open PR(s) still target ${branchName}; approve or close them before approving this branch:\n${list}`);
|
|
51
|
+
}
|
|
52
|
+
await confirmApproverIdentity(branchName);
|
|
53
|
+
await mergeAsApprover({ branchName, baseBranch, prNumber: prInfo.number });
|
|
54
|
+
}
|
|
55
|
+
await cleanUpMergedBranch({ branchName, baseBranch, workingPath });
|
|
56
|
+
logger.newline();
|
|
57
|
+
logger.success(`PR merged into ${baseBranch} - the merge is the recorded approval`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The transition for a named branch when it is a project item's branch, else null.
|
|
61
|
+
*/
|
|
62
|
+
async function resolveTransitionForNamedBranch(branchName, resolved) {
|
|
63
|
+
const projectItemUrl = (await getProjectItemSummaryForBranch(branchName))?.url ?? null;
|
|
64
|
+
return projectItemUrl ? resolveTransition({ projectItemUrl, options: resolved }) : null;
|
|
65
|
+
}
|
|
4
66
|
export const approvePrCommand = {
|
|
5
67
|
name: 'approve-pr',
|
|
6
68
|
aliases: ['approve'],
|
|
7
|
-
description: 'Approve the PR by merging it (the assignee runs this)
|
|
8
|
-
options:
|
|
69
|
+
description: 'Approve the PR by merging it (the assignee runs this) - on a project item\'s branch (advancing the item through every state before it) or any other branch',
|
|
70
|
+
options: [
|
|
71
|
+
{
|
|
72
|
+
longName: 'branch',
|
|
73
|
+
shortName: 'b',
|
|
74
|
+
description: 'Branch whose PR to approve (default: the current branch)',
|
|
75
|
+
defaultValue: '',
|
|
76
|
+
promptWhenDefaultExists: false
|
|
77
|
+
},
|
|
78
|
+
// On a project item's branch the item may be further back; the states it passes through on the
|
|
79
|
+
// way (the assignee of Needs Approval for Release, for one) ask for their own options.
|
|
80
|
+
...deferredHandlerOptions([])
|
|
81
|
+
],
|
|
9
82
|
async execute(resolved) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
83
|
+
const requestedBranch = resolved['branch'] || null;
|
|
84
|
+
// A named branch the platform records as an item's is approved through
|
|
85
|
+
// the workflow engine, from wherever the command is run. With no branch named, the current
|
|
86
|
+
// branch is the target, managed or not.
|
|
87
|
+
const transition = requestedBranch
|
|
88
|
+
? await resolveTransitionForNamedBranch(requestedBranch, resolved)
|
|
89
|
+
: await resolveTransitionIfManaged({ options: resolved });
|
|
90
|
+
if (transition) {
|
|
91
|
+
await advanceAsNeededTo(transition, WorkflowStates.ApprovedAndMerged);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const branchName = requestedBranch ?? await git.getCurrentBranch();
|
|
95
|
+
if (branchName === 'HEAD') {
|
|
96
|
+
throw new Error('You are not on a branch (detached HEAD). Check out the branch to approve, or pass --branch <name>.');
|
|
97
|
+
}
|
|
98
|
+
await approvePrOnBranchWithNoItem(branchName);
|
|
13
99
|
}
|
|
14
100
|
};
|
|
15
101
|
//# 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,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"approve-pr.js","sourceRoot":"","sources":["../../src/commands/approve-pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,EAAE,MAAM,mBAAmB,CAAC;AASjD,eAAO,MAAM,wBAAwB,EAAE,
|
|
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,OA2FtC,CAAC"}
|