geeto 0.1.1 → 0.3.6

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 (121) hide show
  1. package/README.md +138 -43
  2. package/lib/api/copilot-sdk.d.ts.map +1 -1
  3. package/lib/api/copilot-sdk.js +2 -0
  4. package/lib/api/copilot-sdk.js.map +1 -1
  5. package/lib/api/github.d.ts +91 -0
  6. package/lib/api/github.d.ts.map +1 -0
  7. package/lib/api/github.js +163 -0
  8. package/lib/api/github.js.map +1 -0
  9. package/lib/api/trello.js +1 -1
  10. package/lib/api/trello.js.map +1 -1
  11. package/lib/cli/input.d.ts +1 -0
  12. package/lib/cli/input.d.ts.map +1 -1
  13. package/lib/cli/input.js +349 -0
  14. package/lib/cli/input.js.map +1 -1
  15. package/lib/cli/menu.d.ts +4 -0
  16. package/lib/cli/menu.d.ts.map +1 -1
  17. package/lib/cli/menu.js +452 -31
  18. package/lib/cli/menu.js.map +1 -1
  19. package/lib/core/github-setup.d.ts +8 -0
  20. package/lib/core/github-setup.d.ts.map +1 -0
  21. package/lib/core/github-setup.js +114 -0
  22. package/lib/core/github-setup.js.map +1 -0
  23. package/lib/index.js +291 -29
  24. package/lib/index.js.map +1 -1
  25. package/lib/types/index.d.ts +16 -0
  26. package/lib/types/index.d.ts.map +1 -1
  27. package/lib/utils/branch-naming.js +1 -1
  28. package/lib/utils/branch-naming.js.map +1 -1
  29. package/lib/utils/config.d.ts +17 -1
  30. package/lib/utils/config.d.ts.map +1 -1
  31. package/lib/utils/config.js +65 -1
  32. package/lib/utils/config.js.map +1 -1
  33. package/lib/utils/display.d.ts +20 -0
  34. package/lib/utils/display.d.ts.map +1 -1
  35. package/lib/utils/display.js +84 -21
  36. package/lib/utils/display.js.map +1 -1
  37. package/lib/utils/exec.d.ts +1 -1
  38. package/lib/utils/exec.d.ts.map +1 -1
  39. package/lib/utils/exec.js +2 -2
  40. package/lib/utils/exec.js.map +1 -1
  41. package/lib/utils/git-errors.js +3 -3
  42. package/lib/utils/git-errors.js.map +1 -1
  43. package/lib/utils/git.d.ts +9 -0
  44. package/lib/utils/git.d.ts.map +1 -1
  45. package/lib/utils/git.js +15 -0
  46. package/lib/utils/git.js.map +1 -1
  47. package/lib/utils/logging.d.ts +2 -0
  48. package/lib/utils/logging.d.ts.map +1 -1
  49. package/lib/utils/logging.js +7 -1
  50. package/lib/utils/logging.js.map +1 -1
  51. package/lib/workflows/amend.d.ts +9 -0
  52. package/lib/workflows/amend.d.ts.map +1 -0
  53. package/lib/workflows/amend.js +241 -0
  54. package/lib/workflows/amend.js.map +1 -0
  55. package/lib/workflows/branch.d.ts.map +1 -1
  56. package/lib/workflows/branch.js +46 -1
  57. package/lib/workflows/branch.js.map +1 -1
  58. package/lib/workflows/cherry-pick.d.ts +9 -0
  59. package/lib/workflows/cherry-pick.d.ts.map +1 -0
  60. package/lib/workflows/cherry-pick.js +237 -0
  61. package/lib/workflows/cherry-pick.js.map +1 -0
  62. package/lib/workflows/cleanup.d.ts +1 -1
  63. package/lib/workflows/cleanup.d.ts.map +1 -1
  64. package/lib/workflows/cleanup.js +93 -69
  65. package/lib/workflows/cleanup.js.map +1 -1
  66. package/lib/workflows/commit.d.ts.map +1 -1
  67. package/lib/workflows/commit.js +38 -19
  68. package/lib/workflows/commit.js.map +1 -1
  69. package/lib/workflows/compare.d.ts +9 -0
  70. package/lib/workflows/compare.d.ts.map +1 -0
  71. package/lib/workflows/compare.js +231 -0
  72. package/lib/workflows/compare.js.map +1 -0
  73. package/lib/workflows/history.d.ts +9 -0
  74. package/lib/workflows/history.d.ts.map +1 -0
  75. package/lib/workflows/history.js +194 -0
  76. package/lib/workflows/history.js.map +1 -0
  77. package/lib/workflows/issue.d.ts +9 -0
  78. package/lib/workflows/issue.d.ts.map +1 -0
  79. package/lib/workflows/issue.js +211 -0
  80. package/lib/workflows/issue.js.map +1 -0
  81. package/lib/workflows/main-steps.d.ts.map +1 -1
  82. package/lib/workflows/main-steps.js +39 -13
  83. package/lib/workflows/main-steps.js.map +1 -1
  84. package/lib/workflows/main.d.ts.map +1 -1
  85. package/lib/workflows/main.js +30 -39
  86. package/lib/workflows/main.js.map +1 -1
  87. package/lib/workflows/pr.d.ts +9 -0
  88. package/lib/workflows/pr.d.ts.map +1 -0
  89. package/lib/workflows/pr.js +280 -0
  90. package/lib/workflows/pr.js.map +1 -0
  91. package/lib/workflows/release.d.ts +7 -0
  92. package/lib/workflows/release.d.ts.map +1 -0
  93. package/lib/workflows/release.js +445 -0
  94. package/lib/workflows/release.js.map +1 -0
  95. package/lib/workflows/security-gate.d.ts.map +1 -1
  96. package/lib/workflows/security-gate.js +91 -7
  97. package/lib/workflows/security-gate.js.map +1 -1
  98. package/lib/workflows/settings.d.ts +5 -1
  99. package/lib/workflows/settings.d.ts.map +1 -1
  100. package/lib/workflows/settings.js +62 -3
  101. package/lib/workflows/settings.js.map +1 -1
  102. package/lib/workflows/stash.d.ts +9 -0
  103. package/lib/workflows/stash.d.ts.map +1 -0
  104. package/lib/workflows/stash.js +341 -0
  105. package/lib/workflows/stash.js.map +1 -0
  106. package/lib/workflows/stats.d.ts +9 -0
  107. package/lib/workflows/stats.d.ts.map +1 -0
  108. package/lib/workflows/stats.js +288 -0
  109. package/lib/workflows/stats.js.map +1 -0
  110. package/lib/workflows/switch.d.ts +9 -0
  111. package/lib/workflows/switch.d.ts.map +1 -0
  112. package/lib/workflows/switch.js +154 -0
  113. package/lib/workflows/switch.js.map +1 -0
  114. package/lib/workflows/trello-menu.d.ts.map +1 -1
  115. package/lib/workflows/trello-menu.js +59 -19
  116. package/lib/workflows/trello-menu.js.map +1 -1
  117. package/lib/workflows/undo.d.ts +9 -0
  118. package/lib/workflows/undo.d.ts.map +1 -0
  119. package/lib/workflows/undo.js +464 -0
  120. package/lib/workflows/undo.js.map +1 -0
  121. package/package.json +2 -2
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Elegant commit history viewer
3
+ * Display commit log with a beautiful timeline UI
4
+ */
5
+ import { select } from '../cli/menu.js';
6
+ import { colors } from '../utils/colors.js';
7
+ import { execSilent } from '../utils/exec.js';
8
+ import { getCurrentBranch } from '../utils/git.js';
9
+ import { log } from '../utils/logging.js';
10
+ /**
11
+ * Fetch commits with full details
12
+ */
13
+ const getCommits = (limit, offset = 0) => {
14
+ try {
15
+ const fieldSep = '<<GTO>>';
16
+ const recordSep = '<<END>>';
17
+ const format = [
18
+ '%H', // full hash
19
+ '%h', // short hash
20
+ '%s', // subject
21
+ '%b', // body (may contain newlines)
22
+ '%an', // author name
23
+ '%ci', // date ISO
24
+ '%cr', // relative date
25
+ '%D', // ref names
26
+ '%P', // parent hashes (multiple = merge)
27
+ ].join(fieldSep);
28
+ const output = execSilent(`git log --format="${format}${recordSep}" --skip=${offset} -${limit}`).trim();
29
+ if (!output)
30
+ return [];
31
+ // Split on record separator first (handles multi-line body)
32
+ return output
33
+ .split(recordSep)
34
+ .map((record) => record.trim())
35
+ .filter(Boolean)
36
+ .map((record) => {
37
+ const parts = record.split(fieldSep);
38
+ const parents = (parts[8] ?? '').trim().split(' ').filter(Boolean);
39
+ return {
40
+ hash: parts[0] ?? '',
41
+ shortHash: parts[1] ?? '',
42
+ subject: parts[2] ?? '',
43
+ body: (parts[3] ?? '').trim(),
44
+ author: parts[4] ?? '',
45
+ date: parts[5] ?? '',
46
+ relativeDate: parts[6] ?? '',
47
+ refs: parts[7] ?? '',
48
+ isMerge: parents.length > 1,
49
+ };
50
+ })
51
+ .filter((c) => c.hash !== '');
52
+ }
53
+ catch {
54
+ return [];
55
+ }
56
+ };
57
+ /**
58
+ * Format ref tags (HEAD, branches, tags)
59
+ */
60
+ const formatRefs = (refs) => {
61
+ if (!refs.trim())
62
+ return '';
63
+ const parts = refs.split(',').map((r) => r.trim());
64
+ const formatted = parts.map((ref) => {
65
+ if (ref.startsWith('HEAD')) {
66
+ return `${colors.red}${colors.bright}HEAD${colors.reset}`;
67
+ }
68
+ if (ref.startsWith('tag:')) {
69
+ return `${colors.yellow}🏷 ${ref.replace('tag: ', '')}${colors.reset}`;
70
+ }
71
+ if (ref.includes('origin/')) {
72
+ return `${colors.cyan}${ref}${colors.reset}`;
73
+ }
74
+ return `${colors.green}${ref}${colors.reset}`;
75
+ });
76
+ return ` (${formatted.join(', ')})`;
77
+ };
78
+ /**
79
+ * Render a single commit in timeline style
80
+ */
81
+ const renderCommit = (commit, isLast) => {
82
+ const connector = isLast ? '╰' : '├';
83
+ const pipe = isLast ? ' ' : '│';
84
+ // Merge indicator
85
+ const mergeIcon = commit.isMerge ? `${colors.cyan}⤵${colors.reset} ` : '';
86
+ // Hash + refs
87
+ const hashStr = `${colors.yellow}${commit.shortHash}${colors.reset}`;
88
+ const refStr = formatRefs(commit.refs);
89
+ // Subject line
90
+ console.log(` ${colors.gray}${connector}─${colors.reset} ${mergeIcon}${hashStr}${refStr} ${colors.bright}${commit.subject}${colors.reset}`);
91
+ // Author + date
92
+ console.log(` ${colors.gray}${pipe}${colors.reset} ${colors.blue}${commit.author}${colors.reset} ${colors.gray}· ${commit.relativeDate}${colors.reset}`);
93
+ // Body (if present, show first 2 lines)
94
+ if (commit.body) {
95
+ const bodyLines = commit.body.split('\n').filter(Boolean).slice(0, 2);
96
+ for (const bodyLine of bodyLines) {
97
+ const trimmed = bodyLine.length > 80 ? bodyLine.slice(0, 77) + '...' : bodyLine;
98
+ console.log(` ${colors.gray}${pipe}${colors.reset} ${colors.gray}${trimmed}${colors.reset}`);
99
+ }
100
+ }
101
+ // Spacer between commits
102
+ if (!isLast) {
103
+ console.log(` ${colors.gray}│${colors.reset}`);
104
+ }
105
+ };
106
+ /**
107
+ * Get summary statistics
108
+ */
109
+ const getStats = () => {
110
+ try {
111
+ const total = Number.parseInt(execSilent('git rev-list --count HEAD').trim(), 10);
112
+ const authorsOutput = execSilent('git shortlog -sn HEAD | wc -l').trim();
113
+ const authors = Number.parseInt(authorsOutput, 10);
114
+ const firstDate = execSilent('git log --reverse --format="%cr" -1').trim();
115
+ return { totalCommits: total, authors, firstDate };
116
+ }
117
+ catch {
118
+ return { totalCommits: 0, authors: 0, firstDate: '' };
119
+ }
120
+ };
121
+ /**
122
+ * Interactive commit history viewer
123
+ */
124
+ export const handleHistory = async () => {
125
+ log.banner();
126
+ log.step(`${colors.cyan}Commit History${colors.reset}\n`);
127
+ const current = getCurrentBranch();
128
+ const stats = getStats();
129
+ // Header info box
130
+ const line = '─'.repeat(56);
131
+ console.log(`${colors.cyan}┌${line}┐${colors.reset}`);
132
+ console.log(`${colors.cyan}│${colors.reset} Branch: ${colors.green}${colors.bright}${current}${colors.reset}`);
133
+ console.log(`${colors.cyan}│${colors.reset} Commits: ${colors.yellow}${stats.totalCommits}${colors.reset}` +
134
+ ` Authors: ${colors.blue}${stats.authors}${colors.reset}` +
135
+ (stats.firstDate ? ` Since: ${colors.gray}${stats.firstDate}${colors.reset}` : ''));
136
+ console.log(`${colors.cyan}└${line}┘${colors.reset}`);
137
+ const PAGE_SIZE = 15;
138
+ let offset = 0;
139
+ let keepGoing = true;
140
+ while (keepGoing) {
141
+ const commits = getCommits(PAGE_SIZE, offset);
142
+ if (commits.length === 0 && offset === 0) {
143
+ console.log('');
144
+ log.warn('No commits found.');
145
+ return;
146
+ }
147
+ if (commits.length === 0) {
148
+ console.log('');
149
+ log.info('No more commits.');
150
+ return;
151
+ }
152
+ // Timeline header
153
+ console.log('');
154
+ if (offset === 0) {
155
+ console.log(` ${colors.gray}╭── Timeline ──${colors.reset}`);
156
+ }
157
+ else {
158
+ console.log(` ${colors.gray}│ ... continued${colors.reset}`);
159
+ }
160
+ console.log(` ${colors.gray}│${colors.reset}`);
161
+ // Render each commit
162
+ const isLastPage = commits.length < PAGE_SIZE;
163
+ for (const [i, commit] of commits.entries()) {
164
+ const isLast = isLastPage && i === commits.length - 1;
165
+ renderCommit(commit, isLast);
166
+ }
167
+ if (isLastPage) {
168
+ console.log(` ${colors.gray} (end of history)${colors.reset}`);
169
+ console.log('');
170
+ return;
171
+ }
172
+ // Pagination menu
173
+ console.log('');
174
+ const action = await select('', [
175
+ {
176
+ label: `Load more (${offset + PAGE_SIZE + 1}-${offset + PAGE_SIZE * 2})`,
177
+ value: 'more',
178
+ },
179
+ { label: 'Done', value: 'done' },
180
+ ]);
181
+ switch (action) {
182
+ case 'more': {
183
+ offset += PAGE_SIZE;
184
+ break;
185
+ }
186
+ default: {
187
+ keepGoing = false;
188
+ break;
189
+ }
190
+ }
191
+ }
192
+ console.log('');
193
+ };
194
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/workflows/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Create GitHub Issue workflow
3
+ * Interactive issue creation from CLI
4
+ */
5
+ /**
6
+ * Interactive Create Issue workflow
7
+ */
8
+ export declare const handleCreateIssue: () => Promise<void>;
9
+ //# sourceMappingURL=issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/workflows/issue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CA0NtD,CAAA"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Create GitHub Issue workflow
3
+ * Interactive issue creation from CLI
4
+ */
5
+ import { createIssue, listLabels, parseRepoFromUrl } from '../api/github.js';
6
+ import { askQuestion, confirm } from '../cli/input.js';
7
+ import { multiSelect, select } from '../cli/menu.js';
8
+ import { setupGithubConfigInteractive } from '../core/github-setup.js';
9
+ import { colors } from '../utils/colors.js';
10
+ import { hasGithubConfig } from '../utils/config.js';
11
+ import { execSilent } from '../utils/exec.js';
12
+ import { log } from '../utils/logging.js';
13
+ /**
14
+ * Interactive Create Issue workflow
15
+ */
16
+ export const handleCreateIssue = async () => {
17
+ log.banner();
18
+ log.step(`${colors.cyan}Create GitHub Issue${colors.reset}\n`);
19
+ // Check GitHub config
20
+ if (!hasGithubConfig()) {
21
+ const ok = setupGithubConfigInteractive();
22
+ if (!ok) {
23
+ log.info('Setup cancelled. Run --setup-github later.');
24
+ return;
25
+ }
26
+ console.log('');
27
+ }
28
+ // Resolve repo info from remote
29
+ let remoteUrl = '';
30
+ try {
31
+ remoteUrl = execSilent('git remote get-url origin').trim();
32
+ }
33
+ catch {
34
+ log.error('No git remote "origin" found.');
35
+ log.info('Add a remote: git remote add origin <url>');
36
+ return;
37
+ }
38
+ const repoInfo = parseRepoFromUrl(remoteUrl);
39
+ if (!repoInfo) {
40
+ log.error('Could not parse GitHub owner/repo from remote URL.');
41
+ log.info(`Remote: ${remoteUrl}`);
42
+ return;
43
+ }
44
+ log.info(`Repo: ${colors.cyan}${repoInfo.owner}/${repoInfo.repo}${colors.reset}\n`);
45
+ // Issue Title
46
+ if (process.stdin.isTTY) {
47
+ process.stdin.setRawMode(false);
48
+ }
49
+ const title = askQuestion('Issue title: ').trim();
50
+ if (!title) {
51
+ log.error('Title is required.');
52
+ return;
53
+ }
54
+ // Issue Body
55
+ console.log('');
56
+ const bodyChoice = await select('Issue description:', [
57
+ { label: 'Write description', value: 'write' },
58
+ { label: 'Use template (Bug Report)', value: 'bug' },
59
+ { label: 'Use template (Feature Request)', value: 'feature' },
60
+ { label: 'Empty (no description)', value: 'empty' },
61
+ ]);
62
+ let body = '';
63
+ switch (bodyChoice) {
64
+ case 'write': {
65
+ if (process.stdin.isTTY) {
66
+ process.stdin.setRawMode(false);
67
+ }
68
+ body = askQuestion('Description: ').trim();
69
+ break;
70
+ }
71
+ case 'bug': {
72
+ body = [
73
+ '## Bug Report',
74
+ '',
75
+ '### Description',
76
+ 'A clear description of what the bug is.',
77
+ '',
78
+ '### Steps to Reproduce',
79
+ '1. ',
80
+ '2. ',
81
+ '3. ',
82
+ '',
83
+ '### Expected Behavior',
84
+ '',
85
+ '',
86
+ '### Actual Behavior',
87
+ '',
88
+ '',
89
+ '### Environment',
90
+ `- OS: ${process.platform}`,
91
+ `- Node: ${process.version}`,
92
+ ].join('\n');
93
+ log.info('Bug report template applied. Edit in GitHub after creation.');
94
+ break;
95
+ }
96
+ case 'feature': {
97
+ body = [
98
+ '## Feature Request',
99
+ '',
100
+ '### Description',
101
+ 'A clear description of the feature you want.',
102
+ '',
103
+ '### Motivation',
104
+ 'Why is this feature needed?',
105
+ '',
106
+ '### Proposed Solution',
107
+ '',
108
+ '',
109
+ '### Alternatives Considered',
110
+ '',
111
+ ].join('\n');
112
+ log.info('Feature request template applied. Edit in GitHub after creation.');
113
+ break;
114
+ }
115
+ default: {
116
+ body = '';
117
+ break;
118
+ }
119
+ }
120
+ // Labels
121
+ console.log('');
122
+ const spinner = log.spinner();
123
+ spinner.start('Fetching labels...');
124
+ const labels = await listLabels(repoInfo.owner, repoInfo.repo);
125
+ spinner.stop();
126
+ let selectedLabels = [];
127
+ if (labels.length > 0) {
128
+ const labelOptions = labels.map((l) => ({
129
+ label: `${l.name}${l.description ? ` ${colors.gray}— ${l.description}${colors.reset}` : ''}`,
130
+ value: l.name,
131
+ }));
132
+ selectedLabels = await multiSelect('Add labels (optional):', labelOptions);
133
+ }
134
+ // Assignees
135
+ console.log('');
136
+ const assignChoice = await select('Assign to:', [
137
+ { label: 'No one', value: 'none' },
138
+ { label: 'Me (repo owner)', value: 'me' },
139
+ { label: 'Custom username', value: 'custom' },
140
+ ]);
141
+ let assignees = [];
142
+ switch (assignChoice) {
143
+ case 'me': {
144
+ assignees = [repoInfo.owner];
145
+ break;
146
+ }
147
+ case 'custom': {
148
+ if (process.stdin.isTTY) {
149
+ process.stdin.setRawMode(false);
150
+ }
151
+ const username = askQuestion('GitHub username: ').trim();
152
+ if (username)
153
+ assignees = [username];
154
+ break;
155
+ }
156
+ default: {
157
+ break;
158
+ }
159
+ }
160
+ // Summary
161
+ console.log('');
162
+ console.log(`${colors.cyan}┌──────────────────────────────────────────────┐${colors.reset}`);
163
+ console.log(`${colors.cyan}│${colors.reset} ${colors.bright}Issue Summary${colors.reset}`);
164
+ console.log(`${colors.cyan}├──────────────────────────────────────────────┤${colors.reset}`);
165
+ console.log(`${colors.cyan}│${colors.reset} Title: ${colors.bright}${title}${colors.reset}`);
166
+ if (body) {
167
+ const bodyPreview = body.length > 50 ? body.slice(0, 50) + '...' : body;
168
+ const cleanPreview = bodyPreview.replaceAll('\n', ' ');
169
+ console.log(`${colors.cyan}│${colors.reset} Body: ${colors.gray}${cleanPreview}${colors.reset}`);
170
+ }
171
+ if (selectedLabels.length > 0) {
172
+ console.log(`${colors.cyan}│${colors.reset} Labels: ${colors.yellow}${selectedLabels.join(', ')}${colors.reset}`);
173
+ }
174
+ if (assignees.length > 0) {
175
+ console.log(`${colors.cyan}│${colors.reset} Assignee: ${colors.green}${assignees.join(', ')}${colors.reset}`);
176
+ }
177
+ console.log(`${colors.cyan}└──────────────────────────────────────────────┘${colors.reset}`);
178
+ console.log('');
179
+ const proceed = confirm('Create this issue?');
180
+ if (!proceed) {
181
+ log.info('Cancelled.');
182
+ return;
183
+ }
184
+ console.log('');
185
+ // Create Issue
186
+ const issueSpinner = log.spinner();
187
+ issueSpinner.start('Creating issue...');
188
+ const issue = await createIssue({
189
+ owner: repoInfo.owner,
190
+ repo: repoInfo.repo,
191
+ title,
192
+ body,
193
+ labels: selectedLabels,
194
+ assignees,
195
+ });
196
+ if (issue) {
197
+ issueSpinner.succeed('Issue created!');
198
+ console.log('');
199
+ console.log(` ${colors.green}#${issue.number}${colors.reset} ${issue.title}`);
200
+ console.log(` ${colors.cyan}${issue.html_url}${colors.reset}`);
201
+ // OSC 8 clickable link
202
+ console.log('');
203
+ console.log(` \u001B]8;;${issue.html_url}\u0007` +
204
+ `${colors.cyan}Open in browser →${colors.reset}` +
205
+ `\u001B]8;;\u0007`);
206
+ }
207
+ else {
208
+ issueSpinner.fail('Failed to create issue');
209
+ }
210
+ };
211
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/workflows/issue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,IAAmB,EAAE;IACzD,GAAG,CAAC,MAAM,EAAE,CAAA;IACZ,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,sBAAsB,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;IAE9D,sBAAsB;IACtB,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,4BAA4B,EAAE,CAAA;QACzC,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;YACtD,OAAM;QACR,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjB,CAAC;IAED,gCAAgC;IAChC,IAAI,SAAS,GAAG,EAAE,CAAA;IAClB,IAAI,CAAC;QACH,SAAS,GAAG,UAAU,CAAC,2BAA2B,CAAC,CAAC,IAAI,EAAE,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC1C,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;QACrD,OAAM;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAA;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,GAAG,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAA;QAC/D,GAAG,CAAC,IAAI,CAAC,WAAW,SAAS,EAAE,CAAC,CAAA;QAChC,OAAM;IACR,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;IAEnF,cAAc;IACd,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAA;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;QAC/B,OAAM;IACR,CAAC;IAED,aAAa;IACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,oBAAoB,EAAE;QACpD,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,EAAE;QAC9C,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,KAAK,EAAE;QACpD,EAAE,KAAK,EAAE,gCAAgC,EAAE,KAAK,EAAE,SAAS,EAAE;QAC7D,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE;KACpD,CAAC,CAAA;IAEF,IAAI,IAAI,GAAG,EAAE,CAAA;IAEb,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;YACjC,CAAC;YACD,IAAI,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAA;YAC1C,MAAK;QACP,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,GAAG;gBACL,eAAe;gBACf,EAAE;gBACF,iBAAiB;gBACjB,yCAAyC;gBACzC,EAAE;gBACF,wBAAwB;gBACxB,KAAK;gBACL,KAAK;gBACL,KAAK;gBACL,EAAE;gBACF,uBAAuB;gBACvB,EAAE;gBACF,EAAE;gBACF,qBAAqB;gBACrB,EAAE;gBACF,EAAE;gBACF,iBAAiB;gBACjB,SAAS,OAAO,CAAC,QAAQ,EAAE;gBAC3B,WAAW,OAAO,CAAC,OAAO,EAAE;aAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACZ,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAA;YACvE,MAAK;QACP,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,IAAI,GAAG;gBACL,oBAAoB;gBACpB,EAAE;gBACF,iBAAiB;gBACjB,8CAA8C;gBAC9C,EAAE;gBACF,gBAAgB;gBAChB,6BAA6B;gBAC7B,EAAE;gBACF,uBAAuB;gBACvB,EAAE;gBACF,EAAE;gBACF,6BAA6B;gBAC7B,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACZ,GAAG,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAA;YAC5E,MAAK;QACP,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,IAAI,GAAG,EAAE,CAAA;YACT,MAAK;QACP,CAAC;IACH,CAAC;IAED,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;IAC7B,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9D,OAAO,CAAC,IAAI,EAAE,CAAA;IAEd,IAAI,cAAc,GAAa,EAAE,CAAA;IAEjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5F,KAAK,EAAE,CAAC,CAAC,IAAI;SACd,CAAC,CAAC,CAAA;QAEH,cAAc,GAAG,MAAM,WAAW,CAAC,wBAAwB,EAAE,YAAY,CAAC,CAAA;IAC5E,CAAC;IAED,YAAY;IACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE;QAC9C,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;QAClC,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE;QACzC,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE;KAC9C,CAAC,CAAA;IAEF,IAAI,SAAS,GAAa,EAAE,CAAA;IAC5B,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,SAAS,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YAC5B,MAAK;QACP,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;YACjC,CAAC;YACD,MAAM,QAAQ,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAAC,IAAI,EAAE,CAAA;YACxD,IAAI,QAAQ;gBAAE,SAAS,GAAG,CAAC,QAAQ,CAAC,CAAA;YACpC,MAAK;QACP,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAK;QACP,CAAC;IACH,CAAC;IAED,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,mDAAmD,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC5F,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,gBAAgB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC1F,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,mDAAmD,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC5F,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,WAAW,MAAM,CAAC,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC5F,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QACvE,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAI,GAAG,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAClG,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,YAAY,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CACrG,CAAA;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,cAAc,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CACjG,CAAA;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,mDAAmD,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAE5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,MAAM,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACtB,OAAM;IACR,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEf,eAAe;IACf,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;IAClC,YAAY,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IAEvC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC;QAC9B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,KAAK;QACL,IAAI;QACJ,MAAM,EAAE,cAAc;QACtB,SAAS;KACV,CAAC,CAAA;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QAE/D,uBAAuB;QACvB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CACT,eAAe,KAAK,CAAC,QAAQ,QAAQ;YACnC,GAAG,MAAM,CAAC,IAAI,oBAAoB,MAAM,CAAC,KAAK,EAAE;YAChD,kBAAkB,CACrB,CAAA;IACH,CAAC;SAAM,CAAC;QACN,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"main-steps.d.ts","sourceRoot":"","sources":["../../src/workflows/main-steps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAYnD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzE,OAAO,CAAC,IAAI,CAAC,CA6Hf;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACxD,OAAO,CAAC,MAAM,CAAC,CAgOjB;AAED,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6F3F"}
1
+ {"version":3,"file":"main-steps.d.ts","sourceRoot":"","sources":["../../src/workflows/main-steps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AA+CnD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzE,OAAO,CAAC,IAAI,CAAC,CA6Hf;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACxD,OAAO,CAAC,MAAM,CAAC,CAoOjB;AAED,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA6F3F"}
@@ -2,15 +2,41 @@ import { handleCommitWorkflow } from './commit.js';
2
2
  import { confirm, ProgressBar } from '../cli/input.js';
3
3
  import { select } from '../cli/menu.js';
4
4
  import { STEP } from '../core/constants.js';
5
+ import { colors } from '../utils/colors.js';
6
+ import { getStepProgress } from '../utils/display.js';
5
7
  import { exec, execAsync } from '../utils/exec.js';
6
8
  import { safeCheckout, safeMerge } from '../utils/git-errors.js';
7
9
  import { getCurrentBranch, pushWithRetry } from '../utils/git.js';
8
10
  import { log } from '../utils/logging.js';
9
11
  import { saveState } from '../utils/state.js';
12
+ /** Extract a user-friendly message from a push error. */
13
+ function describePushError(error) {
14
+ const stderr = error?.stderr ?? error?.message ?? String(error);
15
+ const lower = stderr.toLowerCase();
16
+ if (lower.includes('non-fast-forward') ||
17
+ lower.includes('tip of your current branch is behind')) {
18
+ return ('Your local branch is behind the remote. Run `git pull` (or `git pull --rebase`)' +
19
+ ' to integrate remote changes, then try again.');
20
+ }
21
+ if (lower.includes('permission denied') || lower.includes('403')) {
22
+ return 'Permission denied. Check that you have write access to this repository.';
23
+ }
24
+ if (lower.includes('authentication failed') ||
25
+ lower.includes('http basic: access denied') ||
26
+ lower.includes('could not read from remote')) {
27
+ return 'Authentication failed. Verify your SSH key, credential helper, or personal access token.';
28
+ }
29
+ if (lower.includes('does not appear to be a git repository')) {
30
+ return "Remote 'origin' is not configured. Add a remote with `git remote add origin <url>`.";
31
+ }
32
+ // Fallback: show first meaningful line of stderr
33
+ const firstLine = stderr.split('\n').find((l) => l.trim() && !l.startsWith('hint:'));
34
+ return firstLine?.trim() ?? 'Push failed. Run `git push` manually for details.';
35
+ }
10
36
  export async function handlePush(state, opts) {
11
37
  if (state.step < STEP.PUSHED || opts?.force) {
12
38
  if (!opts?.suppressStep) {
13
- log.step('Step 4: Push to Remote');
39
+ log.step(`Step 4: Push to Remote ${getStepProgress(4)}`);
14
40
  }
15
41
  let shouldPush;
16
42
  if (opts?.suppressLogs) {
@@ -60,7 +86,7 @@ export async function handlePush(state, opts) {
60
86
  catch (error) {
61
87
  progressBar.complete();
62
88
  console.log('');
63
- log.error('Push failed; see git output for details');
89
+ log.error(describePushError(error));
64
90
  throw error;
65
91
  }
66
92
  }
@@ -103,7 +129,7 @@ export async function handlePush(state, opts) {
103
129
  catch (error) {
104
130
  progressBar.complete();
105
131
  console.log('');
106
- log.error('Push failed; see git output for details');
132
+ log.error(describePushError(error));
107
133
  throw error;
108
134
  }
109
135
  }
@@ -122,7 +148,7 @@ export async function handleMerge(state, opts) {
122
148
  // Return the feature branch name used for later cleanup
123
149
  if (state.step < STEP.MERGED) {
124
150
  if (!opts?.suppressStep) {
125
- log.step('Step 5: Merge to Target Branch');
151
+ log.step(`Step 5: Merge to Target ${getStepProgress(5)}`);
126
152
  }
127
153
  const featureBranch = getCurrentBranch();
128
154
  // Gather local branches and offer them as merge targets (exclude current branch)
@@ -213,7 +239,7 @@ export async function handleMerge(state, opts) {
213
239
  await safeCheckout(featureBranch);
214
240
  return featureBranch;
215
241
  }
216
- log.success(`Merged ${featureBranch} into ${targetBranch} with --no-ff`);
242
+ log.success(`${colors.cyan}${featureBranch}${colors.reset} → merged into ${colors.cyan}${targetBranch}${colors.reset}`);
217
243
  }
218
244
  else {
219
245
  // Squash commits on feature branch first
@@ -234,7 +260,7 @@ export async function handleMerge(state, opts) {
234
260
  await safeCheckout(featureBranch);
235
261
  return featureBranch;
236
262
  }
237
- log.success(`Squashed ${featureBranch} and merged into ${targetBranch} with --no-ff`);
263
+ log.success(`${colors.cyan}${featureBranch}${colors.reset} squashed & merged into ${colors.cyan}${targetBranch}${colors.reset}`);
238
264
  }
239
265
  console.log('');
240
266
  // Push the updated target branch back to remote
@@ -251,10 +277,10 @@ export async function handleMerge(state, opts) {
251
277
  /* ignore */
252
278
  }
253
279
  if (remoteUrl) {
254
- log.info(`Pushing ${targetBranch} to: ${remoteUrl}`);
280
+ // remote URL available for push
255
281
  }
256
282
  else {
257
- log.info(`Pushing ${targetBranch} to remote`);
283
+ // push to default remote
258
284
  }
259
285
  console.log('');
260
286
  const progressBar = new ProgressBar(100, `Pushing ${targetBranch} to remote`);
@@ -297,7 +323,7 @@ export async function handleMerge(state, opts) {
297
323
  catch (error) {
298
324
  progressBar.complete();
299
325
  console.log('');
300
- log.error('Push failed; see git output for details');
326
+ log.error(describePushError(error));
301
327
  throw error;
302
328
  }
303
329
  }
@@ -314,10 +340,10 @@ export async function handleMerge(state, opts) {
314
340
  }
315
341
  export async function handleCleanup(featureBranch, state) {
316
342
  if (state.step < STEP.CLEANUP) {
317
- log.step('Step 6: Cleanup');
343
+ log.step(`Step 6: Cleanup ${getStepProgress(6)}`);
318
344
  if (featureBranch && featureBranch !== state.targetBranch) {
319
345
  // Protect canonical branches from accidental deletion
320
- const protectedBranches = new Set(['main', 'master', 'development', 'develop', 'dev']);
346
+ const protectedBranches = new Set(['main', 'master', 'development', 'develop']);
321
347
  if (protectedBranches.has(featureBranch.toLowerCase())) {
322
348
  log.info(`Skipping deletion of protected branch '${featureBranch}'`);
323
349
  }
@@ -326,7 +352,7 @@ export async function handleCleanup(featureBranch, state) {
326
352
  const deleteAnswer = confirm(`Delete branch '${featureBranch}'?`);
327
353
  if (deleteAnswer) {
328
354
  try {
329
- exec(`git branch -d ${featureBranch}`);
355
+ exec(`git branch -d ${featureBranch}`, true);
330
356
  log.success(`Local branch '${featureBranch}' deleted`);
331
357
  // Also delete remote branch if it exists
332
358
  try {
@@ -363,7 +389,7 @@ export async function handleCleanup(featureBranch, state) {
363
389
  ]);
364
390
  if (forceDeleteChoice === 'force') {
365
391
  try {
366
- exec(`git branch -D ${featureBranch}`);
392
+ exec(`git branch -D ${featureBranch}`, true);
367
393
  log.success(`Local branch '${featureBranch}' deleted`);
368
394
  // Also delete remote branch if it exists
369
395
  try {