infra-kit 0.1.68 โ†’ 0.1.72

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "infra-kit",
3
3
  "type": "module",
4
- "version": "0.1.68",
4
+ "version": "0.1.72",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/cli.js",
7
7
  "module": "dist/cli.js",
@@ -30,13 +30,13 @@
30
30
  "fix": "pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"
31
31
  },
32
32
  "dependencies": {
33
- "@inquirer/checkbox": "^5.0.4",
34
- "@inquirer/confirm": "^6.0.4",
35
- "@inquirer/select": "^5.0.4",
36
- "@modelcontextprotocol/sdk": "^1.26.0",
33
+ "@inquirer/checkbox": "^5.1.0",
34
+ "@inquirer/confirm": "^6.0.8",
35
+ "@inquirer/select": "^5.1.0",
36
+ "@modelcontextprotocol/sdk": "^1.27.1",
37
37
  "commander": "^14.0.3",
38
- "dotenv": "^17.2.3",
39
- "pino": "^10.3.0",
38
+ "dotenv": "^17.3.1",
39
+ "pino": "^10.3.1",
40
40
  "pino-pretty": "^13.1.3",
41
41
  "yaml": "^2.8.2",
42
42
  "zod": "^3.25.76",
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@pkg/eslint-config": "workspace:*",
47
47
  "@pkg/vitest-config": "workspace:*",
48
- "esbuild": "^0.27.2",
48
+ "esbuild": "^0.27.3",
49
49
  "typescript": "^5.9.3"
50
50
  }
51
51
  }
@@ -50,10 +50,12 @@ export const ghMergeDev = async (args: GhMergeDevArgs): Promise<ToolsExecutionRe
50
50
  selectedReleaseBranches = await checkbox({
51
51
  required: true,
52
52
  message: '๐ŸŒฟ Select release branches',
53
- choices: releasePRsList.map((pr) => ({
54
- name: pr.replace('release/v', ''),
55
- value: pr,
56
- })),
53
+ choices: releasePRsList.map((pr) => {
54
+ return {
55
+ name: pr.replace('release/v', ''),
56
+ value: pr,
57
+ }
58
+ }),
57
59
  })
58
60
  }
59
61
 
@@ -33,10 +33,12 @@ export const ghReleaseDeliver = async (args: GhReleaseDeliverArgs): Promise<Tool
33
33
 
34
34
  selectedReleaseBranch = await select({
35
35
  message: '๐ŸŒฟ Select release branch',
36
- choices: releasePRsList.map((pr) => ({
37
- name: pr.replace('release/v', ''),
38
- value: pr,
39
- })),
36
+ choices: releasePRsList.map((pr) => {
37
+ return {
38
+ name: pr.replace('release/v', ''),
39
+ value: pr,
40
+ }
41
+ }),
40
42
  })
41
43
  }
42
44
 
@@ -1,4 +1,3 @@
1
- import confirm from '@inquirer/confirm'
2
1
  import select from '@inquirer/select'
3
2
  import process from 'node:process'
4
3
  import { z } from 'zod'
@@ -41,10 +40,12 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
41
40
 
42
41
  selectedReleaseBranch = await select({
43
42
  message: '๐ŸŒฟ Select release branch',
44
- choices: releasePRsList.map((pr) => ({
45
- name: pr.replace('release/v', ''),
46
- value: pr,
47
- })),
43
+ choices: releasePRsList.map((pr) => {
44
+ return {
45
+ name: pr.replace('release/v', ''),
46
+ value: pr,
47
+ }
48
+ }),
48
49
  })
49
50
  }
50
51
 
@@ -67,10 +68,12 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
67
68
 
68
69
  selectedEnv = await select({
69
70
  message: '๐Ÿงช Select environment',
70
- choices: ENVs.map((env) => ({
71
- name: env,
72
- value: env,
73
- })),
71
+ choices: ENVs.map((env) => {
72
+ return {
73
+ name: env,
74
+ value: env,
75
+ }
76
+ }),
74
77
  })
75
78
  }
76
79
 
@@ -81,18 +84,7 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
81
84
  process.exit(1)
82
85
  }
83
86
 
84
- let shouldSkipTerraform = false
85
-
86
- if (typeof skipTerraform !== 'undefined') {
87
- shouldSkipTerraform = skipTerraform
88
- } else {
89
- commandEcho.setInteractive()
90
-
91
- shouldSkipTerraform = await confirm({
92
- message: '๐Ÿ—๏ธ Skip terraform deployment?',
93
- default: false,
94
- })
95
- }
87
+ const shouldSkipTerraform = skipTerraform ?? false
96
88
 
97
89
  if (shouldSkipTerraform) {
98
90
  commandEcho.addOption('--skip-terraform', true)
@@ -102,6 +94,7 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
102
94
  $.quiet = true
103
95
 
104
96
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
97
+
105
98
  await $`gh workflow run deploy-all.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${skipTerraformFlag}`
106
99
 
107
100
  $.quiet = false
@@ -1,5 +1,4 @@
1
1
  import checkbox from '@inquirer/checkbox'
2
- import confirm from '@inquirer/confirm'
3
2
  import select from '@inquirer/select'
4
3
  import fs from 'node:fs/promises'
5
4
  import { resolve } from 'node:path'
@@ -46,10 +45,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
46
45
 
47
46
  selectedReleaseBranch = await select({
48
47
  message: '๐ŸŒฟ Select release branch',
49
- choices: releasePRsList.map((pr) => ({
50
- name: pr.replace('release/v', ''),
51
- value: pr,
52
- })),
48
+ choices: releasePRsList.map((pr) => {
49
+ return {
50
+ name: pr.replace('release/v', ''),
51
+ value: pr,
52
+ }
53
+ }),
53
54
  })
54
55
  }
55
56
 
@@ -72,10 +73,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
72
73
 
73
74
  selectedEnv = await select({
74
75
  message: '๐Ÿงช Select environment',
75
- choices: ENVs.map((env) => ({
76
- name: env,
77
- value: env,
78
- })),
76
+ choices: ENVs.map((env) => {
77
+ return {
78
+ name: env,
79
+ value: env,
80
+ }
81
+ }),
79
82
  })
80
83
  }
81
84
 
@@ -104,10 +107,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
104
107
 
105
108
  selectedServices = await checkbox({
106
109
  message: '๐Ÿš€ Select services to deploy (space to select, enter to confirm)',
107
- choices: availableServices.map((svc) => ({
108
- name: svc,
109
- value: svc,
110
- })),
110
+ choices: availableServices.map((svc) => {
111
+ return {
112
+ name: svc,
113
+ value: svc,
114
+ }
115
+ }),
111
116
  })
112
117
  }
113
118
 
@@ -119,7 +124,9 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
119
124
  }
120
125
 
121
126
  // Validate all selected services
122
- const invalidServices = selectedServices.filter((svc) => !availableServices.includes(svc))
127
+ const invalidServices = selectedServices.filter((svc) => {
128
+ return !availableServices.includes(svc)
129
+ })
123
130
 
124
131
  if (invalidServices.length > 0) {
125
132
  logger.error(
@@ -128,18 +135,7 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
128
135
  process.exit(1)
129
136
  }
130
137
 
131
- let shouldSkipTerraform = false
132
-
133
- if (typeof skipTerraform !== 'undefined') {
134
- shouldSkipTerraform = skipTerraform
135
- } else {
136
- commandEcho.setInteractive()
137
-
138
- shouldSkipTerraform = await confirm({
139
- message: '๐Ÿ—๏ธ Skip terraform deployment?',
140
- default: false,
141
- })
142
- }
138
+ const shouldSkipTerraform = skipTerraform ?? false
143
139
 
144
140
  if (shouldSkipTerraform) {
145
141
  commandEcho.addOption('--skip-terraform', true)
@@ -149,7 +145,9 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
149
145
  $.quiet = true
150
146
 
151
147
  // Build the workflow command with boolean flags for each selected service
152
- const serviceFlags = selectedServices.flatMap((svc) => ['-f', `${svc}=true`])
148
+ const serviceFlags = selectedServices.flatMap((svc) => {
149
+ return ['-f', `${svc}=true`]
150
+ })
153
151
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
154
152
 
155
153
  await $`gh workflow run deploy-selected-services.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${serviceFlags} ${skipTerraformFlag}`
@@ -1,4 +1,3 @@
1
- import confirm from '@inquirer/confirm'
2
1
  import select from '@inquirer/select'
3
2
  import fs from 'node:fs/promises'
4
3
  import { resolve } from 'node:path'
@@ -24,7 +23,6 @@ interface GhReleaseDeployServiceArgs {
24
23
  /**
25
24
  * Deploy a specific service in a release branch to an environment
26
25
  */
27
- // eslint-disable-next-line sonarjs/cognitive-complexity
28
26
  export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs): Promise<ToolsExecutionResult> => {
29
27
  const { version, env, service, skipTerraform } = args
30
28
 
@@ -47,10 +45,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
47
45
 
48
46
  selectedReleaseBranch = await select({
49
47
  message: '๐ŸŒฟ Select release branch',
50
- choices: releasePRsList.map((pr) => ({
51
- name: pr.replace('release/v', ''),
52
- value: pr,
53
- })),
48
+ choices: releasePRsList.map((pr) => {
49
+ return {
50
+ name: pr.replace('release/v', ''),
51
+ value: pr,
52
+ }
53
+ }),
54
54
  })
55
55
  }
56
56
 
@@ -73,10 +73,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
73
73
 
74
74
  selectedEnv = await select({
75
75
  message: '๐Ÿงช Select environment',
76
- choices: ENVs.map((env) => ({
77
- name: env,
78
- value: env,
79
- })),
76
+ choices: ENVs.map((env) => {
77
+ return {
78
+ name: env,
79
+ value: env,
80
+ }
81
+ }),
80
82
  })
81
83
  }
82
84
 
@@ -99,10 +101,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
99
101
 
100
102
  selectedService = await select({
101
103
  message: '๐Ÿš€ Select service to deploy',
102
- choices: availableServices.map((svc) => ({
103
- name: svc,
104
- value: svc,
105
- })),
104
+ choices: availableServices.map((svc) => {
105
+ return {
106
+ name: svc,
107
+ value: svc,
108
+ }
109
+ }),
106
110
  })
107
111
  }
108
112
 
@@ -113,18 +117,7 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
113
117
  process.exit(1)
114
118
  }
115
119
 
116
- let shouldSkipTerraform = false
117
-
118
- if (typeof skipTerraform !== 'undefined') {
119
- shouldSkipTerraform = skipTerraform
120
- } else {
121
- commandEcho.setInteractive()
122
-
123
- shouldSkipTerraform = await confirm({
124
- message: '๐Ÿ—๏ธ Skip terraform deployment?',
125
- default: false,
126
- })
127
- }
120
+ const shouldSkipTerraform = skipTerraform ?? false
128
121
 
129
122
  if (shouldSkipTerraform) {
130
123
  commandEcho.addOption('--skip-terraform', true)
@@ -134,6 +127,7 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
134
127
  $.quiet = true
135
128
 
136
129
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
130
+
137
131
  await $`gh workflow run deploy-single-service.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} -f service=${selectedService} ${skipTerraformFlag}`
138
132
 
139
133
  $.quiet = false
@@ -10,7 +10,9 @@ import type { ToolsExecutionResult } from 'src/types'
10
10
  export const ghReleaseList = async (): Promise<ToolsExecutionResult> => {
11
11
  const releasePRs = await getReleasePRs()
12
12
 
13
- const releasePRsList = releasePRs.map((pr) => pr.replace('release/', ''))
13
+ const releasePRsList = releasePRs.map((pr) => {
14
+ return pr.replace('release/', '')
15
+ })
14
16
 
15
17
  logger.info('All release branches: \n')
16
18
  logger.info(`\n${releasePRsList.join('\n')}`)
@@ -35,7 +35,9 @@ export const releaseCreateBatch = async (args: ReleaseCreateBatchArgs): Promise<
35
35
  versionInput = await question('Enter versions by comma (e.g. 1.2.5, 1.2.6): ')
36
36
  }
37
37
 
38
- const versionsList = versionInput.split(',').map((version) => version.trim())
38
+ const versionsList = versionInput.split(',').map((version) => {
39
+ return version.trim()
40
+ })
39
41
 
40
42
  commandEcho.addOption('--versions', versionsList.join(', '))
41
43
 
@@ -113,7 +115,9 @@ export const releaseCreateBatch = async (args: ReleaseCreateBatchArgs): Promise<
113
115
  commandEcho.print()
114
116
 
115
117
  const structuredContent = {
116
- createdBranches: releases.map((r) => r.branchName),
118
+ createdBranches: releases.map((r) => {
119
+ return r.branchName
120
+ }),
117
121
  successCount,
118
122
  failureCount,
119
123
  releases,
@@ -1,5 +1,7 @@
1
+ /* eslint-disable sonarjs/cognitive-complexity */
1
2
  import checkbox from '@inquirer/checkbox'
2
3
  import confirm from '@inquirer/confirm'
4
+ import { copyFileSync, existsSync } from 'node:fs'
3
5
  import process from 'node:process'
4
6
  import { z } from 'zod'
5
7
  import { $ } from 'zx'
@@ -18,6 +20,7 @@ const RELEASE_BRANCH_PREFIX = 'release/v'
18
20
 
19
21
  interface WorktreeManagementArgs extends RequiredConfirmedOptionArg {
20
22
  all: boolean
23
+ cursor?: boolean
21
24
  }
22
25
 
23
26
  /**
@@ -25,7 +28,7 @@ interface WorktreeManagementArgs extends RequiredConfirmedOptionArg {
25
28
  * Creates worktrees for active release branches and removes unused ones
26
29
  */
27
30
  export const worktreesAdd = async (options: WorktreeManagementArgs): Promise<ToolsExecutionResult> => {
28
- const { confirmedCommand, all } = options
31
+ const { confirmedCommand, all, cursor } = options
29
32
 
30
33
  commandEcho.start('worktrees-add')
31
34
 
@@ -61,10 +64,12 @@ export const worktreesAdd = async (options: WorktreeManagementArgs): Promise<Too
61
64
  selectedReleaseBranches = await checkbox({
62
65
  required: true,
63
66
  message: '๐ŸŒฟ Select release branches',
64
- choices: releasePRsList.map((pr) => ({
65
- name: pr.replace('release/v', ''),
66
- value: pr,
67
- })),
67
+ choices: releasePRsList.map((pr) => {
68
+ return {
69
+ name: pr.replace('release/v', ''),
70
+ value: pr,
71
+ }
72
+ }),
68
73
  })
69
74
  }
70
75
 
@@ -98,15 +103,31 @@ export const worktreesAdd = async (options: WorktreeManagementArgs): Promise<Too
98
103
  commandEcho.addOption('--yes', true)
99
104
  }
100
105
 
106
+ const openInCursor = cursor ? true : await confirm({ message: 'Open created worktrees in Cursor?' })
107
+
108
+ if (!openInCursor) {
109
+ commandEcho.setInteractive()
110
+ }
111
+
112
+ if (openInCursor) {
113
+ commandEcho.addOption('--cursor', true)
114
+ }
115
+
101
116
  const { branchesToCreate } = categorizeWorktrees({
102
117
  selectedReleaseBranches,
103
118
  currentWorktrees,
104
119
  })
105
120
 
106
- const createdWorktrees = await createWorktrees(branchesToCreate, worktreeDir)
121
+ const createdWorktrees = await createWorktrees(branchesToCreate, worktreeDir, projectRoot)
107
122
 
108
123
  logResults(createdWorktrees)
109
124
 
125
+ if (openInCursor) {
126
+ for (const branch of createdWorktrees) {
127
+ await $`cursor ${worktreeDir}/${branch}`
128
+ }
129
+ }
130
+
110
131
  commandEcho.print()
111
132
 
112
133
  const structuredContent = {
@@ -147,9 +168,13 @@ interface CategorizeWorktreesArgs {
147
168
  const categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToCreate: string[] } => {
148
169
  const { selectedReleaseBranches, currentWorktrees } = args
149
170
 
150
- const currentBranchNames = currentWorktrees.filter((branch) => branch.startsWith(RELEASE_BRANCH_PREFIX))
171
+ const currentBranchNames = currentWorktrees.filter((branch) => {
172
+ return branch.startsWith(RELEASE_BRANCH_PREFIX)
173
+ })
151
174
 
152
- const branchesToCreate = selectedReleaseBranches.filter((branch) => !currentBranchNames.includes(branch))
175
+ const branchesToCreate = selectedReleaseBranches.filter((branch) => {
176
+ return !currentBranchNames.includes(branch)
177
+ })
153
178
 
154
179
  return { branchesToCreate }
155
180
  }
@@ -157,7 +182,7 @@ const categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToCreate:
157
182
  /**
158
183
  * Create worktrees for the specified branches
159
184
  */
160
- const createWorktrees = async (branches: string[], worktreeDir: string): Promise<string[]> => {
185
+ const createWorktrees = async (branches: string[], worktreeDir: string, projectRoot: string): Promise<string[]> => {
161
186
  const created: string[] = []
162
187
 
163
188
  for (const branch of branches) {
@@ -166,6 +191,14 @@ const createWorktrees = async (branches: string[], worktreeDir: string): Promise
166
191
 
167
192
  await $`git worktree add ${worktreePath} ${branch}`
168
193
 
194
+ const rootEnvPath = `${projectRoot}/.env`
195
+
196
+ if (existsSync(rootEnvPath)) {
197
+ copyFileSync(rootEnvPath, `${worktreePath}/.env`)
198
+
199
+ logger.info('๐Ÿ“‹ Copied .env to worktree')
200
+ }
201
+
169
202
  created.push(branch)
170
203
  } catch (error) {
171
204
  logger.error({ error, branch }, `โŒ Failed to create worktree for ${branch}`)
@@ -195,6 +228,7 @@ export const worktreesAddMcpTool = {
195
228
  description: 'Create worktrees for selected release branches',
196
229
  inputSchema: {
197
230
  all: z.boolean().describe('Add worktrees for all release branches without prompting'),
231
+ cursor: z.boolean().optional().describe('Open created worktrees in Cursor'),
198
232
  },
199
233
  outputSchema: {
200
234
  createdWorktrees: z.array(z.string()).describe('List of created worktree branches'),
@@ -62,8 +62,12 @@ const processWorktrees = async (
62
62
  projectRoot: string,
63
63
  ): Promise<WorktreeInfo[]> => {
64
64
  const allWorktrees = [
65
- ...releaseWorktrees.map((branch) => ({ branch, type: 'release' as const })),
66
- ...featureWorktrees.map((branch) => ({ branch, type: 'feature' as const })),
65
+ ...releaseWorktrees.map((branch) => {
66
+ return { branch, type: 'release' as const }
67
+ }),
68
+ ...featureWorktrees.map((branch) => {
69
+ return { branch, type: 'feature' as const }
70
+ }),
67
71
  ]
68
72
 
69
73
  const worktreesInfo: WorktreeInfo[] = []
@@ -97,6 +101,7 @@ const processWorktrees = async (
97
101
  if (a.type !== b.type) {
98
102
  return a.type === 'release' ? -1 : 1
99
103
  }
104
+
100
105
  return a.branch.localeCompare(b.branch)
101
106
  })
102
107
  }
@@ -196,8 +201,12 @@ const logResults = (worktrees: WorktreeInfo[]): void => {
196
201
  logger.info('โ•'.repeat(100))
197
202
 
198
203
  // Separate releases and features
199
- const releases = worktrees.filter((w) => w.type === 'release')
200
- const features = worktrees.filter((w) => w.type === 'feature')
204
+ const releases = worktrees.filter((w) => {
205
+ return w.type === 'release'
206
+ })
207
+ const features = worktrees.filter((w) => {
208
+ return w.type === 'feature'
209
+ })
201
210
 
202
211
  // Display releases first
203
212
  displayWorktreeSection('๐Ÿš€ Releases', releases)
@@ -210,7 +219,10 @@ const logResults = (worktrees: WorktreeInfo[]): void => {
210
219
  displayWorktreeSection('โœจ Features', features)
211
220
 
212
221
  // Summary
213
- const current = worktrees.find((w) => w.isCurrent)
222
+ const current = worktrees.find((w) => {
223
+ return w.isCurrent
224
+ })
225
+
214
226
  logger.info(`\n${'โ•'.repeat(100)}`)
215
227
  logger.info(
216
228
  `๐Ÿ“Š Summary: ${worktrees.length} total worktrees (${releases.length} releases, ${features.length} features)`,
@@ -258,6 +270,7 @@ const displayWorktree = (worktree: WorktreeInfo): void => {
258
270
 
259
271
  // Commit and sync info
260
272
  const syncInfo = worktree.aheadBehind !== 'unknown' ? ` | ${worktree.aheadBehind}` : ''
273
+
261
274
  logger.info(` ๐Ÿ“ ${worktree.commit}${syncInfo}`)
262
275
 
263
276
  // Last commit message
@@ -265,6 +278,7 @@ const displayWorktree = (worktree: WorktreeInfo): void => {
265
278
 
266
279
  // Path (shortened for display)
267
280
  const shortPath = worktree.path.split('/').slice(-2).join('/')
281
+
268
282
  logger.info(` ๐Ÿ“ ${shortPath}`)
269
283
  }
270
284
 
@@ -52,10 +52,12 @@ export const worktreesRemove = async (options: WorktreeManagementArgs): Promise<
52
52
  selectedReleaseBranches = await checkbox({
53
53
  required: true,
54
54
  message: '๐ŸŒฟ Select release branches',
55
- choices: currentWorktrees.map((pr) => ({
56
- name: pr.replace('release/v', ''),
57
- value: pr,
58
- })),
55
+ choices: currentWorktrees.map((pr) => {
56
+ return {
57
+ name: pr.replace('release/v', ''),
58
+ value: pr,
59
+ }
60
+ }),
59
61
  })
60
62
  }
61
63
 
@@ -124,6 +126,7 @@ const removeWorktrees = async (branches: string[], worktreeDir: string): Promise
124
126
  for (const branch of branches) {
125
127
  try {
126
128
  const worktreePath = `${worktreeDir}/${branch}`
129
+
127
130
  await $`git worktree remove ${worktreePath}`
128
131
  removed.push(branch)
129
132
  } catch (error) {
@@ -96,9 +96,13 @@ interface CategorizeWorktreesArgs {
96
96
  const categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToRemove: string[] } => {
97
97
  const { releasePRsList, currentWorktrees } = args
98
98
 
99
- const currentBranchNames = currentWorktrees.filter((branch) => branch.startsWith(RELEASE_BRANCH_PREFIX))
99
+ const currentBranchNames = currentWorktrees.filter((branch) => {
100
+ return branch.startsWith(RELEASE_BRANCH_PREFIX)
101
+ })
100
102
 
101
- const branchesToRemove = currentBranchNames.filter((branch) => !releasePRsList.includes(branch))
103
+ const branchesToRemove = currentBranchNames.filter((branch) => {
104
+ return !releasePRsList.includes(branch)
105
+ })
102
106
 
103
107
  return { branchesToRemove }
104
108
  }
@@ -112,6 +116,7 @@ const removeWorktrees = async (branches: string[], worktreeDir: string): Promise
112
116
  for (const branch of branches) {
113
117
  try {
114
118
  const worktreePath = `${worktreeDir}/${branch}`
119
+
115
120
  await $`git worktree remove ${worktreePath}`
116
121
  removed.push(branch)
117
122
  } catch (error) {
package/src/entry/cli.ts CHANGED
@@ -132,8 +132,9 @@ program
132
132
  .description('Add git worktrees for release branches')
133
133
  .option('-y, --yes', 'Skip confirmation prompt')
134
134
  .option('-a, --all', 'Select all active release branches')
135
+ .option('-c, --cursor', 'Open created worktrees in Cursor')
135
136
  .action(async (options) => {
136
- await worktreesAdd({ confirmedCommand: options.yes, all: options.all })
137
+ await worktreesAdd({ confirmedCommand: options.yes, all: options.all, cursor: options.cursor })
137
138
  })
138
139
 
139
140
  program
@@ -32,7 +32,10 @@ export const getReleasePRs = async (): Promise<string[]> => {
32
32
  process.exit(1)
33
33
  }
34
34
 
35
- const headRefNames = releasePRsArray.map((pr) => pr.headRefName)
35
+ const headRefNames = releasePRsArray.map((pr) => {
36
+ return pr.headRefName
37
+ })
38
+
36
39
  return sortVersions(headRefNames)
37
40
  } catch (error) {
38
41
  logger.error({ error }, 'โŒ Error fetching release PRs')
@@ -148,7 +148,9 @@ const getProjectVersions = async (config: JiraConfig): Promise<JiraVersion[]> =>
148
148
  const findVersionByName = async (versionName: string, config: JiraConfig): Promise<JiraVersion | null> => {
149
149
  try {
150
150
  const versions = await getProjectVersions(config)
151
- const version = versions.find((v) => v.name === versionName)
151
+ const version = versions.find((v) => {
152
+ return v.name === versionName
153
+ })
152
154
 
153
155
  return version || null
154
156
  } catch (error) {
@@ -280,6 +282,7 @@ export const loadJiraConfig = async (): Promise<JiraConfig> => {
280
282
  const email = process.env.JIRA_EMAIL
281
283
 
282
284
  const missingVars: string[] = []
285
+
283
286
  if (!baseUrl) missingVars.push('JIRA_BASE_URL (e.g., https://your-domain.atlassian.net)')
284
287
  if (!token) missingVars.push('JIRA_TOKEN or JIRA_API_TOKEN (your Jira API token)')
285
288
  if (!projectIdStr) missingVars.push('JIRA_PROJECT_ID (numeric project ID)')
@@ -289,7 +292,9 @@ export const loadJiraConfig = async (): Promise<JiraConfig> => {
289
292
  const errorMessage = [
290
293
  'Jira configuration is required but incomplete.',
291
294
  'Please configure the following environment variables:',
292
- ...missingVars.map((v) => ` - ${v}`),
295
+ ...missingVars.map((v) => {
296
+ return ` - ${v}`
297
+ }),
293
298
  '',
294
299
  'You can set these in your .env file or as environment variables.',
295
300
  ].join('\n')
@@ -323,6 +328,7 @@ export const loadJiraConfigOptional = async (): Promise<JiraConfig | null> => {
323
328
  return config
324
329
  } catch (error) {
325
330
  logger.warn({ error }, 'Jira configuration not available, skipping Jira integration')
331
+
326
332
  return null
327
333
  }
328
334
  }
@@ -15,7 +15,9 @@ export const getCurrentWorktrees = async (type: 'release' | 'feature'): Promise<
15
15
  feature: featureWorktreePredicate,
16
16
  }
17
17
 
18
- return worktreeLines.map(worktreePredicateMap[type]).filter((branch) => branch !== null)
18
+ return worktreeLines.map(worktreePredicateMap[type]).filter((branch) => {
19
+ return branch !== null
20
+ })
19
21
  }
20
22
 
21
23
  const releaseWorktreePredicate = (line: string): string | null => {