infra-kit 0.1.80 → 0.1.82
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/dist/cli.js +35 -33
- package/dist/cli.js.map +4 -4
- package/dist/mcp.js +25 -24
- package/dist/mcp.js.map +3 -3
- package/package.json +3 -2
- package/src/commands/env-list/env-list.ts +2 -2
- package/src/commands/gh-merge-dev/gh-merge-dev.ts +5 -7
- package/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts +12 -22
- package/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts +12 -20
- package/src/commands/gh-release-deploy-service/gh-release-deploy-service.ts +12 -22
- package/src/commands/init/index.ts +1 -0
- package/src/commands/{env-init/env-init.ts → init/init.ts} +40 -7
- package/src/commands/release-create-batch/release-create-batch.ts +6 -3
- package/src/commands/worktrees-add/worktrees-add.ts +35 -35
- package/src/commands/worktrees-list/worktrees-list.ts +53 -278
- package/src/commands/worktrees-remove/worktrees-remove.ts +7 -2
- package/src/entry/cli.ts +68 -5
- package/src/lib/command-echo/command-echo.ts +1 -2
- package/src/lib/constants.ts +1 -1
- package/src/lib/release-utils/release-utils.ts +1 -0
- package/src/commands/env-init/index.ts +0 -1
|
@@ -1,300 +1,82 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import { $ } from 'zx'
|
|
3
2
|
|
|
4
|
-
import {
|
|
3
|
+
import { getReleasePRsWithInfo } from 'src/integrations/gh'
|
|
4
|
+
import { getCurrentWorktrees } from 'src/lib/git-utils'
|
|
5
5
|
import { logger } from 'src/lib/logger'
|
|
6
|
+
import { detectReleaseType, formatVersionLabel, getJiraDescriptions } from 'src/lib/release-utils'
|
|
7
|
+
import type { ReleaseType } from 'src/lib/release-utils'
|
|
6
8
|
import type { ToolsExecutionResult } from 'src/types'
|
|
7
9
|
|
|
8
10
|
interface WorktreeInfo {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
isCurrent: boolean
|
|
13
|
-
type: 'release' | 'feature'
|
|
14
|
-
status: string
|
|
15
|
-
lastCommitMessage: string
|
|
16
|
-
aheadBehind: string
|
|
11
|
+
version: string
|
|
12
|
+
type: ReleaseType
|
|
13
|
+
description: string | null
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
|
-
* List all
|
|
17
|
+
* List all release git worktrees with version, type, and Jira description
|
|
21
18
|
*/
|
|
22
19
|
export const worktreesList = async (): Promise<ToolsExecutionResult> => {
|
|
23
|
-
|
|
24
|
-
const [releaseWorktrees, featureWorktrees] = await Promise.all([
|
|
25
|
-
getCurrentWorktrees('release'),
|
|
26
|
-
getCurrentWorktrees('feature'),
|
|
27
|
-
])
|
|
20
|
+
const currentWorktrees = await getCurrentWorktrees('release')
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
logResults(worktreesInfo)
|
|
33
|
-
|
|
34
|
-
const structuredContent = {
|
|
35
|
-
worktrees: worktreesInfo,
|
|
36
|
-
totalCount: worktreesInfo.length,
|
|
37
|
-
releaseCount: releaseWorktrees.length,
|
|
38
|
-
featureCount: featureWorktrees.length,
|
|
39
|
-
}
|
|
22
|
+
if (currentWorktrees.length === 0) {
|
|
23
|
+
logger.info('ℹ️ No active worktrees found')
|
|
40
24
|
|
|
41
25
|
return {
|
|
42
|
-
content: [
|
|
43
|
-
|
|
44
|
-
type: 'text',
|
|
45
|
-
text: JSON.stringify(structuredContent, null, 2),
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
structuredContent,
|
|
49
|
-
}
|
|
50
|
-
} catch (error) {
|
|
51
|
-
logger.error({ error }, '❌ Error listing worktrees')
|
|
52
|
-
throw error
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Process worktrees to get detailed information
|
|
58
|
-
*/
|
|
59
|
-
const processWorktrees = async (
|
|
60
|
-
releaseWorktrees: string[],
|
|
61
|
-
featureWorktrees: string[],
|
|
62
|
-
projectRoot: string,
|
|
63
|
-
): Promise<WorktreeInfo[]> => {
|
|
64
|
-
const allWorktrees = [
|
|
65
|
-
...releaseWorktrees.map((branch) => {
|
|
66
|
-
return { branch, type: 'release' as const }
|
|
67
|
-
}),
|
|
68
|
-
...featureWorktrees.map((branch) => {
|
|
69
|
-
return { branch, type: 'feature' as const }
|
|
70
|
-
}),
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
const worktreesInfo: WorktreeInfo[] = []
|
|
74
|
-
|
|
75
|
-
for (const { branch, type } of allWorktrees) {
|
|
76
|
-
try {
|
|
77
|
-
const worktreePath = `${projectRoot}/${branch}`
|
|
78
|
-
const isCurrent = await isCurrentWorktree(branch)
|
|
79
|
-
const commit = await getWorktreeCommit(worktreePath)
|
|
80
|
-
const status = await getWorktreeStatus(worktreePath)
|
|
81
|
-
const lastCommitMessage = await getLastCommitMessage(worktreePath)
|
|
82
|
-
const aheadBehind = await getAheadBehind(worktreePath)
|
|
83
|
-
|
|
84
|
-
worktreesInfo.push({
|
|
85
|
-
branch,
|
|
86
|
-
path: worktreePath,
|
|
87
|
-
commit: commit.substring(0, 8),
|
|
88
|
-
isCurrent,
|
|
89
|
-
type,
|
|
90
|
-
status,
|
|
91
|
-
lastCommitMessage: lastCommitMessage.substring(0, 60) + (lastCommitMessage.length > 60 ? '...' : ''),
|
|
92
|
-
aheadBehind,
|
|
93
|
-
})
|
|
94
|
-
} catch (error) {
|
|
95
|
-
logger.warn({ error, branch }, `⚠️ Could not process worktree ${branch}`)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return worktreesInfo.sort((a, b) => {
|
|
100
|
-
// Sort by type first (releases before features), then by branch name
|
|
101
|
-
if (a.type !== b.type) {
|
|
102
|
-
return a.type === 'release' ? -1 : 1
|
|
26
|
+
content: [{ type: 'text', text: JSON.stringify({ worktrees: [], count: 0 }, null, 2) }],
|
|
27
|
+
structuredContent: { worktrees: [], count: 0 },
|
|
103
28
|
}
|
|
104
|
-
|
|
105
|
-
return a.branch.localeCompare(b.branch)
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Check if a worktree is currently active
|
|
111
|
-
*/
|
|
112
|
-
const isCurrentWorktree = async (branch: string): Promise<boolean> => {
|
|
113
|
-
try {
|
|
114
|
-
const currentBranch = await $`git branch --show-current`
|
|
115
|
-
|
|
116
|
-
return currentBranch.stdout.trim() === branch
|
|
117
|
-
} catch {
|
|
118
|
-
return false
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Get the commit hash for a worktree
|
|
124
|
-
*/
|
|
125
|
-
const getWorktreeCommit = async (worktreePath: string): Promise<string> => {
|
|
126
|
-
try {
|
|
127
|
-
const result = await $`cd ${worktreePath} && git rev-parse HEAD`
|
|
128
|
-
|
|
129
|
-
return result.stdout.trim()
|
|
130
|
-
} catch {
|
|
131
|
-
return 'unknown'
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Get the status of a worktree
|
|
137
|
-
*/
|
|
138
|
-
const getWorktreeStatus = async (worktreePath: string): Promise<string> => {
|
|
139
|
-
try {
|
|
140
|
-
const result = await $`cd ${worktreePath} && git status --porcelain`
|
|
141
|
-
const changes = result.stdout.trim().split('\n').filter(Boolean)
|
|
142
|
-
|
|
143
|
-
if (changes.length === 0) return 'clean'
|
|
144
|
-
if (changes.length <= 3) return 'modified'
|
|
145
|
-
|
|
146
|
-
return 'dirty'
|
|
147
|
-
} catch {
|
|
148
|
-
return 'unknown'
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Get the last commit message for a worktree
|
|
154
|
-
*/
|
|
155
|
-
const getLastCommitMessage = async (worktreePath: string): Promise<string> => {
|
|
156
|
-
try {
|
|
157
|
-
const result = await $`cd ${worktreePath} && git log -1 --pretty=format:"%s"`
|
|
158
|
-
|
|
159
|
-
return result.stdout.trim()
|
|
160
|
-
} catch {
|
|
161
|
-
return 'No commit message available'
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Get ahead/behind information for a worktree
|
|
167
|
-
*/
|
|
168
|
-
const getAheadBehind = async (worktreePath: string): Promise<string> => {
|
|
169
|
-
try {
|
|
170
|
-
const result =
|
|
171
|
-
await $`cd ${worktreePath} && git rev-list --count --left-right @{u}...HEAD 2>/dev/null || echo "0 0"`
|
|
172
|
-
|
|
173
|
-
const parts = result.stdout.trim().split('\t').map(Number)
|
|
174
|
-
const behind = parts[0] || 0
|
|
175
|
-
const ahead = parts[1] || 0
|
|
176
|
-
|
|
177
|
-
if (ahead === 0 && behind === 0) return 'up to date'
|
|
178
|
-
if (ahead > 0 && behind === 0) return `↑${ahead} ahead`
|
|
179
|
-
if (behind > 0 && ahead === 0) return `↓${behind} behind`
|
|
180
|
-
|
|
181
|
-
return `↑${ahead} ↓${behind}`
|
|
182
|
-
} catch {
|
|
183
|
-
return 'unknown'
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Log the worktrees list in a beautiful formatted way
|
|
189
|
-
*/
|
|
190
|
-
const logResults = (worktrees: WorktreeInfo[]): void => {
|
|
191
|
-
if (worktrees.length === 0) {
|
|
192
|
-
logger.info('\n🌿 Git Worktrees')
|
|
193
|
-
logger.info('─'.repeat(80))
|
|
194
|
-
logger.info('ℹ️ No worktrees found')
|
|
195
|
-
logger.info('─'.repeat(80))
|
|
196
|
-
|
|
197
|
-
return
|
|
198
29
|
}
|
|
199
30
|
|
|
200
|
-
|
|
201
|
-
logger.info('═'.repeat(100))
|
|
202
|
-
|
|
203
|
-
// Separate releases and features
|
|
204
|
-
const releases = worktrees.filter((w) => {
|
|
205
|
-
return w.type === 'release'
|
|
206
|
-
})
|
|
207
|
-
const features = worktrees.filter((w) => {
|
|
208
|
-
return w.type === 'feature'
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
// Display releases first
|
|
212
|
-
displayWorktreeSection('🚀 Releases', releases)
|
|
31
|
+
const [releasePRsInfo, jiraDescriptions] = await Promise.all([getReleasePRsWithInfo(), getJiraDescriptions()])
|
|
213
32
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
33
|
+
const releaseTypes = new Map<string, ReleaseType>(
|
|
34
|
+
releasePRsInfo.map((pr) => {
|
|
35
|
+
return [pr.branch, detectReleaseType(pr.title)]
|
|
36
|
+
}),
|
|
37
|
+
)
|
|
218
38
|
|
|
219
|
-
|
|
39
|
+
const worktrees: WorktreeInfo[] = currentWorktrees.map((branch) => {
|
|
40
|
+
const version = branch.replace('release/', '')
|
|
41
|
+
const type = releaseTypes.get(branch) || 'regular'
|
|
42
|
+
const description = jiraDescriptions.get(version) || null
|
|
220
43
|
|
|
221
|
-
|
|
222
|
-
const current = worktrees.find((w) => {
|
|
223
|
-
return w.isCurrent
|
|
44
|
+
return { version, type, description }
|
|
224
45
|
})
|
|
225
46
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
47
|
+
// Log formatted output
|
|
48
|
+
const maxVersionLength = Math.max(
|
|
49
|
+
...worktrees.map((w) => {
|
|
50
|
+
return w.version.length
|
|
51
|
+
}),
|
|
229
52
|
)
|
|
230
53
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
logger.info('')
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Display a section of worktrees
|
|
240
|
-
*/
|
|
241
|
-
const displayWorktreeSection = (sectionTitle: string, worktrees: WorktreeInfo[]): void => {
|
|
242
|
-
if (worktrees.length === 0) return
|
|
243
|
-
|
|
244
|
-
logger.info(`\n${sectionTitle}`)
|
|
245
|
-
logger.info('─'.repeat(50))
|
|
54
|
+
const formattedLines = worktrees.map((worktree) => {
|
|
55
|
+
const label = formatVersionLabel(worktree.version, worktree.type, maxVersionLength)
|
|
246
56
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (index < worktrees.length - 1) {
|
|
251
|
-
logger.info('')
|
|
57
|
+
if (worktree.description) {
|
|
58
|
+
return `${label} ${worktree.description}`
|
|
252
59
|
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Display a single worktree entry
|
|
258
|
-
*/
|
|
259
|
-
const displayWorktree = (worktree: WorktreeInfo): void => {
|
|
260
|
-
// Worktree status indicators
|
|
261
|
-
const currentIndicator = worktree.isCurrent ? '📍' : ' '
|
|
262
|
-
const statusIndicator = getStatusIndicator(worktree.status)
|
|
263
|
-
|
|
264
|
-
const typeIcon = worktree.type === 'release' ? '🚀' : '✨'
|
|
265
|
-
|
|
266
|
-
// Branch name with color coding
|
|
267
|
-
const branchDisplay = `${typeIcon} ${worktree.branch}`
|
|
268
|
-
|
|
269
|
-
logger.info(`${currentIndicator} ${statusIndicator} ${branchDisplay}`)
|
|
270
|
-
|
|
271
|
-
// Commit and sync info
|
|
272
|
-
const syncInfo = worktree.aheadBehind !== 'unknown' ? ` | ${worktree.aheadBehind}` : ''
|
|
273
|
-
|
|
274
|
-
logger.info(` 📝 ${worktree.commit}${syncInfo}`)
|
|
275
60
|
|
|
276
|
-
|
|
277
|
-
|
|
61
|
+
return label
|
|
62
|
+
})
|
|
278
63
|
|
|
279
|
-
|
|
280
|
-
|
|
64
|
+
logger.info('🌿 Active worktrees:')
|
|
65
|
+
logger.info(`\n${formattedLines.join('\n')}\n`)
|
|
281
66
|
|
|
282
|
-
|
|
283
|
-
|
|
67
|
+
const structuredContent = {
|
|
68
|
+
worktrees,
|
|
69
|
+
count: worktrees.length,
|
|
70
|
+
}
|
|
284
71
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
return '⚠️ '
|
|
294
|
-
case 'dirty':
|
|
295
|
-
return '🔴'
|
|
296
|
-
default:
|
|
297
|
-
return '❓'
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: JSON.stringify(structuredContent, null, 2),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
structuredContent,
|
|
298
80
|
}
|
|
299
81
|
}
|
|
300
82
|
|
|
@@ -307,20 +89,13 @@ export const worktreesListMcpTool = {
|
|
|
307
89
|
worktrees: z
|
|
308
90
|
.array(
|
|
309
91
|
z.object({
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
isCurrent: z.boolean(),
|
|
314
|
-
type: z.enum(['release', 'feature']),
|
|
315
|
-
status: z.string(),
|
|
316
|
-
lastCommitMessage: z.string(),
|
|
317
|
-
aheadBehind: z.string(),
|
|
92
|
+
version: z.string().describe('Release version'),
|
|
93
|
+
type: z.enum(['regular', 'hotfix']).describe('Release type'),
|
|
94
|
+
description: z.string().nullable().describe('Jira version description'),
|
|
318
95
|
}),
|
|
319
96
|
)
|
|
320
97
|
.describe('List of all worktrees with details'),
|
|
321
|
-
|
|
322
|
-
releaseCount: z.number().describe('Number of release worktrees'),
|
|
323
|
-
featureCount: z.number().describe('Number of feature worktrees'),
|
|
98
|
+
count: z.number().describe('Number of worktrees'),
|
|
324
99
|
},
|
|
325
100
|
handler: worktreesList,
|
|
326
101
|
}
|
|
@@ -78,7 +78,12 @@ export const worktreesRemove = async (options: WorktreeManagementArgs): Promise<
|
|
|
78
78
|
if (allSelected) {
|
|
79
79
|
commandEcho.addOption('--all', true)
|
|
80
80
|
} else {
|
|
81
|
-
commandEcho.addOption(
|
|
81
|
+
commandEcho.addOption(
|
|
82
|
+
'--versions',
|
|
83
|
+
selectedReleaseBranches.map((branch) => {
|
|
84
|
+
return branch.replace('release/v', '')
|
|
85
|
+
}),
|
|
86
|
+
)
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
// Ask for confirmation
|
|
@@ -98,7 +103,7 @@ export const worktreesRemove = async (options: WorktreeManagementArgs): Promise<
|
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
// Track --yes flag if confirmation was interactive (user confirmed)
|
|
101
|
-
if (
|
|
106
|
+
if (!confirmedCommand) {
|
|
102
107
|
commandEcho.addOption('--yes', true)
|
|
103
108
|
}
|
|
104
109
|
|
package/src/entry/cli.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import select, { Separator } from '@inquirer/select'
|
|
1
2
|
import { Command, Option } from 'commander'
|
|
3
|
+
import process from 'node:process'
|
|
2
4
|
|
|
3
5
|
import { doctor } from 'src/commands/doctor'
|
|
4
6
|
import { envClear } from 'src/commands/env-clear'
|
|
5
|
-
import { envInit } from 'src/commands/env-init'
|
|
6
7
|
import { envList } from 'src/commands/env-list'
|
|
7
8
|
import { envLoad } from 'src/commands/env-load'
|
|
8
9
|
import { envStatus } from 'src/commands/env-status'
|
|
@@ -12,6 +13,7 @@ import { ghReleaseDeployAll } from 'src/commands/gh-release-deploy-all'
|
|
|
12
13
|
import { ghReleaseDeploySelected } from 'src/commands/gh-release-deploy-selected'
|
|
13
14
|
import { ghReleaseDeployService } from 'src/commands/gh-release-deploy-service'
|
|
14
15
|
import { ghReleaseList } from 'src/commands/gh-release-list'
|
|
16
|
+
import { init } from 'src/commands/init'
|
|
15
17
|
import { releaseCreate } from 'src/commands/release-create'
|
|
16
18
|
import { releaseCreateBatch } from 'src/commands/release-create-batch'
|
|
17
19
|
import { worktreesAdd } from 'src/commands/worktrees-add'
|
|
@@ -187,10 +189,10 @@ program
|
|
|
187
189
|
})
|
|
188
190
|
|
|
189
191
|
program
|
|
190
|
-
.command('
|
|
191
|
-
.description('
|
|
192
|
+
.command('init')
|
|
193
|
+
.description('Inject shell integration into your profile .zshrc')
|
|
192
194
|
.action(async () => {
|
|
193
|
-
await
|
|
195
|
+
await init()
|
|
194
196
|
})
|
|
195
197
|
|
|
196
198
|
program
|
|
@@ -208,4 +210,65 @@ program
|
|
|
208
210
|
await envClear()
|
|
209
211
|
})
|
|
210
212
|
|
|
211
|
-
|
|
213
|
+
if (process.argv.length <= 2) {
|
|
214
|
+
const releaseCommands = [
|
|
215
|
+
'merge-dev',
|
|
216
|
+
'release-list',
|
|
217
|
+
'release-create',
|
|
218
|
+
'release-create-batch',
|
|
219
|
+
'release-deploy-all',
|
|
220
|
+
'release-deploy-service',
|
|
221
|
+
'release-deploy-selected',
|
|
222
|
+
'release-deliver',
|
|
223
|
+
]
|
|
224
|
+
const worktreeCommands = ['worktrees-add', 'worktrees-list', 'worktrees-remove', 'worktrees-sync']
|
|
225
|
+
const envCommands = ['doctor', 'init', 'env-status', 'env-list', 'env-load', 'env-clear']
|
|
226
|
+
|
|
227
|
+
const commandMap = new Map(
|
|
228
|
+
program.commands.map((cmd) => {
|
|
229
|
+
return [cmd.name(), cmd]
|
|
230
|
+
}),
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
const allNames = [...releaseCommands, ...worktreeCommands, ...envCommands]
|
|
234
|
+
const maxLen = Math.max(
|
|
235
|
+
...allNames.map((n) => {
|
|
236
|
+
return n.length
|
|
237
|
+
}),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const toChoices = (names: string[]) => {
|
|
241
|
+
return names
|
|
242
|
+
.filter((n) => {
|
|
243
|
+
return commandMap.has(n)
|
|
244
|
+
})
|
|
245
|
+
.map((n) => {
|
|
246
|
+
return {
|
|
247
|
+
name: `${n.padEnd(maxLen)} ${commandMap.get(n)!.description()}`,
|
|
248
|
+
value: n,
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const selected = await select(
|
|
254
|
+
{
|
|
255
|
+
message: 'Select a command to run',
|
|
256
|
+
choices: [
|
|
257
|
+
new Separator(' '),
|
|
258
|
+
new Separator('— Release Management —'),
|
|
259
|
+
...toChoices(releaseCommands),
|
|
260
|
+
new Separator(' '),
|
|
261
|
+
new Separator('— Worktrees —'),
|
|
262
|
+
...toChoices(worktreeCommands),
|
|
263
|
+
new Separator(' '),
|
|
264
|
+
new Separator('— Environment —'),
|
|
265
|
+
...toChoices(envCommands),
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
{ output: process.stderr },
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
program.parse(['node', 'infra-kit', selected])
|
|
272
|
+
} else {
|
|
273
|
+
program.parse()
|
|
274
|
+
}
|
|
@@ -60,8 +60,7 @@ const createCommandEcho = () => {
|
|
|
60
60
|
.filter(Boolean)
|
|
61
61
|
.join(' ')
|
|
62
62
|
|
|
63
|
-
logger.info(`📟 Equivalent command: \npnpm exec infra-kit ${commandName} ${formattedOptions}`)
|
|
64
|
-
logger.info('')
|
|
63
|
+
logger.info(`📟 Equivalent command: \npnpm exec infra-kit ${commandName} ${formattedOptions}\n`)
|
|
65
64
|
},
|
|
66
65
|
|
|
67
66
|
/**
|
package/src/lib/constants.ts
CHANGED
|
@@ -40,7 +40,7 @@ export const getSessionCacheDir = (): string => {
|
|
|
40
40
|
const session = process.env[INFRA_KIT_SESSION_VAR]
|
|
41
41
|
|
|
42
42
|
if (!session) {
|
|
43
|
-
throw new Error('INFRA_KIT_SESSION is not set. Run `source ~/.zshrc` or `infra-kit
|
|
43
|
+
throw new Error('INFRA_KIT_SESSION is not set. Run `source ~/.zshrc` or `infra-kit init` first.')
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
return path.join(ENV_CACHE_DIR, session)
|
|
@@ -134,6 +134,7 @@ interface FormatBranchChoicesArgs {
|
|
|
134
134
|
*/
|
|
135
135
|
export const formatBranchChoices = (args: FormatBranchChoicesArgs): { name: string; value: string }[] => {
|
|
136
136
|
const { branches, descriptions, types } = args
|
|
137
|
+
|
|
137
138
|
const versionNames = branches.map((b) => {
|
|
138
139
|
return b.replace('release/v', '')
|
|
139
140
|
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { envInit } from './env-init'
|