@idea1/cli 1.5.2 → 1.7.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 +123 -92
- package/dist/commands/approve-pr.d.ts.map +1 -1
- package/dist/commands/approve-pr.js +7 -163
- package/dist/commands/approve-pr.js.map +1 -1
- package/dist/commands/attach-project-item.d.ts.map +1 -1
- package/dist/commands/attach-project-item.js +38 -89
- package/dist/commands/attach-project-item.js.map +1 -1
- package/dist/commands/close-worktree.d.ts.map +1 -1
- package/dist/commands/close-worktree.js +12 -9
- 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 +3 -2
- package/dist/commands/create-worktree.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +19 -14
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/index.d.ts +3 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +5 -3
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/join-project-item.d.ts.map +1 -1
- package/dist/commands/join-project-item.js +38 -77
- package/dist/commands/join-project-item.js.map +1 -1
- package/dist/commands/next-workflow-step.d.ts.map +1 -1
- package/dist/commands/next-workflow-step.js +66 -51
- package/dist/commands/next-workflow-step.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +5 -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 +7 -66
- package/dist/commands/ready-for-approval.js.map +1 -1
- package/dist/commands/release.d.ts.map +1 -1
- package/dist/commands/release.js +5 -4
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/start-agent-implementation.d.ts +3 -0
- package/dist/commands/start-agent-implementation.d.ts.map +1 -0
- package/dist/commands/start-agent-implementation.js +41 -0
- package/dist/commands/start-agent-implementation.js.map +1 -0
- package/dist/commands/start-dev-implementation.d.ts.map +1 -1
- package/dist/commands/start-dev-implementation.js +8 -55
- package/dist/commands/start-dev-implementation.js.map +1 -1
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +81 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +29 -9
- package/dist/interactive.js.map +1 -1
- package/dist/lib/claude-options.d.ts +33 -0
- package/dist/lib/claude-options.d.ts.map +1 -0
- package/dist/lib/claude-options.js +83 -0
- package/dist/lib/claude-options.js.map +1 -0
- package/dist/lib/settings.d.ts +18 -0
- package/dist/lib/settings.d.ts.map +1 -1
- package/dist/lib/settings.js +23 -5
- package/dist/lib/settings.js.map +1 -1
- package/dist/lib/workflow-states.d.ts +21 -3
- package/dist/lib/workflow-states.d.ts.map +1 -1
- package/dist/lib/workflow-states.generated.d.ts +21 -0
- package/dist/lib/workflow-states.generated.d.ts.map +1 -0
- package/dist/lib/workflow-states.generated.js +34 -0
- package/dist/lib/workflow-states.generated.js.map +1 -0
- package/dist/lib/workflow-states.js +47 -26
- package/dist/lib/workflow-states.js.map +1 -1
- package/dist/services/branch-setup.d.ts +42 -0
- package/dist/services/branch-setup.d.ts.map +1 -0
- package/dist/services/branch-setup.js +118 -0
- package/dist/services/branch-setup.js.map +1 -0
- package/dist/services/claude.d.ts +14 -4
- package/dist/services/claude.d.ts.map +1 -1
- package/dist/services/claude.js +39 -4
- package/dist/services/claude.js.map +1 -1
- package/dist/services/config.d.ts +3 -3
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +6 -4
- package/dist/services/config.js.map +1 -1
- package/dist/services/git.d.ts +66 -0
- package/dist/services/git.d.ts.map +1 -1
- package/dist/services/git.js +188 -8
- package/dist/services/git.js.map +1 -1
- package/dist/services/setup.d.ts +3 -1
- package/dist/services/setup.d.ts.map +1 -1
- package/dist/services/setup.js +19 -7
- package/dist/services/setup.js.map +1 -1
- package/dist/services/workflow-engine.d.ts +67 -0
- package/dist/services/workflow-engine.d.ts.map +1 -0
- package/dist/services/workflow-engine.js +371 -0
- package/dist/services/workflow-engine.js.map +1 -0
- package/dist/services/workflow-handlers/agent-implementation.d.ts +9 -0
- package/dist/services/workflow-handlers/agent-implementation.d.ts.map +1 -0
- package/dist/services/workflow-handlers/agent-implementation.js +37 -0
- package/dist/services/workflow-handlers/agent-implementation.js.map +1 -0
- package/dist/services/workflow-handlers/approve-pr.d.ts +8 -0
- package/dist/services/workflow-handlers/approve-pr.d.ts.map +1 -0
- package/dist/services/workflow-handlers/approve-pr.js +161 -0
- package/dist/services/workflow-handlers/approve-pr.js.map +1 -0
- package/dist/services/workflow-handlers/dev-implementation.d.ts +8 -0
- package/dist/services/workflow-handlers/dev-implementation.d.ts.map +1 -0
- package/dist/services/workflow-handlers/dev-implementation.js +34 -0
- package/dist/services/workflow-handlers/dev-implementation.js.map +1 -0
- package/dist/services/workflow-handlers/index.d.ts +18 -0
- package/dist/services/workflow-handlers/index.d.ts.map +1 -0
- package/dist/services/workflow-handlers/index.js +36 -0
- package/dist/services/workflow-handlers/index.js.map +1 -0
- package/dist/services/workflow-handlers/ready-for-approval.d.ts +8 -0
- package/dist/services/workflow-handlers/ready-for-approval.d.ts.map +1 -0
- package/dist/services/workflow-handlers/ready-for-approval.js +60 -0
- package/dist/services/workflow-handlers/ready-for-approval.js.map +1 -0
- package/dist/services/workflow.d.ts +1 -21
- package/dist/services/workflow.d.ts.map +1 -1
- package/dist/services/workflow.js +1 -67
- package/dist/services/workflow.js.map +1 -1
- package/dist/services/worktree.d.ts +23 -33
- package/dist/services/worktree.d.ts.map +1 -1
- package/dist/services/worktree.js +61 -140
- package/dist/services/worktree.js.map +1 -1
- package/dist/types/index.d.ts +41 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/dist/commands/start-project-item.d.ts +0 -27
- package/dist/commands/start-project-item.d.ts.map +0 -1
- package/dist/commands/start-project-item.js +0 -325
- package/dist/commands/start-project-item.js.map +0 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { logger } from '../../lib/logger.js';
|
|
2
|
+
import { promptConfirm } from '../../lib/prompt.js';
|
|
3
|
+
import { WorkflowStates } from '../../lib/workflow-states.js';
|
|
4
|
+
import * as git from '../git.js';
|
|
5
|
+
import * as github from '../github.js';
|
|
6
|
+
import { removeCurrentWorktree, resolveBaseBranch } from '../worktree.js';
|
|
7
|
+
import { requireBranch } from '../workflow-engine.js';
|
|
8
|
+
/**
|
|
9
|
+
* Entering "Approved and Merged": approve the PR when the user is a requested
|
|
10
|
+
* reviewer, drop the branch's metadata file so it does not leak into the target
|
|
11
|
+
* branch, and merge. Afterwards the branch and any worktree are cleaned up.
|
|
12
|
+
*/
|
|
13
|
+
export const approvePrHandler = {
|
|
14
|
+
state: WorkflowStates.ApprovedAndMerged,
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
longName: 'comment',
|
|
18
|
+
shortName: 'c',
|
|
19
|
+
description: 'Custom approval comment',
|
|
20
|
+
defaultValue: '',
|
|
21
|
+
promptWhenDefaultExists: false
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
async prepare(context) {
|
|
25
|
+
const branchName = requireBranch(context);
|
|
26
|
+
const comment = context.options['comment'] || 'Approved via idea1 CLI workflow';
|
|
27
|
+
if (context.workingPath) {
|
|
28
|
+
await git.ensureBranchUpToDate();
|
|
29
|
+
}
|
|
30
|
+
const prInfo = await github.getPrInfo(branchName);
|
|
31
|
+
if (!prInfo) {
|
|
32
|
+
throw new Error('No PR found for this branch. Nothing to approve.');
|
|
33
|
+
}
|
|
34
|
+
logger.info(`PR #${prInfo.number} found`);
|
|
35
|
+
// Re-entering this state after the item was moved back: the merge already happened.
|
|
36
|
+
if (prInfo.state.toUpperCase() === 'MERGED') {
|
|
37
|
+
logger.dim(`PR #${prInfo.number} is already merged; skipping approval and merge.`);
|
|
38
|
+
context.branchRetired = true;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
await approveIfRequestedReviewer(branchName, comment);
|
|
42
|
+
// Remove the branch metadata file before merging so it does not leak into the target branch
|
|
43
|
+
if (context.workingPath) {
|
|
44
|
+
await git.removeBranchMetadataAndPush(branchName);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
await git.removeBranchMetadataDetached(branchName);
|
|
48
|
+
}
|
|
49
|
+
const confirmMerge = await promptConfirm(`Merge PR #${prInfo.number} (${branchName} -> ${context.baseBranch})?`, { default: true });
|
|
50
|
+
if (!confirmMerge) {
|
|
51
|
+
throw new Error('Merge cancelled by user');
|
|
52
|
+
}
|
|
53
|
+
await mergeWithProtectionFallback(branchName);
|
|
54
|
+
context.branchRetired = true;
|
|
55
|
+
},
|
|
56
|
+
async complete(context) {
|
|
57
|
+
const branchName = requireBranch(context);
|
|
58
|
+
await git.fetchLatest();
|
|
59
|
+
if (!context.workingPath) {
|
|
60
|
+
await github.deleteRemoteBranch(branchName);
|
|
61
|
+
printCompletion(context.baseBranch, context.projectItemUrl);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const isWorktree = await git.isInsideWorktree();
|
|
65
|
+
const mainRepoRoot = await git.getMainRepoRoot();
|
|
66
|
+
// Inside a worktree the base branch cannot be checked out in place, so the
|
|
67
|
+
// worktree is removed regardless of removeWorktreeAtState.
|
|
68
|
+
if (isWorktree) {
|
|
69
|
+
const worktreePath = await removeCurrentWorktree(mainRepoRoot);
|
|
70
|
+
await deleteBranchQuietly(branchName);
|
|
71
|
+
printCompletion(context.baseBranch, context.projectItemUrl);
|
|
72
|
+
logger.hint(`Worktree removed: ${worktreePath}`);
|
|
73
|
+
logger.hint(`Change to a different folder (e.g. ${mainRepoRoot}) to continue.`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// Switch to the base branch (it may be checked out in another worktree)
|
|
77
|
+
const baseWorktreePath = await git.getWorktreePathForBranch(context.baseBranch);
|
|
78
|
+
if (baseWorktreePath) {
|
|
79
|
+
logger.step(`Base branch ${context.baseBranch} is in a worktree at ${baseWorktreePath}, pulling there...`);
|
|
80
|
+
await git.updateBranchToLatest(context.baseBranch);
|
|
81
|
+
const settingsBaseBranch = await resolveBaseBranch();
|
|
82
|
+
await git.checkoutAndPullBranch(settingsBaseBranch);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await git.checkoutAndPullBranch(context.baseBranch);
|
|
86
|
+
}
|
|
87
|
+
await deleteBranchQuietly(branchName);
|
|
88
|
+
printCompletion(context.baseBranch, context.projectItemUrl);
|
|
89
|
+
if (baseWorktreePath) {
|
|
90
|
+
logger.hint(`Base branch is in worktree at: ${baseWorktreePath}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
async function approveIfRequestedReviewer(branchName, comment) {
|
|
95
|
+
const approvalStatus = await github.getUserApprovalStatus(branchName);
|
|
96
|
+
if (!approvalStatus) {
|
|
97
|
+
logger.dim('Could not determine approval status, skipping approval');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (approvalStatus.hasAlreadyApproved) {
|
|
101
|
+
logger.dim('You have already approved this PR');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!approvalStatus.isRequestedReviewer) {
|
|
105
|
+
logger.dim('You are not a requested reviewer on this PR');
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const approved = await github.approvePr(branchName, comment);
|
|
109
|
+
if (!approved) {
|
|
110
|
+
logger.warning('Failed to approve PR, continuing with merge...');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Merge the PR; when branch protections block it, offer an admin override.
|
|
115
|
+
* `gh pr merge` emits a variety of messages depending on the rule that blocked
|
|
116
|
+
* the merge, and suggests `--admin` when admin privileges can resolve it.
|
|
117
|
+
*/
|
|
118
|
+
async function mergeWithProtectionFallback(branchName) {
|
|
119
|
+
const mergeResult = await github.mergePr(branchName);
|
|
120
|
+
if (mergeResult.success) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const errorText = mergeResult.error?.toLowerCase() ?? '';
|
|
124
|
+
const isBranchProtectionError = errorText.includes('branch protection') ||
|
|
125
|
+
errorText.includes('required status check') ||
|
|
126
|
+
errorText.includes('required review') ||
|
|
127
|
+
errorText.includes('pull request review is required') ||
|
|
128
|
+
errorText.includes('base branch policy') ||
|
|
129
|
+
errorText.includes('policy prohibits the merge') ||
|
|
130
|
+
errorText.includes('--admin');
|
|
131
|
+
if (!isBranchProtectionError) {
|
|
132
|
+
throw new Error(`Failed to merge PR: ${mergeResult.error}`);
|
|
133
|
+
}
|
|
134
|
+
logger.warning('Merge failed due to branch protections');
|
|
135
|
+
logger.dim(mergeResult.error ?? '');
|
|
136
|
+
const override = await promptConfirm('Would you like to override branch protections with admin privileges?', { default: false });
|
|
137
|
+
if (!override) {
|
|
138
|
+
throw new Error('Merge cancelled by user');
|
|
139
|
+
}
|
|
140
|
+
const adminMergeResult = await github.mergePrWithAdminOverride(branchName);
|
|
141
|
+
if (!adminMergeResult.success) {
|
|
142
|
+
throw new Error(`Failed to merge PR with admin override: ${adminMergeResult.error}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function deleteBranchQuietly(branchName) {
|
|
146
|
+
try {
|
|
147
|
+
await git.deleteBranch(branchName, true);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// The remote branch may already have been deleted automatically after the merge
|
|
151
|
+
logger.dim(`Note: Branch ${branchName} may have been automatically deleted after merge`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function printCompletion(baseBranch, projectItemUrl) {
|
|
155
|
+
logger.newline();
|
|
156
|
+
logger.success('Workflow complete!');
|
|
157
|
+
logger.newline();
|
|
158
|
+
logger.hint(`PR merged into ${baseBranch}`);
|
|
159
|
+
logger.hint(`Project item: ${projectItemUrl}`);
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=approve-pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve-pr.js","sourceRoot":"","sources":["../../../src/services/workflow-handlers/approve-pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WorkflowStateHandler } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Entering "Dev Implementation": the agent's work is committed and pushed and a
|
|
4
|
+
* PR exists, so a developer can test, clean up and finish the work. Afterwards
|
|
5
|
+
* the worktree is removed when `removeWorktreeAtState` says so.
|
|
6
|
+
*/
|
|
7
|
+
export declare const devImplementationHandler: WorkflowStateHandler;
|
|
8
|
+
//# sourceMappingURL=dev-implementation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-implementation.d.ts","sourceRoot":"","sources":["../../../src/services/workflow-handlers/dev-implementation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,oBA0BtC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { logger } from '../../lib/logger.js';
|
|
2
|
+
import { WorkflowStates } from '../../lib/workflow-states.js';
|
|
3
|
+
import * as git from '../git.js';
|
|
4
|
+
import * as github from '../github.js';
|
|
5
|
+
import { removeWorktreeForWorkflowState } from '../worktree.js';
|
|
6
|
+
import { requireBranch, requireWorkingPath } from '../workflow-engine.js';
|
|
7
|
+
/**
|
|
8
|
+
* Entering "Dev Implementation": the agent's work is committed and pushed and a
|
|
9
|
+
* PR exists, so a developer can test, clean up and finish the work. Afterwards
|
|
10
|
+
* the worktree is removed when `removeWorktreeAtState` says so.
|
|
11
|
+
*/
|
|
12
|
+
export const devImplementationHandler = {
|
|
13
|
+
state: WorkflowStates.DevImplementation,
|
|
14
|
+
async prepare(context) {
|
|
15
|
+
const branchName = requireBranch(context);
|
|
16
|
+
requireWorkingPath(context, 'commit and push the implementation');
|
|
17
|
+
if (await git.hasUncommittedChanges()) {
|
|
18
|
+
await git.commitAllChanges(`Agent Implementation of ${context.projectItemUrl} on ${branchName}`);
|
|
19
|
+
}
|
|
20
|
+
await git.pushToRemote(branchName);
|
|
21
|
+
const prInfo = await github.createPrIfNeeded(branchName, context.baseBranch, context.projectItemUrl);
|
|
22
|
+
if (prInfo) {
|
|
23
|
+
logger.hint(`PR: ${prInfo.url}`);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async complete(context) {
|
|
27
|
+
const branchName = requireBranch(context);
|
|
28
|
+
await removeWorktreeForWorkflowState(WorkflowStates.DevImplementation, branchName, context.projectItemUrl, { checkoutBranchInMainRepo: false });
|
|
29
|
+
logger.newline();
|
|
30
|
+
logger.success('Transitioned to Dev Implementation');
|
|
31
|
+
logger.hint('When ready for review, run: idea1 ready-for-approval [--assignee <username>] [--reviewers <user1,user2>]');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=dev-implementation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-implementation.js","sourceRoot":"","sources":["../../../src/services/workflow-handlers/dev-implementation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE1E;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAyB;IAC5D,KAAK,EAAE,cAAc,CAAC,iBAAiB;IAEvC,KAAK,CAAC,OAAO,CAAC,OAAO;QACnB,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,kBAAkB,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QAElE,IAAI,MAAM,GAAG,CAAC,qBAAqB,EAAE,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,gBAAgB,CAAC,2BAA2B,OAAO,CAAC,cAAc,OAAO,UAAU,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAEnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;QACrG,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAO;QACpB,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,8BAA8B,CAAC,cAAc,CAAC,iBAAiB,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhJ,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,0GAA0G,CAAC,CAAC;IAC1H,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandOption, WorkflowState, WorkflowStateHandler } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Side effects attached to entering a workflow state. States without an entry
|
|
4
|
+
* are status-only: entering them records the state and nothing else.
|
|
5
|
+
*/
|
|
6
|
+
export declare const HANDLERS_BY_STATE: ReadonlyMap<WorkflowState, WorkflowStateHandler>;
|
|
7
|
+
/**
|
|
8
|
+
* The handler for a state, for commands dedicated to one transition.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getHandler(state: WorkflowState): WorkflowStateHandler;
|
|
11
|
+
/**
|
|
12
|
+
* Every handler option, for commands that can reach any state (e.g. `next`).
|
|
13
|
+
* The options are declared so they parse on the command line, but marked
|
|
14
|
+
* inapplicable so the resolver never prompts for them up front — the engine
|
|
15
|
+
* prompts for the ones the actual transition needs.
|
|
16
|
+
*/
|
|
17
|
+
export declare function deferredHandlerOptions(): CommandOption[];
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/workflow-handlers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAM/F;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,aAAa,EAAE,oBAAoB,CAG9E,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,oBAAoB,CAMrE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,EAAE,CAQxD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { agentImplementationHandler } from './agent-implementation.js';
|
|
2
|
+
import { devImplementationHandler } from './dev-implementation.js';
|
|
3
|
+
import { readyForApprovalHandler } from './ready-for-approval.js';
|
|
4
|
+
import { approvePrHandler } from './approve-pr.js';
|
|
5
|
+
/**
|
|
6
|
+
* Side effects attached to entering a workflow state. States without an entry
|
|
7
|
+
* are status-only: entering them records the state and nothing else.
|
|
8
|
+
*/
|
|
9
|
+
export const HANDLERS_BY_STATE = new Map([agentImplementationHandler, devImplementationHandler, readyForApprovalHandler, approvePrHandler]
|
|
10
|
+
.map(handler => [handler.state, handler]));
|
|
11
|
+
/**
|
|
12
|
+
* The handler for a state, for commands dedicated to one transition.
|
|
13
|
+
*/
|
|
14
|
+
export function getHandler(state) {
|
|
15
|
+
const handler = HANDLERS_BY_STATE.get(state);
|
|
16
|
+
if (!handler) {
|
|
17
|
+
throw new Error(`No workflow handler is registered for "${state}"`);
|
|
18
|
+
}
|
|
19
|
+
return handler;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Every handler option, for commands that can reach any state (e.g. `next`).
|
|
23
|
+
* The options are declared so they parse on the command line, but marked
|
|
24
|
+
* inapplicable so the resolver never prompts for them up front — the engine
|
|
25
|
+
* prompts for the ones the actual transition needs.
|
|
26
|
+
*/
|
|
27
|
+
export function deferredHandlerOptions() {
|
|
28
|
+
const options = [];
|
|
29
|
+
for (const handler of HANDLERS_BY_STATE.values()) {
|
|
30
|
+
for (const option of handler.options ?? []) {
|
|
31
|
+
options.push({ ...option, dependsOn: () => false });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return options;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/workflow-handlers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAqD,IAAI,GAAG,CACxF,CAAC,0BAA0B,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,gBAAgB,CAAC;KAC9F,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAC5C,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0CAA0C,KAAK,GAAG,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;QACjD,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WorkflowStateHandler } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Entering "Needs Approval for Release": the PR is complete and gets its
|
|
4
|
+
* reviewers and assignee. Afterwards the worktree is removed when
|
|
5
|
+
* `removeWorktreeAtState` says so (this state is the default).
|
|
6
|
+
*/
|
|
7
|
+
export declare const readyForApprovalHandler: WorkflowStateHandler;
|
|
8
|
+
//# sourceMappingURL=ready-for-approval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ready-for-approval.d.ts","sourceRoot":"","sources":["../../../src/services/workflow-handlers/ready-for-approval.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,oBAsDrC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { logger } from '../../lib/logger.js';
|
|
2
|
+
import { WorkflowStates } from '../../lib/workflow-states.js';
|
|
3
|
+
import * as git from '../git.js';
|
|
4
|
+
import * as github from '../github.js';
|
|
5
|
+
import { removeWorktreeForWorkflowState } from '../worktree.js';
|
|
6
|
+
import { requireBranch } from '../workflow-engine.js';
|
|
7
|
+
/**
|
|
8
|
+
* Entering "Needs Approval for Release": the PR is complete and gets its
|
|
9
|
+
* reviewers and assignee. Afterwards the worktree is removed when
|
|
10
|
+
* `removeWorktreeAtState` says so (this state is the default).
|
|
11
|
+
*/
|
|
12
|
+
export const readyForApprovalHandler = {
|
|
13
|
+
state: WorkflowStates.NeedsApprovalForRelease,
|
|
14
|
+
options: [
|
|
15
|
+
{
|
|
16
|
+
longName: 'assignee',
|
|
17
|
+
shortName: 'a',
|
|
18
|
+
description: 'Who to assign the PR to',
|
|
19
|
+
choices: 'github-members',
|
|
20
|
+
allowNone: true
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
longName: 'reviewers',
|
|
24
|
+
shortName: 'r',
|
|
25
|
+
description: 'Who to request a review from (select any number)',
|
|
26
|
+
choices: 'github-members',
|
|
27
|
+
multiSelect: true
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
async prepare(context) {
|
|
31
|
+
const branchName = requireBranch(context);
|
|
32
|
+
const assignee = context.options['assignee'] ?? '';
|
|
33
|
+
const reviewers = (context.options['reviewers'] ?? '')
|
|
34
|
+
.split(',')
|
|
35
|
+
.map(name => name.trim())
|
|
36
|
+
.filter(name => name.length > 0);
|
|
37
|
+
if (context.workingPath) {
|
|
38
|
+
await git.ensureBranchUpToDate();
|
|
39
|
+
}
|
|
40
|
+
const prInfo = await github.checkPrExists(branchName, context.baseBranch);
|
|
41
|
+
if (!prInfo) {
|
|
42
|
+
throw new Error('No PR exists for this branch. Move the item to Dev Implementation first (idea1 next), which creates the PR.');
|
|
43
|
+
}
|
|
44
|
+
logger.info(`PR #${prInfo.number} found`);
|
|
45
|
+
await github.assignReviewers(branchName, reviewers);
|
|
46
|
+
await github.assignAssignee(branchName, assignee);
|
|
47
|
+
if (reviewers.length === 0 && !assignee) {
|
|
48
|
+
logger.dim('No reviewers requested and no assignee set.');
|
|
49
|
+
}
|
|
50
|
+
logger.hint(`PR: ${prInfo.url}`);
|
|
51
|
+
},
|
|
52
|
+
async complete(context) {
|
|
53
|
+
const branchName = requireBranch(context);
|
|
54
|
+
await removeWorktreeForWorkflowState(WorkflowStates.NeedsApprovalForRelease, branchName, context.projectItemUrl, { checkoutBranchInMainRepo: false });
|
|
55
|
+
logger.newline();
|
|
56
|
+
logger.success('PR is ready for approval');
|
|
57
|
+
logger.hint('When approved, run: idea1 approve-pr');
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=ready-for-approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ready-for-approval.js","sourceRoot":"","sources":["../../../src/services/workflow-handlers/ready-for-approval.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAyB;IAC3D,KAAK,EAAE,cAAc,CAAC,uBAAuB;IAC7C,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,UAAU;YACpB,SAAS,EAAE,GAAG;YACd,WAAW,EAAE,yBAAyB;YACtC,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,IAAI;SAChB;QACD;YACE,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,GAAG;YACd,WAAW,EAAE,kDAAkD;YAC/D,OAAO,EAAE,gBAAgB;YACzB,WAAW,EAAE,IAAI;SAClB;KACF;IAED,KAAK,CAAC,OAAO,CAAC,OAAO;QACnB,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;aACnD,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEnC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACnC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6GAA6G,CAAC,CAAC;QACjI,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,MAAM,QAAQ,CAAC,CAAC;QAE1C,MAAM,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAElD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAO;QACpB,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,8BAA8B,CAAC,cAAc,CAAC,uBAAuB,EAAE,UAAU,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC;QAEtJ,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC;CACF,CAAC"}
|
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
import type { WorkflowState,
|
|
2
|
-
/**
|
|
3
|
-
* Whether a workflow state is the target state or a later one in the sequence
|
|
4
|
-
*/
|
|
5
|
-
export declare function isStateAtOrAfter(state: WorkflowState, targetState: WorkflowState): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Validate if a transition is valid from the current workflow state
|
|
8
|
-
*/
|
|
9
|
-
export declare function validateTransition(transition: WorkflowTransition): Promise<{
|
|
10
|
-
valid: boolean;
|
|
11
|
-
currentState: WorkflowState | null;
|
|
12
|
-
error?: string;
|
|
13
|
-
}>;
|
|
14
|
-
/**
|
|
15
|
-
* Get the next available transition from the current workflow state
|
|
16
|
-
*/
|
|
17
|
-
export declare function getNextTransition(): Promise<WorkflowTransition | null>;
|
|
18
|
-
/**
|
|
19
|
-
* Ensure all workflow preconditions are met before proceeding
|
|
20
|
-
*/
|
|
21
|
-
export declare function ensureWorkflowPreconditions(): Promise<void>;
|
|
1
|
+
import type { WorkflowState, PrInfo } from '../types/index.js';
|
|
22
2
|
/**
|
|
23
3
|
* Get comprehensive workflow status for the current branch
|
|
24
4
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAK/D;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC,CAgCD"}
|
|
@@ -1,72 +1,6 @@
|
|
|
1
1
|
import * as git from './git.js';
|
|
2
2
|
import * as github from './github.js';
|
|
3
|
-
import {
|
|
4
|
-
/**
|
|
5
|
-
* Valid workflow state transitions
|
|
6
|
-
*/
|
|
7
|
-
const VALID_TRANSITIONS = {
|
|
8
|
-
'Build Spec in Progress': [],
|
|
9
|
-
'Refinement - Build Spec': [],
|
|
10
|
-
'Refinement - Implementation': [],
|
|
11
|
-
'Ready for Agent Implementation': [],
|
|
12
|
-
'Agent Implementation': ['start-dev-implementation'],
|
|
13
|
-
'Dev Implementation': ['ready-for-approval'],
|
|
14
|
-
'Needs Approval for Release': ['approve-pr'],
|
|
15
|
-
'Approved and Merged': [],
|
|
16
|
-
'Released': []
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Whether a workflow state is the target state or a later one in the sequence
|
|
20
|
-
*/
|
|
21
|
-
export function isStateAtOrAfter(state, targetState) {
|
|
22
|
-
return WORKFLOW_STATE_ORDER.indexOf(state) >= WORKFLOW_STATE_ORDER.indexOf(targetState);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Validate if a transition is valid from the current workflow state
|
|
26
|
-
*/
|
|
27
|
-
export async function validateTransition(transition) {
|
|
28
|
-
const currentState = normalizeWorkflowState(await git.getWorkflowState());
|
|
29
|
-
if (!currentState) {
|
|
30
|
-
return {
|
|
31
|
-
valid: false,
|
|
32
|
-
currentState: null,
|
|
33
|
-
error: 'No workflow state found. This branch may not be under workflow management.'
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
const validTransitions = VALID_TRANSITIONS[currentState];
|
|
37
|
-
if (!validTransitions || !validTransitions.includes(transition)) {
|
|
38
|
-
const availableTransitions = validTransitions && validTransitions.length > 0
|
|
39
|
-
? `Available transitions: ${validTransitions.join(', ')}`
|
|
40
|
-
: 'No transitions available from this state.';
|
|
41
|
-
return {
|
|
42
|
-
valid: false,
|
|
43
|
-
currentState,
|
|
44
|
-
error: `Cannot perform '${transition}' from state '${currentState}'. ${availableTransitions}`
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
return { valid: true, currentState };
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Get the next available transition from the current workflow state
|
|
51
|
-
*/
|
|
52
|
-
export async function getNextTransition() {
|
|
53
|
-
const currentState = normalizeWorkflowState(await git.getWorkflowState());
|
|
54
|
-
if (!currentState) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
const validTransitions = VALID_TRANSITIONS[currentState];
|
|
58
|
-
return validTransitions && validTransitions.length > 0 ? validTransitions[0] : null;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Ensure all workflow preconditions are met before proceeding
|
|
62
|
-
*/
|
|
63
|
-
export async function ensureWorkflowPreconditions() {
|
|
64
|
-
const projectItemUrl = await git.getProjectItemUrl();
|
|
65
|
-
if (!projectItemUrl) {
|
|
66
|
-
throw new Error('This branch is not under workflow management. Start with: idea1 start-project-item <url>');
|
|
67
|
-
}
|
|
68
|
-
await git.ensureBranchUpToDate();
|
|
69
|
-
}
|
|
3
|
+
import { normalizeWorkflowState } from '../lib/workflow-states.js';
|
|
70
4
|
/**
|
|
71
5
|
* Get comprehensive workflow status for the current branch
|
|
72
6
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAqC;IAO3E,MAAM,CAAC,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,GAC/E,MAAM,OAAO,CAAC,UAAU,CAAC;QACvB,GAAG,CAAC,gBAAgB,EAAE;QACtB,GAAG,CAAC,aAAa,EAAE;QACnB,GAAG,CAAC,iBAAiB,EAAE;QACvB,GAAG,CAAC,gBAAgB,EAAE;KACvB,CAAC,CAAC;IAEL,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,MAAM,cAAc,GAAG,oBAAoB,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACvG,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,KAAK,WAAW;QAC9D,CAAC,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,KAAK,CAAC;QACnD,CAAC,CAAC,IAAI,CAAC;IAET,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,OAAO,EAAE,aAAa,KAAK,KAAK,IAAI,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;QACtC,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM;QACN,UAAU;QACV,cAAc;QACd,aAAa;QACb,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClaudePermissionMode, ClaudeEntryPointMode, ClaudeEffortLevel, IsolationMode, WorkflowState } from '../types/index.js';
|
|
1
|
+
import type { ClaudePermissionMode, ClaudeEntryPointMode, ClaudeEffortLevel, ClaudeModel, IsolationMode, WorkflowState } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Run the setup-worktree hook if defined in .idea1/settings.json
|
|
4
4
|
*/
|
|
@@ -20,19 +20,11 @@ export declare function removeWorktreeForWorkflowState(state: WorkflowState, bra
|
|
|
20
20
|
checkoutBranchInMainRepo: boolean;
|
|
21
21
|
}): Promise<void>;
|
|
22
22
|
/**
|
|
23
|
-
* Resolve the
|
|
24
|
-
* 1. CLI argument (if provided)
|
|
25
|
-
* 2. User-level XDG config
|
|
26
|
-
* 3. Repo-level .idea1/settings.json
|
|
27
|
-
* 4. Hardcoded default
|
|
23
|
+
* Resolve the prefix new branches are created under
|
|
28
24
|
*/
|
|
29
25
|
export declare function resolveBranchPrefix(cliPrefix?: string): Promise<string>;
|
|
30
26
|
/**
|
|
31
|
-
* Resolve the
|
|
32
|
-
* 1. CLI argument (if provided)
|
|
33
|
-
* 2. User-level XDG config
|
|
34
|
-
* 3. Repo-level .idea1/settings.json
|
|
35
|
-
* 4. Hardcoded default
|
|
27
|
+
* Resolve the branch new branches are cut from and their pull requests target
|
|
36
28
|
*/
|
|
37
29
|
export declare function resolveBaseBranch(cliBaseBranch?: string): Promise<string>;
|
|
38
30
|
/**
|
|
@@ -60,48 +52,46 @@ export declare function listExistingIntegrationBranches(): Promise<string[]>;
|
|
|
60
52
|
* Extract the integration name from a full integration branch name
|
|
61
53
|
*/
|
|
62
54
|
export declare function extractIntegrationName(fullBranchName: string): Promise<string>;
|
|
63
|
-
/**
|
|
64
|
-
* Prepare repository for worktree creation with a pre-computed full branch name.
|
|
65
|
-
* The sourceBranch is the branch to base the new branch off of (may differ from baseBranch for PRs).
|
|
66
|
-
*/
|
|
67
|
-
export declare function prepareBranchForWorktreeWithFullName(fullBranchName: string, shortBranchName: string, sourceBranchName: string, baseBranchName: string): Promise<string>;
|
|
68
55
|
/**
|
|
69
56
|
* Ensure an integration branch exists, creating it from baseBranch if needed
|
|
70
57
|
*/
|
|
71
58
|
export declare function ensureIntegrationBranch(integrationBranchName: string, baseBranchName: string): Promise<void>;
|
|
72
59
|
/**
|
|
73
|
-
* Options shared by every
|
|
60
|
+
* Options shared by every path that launches a Claude session on a branch.
|
|
74
61
|
*/
|
|
75
62
|
export interface BranchSetupOptions {
|
|
76
63
|
projectItemUrl?: string;
|
|
77
64
|
permissionMode?: ClaudePermissionMode;
|
|
65
|
+
model?: ClaudeModel;
|
|
78
66
|
effort?: ClaudeEffortLevel;
|
|
79
67
|
claudeEntryPointMode?: ClaudeEntryPointMode;
|
|
80
68
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Set up the working environment for a freshly-prepared branch, in whichever
|
|
83
|
-
* location the user chose: an isolated worktree or the main repository.
|
|
84
|
-
* Returns the directory the branch is checked out in.
|
|
85
|
-
*/
|
|
86
|
-
export declare function setupBranchEnvironment(isolationMode: IsolationMode, fullBranchName: string, shortBranchName: string, baseBranchName: string, options?: BranchSetupOptions): Promise<string>;
|
|
87
69
|
/**
|
|
88
70
|
* Setup worktree isolation - creates worktree, runs hooks, optionally launches Claude
|
|
89
71
|
*/
|
|
90
72
|
export declare function setupWorktreeIsolation(fullBranchName: string, shortBranchName: string, baseBranchName: string, options?: BranchSetupOptions): Promise<string>;
|
|
91
73
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
74
|
+
* Ensure a branch has a local working environment: reuse the checkout that
|
|
75
|
+
* already holds it, or create one — an isolated worktree, or the branch checked
|
|
76
|
+
* out in the main repository (creating a local tracking branch when it exists
|
|
77
|
+
* only on origin). The repo-specific setup hook runs for newly created
|
|
78
|
+
* worktrees only; the main repository is already set up for development.
|
|
79
|
+
* Returns the directory the branch is checked out in.
|
|
80
|
+
*/
|
|
81
|
+
export declare function ensureBranchEnvironment(isolationMode: IsolationMode, branchName: string): Promise<{
|
|
82
|
+
workingPath: string;
|
|
83
|
+
created: boolean;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Invoke Claude on a branch's working directory per the entry-point mode, then
|
|
87
|
+
* print the directory path and next-step hint. This is the only place the CLI
|
|
88
|
+
* starts a Claude session that writes code.
|
|
95
89
|
*/
|
|
96
|
-
export declare function
|
|
90
|
+
export declare function launchClaudeForBranch(workingPath: string, options?: BranchSetupOptions): Promise<void>;
|
|
97
91
|
/**
|
|
98
|
-
*
|
|
99
|
-
* worktrees only — the main repository is already set up), invoke Claude per
|
|
100
|
-
* the entry-point mode, and print the directory path and next-step hint.
|
|
101
|
-
* Shared by every setup path: new branches (worktree or main repo) and
|
|
102
|
-
* join-project-item (existing branches).
|
|
92
|
+
* Tell the user where the branch is checked out and how to move the workflow on.
|
|
103
93
|
*/
|
|
104
|
-
export declare function
|
|
94
|
+
export declare function printWorkingDirectoryHints(workingPath: string): void;
|
|
105
95
|
/**
|
|
106
96
|
* Prepare repository for worktree creation - validates, fetches, and creates branch
|
|
107
97
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/services/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,iBAAiB,EAAmB,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/services/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAmB,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAanK;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB1E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAejF;AAED;;;;;;;GAOG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE;IAAE,wBAAwB,EAAE,OAAO,CAAA;CAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAoCD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO/E;AAED;;;;;GAKG;AACH,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,MAAM,CAAC,CAOtE;AAkCD;;;GAGG;AACH,wBAAsB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOtH;AAED;;GAEG;AACH,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAazE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBpF;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,qBAAqB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAclH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAgBpD;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhH;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAMpE;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
|