infra-kit 0.1.72 → 0.1.74

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.72",
4
+ "version": "0.1.74",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/cli.js",
7
7
  "module": "dist/cli.js",
@@ -30,9 +30,9 @@
30
30
  "fix": "pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"
31
31
  },
32
32
  "dependencies": {
33
- "@inquirer/checkbox": "^5.1.0",
34
- "@inquirer/confirm": "^6.0.8",
35
- "@inquirer/select": "^5.1.0",
33
+ "@inquirer/checkbox": "^5.1.2",
34
+ "@inquirer/confirm": "^6.0.10",
35
+ "@inquirer/select": "^5.1.2",
36
36
  "@modelcontextprotocol/sdk": "^1.27.1",
37
37
  "commander": "^14.0.3",
38
38
  "dotenv": "^17.3.1",
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@pkg/eslint-config": "workspace:*",
47
47
  "@pkg/vitest-config": "workspace:*",
48
- "esbuild": "^0.27.3",
48
+ "esbuild": "^0.27.4",
49
49
  "typescript": "^5.9.3"
50
50
  }
51
51
  }
@@ -0,0 +1,105 @@
1
+ import { z } from 'zod'
2
+ import { $ } from 'zx'
3
+
4
+ import { logger } from 'src/lib/logger'
5
+ import type { ToolsExecutionResult } from 'src/types'
6
+
7
+ interface CheckResult {
8
+ name: string
9
+ status: 'pass' | 'fail'
10
+ message: string
11
+ }
12
+
13
+ const checkCommand = async (
14
+ name: string,
15
+ command: string[],
16
+ successMsg: string,
17
+ failMsg: string,
18
+ ): Promise<CheckResult> => {
19
+ try {
20
+ await $`${command}`
21
+
22
+ return { name, status: 'pass', message: successMsg }
23
+ } catch {
24
+ return { name, status: 'fail', message: failMsg }
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Check installation and authentication status of gh and doppler CLIs
30
+ */
31
+ export const doctor = async (): Promise<ToolsExecutionResult> => {
32
+ const checks: CheckResult[] = await Promise.all([
33
+ checkCommand(
34
+ 'gh installed',
35
+ ['gh', '--version'],
36
+ 'GitHub CLI is installed',
37
+ 'GitHub CLI is not installed. Install from: https://cli.github.com/',
38
+ ),
39
+ checkCommand(
40
+ 'gh authenticated',
41
+ ['gh', 'auth', 'status'],
42
+ 'GitHub CLI is authenticated',
43
+ 'GitHub CLI is not authenticated. Run: gh auth login',
44
+ ),
45
+ checkCommand(
46
+ 'doppler installed',
47
+ ['doppler', '--version'],
48
+ 'Doppler CLI is installed',
49
+ 'Doppler CLI is not installed. Install from: https://docs.doppler.com/docs/install-cli',
50
+ ),
51
+ checkCommand(
52
+ 'doppler authenticated',
53
+ ['doppler', 'me'],
54
+ 'Doppler CLI is authenticated',
55
+ 'Doppler CLI is not authenticated. Run: doppler login',
56
+ ),
57
+ ])
58
+
59
+ logger.info('Doctor check results:\n')
60
+
61
+ for (const check of checks) {
62
+ const icon = check.status === 'pass' ? '[PASS]' : '[FAIL]'
63
+
64
+ logger.info(` ${icon} ${check.name}: ${check.message}`)
65
+ }
66
+
67
+ const structuredContent = {
68
+ checks: checks.map((c) => {
69
+ return { name: c.name, status: c.status, message: c.message }
70
+ }),
71
+ allPassed: checks.every((c) => {
72
+ return c.status === 'pass'
73
+ }),
74
+ }
75
+
76
+ return {
77
+ content: [
78
+ {
79
+ type: 'text',
80
+ text: JSON.stringify(structuredContent, null, 2),
81
+ },
82
+ ],
83
+ structuredContent,
84
+ }
85
+ }
86
+
87
+ // MCP Tool Registration
88
+ export const doctorMcpTool = {
89
+ name: 'doctor',
90
+ description: 'Check installation and authentication status of gh and doppler CLIs',
91
+ inputSchema: {},
92
+ outputSchema: {
93
+ checks: z
94
+ .array(
95
+ z.object({
96
+ name: z.string().describe('Name of the check'),
97
+ status: z.enum(['pass', 'fail']).describe('Check result'),
98
+ message: z.string().describe('Details about the check result'),
99
+ }),
100
+ )
101
+ .describe('List of all check results'),
102
+ allPassed: z.boolean().describe('Whether all checks passed'),
103
+ },
104
+ handler: doctor,
105
+ }
@@ -0,0 +1 @@
1
+ export { doctor, doctorMcpTool } from './doctor'
@@ -0,0 +1,99 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import process from 'node:process'
4
+ import { z } from 'zod'
5
+
6
+ import type { EnvCache } from 'src/lib/constants'
7
+ import {
8
+ ENV_CACHE_DIR,
9
+ ENV_CACHE_FILE,
10
+ INFRA_KIT_ENV_CONFIG_VAR,
11
+ INFRA_KIT_ENV_LOADED_AT_VAR,
12
+ INFRA_KIT_ENV_PROJECT_VAR,
13
+ } from 'src/lib/constants'
14
+ import { logger } from 'src/lib/logger'
15
+ import type { ToolsExecutionResult } from 'src/types'
16
+
17
+ /**
18
+ * Clear previously loaded environment variables. Usage: source <(infra-kit env-clear)
19
+ */
20
+ export const envClear = async (): Promise<ToolsExecutionResult> => {
21
+ const cachePath = path.join(ENV_CACHE_DIR, ENV_CACHE_FILE)
22
+
23
+ if (!process.env[INFRA_KIT_ENV_CONFIG_VAR]) {
24
+ logger.error('No loaded environment found. Run `env-load` first.')
25
+
26
+ return {
27
+ content: [
28
+ {
29
+ type: 'text',
30
+ text: 'No loaded environment found. Run `env-load` first.',
31
+ },
32
+ ],
33
+ }
34
+ }
35
+
36
+ const cache: EnvCache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'))
37
+ const varNames = cache.varNames
38
+
39
+ // Only unset vars that are actually set in the current session
40
+ const activeVars = varNames.filter((v) => {
41
+ return v in process.env
42
+ })
43
+
44
+ if (activeVars.length === 0) {
45
+ fs.unlinkSync(cachePath)
46
+ logger.info('Current session is clear, no environment variables to unset.')
47
+
48
+ return {
49
+ content: [
50
+ {
51
+ type: 'text',
52
+ text: 'Current session is clear, no environment variables to unset.',
53
+ },
54
+ ],
55
+ }
56
+ }
57
+
58
+ // Output unset statements for shell sourcing
59
+ for (const varName of activeVars) {
60
+ process.stdout.write(`unset ${varName}\n`)
61
+ }
62
+ process.stdout.write(`unset ${INFRA_KIT_ENV_CONFIG_VAR}\n`)
63
+ process.stdout.write(`unset ${INFRA_KIT_ENV_PROJECT_VAR}\n`)
64
+ process.stdout.write(`unset ${INFRA_KIT_ENV_LOADED_AT_VAR}\n`)
65
+
66
+ // Remove cache file
67
+ fs.unlinkSync(cachePath)
68
+
69
+ logger.info(`Cleared ${activeVars.length} environment variables`)
70
+
71
+ const structuredContent = {
72
+ variableCount: activeVars.length,
73
+ unsetStatements: activeVars.map((v) => {
74
+ return `unset ${v}`
75
+ }),
76
+ }
77
+
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: JSON.stringify(structuredContent, null, 2),
83
+ },
84
+ ],
85
+ structuredContent,
86
+ }
87
+ }
88
+
89
+ // MCP Tool Registration
90
+ export const envClearMcpTool = {
91
+ name: 'env-clear',
92
+ description: 'Clear previously loaded environment variables. Usage: source <(infra-kit env-clear)',
93
+ inputSchema: {},
94
+ outputSchema: {
95
+ variableCount: z.number().describe('Number of variables cleared'),
96
+ unsetStatements: z.array(z.string()).describe('Unset statements generated'),
97
+ },
98
+ handler: envClear,
99
+ }
@@ -0,0 +1 @@
1
+ export { envClear, envClearMcpTool } from './env-clear'
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod'
2
+
3
+ import { validateDopplerCliAndAuth } from 'src/integrations/doppler'
4
+ import { getDopplerProject } from 'src/integrations/doppler/doppler-project'
5
+ import { ENVs } from 'src/lib/constants'
6
+ import { logger } from 'src/lib/logger'
7
+ import type { ToolsExecutionResult } from 'src/types'
8
+
9
+ /**
10
+ * List available Doppler configs for the detected project
11
+ */
12
+ export const envList = async (): Promise<ToolsExecutionResult> => {
13
+ await validateDopplerCliAndAuth()
14
+
15
+ const project = await getDopplerProject()
16
+
17
+ logger.info(`Doppler Project: ${project}\n`)
18
+ logger.info('Available Configs:')
19
+
20
+ for (const env of ENVs) {
21
+ logger.info(` - ${env}`)
22
+ }
23
+
24
+ const structuredContent = {
25
+ project,
26
+ configs: ENVs,
27
+ }
28
+
29
+ return {
30
+ content: [
31
+ {
32
+ type: 'text',
33
+ text: JSON.stringify(structuredContent, null, 2),
34
+ },
35
+ ],
36
+ structuredContent,
37
+ }
38
+ }
39
+
40
+ // MCP Tool Registration
41
+ export const envListMcpTool = {
42
+ name: 'env-list',
43
+ description: 'List available Doppler configs for the detected project',
44
+ inputSchema: {},
45
+ outputSchema: {
46
+ project: z.string().describe('Detected Doppler project name'),
47
+ configs: z.array(z.string()).describe('Available environment configs'),
48
+ },
49
+ handler: envList,
50
+ }
@@ -0,0 +1 @@
1
+ export { envList, envListMcpTool } from './env-list'
@@ -0,0 +1,94 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import process from 'node:process'
4
+ import { z } from 'zod'
5
+ import { $ } from 'zx'
6
+
7
+ import { validateDopplerCliAndAuth } from 'src/integrations/doppler'
8
+ import { getDopplerProject } from 'src/integrations/doppler/doppler-project'
9
+ import type { EnvCache } from 'src/lib/constants'
10
+ import {
11
+ ENV_CACHE_DIR,
12
+ ENV_CACHE_FILE,
13
+ INFRA_KIT_ENV_CONFIG_VAR,
14
+ INFRA_KIT_ENV_LOADED_AT_VAR,
15
+ INFRA_KIT_ENV_PROJECT_VAR,
16
+ } from 'src/lib/constants'
17
+ import { logger } from 'src/lib/logger'
18
+ import type { ToolsExecutionResult } from 'src/types'
19
+
20
+ interface EnvLoadArgs {
21
+ config: string
22
+ }
23
+
24
+ /**
25
+ * Load environment variables from Doppler for the given config
26
+ */
27
+ export const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult> => {
28
+ await validateDopplerCliAndAuth()
29
+
30
+ const { config } = args
31
+
32
+ const project = await getDopplerProject()
33
+
34
+ const result = await $`doppler secrets download --no-file --format env --project ${project} --config ${config}`
35
+ const envContent = result.stdout.trim()
36
+
37
+ // Output shell-sourceable format
38
+ process.stdout.write('set -a\n')
39
+ process.stdout.write(`${envContent}\n`)
40
+ process.stdout.write('set +a\n')
41
+ process.stdout.write(`export ${INFRA_KIT_ENV_CONFIG_VAR}=${config}\n`)
42
+ process.stdout.write(`export ${INFRA_KIT_ENV_PROJECT_VAR}=${project}\n`)
43
+ process.stdout.write(`export ${INFRA_KIT_ENV_LOADED_AT_VAR}=${new Date().toISOString()}\n`)
44
+
45
+ // Extract variable names and save to cache
46
+ const varNames = envContent
47
+ .split('\n')
48
+ .filter((line) => {
49
+ return line.includes('=')
50
+ })
51
+ .map((line) => {
52
+ return line.split('=')[0]!
53
+ })
54
+
55
+ const cachePath = path.join(ENV_CACHE_DIR, ENV_CACHE_FILE)
56
+
57
+ const cache: EnvCache = { config, loadedAt: new Date().toISOString(), varNames }
58
+
59
+ fs.mkdirSync(ENV_CACHE_DIR, { recursive: true })
60
+ fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2))
61
+
62
+ logger.info(`Loaded ${varNames.length} variables from ${project}/${config}`)
63
+
64
+ const structuredContent = {
65
+ variableCount: varNames.length,
66
+ project,
67
+ config,
68
+ }
69
+
70
+ return {
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: JSON.stringify(structuredContent, null, 2),
75
+ },
76
+ ],
77
+ structuredContent,
78
+ }
79
+ }
80
+
81
+ // MCP Tool Registration
82
+ export const envLoadMcpTool = {
83
+ name: 'env-load',
84
+ description: 'Load environment variables from Doppler for a given config. Usage: source <(infra-kit env-load -c dev)',
85
+ inputSchema: {
86
+ config: z.string().describe('Environment config name to load (e.g. dev, arthur, renana)'),
87
+ },
88
+ outputSchema: {
89
+ variableCount: z.number().describe('Number of variables loaded'),
90
+ project: z.string().describe('Doppler project name'),
91
+ config: z.string().describe('Doppler config name'),
92
+ },
93
+ handler: envLoad,
94
+ }
@@ -0,0 +1 @@
1
+ export { envLoad, envLoadMcpTool } from './env-load'
@@ -0,0 +1,97 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import process from 'node:process'
4
+ import { z } from 'zod'
5
+
6
+ import { validateDopplerCliAndAuth } from 'src/integrations/doppler'
7
+ import { getDopplerProject } from 'src/integrations/doppler/doppler-project'
8
+ import type { EnvCache } from 'src/lib/constants'
9
+ import {
10
+ ENV_CACHE_DIR,
11
+ ENV_CACHE_FILE,
12
+ ENVs,
13
+ INFRA_KIT_ENV_CONFIG_VAR,
14
+ INFRA_KIT_ENV_LOADED_AT_VAR,
15
+ INFRA_KIT_ENV_PROJECT_VAR,
16
+ } from 'src/lib/constants'
17
+ import { logger } from 'src/lib/logger'
18
+ import type { ToolsExecutionResult } from 'src/types'
19
+
20
+ /**
21
+ * Show Doppler authentication status and detected project info
22
+ */
23
+ export const envStatus = async (): Promise<ToolsExecutionResult> => {
24
+ await validateDopplerCliAndAuth()
25
+
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(', ')}`)
32
+
33
+ // Check session-loaded vars
34
+ const cachePath = path.join(ENV_CACHE_DIR, ENV_CACHE_FILE)
35
+
36
+ let sessionLoadedCount = 0
37
+ let sessionTotalCount = 0
38
+ const sessionConfig = process.env[INFRA_KIT_ENV_CONFIG_VAR] ?? null
39
+ const sessionProject = process.env[INFRA_KIT_ENV_PROJECT_VAR] ?? null
40
+ const sessionLoadedAt = process.env[INFRA_KIT_ENV_LOADED_AT_VAR] ?? null
41
+
42
+ if (sessionConfig) {
43
+ if (fs.existsSync(cachePath)) {
44
+ const cache: EnvCache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'))
45
+
46
+ sessionTotalCount = cache.varNames.length
47
+ sessionLoadedCount = cache.varNames.filter((v) => {
48
+ return v in process.env
49
+ }).length
50
+ }
51
+
52
+ logger.info(
53
+ ` Session: ${sessionLoadedCount} of ${sessionTotalCount} vars loaded (project: ${sessionProject}, config: ${sessionConfig}, loaded at: ${sessionLoadedAt})`,
54
+ )
55
+ } else {
56
+ logger.info(' Session: no env loaded')
57
+ }
58
+
59
+ const structuredContent = {
60
+ authenticated: true,
61
+ project,
62
+ configs: ENVs,
63
+ sessionLoadedCount,
64
+ sessionTotalCount,
65
+ sessionConfig,
66
+ sessionProject,
67
+ sessionLoadedAt,
68
+ }
69
+
70
+ return {
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: JSON.stringify(structuredContent, null, 2),
75
+ },
76
+ ],
77
+ structuredContent,
78
+ }
79
+ }
80
+
81
+ // MCP Tool Registration
82
+ export const envStatusMcpTool = {
83
+ name: 'env-status',
84
+ description: 'Show Doppler authentication status and detected project info',
85
+ inputSchema: {},
86
+ outputSchema: {
87
+ authenticated: z.boolean().describe('Whether the user is authenticated'),
88
+ project: z.string().describe('Detected Doppler project name'),
89
+ configs: z.array(z.string()).describe('Available environment configs'),
90
+ sessionLoadedCount: z.number().describe('Number of cached vars active in the current session'),
91
+ sessionTotalCount: z.number().describe('Total number of cached var names'),
92
+ sessionConfig: z.string().nullable().describe('Doppler config name of the loaded session'),
93
+ sessionProject: z.string().nullable().describe('Doppler project name of the loaded session'),
94
+ sessionLoadedAt: z.string().nullable().describe('ISO 8601 timestamp of when the env was loaded'),
95
+ },
96
+ handler: envStatus,
97
+ }
@@ -0,0 +1 @@
1
+ export { envStatus, envStatusMcpTool } from './env-status'
package/src/entry/cli.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { Command } from 'commander'
2
2
 
3
+ import { doctor } from 'src/commands/doctor'
4
+ import { envClear } from 'src/commands/env-clear'
5
+ import { envList } from 'src/commands/env-list'
6
+ import { envLoad } from 'src/commands/env-load'
7
+ import { envStatus } from 'src/commands/env-status'
3
8
  // Commands
4
9
  import { ghMergeDev } from 'src/commands/gh-merge-dev'
5
10
  import { ghReleaseDeliver } from 'src/commands/gh-release-deliver'
@@ -13,8 +18,6 @@ import { worktreesAdd } from 'src/commands/worktrees-add'
13
18
  import { worktreesList } from 'src/commands/worktrees-list'
14
19
  import { worktreesRemove } from 'src/commands/worktrees-remove'
15
20
  import { worktreesSync } from 'src/commands/worktrees-sync'
16
- // Integrations
17
- import { validateGitHubCliAndAuth } from 'src/integrations/gh'
18
21
  import { loadEnvFromGitRoot } from 'src/lib/load-env'
19
22
 
20
23
  // Load .env before anything else
@@ -153,6 +156,40 @@ program
153
156
  await worktreesRemove({ confirmedCommand: options.yes, all: options.all })
154
157
  })
155
158
 
156
- await validateGitHubCliAndAuth()
159
+ program
160
+ .command('doctor')
161
+ .description('Check installation and authentication status of gh and doppler CLIs')
162
+ .action(async () => {
163
+ await doctor()
164
+ })
165
+
166
+ program
167
+ .command('env-status')
168
+ .description('Show Doppler authentication status and detected project info')
169
+ .action(async () => {
170
+ await envStatus()
171
+ })
172
+
173
+ program
174
+ .command('env-list')
175
+ .description('List available Doppler configs for the detected project')
176
+ .action(async () => {
177
+ await envList()
178
+ })
179
+
180
+ program
181
+ .command('env-load')
182
+ .description('Load environment variables from Doppler. Usage: source <(infra-kit env-load -c dev)')
183
+ .requiredOption('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')
184
+ .action(async (options) => {
185
+ await envLoad({ config: options.config })
186
+ })
187
+
188
+ program
189
+ .command('env-clear')
190
+ .description('Clear previously loaded environment variables. Usage: source <(infra-kit env-clear)')
191
+ .action(async () => {
192
+ await envClear()
193
+ })
157
194
 
158
195
  program.parse()
@@ -0,0 +1,25 @@
1
+ import process from 'node:process'
2
+ import { $ } from 'zx'
3
+
4
+ import { logger } from 'src/lib/logger'
5
+
6
+ /**
7
+ * Validate Doppler CLI installation and authentication status and throw an error if not valid
8
+ */
9
+ export const validateDopplerCliAndAuth = async () => {
10
+ try {
11
+ await $`doppler --version`
12
+ } catch (error: unknown) {
13
+ logger.error({ error }, 'Error: Doppler CLI is not installed.')
14
+ logger.error('Please install it from: https://docs.doppler.com/docs/install-cli')
15
+ process.exit(1)
16
+ }
17
+
18
+ try {
19
+ await $`doppler me`
20
+ } catch (error: unknown) {
21
+ logger.error({ error }, 'Error: Doppler CLI is not authenticated.')
22
+ logger.error('Please authenticate by running: doppler login')
23
+ process.exit(1)
24
+ }
25
+ }
@@ -0,0 +1,23 @@
1
+ import path from 'node:path'
2
+
3
+ import { DOPPLER_PROJECT_MAP } from 'src/lib/constants'
4
+ import { getProjectRoot } from 'src/lib/git-utils'
5
+
6
+ /**
7
+ * Resolve Doppler project name from the current working directory
8
+ */
9
+ export const getDopplerProject = async (): Promise<string> => {
10
+ const projectRoot = await getProjectRoot()
11
+
12
+ const dirName = path.basename(projectRoot)
13
+ const dopplerProject = DOPPLER_PROJECT_MAP[dirName]
14
+
15
+ if (!dopplerProject) {
16
+ throw new Error(
17
+ `Could not determine Doppler project for directory "${dirName}". ` +
18
+ `Expected one of: ${Object.keys(DOPPLER_PROJECT_MAP).join(', ')}`,
19
+ )
20
+ }
21
+
22
+ return dopplerProject
23
+ }
@@ -0,0 +1,2 @@
1
+ export { validateDopplerCliAndAuth } from './doppler-cli-auth'
2
+ export { getDopplerProject } from './doppler-project'
@@ -3,6 +3,24 @@
3
3
  */
4
4
  export const ENVs = ['dev', 'arthur', 'renana', 'roman', 'eliran', 'oriana']
5
5
 
6
+ export const DOPPLER_PROJECT_MAP: Record<string, string> = {
7
+ 'hulyo-monorepo': 'hulyo',
8
+ 'travelist-monorepo': 'travelist',
9
+ }
10
+
11
+ export const ENV_CACHE_DIR = './node_modules/.cache/infra-kit'
12
+ export const ENV_CACHE_FILE = 'env-cache.json'
13
+
14
+ export const INFRA_KIT_ENV_CONFIG_VAR = 'INFRA_KIT_ENV_CONFIG'
15
+ export const INFRA_KIT_ENV_PROJECT_VAR = 'INFRA_KIT_ENV_PROJECT'
16
+ export const INFRA_KIT_ENV_LOADED_AT_VAR = 'INFRA_KIT_ENV_LOADED_AT'
17
+
18
+ export interface EnvCache {
19
+ config: string
20
+ loadedAt: string
21
+ varNames: string[]
22
+ }
23
+
6
24
  export const WORKTREES_DIR_SUFFIX = '-worktrees'
7
25
  // eslint-disable-next-line sonarjs/publicly-writable-directories
8
26
  export const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'
@@ -15,6 +15,7 @@ export const loadEnvFromGitRoot = async (): Promise<void> => {
15
15
 
16
16
  const gitRoot = await getProjectRoot()
17
17
 
18
+ // TODO: remove this after new env managemement
18
19
  config({ path: resolve(gitRoot, '.env'), quiet: true })
19
20
 
20
21
  logger.info('Loaded .env file from git repository root')
@@ -1,5 +1,9 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2
2
 
3
+ import { envClearMcpTool } from 'src/commands/env-clear'
4
+ import { envListMcpTool } from 'src/commands/env-list'
5
+ import { envLoadMcpTool } from 'src/commands/env-load'
6
+ import { envStatusMcpTool } from 'src/commands/env-status'
3
7
  import { ghMergeDevMcpTool } from 'src/commands/gh-merge-dev'
4
8
  import { ghReleaseDeliverMcpTool } from 'src/commands/gh-release-deliver'
5
9
  import { ghReleaseDeployAllMcpTool } from 'src/commands/gh-release-deploy-all'
@@ -15,6 +19,10 @@ import { worktreesSyncMcpTool } from 'src/commands/worktrees-sync'
15
19
  import { createToolHandler } from 'src/lib/tool-handler'
16
20
 
17
21
  const tools = [
22
+ envStatusMcpTool,
23
+ envListMcpTool,
24
+ envLoadMcpTool,
25
+ envClearMcpTool,
18
26
  ghMergeDevMcpTool,
19
27
  releaseCreateMcpTool,
20
28
  releaseCreateBatchMcpTool,