@idea1/cli 1.9.1 → 1.10.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.
Files changed (166) hide show
  1. package/README.md +123 -66
  2. package/dist/cli/named-lists.d.ts +1 -1
  3. package/dist/cli/named-lists.d.ts.map +1 -1
  4. package/dist/cli/named-lists.js +18 -2
  5. package/dist/cli/named-lists.js.map +1 -1
  6. package/dist/cli/parser.d.ts +3 -2
  7. package/dist/cli/parser.d.ts.map +1 -1
  8. package/dist/cli/parser.js +4 -3
  9. package/dist/cli/parser.js.map +1 -1
  10. package/dist/cli/resolver.d.ts +3 -0
  11. package/dist/cli/resolver.d.ts.map +1 -1
  12. package/dist/cli/resolver.js +41 -36
  13. package/dist/cli/resolver.js.map +1 -1
  14. package/dist/cli.d.ts.map +1 -1
  15. package/dist/cli.js +15 -1
  16. package/dist/cli.js.map +1 -1
  17. package/dist/commands/approve-pr.d.ts.map +1 -1
  18. package/dist/commands/approve-pr.js +2 -54
  19. package/dist/commands/approve-pr.js.map +1 -1
  20. package/dist/commands/help.d.ts.map +1 -1
  21. package/dist/commands/help.js +11 -6
  22. package/dist/commands/help.js.map +1 -1
  23. package/dist/commands/index.d.ts +2 -1
  24. package/dist/commands/index.d.ts.map +1 -1
  25. package/dist/commands/index.js +5 -1
  26. package/dist/commands/index.js.map +1 -1
  27. package/dist/commands/join-project-item.d.ts.map +1 -1
  28. package/dist/commands/join-project-item.js +31 -12
  29. package/dist/commands/join-project-item.js.map +1 -1
  30. package/dist/commands/next-workflow-step.d.ts.map +1 -1
  31. package/dist/commands/next-workflow-step.js +1 -0
  32. package/dist/commands/next-workflow-step.js.map +1 -1
  33. package/dist/commands/ready-for-approval.d.ts.map +1 -1
  34. package/dist/commands/ready-for-approval.js +7 -67
  35. package/dist/commands/ready-for-approval.js.map +1 -1
  36. package/dist/commands/release.d.ts.map +1 -1
  37. package/dist/commands/release.js +7 -9
  38. package/dist/commands/release.js.map +1 -1
  39. package/dist/commands/ship-local-changes.d.ts +2 -0
  40. package/dist/commands/ship-local-changes.d.ts.map +1 -1
  41. package/dist/commands/ship-local-changes.js +30 -5
  42. package/dist/commands/ship-local-changes.js.map +1 -1
  43. package/dist/commands/start-agent-implementation.d.ts.map +1 -1
  44. package/dist/commands/start-agent-implementation.js +4 -1
  45. package/dist/commands/start-agent-implementation.js.map +1 -1
  46. package/dist/commands/start-dev-implementation.d.ts.map +1 -1
  47. package/dist/commands/start-dev-implementation.js +1 -0
  48. package/dist/commands/start-dev-implementation.js.map +1 -1
  49. package/dist/commands/start.d.ts.map +1 -1
  50. package/dist/commands/start.js +6 -3
  51. package/dist/commands/start.js.map +1 -1
  52. package/dist/commands/url-handler.d.ts +5 -0
  53. package/dist/commands/url-handler.d.ts.map +1 -0
  54. package/dist/commands/url-handler.js +38 -0
  55. package/dist/commands/url-handler.js.map +1 -0
  56. package/dist/jobs/targets.d.ts +6 -1
  57. package/dist/jobs/targets.d.ts.map +1 -1
  58. package/dist/jobs/targets.js +12 -8
  59. package/dist/jobs/targets.js.map +1 -1
  60. package/dist/lib/claude-options.d.ts +47 -34
  61. package/dist/lib/claude-options.d.ts.map +1 -1
  62. package/dist/lib/claude-options.js +95 -82
  63. package/dist/lib/claude-options.js.map +1 -1
  64. package/dist/lib/claude-sessions.generated.d.ts +25 -0
  65. package/dist/lib/claude-sessions.generated.d.ts.map +1 -0
  66. package/dist/lib/claude-sessions.generated.js +16 -0
  67. package/dist/lib/claude-sessions.generated.js.map +1 -0
  68. package/dist/lib/settings.d.ts +10 -4
  69. package/dist/lib/settings.d.ts.map +1 -1
  70. package/dist/lib/settings.js +45 -15
  71. package/dist/lib/settings.js.map +1 -1
  72. package/dist/prompts/platform-prompts.d.ts +2 -0
  73. package/dist/prompts/platform-prompts.d.ts.map +1 -1
  74. package/dist/prompts/platform-prompts.js +9 -4
  75. package/dist/prompts/platform-prompts.js.map +1 -1
  76. package/dist/prompts/project-item-prompts.d.ts +3 -12
  77. package/dist/prompts/project-item-prompts.d.ts.map +1 -1
  78. package/dist/prompts/project-item-prompts.js +3 -18
  79. package/dist/prompts/project-item-prompts.js.map +1 -1
  80. package/dist/services/claude.d.ts +12 -7
  81. package/dist/services/claude.d.ts.map +1 -1
  82. package/dist/services/claude.js +7 -4
  83. package/dist/services/claude.js.map +1 -1
  84. package/dist/services/config.d.ts +5 -0
  85. package/dist/services/config.d.ts.map +1 -1
  86. package/dist/services/config.js +9 -0
  87. package/dist/services/config.js.map +1 -1
  88. package/dist/services/git.d.ts +5 -0
  89. package/dist/services/git.d.ts.map +1 -1
  90. package/dist/services/git.js +15 -3
  91. package/dist/services/git.js.map +1 -1
  92. package/dist/services/github.d.ts +25 -7
  93. package/dist/services/github.d.ts.map +1 -1
  94. package/dist/services/github.js +23 -9
  95. package/dist/services/github.js.map +1 -1
  96. package/dist/services/os-launcher.d.ts +29 -0
  97. package/dist/services/os-launcher.d.ts.map +1 -0
  98. package/dist/services/os-launcher.js +104 -0
  99. package/dist/services/os-launcher.js.map +1 -0
  100. package/dist/services/platform.d.ts +17 -3
  101. package/dist/services/platform.d.ts.map +1 -1
  102. package/dist/services/platform.js +79 -7
  103. package/dist/services/platform.js.map +1 -1
  104. package/dist/services/repository-registry.d.ts +11 -0
  105. package/dist/services/repository-registry.d.ts.map +1 -0
  106. package/dist/services/repository-registry.js +43 -0
  107. package/dist/services/repository-registry.js.map +1 -0
  108. package/dist/services/setup.d.ts.map +1 -1
  109. package/dist/services/setup.js +21 -1
  110. package/dist/services/setup.js.map +1 -1
  111. package/dist/services/url-handler.d.ts +23 -0
  112. package/dist/services/url-handler.d.ts.map +1 -0
  113. package/dist/services/url-handler.js +236 -0
  114. package/dist/services/url-handler.js.map +1 -0
  115. package/dist/services/worktree.d.ts +1 -19
  116. package/dist/services/worktree.d.ts.map +1 -1
  117. package/dist/services/worktree.js +0 -34
  118. package/dist/services/worktree.js.map +1 -1
  119. package/dist/types/index.d.ts +27 -25
  120. package/dist/types/index.d.ts.map +1 -1
  121. package/dist/workflow/data/project-item.d.ts +4 -0
  122. package/dist/workflow/data/project-item.d.ts.map +1 -1
  123. package/dist/workflow/data/team-member.d.ts +14 -0
  124. package/dist/workflow/data/team-member.d.ts.map +1 -0
  125. package/dist/workflow/data/team-member.js +2 -0
  126. package/dist/workflow/data/team-member.js.map +1 -0
  127. package/dist/workflow/data/workflow-context.d.ts +1 -1
  128. package/dist/workflow/data/workflow-states.d.ts +11 -2
  129. package/dist/workflow/data/workflow-states.d.ts.map +1 -1
  130. package/dist/workflow/data/workflow-states.generated.d.ts +17 -0
  131. package/dist/workflow/data/workflow-states.generated.d.ts.map +1 -1
  132. package/dist/workflow/data/workflow-states.generated.js +41 -0
  133. package/dist/workflow/data/workflow-states.generated.js.map +1 -1
  134. package/dist/workflow/data/workflow-states.js +21 -1
  135. package/dist/workflow/data/workflow-states.js.map +1 -1
  136. package/dist/workflow/engine/agent-session.d.ts +16 -0
  137. package/dist/workflow/engine/agent-session.d.ts.map +1 -0
  138. package/dist/workflow/engine/agent-session.js +109 -0
  139. package/dist/workflow/engine/agent-session.js.map +1 -0
  140. package/dist/workflow/engine/approval-flow.d.ts +39 -5
  141. package/dist/workflow/engine/approval-flow.d.ts.map +1 -1
  142. package/dist/workflow/engine/approval-flow.js +156 -2
  143. package/dist/workflow/engine/approval-flow.js.map +1 -1
  144. package/dist/workflow/engine/handlers/agent-implementation.d.ts +5 -4
  145. package/dist/workflow/engine/handlers/agent-implementation.d.ts.map +1 -1
  146. package/dist/workflow/engine/handlers/agent-implementation.js +13 -19
  147. package/dist/workflow/engine/handlers/agent-implementation.js.map +1 -1
  148. package/dist/workflow/engine/handlers/dev-implementation.js +1 -1
  149. package/dist/workflow/engine/handlers/dev-implementation.js.map +1 -1
  150. package/dist/workflow/engine/handlers/ready-for-approval.d.ts +7 -6
  151. package/dist/workflow/engine/handlers/ready-for-approval.d.ts.map +1 -1
  152. package/dist/workflow/engine/handlers/ready-for-approval.js +17 -19
  153. package/dist/workflow/engine/handlers/ready-for-approval.js.map +1 -1
  154. package/dist/workflow/engine/release-engine.d.ts +16 -5
  155. package/dist/workflow/engine/release-engine.d.ts.map +1 -1
  156. package/dist/workflow/engine/release-engine.js +81 -9
  157. package/dist/workflow/engine/release-engine.js.map +1 -1
  158. package/dist/workflow/engine/ship-flow.d.ts +15 -4
  159. package/dist/workflow/engine/ship-flow.d.ts.map +1 -1
  160. package/dist/workflow/engine/ship-flow.js +80 -21
  161. package/dist/workflow/engine/ship-flow.js.map +1 -1
  162. package/dist/workflow/engine/workflow-engine.d.ts +52 -16
  163. package/dist/workflow/engine/workflow-engine.d.ts.map +1 -1
  164. package/dist/workflow/engine/workflow-engine.js +146 -31
  165. package/dist/workflow/engine/workflow-engine.js.map +1 -1
  166. package/package.json +1 -1
@@ -1,12 +1,13 @@
1
1
  import { logger } from '../../lib/logger.js';
2
- import { claudeEntryPointOption } from '../../lib/claude-options.js';
2
+ import { CLAUDE_ENTRY_POINT_OPTION_NAME } from '../../lib/claude-options.js';
3
3
  import { isolationModeOption, resolveIsolationMode } from '../../lib/isolation.js';
4
4
  import * as git from '../../services/git.js';
5
5
  import * as github from '../../services/github.js';
6
+ import * as platform from '../../services/platform.js';
6
7
  import * as worktree from '../../services/worktree.js';
7
8
  import { WorkflowBranchState } from '../data/workflow-context.js';
8
9
  import { WorkflowStates } from '../data/workflow-states.js';
9
- import { mergeConfirmationOption } from './approval-flow.js';
10
+ import { approvePrOnBranchWithNoItem, assigneeOption, mergeConfirmationOption, readyForApprovalOnBranchWithNoItem } from './approval-flow.js';
10
11
  import { branchCreationOptions } from './branch-setup.js';
11
12
  import { reviewersOption } from './handlers/ready-for-approval.js';
12
13
  import { advanceAsNeededTo, requireLiveContext, startWorkflowManagementAtCommit } from './workflow-engine.js';
@@ -155,24 +156,81 @@ export async function carryLocalChanges(transition, changes) {
155
156
  });
156
157
  }
157
158
  const { branchName } = requireLiveContext(transition);
159
+ transition.workingPath = await checkOutCarriedBranch(options, changes, branchName, commitSha, treeSha);
160
+ logger.success(`Carried the uncommitted changes onto ${branchName} (${commitSha.substring(0, 12)})`);
161
+ logger.hint(`Working directory: ${transition.workingPath}`);
162
+ }
163
+ /**
164
+ * Give a branch made from carried changes its local checkout per the isolation mode, and make the
165
+ * checkout the working directory; returns its path. In the main repository, the checkout that held
166
+ * the changes switches to the branch with its working tree as it is, which is the branch's tip.
167
+ * Otherwise the branch gets a worktree, and the checkout that held the changes is cleaned of them,
168
+ * unless they changed meanwhile.
169
+ */
170
+ async function checkOutCarriedBranch(options, changes, branchName, commitSha, treeSha) {
171
+ const { sourceBranch, checkoutPath } = changes;
158
172
  if (resolveIsolationMode(options) === 'main-repo') {
159
173
  await git.switchToCommitKeepingWorkingTree(branchName, commitSha);
160
- transition.workingPath = checkoutPath;
174
+ return checkoutPath;
175
+ }
176
+ const { workingPath } = await worktree.ensureBranchEnvironment('worktree', branchName);
177
+ if (await git.writeWorkingTreeTree() === treeSha) {
178
+ await git.discardWorkingTreeChanges();
179
+ logger.dim(`Removed the carried changes from ${checkoutPath}, which stays on ${sourceBranch}`);
161
180
  }
162
181
  else {
163
- const { workingPath } = await worktree.ensureBranchEnvironment('worktree', branchName);
164
- if (await git.writeWorkingTreeTree() === treeSha) {
165
- await git.discardWorkingTreeChanges();
166
- logger.dim(`Removed the carried changes from ${checkoutPath}, which stays on ${sourceBranch}`);
167
- }
168
- else {
169
- logger.warning(`The changes in ${checkoutPath} changed while they were carried, so they were left there. Discard them once you have checked ${branchName}.`);
170
- }
171
- transition.workingPath = workingPath;
172
- process.chdir(workingPath);
182
+ logger.warning(`The changes in ${checkoutPath} changed while they were carried, so they were left there. Discard them once you have checked ${branchName}.`);
183
+ }
184
+ process.chdir(workingPath);
185
+ return workingPath;
186
+ }
187
+ /**
188
+ * Ship the uncommitted changes of the base branch checkout with no project item: they are committed
189
+ * onto a new branch on origin, which gets a PR into the base branch assigned to the person running
190
+ * the command, and the PR merges once the required checks pass - `ready-for-approval` and
191
+ * `approve-pr` on a branch with no item, with nothing asked on the way. No workflow status is
192
+ * recorded anywhere.
193
+ *
194
+ * Reads `commit-message`, `branch-name`, `base-branch` and `isolation` from the options.
195
+ */
196
+ export async function shipWithoutItem(options) {
197
+ const changes = await findLocalChanges(options['base-branch'] || await worktree.resolveBaseBranch());
198
+ if (!changes) {
199
+ throw new Error('There are no uncommitted changes to ship.');
200
+ }
201
+ const { sourceBranch, checkoutPath } = changes;
202
+ process.chdir(checkoutPath);
203
+ logger.section(`Carry uncommitted changes from ${sourceBranch}`);
204
+ const self = await platform.resolveTeammate(await github.getCurrentLogin());
205
+ const message = options['commit-message'] || `Changes carried from ${sourceBranch}`;
206
+ const shortBranchName = options['branch-name'] || carriedBranchName(options['commit-message']);
207
+ const branchName = `${await worktree.resolveBranchPrefix()}/${shortBranchName}`;
208
+ if (await git.branchExists(branchName)) {
209
+ throw new Error(`Branch '${branchName}' already exists. Pass --branch-name to choose a different name.`);
173
210
  }
211
+ const treeSha = await git.writeWorkingTreeTree();
212
+ const commitSha = await git.commitTree(treeSha, 'HEAD', message);
213
+ await git.pushCommitToBranch(branchName, commitSha, null);
214
+ await checkOutCarriedBranch(options, changes, branchName, commitSha, treeSha);
174
215
  logger.success(`Carried the uncommitted changes onto ${branchName} (${commitSha.substring(0, 12)})`);
175
- logger.hint(`Working directory: ${transition.workingPath}`);
216
+ const branchOptions = {
217
+ ...options,
218
+ [assigneeOption.longName]: self.email,
219
+ [reviewersOption.longName]: options[reviewersOption.longName] ?? '',
220
+ [mergeConfirmationOption.longName]: 'true',
221
+ 'base-branch': sourceBranch,
222
+ title: message
223
+ };
224
+ await readyForApprovalOnBranchWithNoItem(branchName, branchOptions);
225
+ await approvePrOnBranchWithNoItem(branchName, true);
226
+ }
227
+ /**
228
+ * The name, under the branch prefix, of a branch made from carried changes with no item to name it:
229
+ * the commit message as a slug, else the time.
230
+ */
231
+ function carriedBranchName(commitMessage) {
232
+ const slug = (commitMessage ?? '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').substring(0, 40).replace(/-+$/, '');
233
+ return slug || `changes-${new Date().toISOString().replace(/\D/g, '').substring(0, 12)}`;
176
234
  }
177
235
  /**
178
236
  * The tip on origin of an item's live branch that changes can be carried onto: one cut from the
@@ -203,17 +261,18 @@ async function requireBranchWithNoCommitsOfItsOwn(context, sourceBranch) {
203
261
  /**
204
262
  * Advance the item through every workflow state up to Approved and Merged, asking nothing: the
205
263
  * states on the way get the options a person would otherwise be asked for. No Claude session is
206
- * started on the way through Agent Implementation, the PR is assigned to the person running the
207
- * command, who merges it once the required checks pass (which brings the base branch's local
208
- * checkout up to date with the merge). Each state runs its usual automation, so a run that stops -
209
- * on failing checks, say - continues from where it stopped when run again.
264
+ * started on the way through Agent Implementation, the item and its PR are assigned to the person
265
+ * running the command - the team member whose linked GitHub account `gh` is signed in as - who
266
+ * merges it once the required checks pass (which brings the base branch's local checkout up to
267
+ * date with the merge). Each state runs its usual automation, so a run that stops - on failing
268
+ * checks, say - continues from where it stopped when run again.
210
269
  */
211
270
  export async function approveAndMerge(transition) {
212
- const login = await github.getCurrentLogin();
271
+ const self = await platform.resolveTeammate(await github.getCurrentLogin());
213
272
  Object.assign(transition.options, {
214
273
  [isolationModeOption.longName]: resolveIsolationMode(transition.options),
215
- [claudeEntryPointOption.longName]: 'none',
216
- assignee: login,
274
+ [CLAUDE_ENTRY_POINT_OPTION_NAME]: 'none',
275
+ [assigneeOption.longName]: self.email,
217
276
  [reviewersOption.longName]: transition.options[reviewersOption.longName] ?? '',
218
277
  [mergeConfirmationOption.longName]: 'true'
219
278
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ship-flow.js","sourceRoot":"","sources":["../../../src/workflow/engine/ship-flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ship-flow.js","sourceRoot":"","sources":["../../../src/workflow/engine/ship-flow.ts"],"names":[],"mappings":"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"}
@@ -24,17 +24,32 @@ import { type WorkflowState } from '../data/workflow-states.js';
24
24
  *
25
25
  * A command resolves the transition it operates on and, when it changes the item, calls the
26
26
  * operation that says so: `advanceAsNeededTo` to move the item on, `reenterState` to run the
27
- * automation of the state it is already in. Both put the item under workflow management on the way
27
+ * automation of the state it is already in, `advanceOrReenter` for either. They all put the item under workflow management on the way
28
28
  * in - an item with no live branch gets one, created on origin and recorded on the platform as the
29
29
  * item's - so a command never arranges that for itself and every handler runs on a branch.
30
30
  *
31
31
  * The workflow changes the item's context; the branch itself carries the work. A branch's PR is
32
32
  * therefore gated on a CI/CD run of exactly what merges, and approving merges that run's head.
33
33
  *
34
+ * Entering some states takes a teammate assignment for the item (`getAssignmentRequirement`):
35
+ * optional on the way into the early states, required on the way into Needs Approval for Release,
36
+ * where the assignee approves the pull request. The engine asks for the teammate once per
37
+ * transition, before any slow work, and records the assignment with the first such state it
38
+ * enters. An item out of scope (in no project) has no assignee.
39
+ *
34
40
  * One thing lives locally, and only here: the item URL of each branch is remembered in the clone's
35
41
  * git config, so "is this branch under workflow?" and "which item?" are answered instantly for
36
42
  * display. The platform is the truth.
37
43
  */
44
+ /**
45
+ * An item's place in the project plan, as far as a transition needs it.
46
+ */
47
+ export interface ProjectItemPlan {
48
+ /** The Project the item is planned in; null for an item out of scope, which has no assignee. */
49
+ projectId: string | null;
50
+ /** The team member the item is assigned to; null when it is unassigned. */
51
+ assignedToUserId: string | null;
52
+ }
38
53
  /**
39
54
  * One project item moving through the workflow, as the engine and the state handlers see it.
40
55
  */
@@ -44,11 +59,18 @@ export interface WorkflowTransition {
44
59
  context: WorkflowContext | null;
45
60
  /** The item's current state; null when it is outside workflow management. */
46
61
  currentState: WorkflowState | null;
62
+ /** The item's place in the project plan, as read before the transition. */
63
+ plan: ProjectItemPlan;
47
64
  /** Local checkout of the branch (worktree or main repo), or null when none exists. */
48
65
  workingPath: string | null;
49
66
  /** Resolved command options the handlers read (model, effort, assignee, ...). */
50
67
  options: Record<string, string>;
51
68
  }
69
+ /**
70
+ * What is known of a project item before a transition moves it: enough to ask for everything the
71
+ * transition will need.
72
+ */
73
+ export type ItemBeforeTransition = Pick<WorkflowTransition, 'projectItemUrl' | 'currentState' | 'plan'>;
52
74
  /**
53
75
  * Side effects attached to entering a workflow state. `prepare` runs before the new state is
54
76
  * recorded (it must succeed for the transition to happen); `complete` runs after the state has been
@@ -104,12 +126,10 @@ export interface TargetSummary {
104
126
  target: string;
105
127
  /** What progress output calls the target: `#<id> <title>` for an item, the branch name otherwise. */
106
128
  label: string;
107
- /** The item's URL; null for a branch with no project item. */
108
- projectItemUrl: string | null;
129
+ /** The project item, with its state (null outside workflow management); null for a branch with no project item. */
130
+ item: ItemBeforeTransition | null;
109
131
  /** The branch carrying the work; null for an item with no live branch in this repository. */
110
132
  branchName: string | null;
111
- /** The item's state; null for an item outside workflow management or a branch with no item. */
112
- currentState: WorkflowState | null;
113
133
  }
114
134
  /**
115
135
  * What a target is - its item, branch and state - read without moving into any checkout or
@@ -135,27 +155,43 @@ export declare function startWorkflowManagementAtCommit(transition: WorkflowTran
135
155
  /**
136
156
  * Move the item to `targetState` one state at a time: each state on the way is entered in order -
137
157
  * its handler prepares, the state is recorded on the item, its handler completes - exactly as
138
- * advancing to each state with its own command would. The options of every handler on the way are
139
- * asked for before the first state is entered. An item that is not under workflow management yet
140
- * is put under it first, so advancing an item that has never been started to the first state is
141
- * what starts it; an item already at or past `targetState` keeps its state and only gains its
142
- * branch, so advancing again is a no-op and a run that stopped part way continues where it stopped.
158
+ * advancing to each state with its own command would. The options of every handler on the way,
159
+ * and the teammate assignment when a state on the way takes one, are asked for before anything
160
+ * else happens. An item that is not under workflow management yet is put under it first, so
161
+ * advancing an item that has never been started to the first state is what starts it; an item
162
+ * already at or past `targetState` keeps its state and only gains its branch, so advancing again
163
+ * is a no-op and a run that stopped part way continues where it stopped.
164
+ *
165
+ * The assignment is recorded once, with the first state entered that takes one. Creating the
166
+ * branch of an item outside workflow management enters the first state by itself, so that state is
167
+ * recorded again with the assignment right after.
143
168
  */
144
169
  export declare function advanceAsNeededTo(transition: WorkflowTransition, targetState: WorkflowState): Promise<void>;
145
170
  /**
146
171
  * Run the automation of the state the item is already in, without a transition: the state's
147
172
  * handler prepares and completes again, so its working environment is set up and its session
148
173
  * starts afresh. The item's status stays as it is; a pull request the handler found or opened for
149
- * the branch is recorded on the item alongside it.
174
+ * the branch is recorded on the item alongside it. A state that requires a teammate assignment
175
+ * requires it again: the assignee is asked for, as entering the state does, and recorded.
150
176
  */
151
177
  export declare function reenterState(transition: WorkflowTransition, state: WorkflowState): Promise<void>;
152
178
  /**
153
- * Prompt for every handler option that was not supplied on the command line and that advancing
154
- * from `fromState` to `targetState` needs, so a handler reached through `next` asks the same
155
- * questions as its dedicated command would. A batch asks this for each of its items, up front, so
156
- * its unattended runs are asked nothing; an option answered once is not asked again.
179
+ * Bring the item to `targetState` with that state's automation run: an item already in it re-enters
180
+ * it (`reenterState`), so the automation runs again - a pull request that needs its assignee gets
181
+ * one - and an item before it advances to it (`advanceAsNeededTo`). An item past it keeps its state.
182
+ */
183
+ export declare function advanceOrReenter(transition: WorkflowTransition, targetState: WorkflowState): Promise<void>;
184
+ /**
185
+ * Ask for everything that advancing the item to `targetState` needs and was not supplied on the
186
+ * command line: the options of every handler on the way, so a handler reached through `next` asks
187
+ * the same questions as its dedicated command would, and the teammate to assign the item to when a
188
+ * state on the way takes an assignment (an item already in a state that requires one is asked again,
189
+ * since entering that state again re-runs its automation). Every answer goes into `options`; the assignment is also
190
+ * returned, as the email of the teammate to record (null when there is none to record). A batch
191
+ * asks this for each of its items, up front, so its unattended runs are asked nothing; an option
192
+ * answered once is not asked again.
157
193
  */
158
- export declare function resolveOptionsForAdvancing(fromState: WorkflowState | null, targetState: WorkflowState, options: Record<string, string>): Promise<void>;
194
+ export declare function resolveOptionsForAdvancing(item: ItemBeforeTransition, targetState: WorkflowState, options: Record<string, string>): Promise<string | null>;
159
195
  /**
160
196
  * The summary of the project item a branch in this repository implements, with the item's workflow
161
197
  * context. Null for a branch outside workflow management, which the base branch always is: no item
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-engine.d.ts","sourceRoot":"","sources":["../../../src/workflow/engine/workflow-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow-engine.d.ts","sourceRoot":"","sources":["../../../src/workflow/engine/workflow-engine.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,14 @@ import { logger } from '../../lib/logger.js';
2
2
  import { resolveOptions } from '../../cli/resolver.js';
3
3
  import { resolveIsolationMode } from '../../lib/isolation.js';
4
4
  import { isProjectItemUrl } from '../../lib/project-item-url.js';
5
+ import { promptSelect } from '../../lib/prompt.js';
5
6
  import * as git from '../../services/git.js';
6
7
  import * as github from '../../services/github.js';
7
8
  import * as platform from '../../services/platform.js';
8
9
  import * as worktree from '../../services/worktree.js';
9
10
  import { WorkflowBranchState } from '../data/workflow-context.js';
10
- import { WorkflowStates, getWorkflowStatesBetween, isStateAtOrAfter, normalizeWorkflowState } from '../data/workflow-states.js';
11
+ import { WorkflowStates, getAssignmentRequirement, getStateAssignmentRequirement, getWorkflowStatesBetween, isStateAtOrAfter, normalizeWorkflowState } from '../data/workflow-states.js';
12
+ import { approverGitHubLogin, assigneeOption } from './approval-flow.js';
11
13
  import { collectBranchCreationChoices } from './branch-setup.js';
12
14
  import { HANDLERS_BY_STATE, getHandler } from './handlers/index.js';
13
15
  /**
@@ -63,7 +65,7 @@ export async function readTarget(target) {
63
65
  const branchName = await branchNameForTarget(trimmed);
64
66
  const branchItem = await getProjectItemSummaryForBranch(branchName);
65
67
  if (!branchItem) {
66
- return { target: trimmed, label: branchName, projectItemUrl: null, branchName, currentState: null };
68
+ return { target: trimmed, label: branchName, item: null, branchName };
67
69
  }
68
70
  item = branchItem;
69
71
  }
@@ -71,11 +73,20 @@ export async function readTarget(target) {
71
73
  return {
72
74
  target: trimmed,
73
75
  label: `#${item.externalId} ${item.title}`,
74
- projectItemUrl: item.url,
75
- branchName: await liveBranchHere(context) ? context.branchName : null,
76
- currentState: context ? normalizeWorkflowState(context.workflowStatus) : null
76
+ item: {
77
+ projectItemUrl: item.url,
78
+ currentState: context ? normalizeWorkflowState(context.workflowStatus) : null,
79
+ plan: planOf(item)
80
+ },
81
+ branchName: await liveBranchHere(context) ? context.branchName : null
77
82
  };
78
83
  }
84
+ /**
85
+ * The item's place in the project plan, from its summary.
86
+ */
87
+ function planOf(item) {
88
+ return { projectId: item.projectId, assignedToUserId: item.assignedToUserId };
89
+ }
79
90
  /**
80
91
  * The branch a branch-name or PR URL target names: the PR's head branch, or the name itself.
81
92
  */
@@ -112,6 +123,7 @@ async function transitionForItem(item, options) {
112
123
  projectItemUrl: item.url,
113
124
  context,
114
125
  currentState: context ? normalizeWorkflowState(context.workflowStatus) : null,
126
+ plan: planOf(item),
115
127
  workingPath: null,
116
128
  options
117
129
  };
@@ -132,6 +144,7 @@ async function transitionForManagedBranch(item, options) {
132
144
  projectItemUrl: item.url,
133
145
  context,
134
146
  currentState: normalizeWorkflowState(context.workflowStatus),
147
+ plan: planOf(item),
135
148
  workingPath: await enterCheckout(context.branchName),
136
149
  options
137
150
  };
@@ -302,31 +315,45 @@ async function createRecordedBranch(transition, record, startCommit) {
302
315
  }
303
316
  transition.context = item.workflowContext;
304
317
  transition.currentState = item.workflowContext ? normalizeWorkflowState(item.workflowContext.workflowStatus) : null;
318
+ transition.plan = planOf(item);
305
319
  transition.workingPath = null;
306
320
  }
307
321
  /**
308
322
  * Move the item to `targetState` one state at a time: each state on the way is entered in order -
309
323
  * its handler prepares, the state is recorded on the item, its handler completes - exactly as
310
- * advancing to each state with its own command would. The options of every handler on the way are
311
- * asked for before the first state is entered. An item that is not under workflow management yet
312
- * is put under it first, so advancing an item that has never been started to the first state is
313
- * what starts it; an item already at or past `targetState` keeps its state and only gains its
314
- * branch, so advancing again is a no-op and a run that stopped part way continues where it stopped.
324
+ * advancing to each state with its own command would. The options of every handler on the way,
325
+ * and the teammate assignment when a state on the way takes one, are asked for before anything
326
+ * else happens. An item that is not under workflow management yet is put under it first, so
327
+ * advancing an item that has never been started to the first state is what starts it; an item
328
+ * already at or past `targetState` keeps its state and only gains its branch, so advancing again
329
+ * is a no-op and a run that stopped part way continues where it stopped.
330
+ *
331
+ * The assignment is recorded once, with the first state entered that takes one. Creating the
332
+ * branch of an item outside workflow management enters the first state by itself, so that state is
333
+ * recorded again with the assignment right after.
315
334
  */
316
335
  export async function advanceAsNeededTo(transition, targetState) {
336
+ const wasUnmanaged = transition.currentState === null;
337
+ let assignee = await resolveOptionsForAdvancing(transition, targetState, transition.options);
317
338
  await startWorkflowManagement(transition, targetState);
339
+ if (assignee !== null && wasUnmanaged && transition.currentState !== null && getStateAssignmentRequirement(transition.currentState) !== 'none') {
340
+ await persistState(transition, transition.currentState, assignee);
341
+ assignee = null;
342
+ }
318
343
  if (transition.currentState !== null && isStateAtOrAfter(transition.currentState, targetState)) {
319
344
  logger.info(`Already at "${transition.currentState}"; nothing to advance to reach "${targetState}".`);
320
345
  return;
321
346
  }
322
- const steps = getWorkflowStatesBetween(transition.currentState, targetState);
323
- await resolveOptionsForAdvancing(transition.currentState, targetState, transition.options);
324
- for (const state of steps) {
347
+ for (const state of getWorkflowStatesBetween(transition.currentState, targetState)) {
325
348
  logger.status(`Workflow: ${transition.currentState ?? '(not started)'} → ${state}`);
326
349
  const handler = HANDLERS_BY_STATE.get(state);
350
+ const assigneeForState = assignee !== null && getStateAssignmentRequirement(state) !== 'none' ? assignee : null;
327
351
  await handler?.prepare?.(transition);
328
- await persistState(transition, state);
352
+ await persistState(transition, state, assigneeForState);
329
353
  await handler?.complete?.(transition);
354
+ if (assigneeForState !== null) {
355
+ assignee = null;
356
+ }
330
357
  await refreshWorkingPath(transition);
331
358
  }
332
359
  }
@@ -348,31 +375,113 @@ async function refreshWorkingPath(transition) {
348
375
  * Run the automation of the state the item is already in, without a transition: the state's
349
376
  * handler prepares and completes again, so its working environment is set up and its session
350
377
  * starts afresh. The item's status stays as it is; a pull request the handler found or opened for
351
- * the branch is recorded on the item alongside it.
378
+ * the branch is recorded on the item alongside it. A state that requires a teammate assignment
379
+ * requires it again: the assignee is asked for, as entering the state does, and recorded.
352
380
  */
353
381
  export async function reenterState(transition, state) {
354
382
  await startWorkflowManagement(transition, state);
355
383
  const handler = getHandler(state);
384
+ const assignee = await resolveAssignee(transition, state, reentryAssignmentRequirement(state), transition.options);
356
385
  await resolveHandlerOptions(transition.options, [handler]);
357
386
  const recordedPullRequestUrl = requireContext(transition).pullRequestUrl;
358
387
  await handler.prepare?.(transition);
359
- if (requireContext(transition).pullRequestUrl !== recordedPullRequestUrl) {
360
- await persistState(transition, requireCurrentState(transition));
388
+ if (assignee !== null || requireContext(transition).pullRequestUrl !== recordedPullRequestUrl) {
389
+ await persistState(transition, requireCurrentState(transition), assignee?.email ?? null);
361
390
  }
362
391
  await handler.complete?.(transition);
363
392
  }
393
+ /** Entering a state again takes the assignment its first entry does only when the state requires one. */
394
+ function reentryAssignmentRequirement(state) {
395
+ return getStateAssignmentRequirement(state) === 'required' ? 'required' : 'none';
396
+ }
364
397
  /**
365
- * Prompt for every handler option that was not supplied on the command line and that advancing
366
- * from `fromState` to `targetState` needs, so a handler reached through `next` asks the same
367
- * questions as its dedicated command would. A batch asks this for each of its items, up front, so
368
- * its unattended runs are asked nothing; an option answered once is not asked again.
398
+ * Bring the item to `targetState` with that state's automation run: an item already in it re-enters
399
+ * it (`reenterState`), so the automation runs again - a pull request that needs its assignee gets
400
+ * one - and an item before it advances to it (`advanceAsNeededTo`). An item past it keeps its state.
369
401
  */
370
- export async function resolveOptionsForAdvancing(fromState, targetState, options) {
371
- if (fromState !== null && isStateAtOrAfter(fromState, targetState)) {
402
+ export async function advanceOrReenter(transition, targetState) {
403
+ if (transition.currentState === targetState) {
404
+ await reenterState(transition, targetState);
372
405
  return;
373
406
  }
374
- const entered = new Set(getWorkflowStatesBetween(fromState, targetState));
375
- await resolveHandlerOptions(options, [...HANDLERS_BY_STATE.values()].filter(handler => entered.has(handler.state)));
407
+ await advanceAsNeededTo(transition, targetState);
408
+ }
409
+ /**
410
+ * Ask for everything that advancing the item to `targetState` needs and was not supplied on the
411
+ * command line: the options of every handler on the way, so a handler reached through `next` asks
412
+ * the same questions as its dedicated command would, and the teammate to assign the item to when a
413
+ * state on the way takes an assignment (an item already in a state that requires one is asked again,
414
+ * since entering that state again re-runs its automation). Every answer goes into `options`; the assignment is also
415
+ * returned, as the email of the teammate to record (null when there is none to record). A batch
416
+ * asks this for each of its items, up front, so its unattended runs are asked nothing; an option
417
+ * answered once is not asked again.
418
+ */
419
+ export async function resolveOptionsForAdvancing(item, targetState, options) {
420
+ const fromState = item.currentState;
421
+ const reenters = fromState === targetState && reentryAssignmentRequirement(targetState) === 'required';
422
+ if (fromState !== null && isStateAtOrAfter(fromState, targetState) && !reenters) {
423
+ return null;
424
+ }
425
+ const entered = reenters ? [targetState] : getWorkflowStatesBetween(fromState, targetState);
426
+ const requirement = reenters ? 'required' : getAssignmentRequirement(fromState, targetState);
427
+ const assignee = await resolveAssignee(item, targetState, requirement, options);
428
+ if (assignee !== null && entered.includes(WorkflowStates.NeedsApprovalForRelease)) {
429
+ approverGitHubLogin(assignee);
430
+ }
431
+ await resolveHandlerOptions(options, [...HANDLERS_BY_STATE.values()].filter(handler => entered.includes(handler.state)));
432
+ return assignee?.email ?? null;
433
+ }
434
+ /**
435
+ * The teammate the item is assigned to on its way to `targetState`. Resolved from the `assignee`
436
+ * option when it was supplied (a teammate's email or GitHub login, or empty for none) and asked for
437
+ * otherwise - with "none", which keeps the current assignee, where the assignment is optional, and
438
+ * from the team's members alone, defaulting to the current assignee, where it is required. The
439
+ * option is left holding the teammate's email, or empty for none. An item out of scope has no
440
+ * assignee: an optional assignment is skipped, a required one refused. Returns the teammate to
441
+ * record, or null when there is nothing to record.
442
+ */
443
+ async function resolveAssignee(item, targetState, requirement, options) {
444
+ if (requirement === 'none') {
445
+ return null;
446
+ }
447
+ if (item.plan.projectId === null) {
448
+ if (requirement === 'required') {
449
+ throw new Error(`Assign ${item.projectItemUrl} to a project first: an item out of scope has no assignee, and "${targetState}" needs one.`);
450
+ }
451
+ logger.dim(`${item.projectItemUrl} is out of scope (in no project), so it has no assignee to set.`);
452
+ options[assigneeOption.longName] = '';
453
+ return null;
454
+ }
455
+ const members = await platform.listTeamMembers();
456
+ const current = members.find(member => member.userId === item.plan.assignedToUserId) ?? null;
457
+ const supplied = options[assigneeOption.longName];
458
+ const required = requirement === 'required';
459
+ const identity = supplied === undefined ? await promptForAssignee(members, current, required) : supplied.trim();
460
+ const assignee = identity.length > 0
461
+ ? await platform.resolveTeammate(identity)
462
+ : keepCurrentAssignee(current, required, targetState);
463
+ options[assigneeOption.longName] = assignee?.email ?? '';
464
+ return assignee;
465
+ }
466
+ /**
467
+ * No teammate named: none to record where the assignment is optional; where it is required, the
468
+ * current assignee, which then has to exist.
469
+ */
470
+ function keepCurrentAssignee(current, required, targetState) {
471
+ if (!required) {
472
+ return null;
473
+ }
474
+ if (!current) {
475
+ throw new Error(`"${targetState}" needs a teammate assignment: pass --assignee <email or GitHub login>, the assignee approves the pull request.`);
476
+ }
477
+ return current;
478
+ }
479
+ async function promptForAssignee(members, current, required) {
480
+ const memberChoices = members.map(member => ({ label: member.email, value: member.email }));
481
+ if (required) {
482
+ return promptSelect('Assign to a teammate', memberChoices, { default: current?.email });
483
+ }
484
+ return promptSelect('Assign to a teammate', [{ label: `None (keep ${current?.email ?? 'unassigned'})`, value: '' }, ...memberChoices], { default: '' });
376
485
  }
377
486
  async function resolveHandlerOptions(options, handlers) {
378
487
  for (const handler of handlers) {
@@ -397,14 +506,20 @@ async function resolveHandlerOptions(options, handlers) {
397
506
  }
398
507
  /**
399
508
  * Record the new state where it lives: the item's workflow context on idea1.ai, together with the
400
- * pull request of the item's branch once a handler has found or opened it. The item's status is the
401
- * state of the work for every clone and for the web app alike, and its pull request link stays
402
- * recorded once the pull request merges or closes.
403
- */
404
- async function persistState(transition, targetState) {
509
+ * pull request of the item's branch once a handler has found or opened it, and the teammate the
510
+ * item is assigned to when the state takes an assignment (null leaves the assignment as it is).
511
+ * The item's status is the state of the work for every clone and for the web app alike, and its
512
+ * pull request link stays recorded once the pull request merges or closes. A state that could not
513
+ * be recorded is still the state the run reached; an assignment that could not be recorded stops
514
+ * the run, since the assignee is who the work goes to next.
515
+ */
516
+ async function persistState(transition, targetState, assignedToEmail) {
405
517
  const context = requireContext(transition);
406
518
  const pullRequestUrl = context.pullRequestUrl.length > 0 ? context.pullRequestUrl : null;
407
- await platform.setWorkflowStatus(transition.projectItemUrl, targetState, pullRequestUrl);
519
+ const recorded = await platform.setWorkflowStatus(transition.projectItemUrl, targetState, pullRequestUrl, assignedToEmail);
520
+ if (!recorded && assignedToEmail !== null) {
521
+ throw new Error(`Could not record "${targetState}" with the assignment to ${assignedToEmail} on ${transition.projectItemUrl}.`);
522
+ }
408
523
  context.workflowStatus = targetState;
409
524
  transition.currentState = targetState;
410
525
  }