infra-kit 0.1.75 → 0.1.77

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.75",
4
+ "version": "0.1.77",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/cli.js",
7
7
  "module": "dist/cli.js",
@@ -6,17 +6,17 @@ import { z } from 'zod'
6
6
  import {
7
7
  ENV_CLEAR_FILE,
8
8
  ENV_LOAD_FILE,
9
- getSessionCacheDir,
10
9
  INFRA_KIT_ENV_CONFIG_VAR,
11
10
  INFRA_KIT_ENV_LOADED_AT_VAR,
12
11
  INFRA_KIT_ENV_PROJECT_VAR,
12
+ getSessionCacheDir,
13
13
  parseVarNamesFromEnvFile,
14
14
  } from 'src/lib/constants'
15
15
  import { logger } from 'src/lib/logger'
16
16
  import type { ToolsExecutionResult } from 'src/types'
17
17
 
18
18
  /**
19
- * Clear previously loaded environment variables. Usage: env-clear (after running eval "$(infra-kit env-init)" in shell)
19
+ * Clear loaded env vars. Prints a file path to stdout that must be sourced to apply. The env-clear shell alias does this automatically.
20
20
  */
21
21
  export const envClear = async (): Promise<ToolsExecutionResult> => {
22
22
  const cacheDir = getSessionCacheDir()
@@ -59,8 +59,6 @@ export const envClear = async (): Promise<ToolsExecutionResult> => {
59
59
  // Remove env load file so env-clear can detect "no env loaded" next time
60
60
  fs.unlinkSync(envLoadPath)
61
61
 
62
- logger.info(`Cleared ${varNames.length} environment variables`)
63
-
64
62
  const structuredContent = {
65
63
  variableCount: varNames.length,
66
64
  unsetStatements: unsetLines,
@@ -81,9 +79,10 @@ export const envClear = async (): Promise<ToolsExecutionResult> => {
81
79
  export const envClearMcpTool = {
82
80
  name: 'env-clear',
83
81
  description:
84
- 'Clear previously loaded environment variables. Usage: env-clear (after running eval "$(infra-kit env-init)" in shell)',
82
+ 'Clear loaded env vars. Returns a file path that must be sourced (source <path>) to apply. The env-clear shell alias does this automatically.',
85
83
  inputSchema: {},
86
84
  outputSchema: {
85
+ filePath: z.string().describe('Path to the file that must be sourced to apply'),
87
86
  variableCount: z.number().describe('Number of variables cleared'),
88
87
  unsetStatements: z.array(z.string()).describe('Unset statements generated'),
89
88
  },
@@ -1,7 +1,6 @@
1
1
  import fs from 'node:fs'
2
2
  import os from 'node:os'
3
3
  import path from 'node:path'
4
- import process from 'node:process'
5
4
 
6
5
  import { logger } from 'src/lib/logger'
7
6
 
@@ -12,15 +11,7 @@ const MARKER_COMMENT = '# infra-kit shell functions'
12
11
  */
13
12
  export const envInit = async (): Promise<void> => {
14
13
  const zshrcPath = path.join(os.homedir(), '.zshrc')
15
- const binPath = getBinPath()
16
-
17
- if (!fs.existsSync(binPath)) {
18
- logger.error(`Could not find infra-kit binary at ${binPath}`)
19
-
20
- return
21
- }
22
-
23
- const shellBlock = buildShellBlock(binPath)
14
+ const shellBlock = buildShellBlock()
24
15
 
25
16
  if (fs.existsSync(zshrcPath)) {
26
17
  const content = fs.readFileSync(zshrcPath, 'utf-8')
@@ -34,11 +25,6 @@ export const envInit = async (): Promise<void> => {
34
25
  logger.info('Run `source ~/.zshrc` or open a new terminal to activate.')
35
26
  }
36
27
 
37
- const getBinPath = (): string => {
38
- // resolve the absolute path to the infra-kit binary
39
- return path.resolve(path.join(path.dirname(process.argv[1]!), 'cli.js'))
40
- }
41
-
42
28
  const isBlockLine = (line: string): boolean => {
43
29
  return (
44
30
  line.startsWith('#') ||
@@ -69,15 +55,15 @@ const removeExistingBlock = (content: string): string => {
69
55
  return before + (remaining ? `\n${remaining}` : '')
70
56
  }
71
57
 
72
- const buildShellBlock = (binPath: string): string => {
73
- const runCmd = `node ${binPath}`
58
+ const buildShellBlock = (): string => {
59
+ const runCmd = 'pnpm exec infra-kit'
74
60
 
75
61
  return [
76
62
  MARKER_COMMENT,
77
63
  'if [[ -z "${INFRA_KIT_SESSION}" ]]; then',
78
64
  ' export INFRA_KIT_SESSION=$(head -c 4 /dev/urandom | xxd -p)',
79
65
  'fi',
80
- `env-load() { local f; f=$(${runCmd} env-load "$@") && source "$f"; }`,
81
- `env-clear() { local f; f=$(${runCmd} env-clear) && source "$f"; }`,
66
+ `env-load() { local f; f=$(${runCmd} env-load "$@") && source "$f" && ${runCmd} env-status; }`,
67
+ `env-clear() { local f; f=$(${runCmd} env-clear) && source "$f" && ${runCmd} env-status; }`,
82
68
  ].join('\n')
83
69
  }
@@ -16,12 +16,10 @@ import {
16
16
  INFRA_KIT_ENV_PROJECT_VAR,
17
17
  getSessionCacheDir,
18
18
  } from 'src/lib/constants'
19
- import { logger } from 'src/lib/logger'
20
19
  import type { ToolsExecutionResult } from 'src/types'
21
20
 
22
21
  interface EnvLoadArgs {
23
22
  config?: string
24
- quiet?: boolean
25
23
  }
26
24
 
27
25
  /**
@@ -30,7 +28,7 @@ interface EnvLoadArgs {
30
28
  export const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult> => {
31
29
  await validateDopplerCliAndAuth()
32
30
 
33
- const { config, quiet } = args
31
+ const { config } = args
34
32
 
35
33
  commandEcho.start('env-load')
36
34
 
@@ -40,12 +38,17 @@ export const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult>
40
38
  selectedConfig = config
41
39
  } else {
42
40
  commandEcho.setInteractive()
43
- selectedConfig = await select({
44
- message: 'Select environment config',
45
- choices: ENVs.map((env) => {
46
- return { name: env, value: env }
47
- }),
48
- })
41
+ selectedConfig = await select(
42
+ {
43
+ message: 'Select environment config',
44
+ choices: ENVs.map((env) => {
45
+ return { name: env, value: env }
46
+ }),
47
+ },
48
+ // Render to stderr so the prompt is visible when stdout is captured via $() in the shell function.
49
+ // Only env-load and env-clear use the $() stdout-capture shell pattern.
50
+ { output: process.stderr },
51
+ )
49
52
  }
50
53
 
51
54
  commandEcho.addOption('--config', selectedConfig)
@@ -80,11 +83,9 @@ export const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult>
80
83
  // REQUIRED
81
84
  process.stdout.write(`${envFilePath}\n`)
82
85
 
83
- const varCount = envContent.split('\n').filter((line) => line.includes('=')).length
84
-
85
- if (!quiet) {
86
- logger.info(`Loaded ${varCount} variables from ${project}/${selectedConfig}`)
87
- }
86
+ const varCount = envContent.split('\n').filter((line) => {
87
+ return line.includes('=')
88
+ }).length
88
89
 
89
90
  const structuredContent = {
90
91
  variableCount: varCount,
@@ -107,11 +108,12 @@ export const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult>
107
108
  export const envLoadMcpTool = {
108
109
  name: 'env-load',
109
110
  description:
110
- 'Load environment variables from Doppler for a given config. Usage: env-load -c dev (after running eval "$(infra-kit env-init)" in shell)',
111
+ 'Load Doppler env vars for a config. Returns a file path that must be sourced (source <path>) to apply variables. The env-load shell alias does this automatically.',
111
112
  inputSchema: {
112
113
  config: z.string().describe('Environment config name to load (e.g. dev, arthur, renana)'),
113
114
  },
114
115
  outputSchema: {
116
+ filePath: z.string().describe('Path to the file that must be sourced to apply variables'),
115
117
  variableCount: z.number().describe('Number of variables loaded'),
116
118
  project: z.string().describe('Doppler project name'),
117
119
  config: z.string().describe('Doppler config name'),
@@ -3,10 +3,8 @@ import process from 'node:process'
3
3
  import { z } from 'zod'
4
4
 
5
5
  import { validateDopplerCliAndAuth } from 'src/integrations/doppler'
6
- import { getDopplerProject } from 'src/integrations/doppler/doppler-project'
7
6
  import {
8
7
  ENV_LOAD_FILE,
9
- ENVs,
10
8
  INFRA_KIT_ENV_CONFIG_VAR,
11
9
  INFRA_KIT_ENV_LOADED_AT_VAR,
12
10
  INFRA_KIT_ENV_PROJECT_VAR,
@@ -23,12 +21,7 @@ import type { ToolsExecutionResult } from 'src/types'
23
21
  export const envStatus = async (): Promise<ToolsExecutionResult> => {
24
22
  await validateDopplerCliAndAuth()
25
23
 
26
- const project = await getDopplerProject()
27
-
28
- logger.info('Doppler Environment Status:\n')
29
- logger.info(` Authenticated: yes`)
30
- logger.info(` Detected Project: ${project}`)
31
- logger.info(` Available Configs: ${ENVs.join(', ')}`)
24
+ logger.info('Environment Session Status:\n')
32
25
 
33
26
  // Check session-loaded vars — getSessionCacheDir() throws if INFRA_KIT_SESSION is unset
34
27
  const cacheDir = getSessionCacheDir()
@@ -55,15 +48,12 @@ export const envStatus = async (): Promise<ToolsExecutionResult> => {
55
48
  logger.info(
56
49
  ` Session: ${sessionLoadedCount} of ${sessionTotalCount} vars loaded (project: ${sessionProject}, config: ${sessionConfig}, loaded at: ${sessionLoadedAt})`,
57
50
  )
58
- logger.info(` Session ID: ${sessionId}`)
59
51
  } else {
60
52
  logger.info(' Session: no env loaded')
61
53
  }
54
+ logger.info(` Session ID: ${sessionId}`)
62
55
 
63
56
  const structuredContent = {
64
- authenticated: true,
65
- project,
66
- configs: ENVs,
67
57
  sessionId,
68
58
  sessionLoadedCount,
69
59
  sessionTotalCount,
@@ -89,9 +79,6 @@ export const envStatusMcpTool = {
89
79
  description: 'Show Doppler authentication status and detected project info',
90
80
  inputSchema: {},
91
81
  outputSchema: {
92
- authenticated: z.boolean().describe('Whether the user is authenticated'),
93
- project: z.string().describe('Detected Doppler project name'),
94
- configs: z.array(z.string()).describe('Available environment configs'),
95
82
  sessionId: z.string().describe('Current terminal session ID'),
96
83
  sessionLoadedCount: z.number().describe('Number of cached vars active in the current session'),
97
84
  sessionTotalCount: z.number().describe('Total number of cached var names'),
package/src/entry/cli.ts CHANGED
@@ -183,16 +183,15 @@ program
183
183
 
184
184
  program
185
185
  .command('env-load')
186
- .description('Load environment variables from Doppler. Usage: env-load -c dev (after shell init)')
186
+ .description('Load Doppler env vars for a config. Prints a file path to stdout — auto-sourced by the env-load shell alias, or run source <path> manually')
187
187
  .option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')
188
- .option('-q, --quiet', 'Suppress info logging')
189
188
  .action(async (options) => {
190
- await envLoad({ config: options.config, quiet: options.quiet })
189
+ await envLoad({ config: options.config })
191
190
  })
192
191
 
193
192
  program
194
193
  .command('env-clear')
195
- .description('Clear previously loaded environment variables. Usage: env-clear (after shell init)')
194
+ .description('Clear loaded env vars. Prints a file path to stdout — auto-sourced by the env-clear shell alias, or run source <path> manually')
196
195
  .action(async () => {
197
196
  await envClear()
198
197
  })
@@ -13,7 +13,7 @@ export const DOPPLER_PROJECT_MAP: Record<string, string> = {
13
13
  }
14
14
 
15
15
  export const ENV_CACHE_DIR = './node_modules/.cache/infra-kit'
16
- export const ENV_LOAD_FILE = 'env-load.env'
16
+ export const ENV_LOAD_FILE = 'env-load.sh'
17
17
  export const ENV_CLEAR_FILE = 'env-clear.sh'
18
18
 
19
19
  export const INFRA_KIT_SESSION_VAR = 'INFRA_KIT_SESSION'
@@ -28,8 +28,12 @@ export const parseVarNamesFromEnvFile = (filePath: string): string[] => {
28
28
 
29
29
  return content
30
30
  .split('\n')
31
- .filter((line) => line.includes('=') && !line.startsWith('set '))
32
- .map((line) => line.split('=')[0]!)
31
+ .filter((line) => {
32
+ return line.includes('=') && !line.startsWith('set ')
33
+ })
34
+ .map((line) => {
35
+ return line.split('=')[0]!
36
+ })
33
37
  }
34
38
 
35
39
  export const getSessionCacheDir = (): string => {