infra-kit 0.1.81 → 0.1.85
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/.eslintcache +1 -0
- package/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-eslint-check.log +5 -0
- package/.turbo/turbo-prettier-check.log +5 -0
- package/.turbo/turbo-test.log +17 -0
- package/.turbo/turbo-ts-check.log +5 -0
- package/dist/cli.js +31 -27
- package/dist/cli.js.map +4 -4
- package/dist/mcp.js +22 -19
- package/dist/mcp.js.map +3 -3
- package/package.json +12 -12
- package/src/commands/env-list/env-list.ts +2 -2
- package/src/commands/gh-merge-dev/gh-merge-dev.ts +2 -2
- package/src/commands/init/index.ts +1 -0
- package/src/commands/{env-init/env-init.ts → init/init.ts} +40 -7
- package/src/entry/cli.ts +68 -5
- package/src/lib/command-echo/command-echo.ts +2 -3
- package/src/lib/constants.ts +1 -1
- package/src/lib/release-utils/release-utils.ts +2 -1
- package/src/mcp/server.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -0
- package/.env.example +0 -17
- package/src/commands/env-init/index.ts +0 -1
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "infra-kit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.85",
|
|
5
5
|
"description": "infra-kit",
|
|
6
6
|
"main": "dist/cli.js",
|
|
7
7
|
"module": "dist/cli.js",
|
|
8
8
|
"bin": {
|
|
9
|
-
"infra-kit": "dist/cli.js"
|
|
9
|
+
"infra-kit": "dist/cli.js",
|
|
10
|
+
"ik": "dist/cli.js"
|
|
10
11
|
},
|
|
11
12
|
"engines": {
|
|
12
|
-
"node": ">=
|
|
13
|
+
"node": ">=24.x"
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
15
16
|
"inspector": "npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug",
|
|
16
17
|
"build": "pnpm run clean-artifacts && node ./scripts/build.js",
|
|
17
|
-
"clean-artifacts": "
|
|
18
|
-
"clean-cache": "
|
|
18
|
+
"clean-artifacts": "rm -rf dist",
|
|
19
|
+
"clean-cache": "rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc",
|
|
19
20
|
"prettier-fix": "pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../.prettierignore",
|
|
20
21
|
"prettier-check": "pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../.prettierignore",
|
|
21
22
|
"eslint-check": "pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src",
|
|
22
23
|
"eslint-fix": "pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix",
|
|
23
24
|
"ts-check": "tsc --noEmit",
|
|
24
|
-
"ts-report": "rimraf .coverage/typescript && mkdir -p .coverage/typescript && typescript-coverage-report -s -t 95 -o .coverage/typescript",
|
|
25
25
|
"test": "pnpm exec vitest run --reporter=dot",
|
|
26
26
|
"test-watch": "pnpm exec vitest --watch",
|
|
27
27
|
"test-ui": "pnpm exec vitest --ui",
|
|
@@ -30,21 +30,21 @@
|
|
|
30
30
|
"fix": "pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@inquirer/checkbox": "^5.1.
|
|
34
|
-
"@inquirer/confirm": "^6.0.
|
|
35
|
-
"@inquirer/select": "^5.1.
|
|
36
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
33
|
+
"@inquirer/checkbox": "^5.1.3",
|
|
34
|
+
"@inquirer/confirm": "^6.0.11",
|
|
35
|
+
"@inquirer/select": "^5.1.3",
|
|
36
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
37
|
"commander": "^14.0.3",
|
|
38
38
|
"pino": "^10.3.1",
|
|
39
39
|
"pino-pretty": "^13.1.3",
|
|
40
|
-
"yaml": "^2.8.
|
|
40
|
+
"yaml": "^2.8.3",
|
|
41
41
|
"zod": "^3.25.76",
|
|
42
42
|
"zx": "^8.8.5"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@pkg/eslint-config": "workspace:*",
|
|
46
46
|
"@pkg/vitest-config": "workspace:*",
|
|
47
|
-
"esbuild": "^0.
|
|
47
|
+
"esbuild": "^0.28.0",
|
|
48
48
|
"typescript": "^5.9.3"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -14,8 +14,8 @@ export const envList = async (): Promise<ToolsExecutionResult> => {
|
|
|
14
14
|
|
|
15
15
|
const project = await getDopplerProject()
|
|
16
16
|
|
|
17
|
-
logger.info(`Doppler
|
|
18
|
-
logger.info('Available
|
|
17
|
+
logger.info(`Doppler project: ${project}\n`)
|
|
18
|
+
logger.info('Available configs:')
|
|
19
19
|
|
|
20
20
|
for (const env of ENVs) {
|
|
21
21
|
logger.info(` - ${env}`)
|
|
@@ -129,14 +129,14 @@ export const ghMergeDev = async (args: GhMergeDevArgs): Promise<ToolsExecutionRe
|
|
|
129
129
|
logger.info('📋 Manual merge script for failed branches:')
|
|
130
130
|
for (const branch of failedBranches) {
|
|
131
131
|
logger.info(
|
|
132
|
-
`# Merge dev into ${branch} and resolve conflicts if any \ngit switch ${branch} && git pull origin ${branch} && git merge origin/dev\ngit push origin ${branch} && git switch dev\n`,
|
|
132
|
+
`# Merge dev into ${branch} and resolve conflicts if any \n\ngit switch ${branch} && git pull origin ${branch} && git merge origin/dev\ngit push origin ${branch} && git switch dev\n`,
|
|
133
133
|
)
|
|
134
134
|
}
|
|
135
135
|
logger.info(
|
|
136
136
|
`✅ ${selectedReleaseBranches.length - failedBranches.length}/${selectedReleaseBranches.length} merges completed successfully.`,
|
|
137
137
|
)
|
|
138
138
|
} else {
|
|
139
|
-
logger.info('✅ All merges completed successfully
|
|
139
|
+
logger.info('✅ All merges completed successfully!\n')
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
commandEcho.print()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { init } from './init'
|
|
@@ -4,12 +4,16 @@ import path from 'node:path'
|
|
|
4
4
|
|
|
5
5
|
import { logger } from 'src/lib/logger'
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const MARKER_START = '# -- infra-kit:begin --'
|
|
8
|
+
const MARKER_END = '# -- infra-kit:end --'
|
|
9
|
+
|
|
10
|
+
const LEGACY_PAIRED: [start: string, end: string][] = [['# region infra-kit', '# endregion infra-kit']]
|
|
11
|
+
const LEGACY_SINGLE = '# infra-kit shell functions'
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* Append infra-kit shell functions directly to .zshrc.
|
|
11
15
|
*/
|
|
12
|
-
export const
|
|
16
|
+
export const init = async (): Promise<void> => {
|
|
13
17
|
const zshrcPath = path.join(os.homedir(), '.zshrc')
|
|
14
18
|
const shellBlock = buildShellBlock()
|
|
15
19
|
|
|
@@ -28,6 +32,7 @@ export const envInit = async (): Promise<void> => {
|
|
|
28
32
|
const isBlockLine = (line: string): boolean => {
|
|
29
33
|
return (
|
|
30
34
|
line.startsWith('#') ||
|
|
35
|
+
line.startsWith('alias ') ||
|
|
31
36
|
line.startsWith('env-load') ||
|
|
32
37
|
line.startsWith('env-clear') ||
|
|
33
38
|
line.startsWith('env-status') ||
|
|
@@ -37,14 +42,40 @@ const isBlockLine = (line: string): boolean => {
|
|
|
37
42
|
)
|
|
38
43
|
}
|
|
39
44
|
|
|
45
|
+
const removeBetween = (content: string, start: string, end: string): string | null => {
|
|
46
|
+
const startIdx = content.indexOf(start)
|
|
47
|
+
const endIdx = content.indexOf(end)
|
|
48
|
+
|
|
49
|
+
if (startIdx === -1 || endIdx === -1) return null
|
|
50
|
+
|
|
51
|
+
// eslint-disable-next-line sonarjs/slow-regex
|
|
52
|
+
const before = content.slice(0, startIdx).replace(/\n+$/, '')
|
|
53
|
+
const after = content.slice(endIdx + end.length).replace(/^\n+/, '')
|
|
54
|
+
|
|
55
|
+
return before + (after ? `\n${after}` : '')
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
const removeExistingBlock = (content: string): string => {
|
|
41
|
-
|
|
59
|
+
// 1. Current markers
|
|
60
|
+
const result = removeBetween(content, MARKER_START, MARKER_END)
|
|
61
|
+
|
|
62
|
+
if (result !== null) return result
|
|
63
|
+
|
|
64
|
+
// 2. Legacy paired markers (# region / # endregion)
|
|
65
|
+
for (const [start, end] of LEGACY_PAIRED) {
|
|
66
|
+
const legacyResult = removeBetween(content, start, end)
|
|
67
|
+
|
|
68
|
+
if (legacyResult !== null) return legacyResult
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 3. Oldest format: single marker + heuristic scan
|
|
72
|
+
const legacyIdx = content.indexOf(LEGACY_SINGLE)
|
|
42
73
|
|
|
43
|
-
if (
|
|
74
|
+
if (legacyIdx === -1) return content
|
|
44
75
|
|
|
45
76
|
// eslint-disable-next-line sonarjs/slow-regex
|
|
46
|
-
const before = content.slice(0,
|
|
47
|
-
const afterLines = content.slice(
|
|
77
|
+
const before = content.slice(0, legacyIdx).replace(/\n+$/, '')
|
|
78
|
+
const afterLines = content.slice(legacyIdx).split('\n')
|
|
48
79
|
|
|
49
80
|
let i = 0
|
|
50
81
|
|
|
@@ -61,7 +92,7 @@ const buildShellBlock = (): string => {
|
|
|
61
92
|
const runCmd = 'pnpm exec infra-kit'
|
|
62
93
|
|
|
63
94
|
return [
|
|
64
|
-
|
|
95
|
+
MARKER_START,
|
|
65
96
|
// eslint-disable-next-line no-template-curly-in-string
|
|
66
97
|
'if [[ -z "${INFRA_KIT_SESSION}" ]]; then',
|
|
67
98
|
' export INFRA_KIT_SESSION=$(head -c 4 /dev/urandom | xxd -p)',
|
|
@@ -69,5 +100,7 @@ const buildShellBlock = (): string => {
|
|
|
69
100
|
`env-load() { local f; f=$(${runCmd} env-load "$@") && source "$f" && ${runCmd} env-status; }`,
|
|
70
101
|
`env-clear() { local f; f=$(${runCmd} env-clear) && source "$f" && ${runCmd} env-status; }`,
|
|
71
102
|
`env-status() { ${runCmd} env-status; }`,
|
|
103
|
+
`alias ik='${runCmd}'`,
|
|
104
|
+
MARKER_END,
|
|
72
105
|
].join('\n')
|
|
73
106
|
}
|
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
|
+
}
|
|
@@ -55,13 +55,12 @@ const createCommandEcho = () => {
|
|
|
55
55
|
return `${opt.flag} "${opt.value.join(', ')}"`
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
return `${opt.flag} ${opt.value}`
|
|
58
|
+
return `${opt.flag} "${opt.value}"`
|
|
59
59
|
})
|
|
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)
|
|
@@ -111,8 +111,9 @@ export const getJiraDescriptions = async (): Promise<Map<string, string>> => {
|
|
|
111
111
|
*/
|
|
112
112
|
export const formatVersionLabel = (version: string, type: ReleaseType, maxVersionLength?: number): string => {
|
|
113
113
|
const padding = maxVersionLength ? ' '.repeat(maxVersionLength - version.length + 3) : ' '
|
|
114
|
+
const tag = `[${type}]`.padEnd(11)
|
|
114
115
|
|
|
115
|
-
return `${version}${padding}
|
|
116
|
+
return `${version}${padding}${tag}`
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
/**
|