infra-kit 0.1.68 โ†’ 0.1.71

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.71",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/cli.js",
7
7
  "module": "dist/cli.js",
@@ -35,8 +35,8 @@
35
35
  "@inquirer/select": "^5.0.4",
36
36
  "@modelcontextprotocol/sdk": "^1.26.0",
37
37
  "commander": "^14.0.3",
38
- "dotenv": "^17.2.3",
39
- "pino": "^10.3.0",
38
+ "dotenv": "^17.2.4",
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
 
@@ -41,10 +41,12 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
41
41
 
42
42
  selectedReleaseBranch = await select({
43
43
  message: '๐ŸŒฟ Select release branch',
44
- choices: releasePRsList.map((pr) => ({
45
- name: pr.replace('release/v', ''),
46
- value: pr,
47
- })),
44
+ choices: releasePRsList.map((pr) => {
45
+ return {
46
+ name: pr.replace('release/v', ''),
47
+ value: pr,
48
+ }
49
+ }),
48
50
  })
49
51
  }
50
52
 
@@ -67,10 +69,12 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
67
69
 
68
70
  selectedEnv = await select({
69
71
  message: '๐Ÿงช Select environment',
70
- choices: ENVs.map((env) => ({
71
- name: env,
72
- value: env,
73
- })),
72
+ choices: ENVs.map((env) => {
73
+ return {
74
+ name: env,
75
+ value: env,
76
+ }
77
+ }),
74
78
  })
75
79
  }
76
80
 
@@ -102,6 +106,7 @@ export const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<
102
106
  $.quiet = true
103
107
 
104
108
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
109
+
105
110
  await $`gh workflow run deploy-all.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${skipTerraformFlag}`
106
111
 
107
112
  $.quiet = false
@@ -46,10 +46,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
46
46
 
47
47
  selectedReleaseBranch = await select({
48
48
  message: '๐ŸŒฟ Select release branch',
49
- choices: releasePRsList.map((pr) => ({
50
- name: pr.replace('release/v', ''),
51
- value: pr,
52
- })),
49
+ choices: releasePRsList.map((pr) => {
50
+ return {
51
+ name: pr.replace('release/v', ''),
52
+ value: pr,
53
+ }
54
+ }),
53
55
  })
54
56
  }
55
57
 
@@ -72,10 +74,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
72
74
 
73
75
  selectedEnv = await select({
74
76
  message: '๐Ÿงช Select environment',
75
- choices: ENVs.map((env) => ({
76
- name: env,
77
- value: env,
78
- })),
77
+ choices: ENVs.map((env) => {
78
+ return {
79
+ name: env,
80
+ value: env,
81
+ }
82
+ }),
79
83
  })
80
84
  }
81
85
 
@@ -104,10 +108,12 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
104
108
 
105
109
  selectedServices = await checkbox({
106
110
  message: '๐Ÿš€ Select services to deploy (space to select, enter to confirm)',
107
- choices: availableServices.map((svc) => ({
108
- name: svc,
109
- value: svc,
110
- })),
111
+ choices: availableServices.map((svc) => {
112
+ return {
113
+ name: svc,
114
+ value: svc,
115
+ }
116
+ }),
111
117
  })
112
118
  }
113
119
 
@@ -119,7 +125,9 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
119
125
  }
120
126
 
121
127
  // Validate all selected services
122
- const invalidServices = selectedServices.filter((svc) => !availableServices.includes(svc))
128
+ const invalidServices = selectedServices.filter((svc) => {
129
+ return !availableServices.includes(svc)
130
+ })
123
131
 
124
132
  if (invalidServices.length > 0) {
125
133
  logger.error(
@@ -149,7 +157,9 @@ export const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs)
149
157
  $.quiet = true
150
158
 
151
159
  // Build the workflow command with boolean flags for each selected service
152
- const serviceFlags = selectedServices.flatMap((svc) => ['-f', `${svc}=true`])
160
+ const serviceFlags = selectedServices.flatMap((svc) => {
161
+ return ['-f', `${svc}=true`]
162
+ })
153
163
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
154
164
 
155
165
  await $`gh workflow run deploy-selected-services.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${serviceFlags} ${skipTerraformFlag}`
@@ -47,10 +47,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
47
47
 
48
48
  selectedReleaseBranch = await select({
49
49
  message: '๐ŸŒฟ Select release branch',
50
- choices: releasePRsList.map((pr) => ({
51
- name: pr.replace('release/v', ''),
52
- value: pr,
53
- })),
50
+ choices: releasePRsList.map((pr) => {
51
+ return {
52
+ name: pr.replace('release/v', ''),
53
+ value: pr,
54
+ }
55
+ }),
54
56
  })
55
57
  }
56
58
 
@@ -73,10 +75,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
73
75
 
74
76
  selectedEnv = await select({
75
77
  message: '๐Ÿงช Select environment',
76
- choices: ENVs.map((env) => ({
77
- name: env,
78
- value: env,
79
- })),
78
+ choices: ENVs.map((env) => {
79
+ return {
80
+ name: env,
81
+ value: env,
82
+ }
83
+ }),
80
84
  })
81
85
  }
82
86
 
@@ -99,10 +103,12 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
99
103
 
100
104
  selectedService = await select({
101
105
  message: '๐Ÿš€ Select service to deploy',
102
- choices: availableServices.map((svc) => ({
103
- name: svc,
104
- value: svc,
105
- })),
106
+ choices: availableServices.map((svc) => {
107
+ return {
108
+ name: svc,
109
+ value: svc,
110
+ }
111
+ }),
106
112
  })
107
113
  }
108
114
 
@@ -134,6 +140,7 @@ export const ghReleaseDeployService = async (args: GhReleaseDeployServiceArgs):
134
140
  $.quiet = true
135
141
 
136
142
  const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []
143
+
137
144
  await $`gh workflow run deploy-single-service.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} -f service=${selectedService} ${skipTerraformFlag}`
138
145
 
139
146
  $.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 => {
@@ -6,23 +6,25 @@ interface ToolHandlerArgs {
6
6
  handler: (params: any) => Promise<ToolsExecutionResult>
7
7
  }
8
8
 
9
- export const createToolHandler = (args: ToolHandlerArgs) => async (params: unknown) => {
10
- const { toolName, handler } = args
9
+ export const createToolHandler = (args: ToolHandlerArgs) => {
10
+ return async (params: unknown) => {
11
+ const { toolName, handler } = args
11
12
 
12
- logger.info({ msg: `Tool execution started: ${toolName}`, params })
13
- try {
14
- const payload = await handler({ ...(params as object), confirmedCommand: true })
13
+ logger.info({ msg: `Tool execution started: ${toolName}`, params })
14
+ try {
15
+ const payload = await handler({ ...(params as object), confirmedCommand: true })
15
16
 
16
- logger.info({ msg: `Tool execution successful: ${toolName}` })
17
+ logger.info({ msg: `Tool execution successful: ${toolName}` })
17
18
 
18
- return payload
19
- } catch (error) {
20
- logger.error({
21
- err: error,
22
- params,
23
- msg: `Tool execution failed: ${toolName}`,
24
- })
19
+ return payload
20
+ } catch (error) {
21
+ logger.error({
22
+ err: error,
23
+ params,
24
+ msg: `Tool execution failed: ${toolName}`,
25
+ })
25
26
 
26
- throw error
27
+ throw error
28
+ }
27
29
  }
28
30
  }
@@ -16,6 +16,7 @@ export const sortVersions = (versions: string[]): string[] => {
16
16
 
17
17
  if (majA !== majB) return (majA ?? 0) - (majB ?? 0)
18
18
  if (minA !== minB) return (minA ?? 0) - (minB ?? 0)
19
+
19
20
  return (patchA ?? 0) - (patchB ?? 0)
20
21
  })
21
22
  }