infra-kit 0.1.81 → 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/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "infra-kit",
3
3
  "type": "module",
4
- "version": "0.1.81",
4
+ "version": "0.1.82",
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
13
  "node": ">=20.x"
@@ -14,8 +14,8 @@ export const envList = async (): Promise<ToolsExecutionResult> => {
14
14
 
15
15
  const project = await getDopplerProject()
16
16
 
17
- logger.info(`Doppler Project: ${project}\n`)
18
- logger.info('Available Configs:')
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}`)
@@ -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 MARKER_COMMENT = '# infra-kit shell functions'
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 envInit = async (): Promise<void> => {
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
- const markerIdx = content.indexOf(MARKER_COMMENT)
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 (markerIdx === -1) return content
74
+ if (legacyIdx === -1) return content
44
75
 
45
76
  // eslint-disable-next-line sonarjs/slow-regex
46
- const before = content.slice(0, markerIdx).replace(/\n+$/, '')
47
- const afterLines = content.slice(markerIdx).split('\n')
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
- MARKER_COMMENT,
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('env-init')
191
- .description('Set up shell functions for env-load/env-clear in .zshrc')
192
+ .command('init')
193
+ .description('Inject shell integration into your profile .zshrc')
192
194
  .action(async () => {
193
- await envInit()
195
+ await init()
194
196
  })
195
197
 
196
198
  program
@@ -208,4 +210,65 @@ program
208
210
  await envClear()
209
211
  })
210
212
 
211
- program.parse()
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
  /**
@@ -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 env-init` first.')
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)
@@ -1 +0,0 @@
1
- export { envInit } from './env-init'