infra-kit 0.1.75 → 0.1.76
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/dist/cli.js +28 -28
- package/dist/cli.js.map +3 -3
- package/dist/mcp.js +28 -28
- package/dist/mcp.js.map +3 -3
- package/package.json +1 -1
- package/src/commands/env-clear/env-clear.ts +4 -5
- package/src/commands/env-init/env-init.ts +5 -19
- package/src/commands/env-load/env-load.ts +17 -15
- package/src/commands/env-status/env-status.ts +2 -15
- package/src/entry/cli.ts +3 -4
- package/src/lib/constants.ts +7 -3
package/package.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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 = (
|
|
73
|
-
const runCmd =
|
|
58
|
+
const buildShellBlock = (): string => {
|
|
59
|
+
const runCmd = 'pnpm dlx 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
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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) =>
|
|
84
|
-
|
|
85
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
189
|
+
await envLoad({ config: options.config })
|
|
191
190
|
})
|
|
192
191
|
|
|
193
192
|
program
|
|
194
193
|
.command('env-clear')
|
|
195
|
-
.description('Clear
|
|
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
|
})
|
package/src/lib/constants.ts
CHANGED
|
@@ -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.
|
|
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) =>
|
|
32
|
-
|
|
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 => {
|